/// <summary> /// Update depiction style /// </summary> /// <param name="psc"></param> public void UpdateDepictions(ParsedStructureCriteria psc) { SmallWorldPredefinedParameters swp = psc.SmallWorldParameters; // new values if (Qm == null || Qm.ResultsFormatter == null || Qm.ResultsFormatter.StructureHighlightPssc == null || Qm.ResultsFormatter.StructureHighlightPssc.SmallWorldParameters == null) { return; } ResultsFormatter fmtr = Qm.ResultsFormatter; SmallWorldPredefinedParameters swp2 = // current view values fmtr.StructureHighlightPssc.SmallWorldParameters; psc.Highlight = swp2.Highlight = swp.Highlight; psc.Align = swp2.Align = swp.Align; int i = SmallWorldData.GetSvgOptionsIndex(swp2.Highlight, swp2.Align); SmallWorldDepictions d = fmtr.SmallWorldDepictions; if ((swp.Highlight || swp.Align) && d != null && i != 0 && d.SvgDict[i] == null) // need to start retrieval for depiction type we don't alread have? { d.StartDepictionRetrieval(Qm, psc.QueryColumn, swp2.Highlight, swp2.Align); return; // leave display as is for now } else // clear current decpiction so new one shows { Qm.DataTableManager.ResetFormattedValues(psc.QueryColumn); // clear existing bitmaps Qm.MoleculeGrid.RefreshDataSource(); } return; }
/// <summary> /// Scale and translate structure and format into buffer /// </summary> /// <param name="mol">The structure</param> /// <param name="cellStyle">Style/conditional formatting to apply to cell</param> /// <param name="commandChar">Command character to use in buffer</param> /// <param name="x">Coordinate of left side of structure</param> /// <param name="width">Width of molecule box in milliinches</param> /// <param name="r">Row in buffer to put on. If less than 0 then return formatted data</param> /// <param name="heightInLines">number of lines used</param> public FormattedFieldInfo FormatStructure( MoleculeMx mol, CellStyleMx cellStyle, char commandChar, int x, int width, int r, ResultsField rfld = null, DataRowMx dataRow = null) { Rectangle destRect, boundingRect; int height; // formatted height in milliinches bool markBoundaries; int fixedHeight; Bitmap bm; Font font; string txt, molfile, molString = "", svg, cid = null; int translateType, desiredBondLength = 100; int pixWidth = 0, pixHeight = 0; bool debug = DataTableManager.DebugDetails; if (debug) { DebugLog.Message("=============================== FormattingStructure ==============================="); } PerformanceTimer pt = PT.Start("FormatStructure"); Stopwatch swTotal = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew(); try { MoleculeFormat initialCsType = mol.PrimaryFormat; string initialCsValue = mol.PrimaryValue; QueryColumn qc = (rfld != null) ? rfld.QueryColumn : null; FormattedFieldInfo ffi = new FormattedFieldInfo(); if (dataRow != null) // get any cid in row { int ki = DataTableManager.DefaultKeyValueVoPos; if (ki < dataRow.Length) { cid = dataRow[ki] as string; } } //DebugLog.Message("FormatStructure " + cid); //if (!Rf.Grid) x = x; // debug /////////////////////////////////// // Highlight structure /////////////////////////////////// if (StructureHighlightPssc != null) { ParsedStructureCriteria pssc = StructureHighlightPssc; // Hilight substructure search match if (pssc.SearchType == StructureSearchType.Substructure || // regular SSS pssc.SearchTypeUnion == StructureSearchType.Substructure) // handles related search for just SSS to get hilighting { if (HighlightStructureMatches) { try { mol = StrMatcher.HighlightMatchingSubstructure(mol); if (DebugMx.False) // debug { //string highlightChildren = mol.MolLib.HighlightChildren; //Color highlightColor = mol.MolLib.HighlightColor; if (debug) { DebugLog.StopwatchMessage("tHilight", sw); } } } catch (Exception ex) { ex = ex; } } if (AlignStructureToQuery) { try { mol = StrMatcher.AlignToMatchingSubstructure(mol); if (debug) { DebugLog.StopwatchMessage("tOrient", sw); } } catch (Exception ex) { ex = ex; } } } // Hilight SmallWorld structure match else if (pssc.SearchType == StructureSearchType.SmallWorld) // Hilight SmallWorld structure search results { if (SmallWorldDepictions == null) { SmallWorldDepictions = new SmallWorldDepictions(); } SmallWorldPredefinedParameters swp = pssc.SmallWorldParameters; //DebugLog.Message("Depict " + cid + ", Hilight " + swp.Highlight + ", Align " + swp.Align); // + "\r\n" + new StackTrace(true)); if ((swp.Highlight || swp.Align) & Lex.IsDefined(cid)) // call depiction for these { svg = SmallWorldDepictions.GetDepiction(cid, swp.Highlight, swp.Align); if (Lex.IsDefined(svg)) // have depiction? { { pixWidth = MoleculeMx.MilliinchesToPixels(width); bm = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth); ffi.FormattedBitmap = mol.FormattedBitmap = bm; // store in formatting info and chem structure return(ffi); } } else if (svg == null) // start retrieval of this decpiction type & fall through to get default structure initially { SmallWorldDepictions.StartDepictionRetrieval(Qm, StructureHighlightQc, swp.Highlight, swp.Align); } else { } // tried to get it but failed, fall through to get basic structure } } else if (mol.AltFormDefined("Svg")) // svg form exist (e.g. SmallWorld or "related" structure search)? { svg = mol.SvgString; if (Lex.IsDefined(svg)) { pixWidth = MoleculeMx.MilliinchesToPixels(width); bm = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth); ffi.FormattedBitmap = mol.FormattedBitmap = bm; // store in formatting info and chem structure return(ffi); } } } /////////////////////////////////// // Handle each output device /////////////////////////////////// ffi.HeightInLines = 1; // min of 1 line if (Rf.SdFile) { FormatSdfileStructure(mol); return(null); } int pageHeight = 11000; if (Rf.PageMargins != null) { pageHeight = Rf.PageMargins.Top + Rf.PageHeight + Rf.PageMargins.Bottom; } if (Rf.Excel || Rf.Word) { translateType = 2; } else { translateType = 0; } if (!Rf.FixedHeightStructures) { fixedHeight = 0; // not fixed height } else if (Rf.Excel || Rf.Word) { fixedHeight = 1; // always fixed height } else { fixedHeight = 2; // fixed height unless need to expand } if (Rf.Word && Rf.FixedHeightStructures) { markBoundaries = true; } else { markBoundaries = false; } destRect = new Rectangle(0, 0, width, width * 4 / 5); // default dest rect /////////////////////////////////////////////////////////////////////////// // Tempory fake generation of HELM & associatedimage for biopolymer testing /////////////////////////////////////////////////////////////////////////// //if (MoleculeMx.HelmEnabled == DebugMx.False) // artificially generate helm molecules // MoleculeMx.SetMoleculeToTestHelmString(mol.GetCorpId().ToString(), mol); /////////////////////////////////////////////////////////////////////////// // End of tempory fake generation of HELM & associatedimage for biopolymer testing /////////////////////////////////////////////////////////////////////////// bool fitStructure = true; if (mol.IsChemStructureFormat) { if (Rf.Grid) // special scale for grid { double scale = (float)width / MoleculeMx.StandardBoxWidth; desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange((int)(MoleculeMx.StandardBondLength * scale)); //desiredBondLength = (int)(ChemicalStructure.StandardBondLength * (Rf.PageScale / 100.0)); desiredBondLength = (int)(desiredBondLength * 90.0 / 100.0); // scale down a bit for grid if (debug) { DebugLog.StopwatchMessage("tAdjustBondLength1", sw); } } else // set desired bond length based on page scaling { float scale = (float)width / MoleculeMx.StandardBoxWidth; desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange((int)(MoleculeMx.StandardBondLength * scale)); //desiredBondLength = (int)(ChemicalStructure.StandardBondLength * (Rf.PageScale / 100.0)); if (debug) { DebugLog.StopwatchMessage("tAdjustBondLength2", sw); } } if (desiredBondLength < 1) { desiredBondLength = 1; } if (debug) { DebugLog.StopwatchMessage("tBeforeFit", sw); } if (fitStructure) { mol.CdkMol.FitStructureIntoRectangle // scale and translate structure into supplied rectangle. (ref destRect, desiredBondLength, translateType, fixedHeight, markBoundaries, pageHeight, out boundingRect); } if (debug) { DebugLog.StopwatchMessage("tFitStructure", sw); } ffi.HeightInLines = (int)(destRect.Height / Rf.LineHeight + 1); // lines needed } else if (mol.IsBiopolymerFormat) { if (mol.PrimaryFormat == MoleculeFormat.Helm && Rf.Excel) { svg = HelmControl.GetSvg(mol.HelmString); float inchWidth = width / 1000.0f; // convert width milliinches to inches Svg.SvgDocument svgDoc = SvgUtil.AdjustSvgDocumentToFitContent(svg, inchWidth, Svg.SvgUnitType.Inch); RectangleF svgbb = svgDoc.Bounds; float ar = svgbb.Width / svgbb.Height; // aspect ratio of svg bounding box height = (int)(width / ar); // height in milliinches ffi.HeightInLines = (int)(height / Rf.LineHeight) + 1; // lines needed destRect = new Rectangle(0, 0, width, height); } } ////////////////////////// /// Output to Grid ////////////////////////// if (Rf.Grid) { pixWidth = MoleculeMx.MilliinchesToPixels(destRect.Width); pixHeight = MoleculeMx.MilliinchesToPixels(destRect.Height); if (cellStyle == null) { if (Qm == null || Qm.MoleculeGrid == null) { font = new Font("Tahoma", 8.25f); } else { font = new Font(Qm.MoleculeGrid.Font, FontStyle.Underline); } cellStyle = new CellStyleMx(font, Color.Blue, Color.Empty); } if (mol.IsChemStructureFormat) // molfile type molecule { if (debug) { DebugLog.StopwatchMessage("tBeforeGetDisplayPreferences", sw); } DisplayPreferences dp = mol.GetDisplayPreferences(); if (debug) { DebugLog.StopwatchMessage("tGetDisplayPreferences", sw); } //desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange(desiredBondLength); // be sure bond len within allowed range //if (debug) DebugLog.StopwatchMessage("tAdjustBondLengthToValidRange", sw); //dp.StandardBondLength = MoleculeMx.MilliinchesToDecipoints(desiredBondLength); bm = mol.CdkMol.GetFixedHeightMoleculeBitmap(pixWidth, pixHeight, dp, cellStyle, mol.Caption); if (debug) { DebugLog.StopwatchMessage("tGetBitmap", sw); } } else if (mol.IsBiopolymerFormat) // Output HELM image for biopolymer { pixWidth = MoleculeMx.MilliinchesToPixels(width); bm = HelmConverter.HelmToBitmap(mol, pixWidth); } else { bm = new Bitmap(1, 1); } ffi.FormattedBitmap = mol.FormattedBitmap = bm; // store in formatting & structure ffi.FormattedText = "Formatted"; // indicate formatted (could save structure string but not needed and avoids possible conversion overhead) return(ffi); } ////////////////////////// /// Output to Html ////////////////////////// else if (Rf.Html) { if (r >= 0) { AssureTbFree(0, r + ffi.HeightInLines - 1); } if (mol.IsChemStructureFormat) { FormatChemStructureHtml(mol, destRect, width, r); } else if (mol.IsBiopolymerFormat) { FormatBiopolymerStructureHtml(mol, destRect, width, r); } if (debug) { DebugLog.StopwatchMessage("tFormatHtmlStructure", sw); } ffi.FormattedBitmap = mol.FormattedBitmap; ffi.FormattedText = mol.FormattedText; return(ffi); } ///////////////////////////////////////////////////////////////// /// Other format, store Smiles or Helm & any cellStyle in buffer ///////////////////////////////////////////////////////////////// else { if (mol.IsChemStructureFormat) { if (Rf.ExportStructureFormat == ExportStructureFormat.Smiles) { molString = mol.GetSmilesString(); } else { molString = mol.GetChimeString(); // use Chime if not smiles } } else if (mol.IsBiopolymerFormat) { molString = mol.PrimaryValue; // usually Helm but could be sequence } txt = String.Format("{0} {1} {2} {3} {4} {5} {6}", x, width, destRect.Left, destRect.Top, destRect.Right, destRect.Bottom, molString); if (cellStyle != null) // apply style to cell? { txt += " <CellStyle " + cellStyle.Serialize() + ">"; } txt = commandChar + " " + txt + "\t"; if (r >= 0) { AssureTbFree(0, r + ffi.HeightInLines - 1); Tb.Lines[r] += txt; // put in buffer } else { return(new FormattedFieldInfo(txt)); // just return formatting } } return(null); } catch (Exception ex) { DebugLog.Message(DebugLog.FormatExceptionMessage(ex)); return(null); } finally { pt.Update(); int formatCount = pt.Count; //ClientLog.Message(pt.ToString() + ", " + cs.GetMolHeader()[2]); // + ", " + new StackTrace(true)); if (debug) { DebugLog.StopwatchMessage("tTotalTime", swTotal); } } }
/// <summary> /// See if a ClickFunction command & process if so /// </summary> /// <param name="command"></param> /// <param name="qm"></param> /// <param name="cInf"></param> public static void Process( string command, QueryManager qm, CellInfo cInf = null) { QueryTable rootQt, qt; QueryColumn qc; MetaTable mt; MetaColumn mc; Query q2; string dbName = "", mtName = "", mcName = ""; List <string> args0, args; string funcName, arg1, arg2, arg3, arg4, arg5; string value = "", keyValue = ""; int ai; try { // Parse click function arguments stripping all single quotes. // Arguments may be defined in the clickfunction definition including col values // indicated by field.Value in the metacolumn clickfunction definition. // If no args are defined in the clickfunction definition then a field value // argument will be added by default or the keyValue if [keyvalue] appears in the // ClickFunction definition CurrentClickQueryManager = qm; args0 = Lex.ParseAllExcludingDelimiters(command, "( , )", false); args = new List <string>(); for (ai = 0; ai < args0.Count; ai++) // strip all single quotes { string arg = args0[ai]; if (arg.StartsWith("'")) { arg = Lex.RemoveSingleQuotes(arg); } //if (Lex.Eq(arg, "[rowcol]") && cInf!= null) //{ // pass grid row & col // args.Add(cInf.GridRowHandle.ToString()); // args.Add(cInf.GridColAbsoluteIndex.ToString()); //} //else args.Add(arg); } funcName = args[0]; arg1 = (args.Count >= 2 ? args[1] : ""); // get other args arg2 = (args.Count >= 3 ? args[2] : ""); arg3 = (args.Count >= 4 ? args[3] : ""); arg4 = (args.Count >= 5 ? args[4] : ""); arg5 = (args.Count >= 6 ? args[5] : ""); if (Lex.Eq(funcName, "DisplayAllData")) { // do all data display for supplied root table and key, i.e. DisplayAllData(TableName, KeyColName, KeyValue) ParseMetaTableMetaColumn(arg1, out mt, arg2, out mc); string extKey = arg3; string intKey = CompoundId.Normalize(extKey, mt); Progress.Show("Building Query..."); _query = QueryEngine.GetSelectAllDataQuery(mt.Name, intKey); Progress.Show("Retrieving data..."); // put up progress dialog since this may take a while QbUtil.RunPopupQuery(_query, mt.KeyMetaColumn.Name + " " + extKey); Progress.Hide(); return; } else if (Lex.Eq(funcName, "DisplayAllDataUsingDbName")) { // display all data for supplied database synonym & key value, i.e. DisplayAllData2(DataBaseSynonym, KeyValue) mtName = null; dbName = arg1; RootTable rti = RootTable.GetFromTableLabel(dbName); if (rti != null) { mtName = rti.MetaTableName; } else // try synonyms { DictionaryMx dict = DictionaryMx.Get("Database_Synonyms"); if (dict != null) { mtName = dict.LookupDefinition(dbName); } } if (String.IsNullOrEmpty(mtName)) { MessageBoxMx.ShowError("Unrecognized database: " + dbName); return; } mt = MetaTableCollection.Get(mtName); if (mt == null) { MessageBoxMx.ShowError("Can't find key metatable " + mtName + " for database " + dbName); return; } string extKey = arg2; string intKey = CompoundId.Normalize(extKey, mt); Progress.Show("Building Query..."); _query = QueryEngine.GetSelectAllDataQuery(mt.Name, intKey); Progress.Show("Retrieving data..."); // put up progress dialog since this may take a while QbUtil.RunPopupQuery(_query, mt.KeyMetaColumn.Name + " " + extKey); return; } // Run a query displaying results to a grid or web page and substituting a parameter value else if (Lex.Eq(funcName, "RunHtmlQuery") || Lex.Eq(funcName, "RunGridQuery")) { // command to display to grid or html if (arg1.StartsWith("MetaTreeNode=", StringComparison.OrdinalIgnoreCase)) { // query based on metatables under a tree node string nodeName = arg1.Substring("MetaTreeNode=".Length).Trim(); _cid = arg2; MetaTreeNode mtn = MetaTree.GetNode(nodeName); if (mtn == null) { MessageBoxMx.ShowError("Can't find tree node referenced in ClickFunction: " + nodeName); return; } _query = new Query(); MetaTable rootMt = null; foreach (MetaTreeNode mtn_ in mtn.Nodes) { if (!mtn_.IsDataTableType) { continue; } mt = MetaTableCollection.Get(mtn_.Target); if (mt == null) { continue; } if (rootMt == null) { rootMt = mt.Root; rootQt = new QueryTable(_query, rootMt); } if (mt == rootMt) { continue; } qt = new QueryTable(_query, mt); } if (_query.Tables.Count == 0) { MessageBoxMx.ShowError("No valid data tables found: " + nodeName); return; } _query.KeyCriteria = "= " + _cid; _title = mtn.Label + " for " + _query.Tables[0].MetaTable.MetaColumns[0].Label + " " + CompoundId.Format(_cid); } else if (arg1.StartsWith("Query=", StringComparison.OrdinalIgnoreCase)) { // query based on saved query string qIdString = arg1.Substring("Query=".Length).Trim(); if (qIdString.StartsWith("Query_", StringComparison.OrdinalIgnoreCase)) { qIdString = qIdString.Substring("Query_".Length).Trim(); } int qId = int.Parse(qIdString); _query = QbUtil.ReadQuery(qId); _cid = arg2; _query.KeyCriteria = "= " + _cid; _title = _query.UserObject.Name + " for " + _query.Tables[0].MetaTable.MetaColumns[0].Label + " " + CompoundId.Format(_cid); } else // explicit mql string to execute { _mql = arg1; // mql to execute if (Lex.IsUndefined(_mql)) { throw new Exception("Expected MQL query not found: " + command); } mt = null; mc = null; if (Lex.IsDefined(arg2) && Lex.IsDefined(arg3)) { mtName = arg2; mcName = arg3; value = arg4; // value to plug in to mql keyValue = value; ParseMetaTableMetaColumn(arg2, out mt, arg3, out mc); } else if (cInf != null) { mt = cInf.Mt; mc = cInf.Mc; value = cInf?.DataValue?.ToString(); keyValue = qm?.DataTableManager?.GetRowKey(cInf.DataRowIndex); } if (mt == null || mc == null) { throw new Exception("Invalid MetaTable or MetaColumn name(s): " + command); } if (!mc.IsNumeric) { value = Lex.AddSingleQuotes(value); // quote if not numeric } int i1 = _mql.ToLower().IndexOf("[value]"); // see if a value parameter if (i1 >= 0) { string value2 = value; _mql = _mql.Replace(_mql.Substring(i1, 7), value); _title = mc.Label + " " + value; } i1 = _mql.ToLower().IndexOf("[keyvalue]"); // see if a key value parameter if (i1 >= 0) { _mql = _mql.Replace(_mql.Substring(i1, 10), keyValue); _title = mt.KeyMetaColumn.Label + " " + keyValue; } try { _query = MqlUtil.ConvertMqlToQuery(_mql); } catch (Exception ex) { MessageBoxMx.ShowError("Error converting Mql to query: " + ex.Message); return; } } if (Lex.Eq(funcName, "RunHtmlQuery")) { QbUtil.RunPopupQuery(_query, _title, OutputDest.Html); } else // output to grid { QbUtil.RunPopupQuery(_query, _title, OutputDest.WinForms); } //else // create new grid query & run (will lose results for current query) //{ // QbUtil.NewQuery(_title); // show in query builder // QbUtil.SetCurrentQueryInstance(_query); // QbUtil.RenderQuery(); // string nextCommand = QueryExec.RunQuery(_query, OutputDest.Grid); //} return; } // Open a URL, normally substituting parameter value else if (Lex.Eq(funcName, "OpenUrl")) { string url = arg1; // url to execute value = arg2; // value to plug in to url int i1 = Lex.IndexOf(url, "[value]"); // fill in one of the value place holders if (i1 >= 0) { string value2 = value; url = url.Replace(url.Substring(i1, 7), value); } else // check to see if we are matching on key { i1 = Lex.IndexOf(url, "[keyvalue]"); if (i1 >= 0) { url = url.Replace(url.Substring(i1, 10), value); } } SystemUtil.StartProcess(url); return; } else if (Lex.Eq(funcName, "OpenUrlFromSmallWorldCid")) { SmallWorldDepictions.OpenUrlFromSmallWorldCid(arg1); return; } else if (Lex.Eq(funcName, "ShowProjectDescription")) { string projName = arg1; QbUtil.ShowProjectDescription(projName); return; } else if (Lex.Eq(funcName, "ShowTableDescription")) { mtName = arg1; QbUtil.ShowTableDescription(mtName); return; } else if (Lex.Eq(funcName, "DisplayDrilldownDetail")) { // drill down into a result value mtName = arg1; // table mcName = arg2; // column int level = Int32.Parse(arg3); string resultId = arg4; // quoted resultId to get q2 = QueryEngine.GetSummarizationDetailQuery(mtName, mcName, level, resultId); if (q2 == null) { throw new Exception("Unable to build drill-down query for: " + mtName + "." + mcName); } bool success = QbUtil.RunPopupQuery(q2, "Result Detail", OutputDest.WinForms); return; } //else if (Lex.Eq(funcName, "PopupSmilesStructure")) // display structure for a Smiles string (still needs some work...) //{ // string molString = arg1.ToString(); // ChemicalStructure cs = new ChemicalStructure(StructureFormat.Smiles, molString); // ToolHelper.DisplayStructureInPopupGrid("Title...", "Smiles", "Structure", cs); //} //else if (Lex.Eq(funcName, "PopupChimeStructure")) // display structure for a Chime string //{ // string molString = arg1.ToString(); // ChemicalStructure cs = new ChemicalStructure(StructureFormat.Smiles, molString); // ToolHelper.DisplayStructureInPopupGrid("Title...", "Smiles", "Structure", cs); //} else if (Lex.Eq(funcName, "DisplayWebPage")) { // substitute a field value into a url & display associated web page string url = arg1; ParseMetaTableMetaColumn(arg2, out mt, arg3, out mc); value = arg4; // value to plug in to mql // value = "{6E9C28EF-407E-44A0-9007-5FFB735A5C6C}"; // debug // value = "{0AC17903-E551-445E-BFAA-860023D2884F}"; // debug // value = "{63EE71F9-15BA-42FB-AFDC-C399103707B1}"; // debug // value = "{80591183-B7BA-4669-8C5F-7E7F53D981CE}"; //lex.OpenString(mc.ClickFunction); // reparse url to get proper case //funcName = lex.GetNonDelimiter(); //url = Lex.RemoveAllQuotes(lex.GetNonDelimiter()); _title = mc.Label + " " + value; int i1 = url.ToLower().IndexOf("[value]"); // fill in one of the value place holders if (i1 >= 0) { url = url.Replace(url.Substring(i1, 7), value); } else // check to see if we are matching on key { i1 = url.ToLower().IndexOf("[keyvalue]"); if (i1 >= 0) { url = url.Replace(url.Substring(i1, 10), value); _title = mt.KeyMetaColumn.Label + " " + value; } } UIMisc.ShowHtmlPopupFormDocument(url, _title); return; } else if (Lex.Eq(funcName, "DisplayOracleBlobDocument")) // display a document contained in an Oracle blob column { // Syntax: DisplayOracleBlobDocument(<table-to-lookup>, <value_match_column>, <file-name-or-type-col>, <content-column>) string table = arg1; string matchCol = arg2; string typeCol = arg3; string contentCol = arg4; string matchVal = arg5; // value to match try { string typeName; byte[] ba; UalUtil.SelectOracleBlob(table, matchCol, typeCol, contentCol, matchVal, out typeName, out ba); if (ba == null || ba.Length == 0) { return; } UIMisc.SaveAndOpenBinaryDocument(typeName, ba); } catch (Exception ex) { MessageBoxMx.ShowError("Error retrieving document: " + ex.Message); return; } return; } else if (Lex.Eq(funcName, "DisplayOracleClobDocument")) // display a document contained in an Oracle clob column { // Syntax: DisplayOracleBlobDocument(<table-to-lookup>, <value_match_column>, <file-name-or-type-col>, <content-column>) string table = arg1; string matchCol = arg2; string typeCol = arg3; string contentCol = arg4; string matchVal = arg5; // value to match try { string typeName, clobString; UalUtil.SelectOracleClob(table, matchCol, typeCol, contentCol, matchVal, out typeName, out clobString); if (Lex.IsUndefined(clobString)) { return; } UIMisc.SaveAndOpenBase64BinaryStringDocument(typeName, clobString); // assume clob string is a Base64Binary string } catch (Exception ex) { MessageBoxMx.ShowError("Error retrieving document: " + ex.Message); return; } return; } else if (Plugins.IsMethodExtensionPoint(funcName)) { List <object> objArgs = new List <object>(); for (ai = 1; ai < args.Count; ai++) // build list of object arguments { objArgs.Add(args[ai]); } Plugins.CallStringExtensionPointMethod(funcName, objArgs); } else if (Lex.Eq(funcName, "None")) // dummy click function { return; } else { MessageBoxMx.ShowError("Unrecogized click function: " + funcName); return; } } catch (Exception ex) { Exception ex2 = ex; if (ex.InnerException != null) { ex2 = ex.InnerException; } string msg = "Error executing ClickFunction: " + command + "\r\n" + DebugLog.FormatExceptionMessage(ex); MessageBoxMx.ShowError(msg); ServicesLog.Message(msg); } }