/// <summary> /// Sets the content of the tooltip (when we want to descibe something present in the completionData list) /// </summary> private static void SetToolTip() { var popupMinWidth = 250; var toDisplay = new StringBuilder(); GoToDefinitionFile = null; // only select one item from the list var data = GetCurrentlyDisplayedCompletionData(); if (data == null) { return; } CurrentWord = data.DisplayText; // general stuff toDisplay.Append("<div class='InfoToolTip' id='ToolTip'>"); toDisplay.Append(@" <table width='100%' class='ToolTipName'> <tr style='vertical-align: top;'> <td> <table width='100%' style='margin: 0; padding: 0;'> <tr> <td rowspan='2' style='width: 25px;'> <img src='" + data.Type + @"'> </td> <td> " + data.DisplayText + @" </td> </tr> <tr> <td> <span class='ToolTipSubString'>" + data.Type + @"</span> </td> </tr> </table> </td>"); if (_currentCompletionList.Count > 1) { toDisplay.Append(@" <td class='ToolTipCount'>" + (IndexToShow + 1) + "/" + _currentCompletionList.Count + @" </td>"); } toDisplay.Append(@" </tr> </table>"); // the rest depends on the item type try { switch (data.Type) { case CompletionType.TempTable: case CompletionType.Table: popupMinWidth = Math.Min(500, Npp.NppScreen.WorkingArea.Width / 2); // buffer if (data.FromParser) { if (data.ParsedItem is ParsedDefine) { toDisplay.Append(FormatRowWithImg(ParseFlag.Buffer.ToString(), "BUFFER FOR " + FormatSubString(data.SubString))); } if (data.ParsedItem is ParsedTable && !string.IsNullOrEmpty(data.SubString)) { toDisplay.Append(FormatRow("Is like", (data.SubString.Contains("?")) ? "Unknow table [" + ((ParsedTable)data.ParsedItem).LcLikeTable + "]" : data.SubString.Replace("Like ", ""))); } } var tbItem = ParserHandler.FindAnyTableOrBufferByName(data.DisplayText); if (tbItem != null) { if (!string.IsNullOrEmpty(tbItem.Description)) { toDisplay.Append(FormatRow("Description", tbItem.Description)); } if (tbItem.Fields.Count > 0) { toDisplay.Append(FormatSubtitle("FIELDS [x" + tbItem.Fields.Count + "]")); toDisplay.Append("<table width='100%;'>"); foreach (var parsedField in tbItem.Fields) { toDisplay.Append("<tr><td><img src='" + (parsedField.Flag.HasFlag(ParsedFieldFlag.Primary) ? CompletionType.FieldPk.ToString() : CompletionType.Field.ToString()) + "'></td><td style='padding-right: 4px'>" + (parsedField.Flag.HasFlag(ParsedFieldFlag.Mandatory) ? "<img src='Mandatory'>" : "") + "</td><td style='padding-right: 8px'>" + parsedField.Name + "</td><td style='padding-right: 8px'>" + parsedField.Type + "</td><td style='padding-right: 8px'> = " + (parsedField.Type == ParsedPrimitiveType.Character ? parsedField.InitialValue.ProQuoter() : parsedField.InitialValue) + "</td><td style='padding-right: 8px'>" + parsedField.Description + "</td></tr>"); } toDisplay.Append("</table>"); } if (tbItem.Triggers.Count > 0) { toDisplay.Append(FormatSubtitle("TRIGGERS [x" + tbItem.Triggers.Count + "]")); foreach (var parsedTrigger in tbItem.Triggers) { toDisplay.Append(FormatRow(parsedTrigger.Event, "<a class='ToolGotoDefinition' href='trigger#" + parsedTrigger.ProcName + "'>" + parsedTrigger.ProcName + "</a>")); } } if (tbItem.Indexes.Count > 0) { toDisplay.Append(FormatSubtitle("INDEXES [x" + tbItem.Indexes.Count + "]")); foreach (var parsedIndex in tbItem.Indexes) { toDisplay.Append(FormatRow(parsedIndex.Name, ((parsedIndex.Flag != ParsedIndexFlag.None) ? parsedIndex.Flag + " - " : "") + parsedIndex.FieldsList.Aggregate((i, j) => i + ", " + j))); } } } break; case CompletionType.Sequence: toDisplay.Append(FormatRow("Database logical name", data.SubString)); break; case CompletionType.Database: var dbItem = DataBase.GetDb(data.DisplayText); toDisplay.Append(FormatRow("Logical name", dbItem.LogicalName)); toDisplay.Append(FormatRow("Physical name", dbItem.PhysicalName)); toDisplay.Append(FormatRow("Progress version", dbItem.ProgressVersion)); toDisplay.Append(FormatRow("Number of Tables", dbItem.Tables.Count.ToString())); break; case CompletionType.Field: case CompletionType.FieldPk: // find field var fieldFound = DataBase.FindFieldByName(data.DisplayText, (ParsedTable)data.ParsedItem); if (fieldFound != null) { if (fieldFound.AsLike == ParsedAsLike.Like) { toDisplay.Append(FormatRow("Is LIKE", fieldFound.TempType)); } toDisplay.Append(FormatRow("Type", FormatSubString(data.SubString))); toDisplay.Append(FormatRow("Owner table", ((ParsedTable)data.ParsedItem).Name)); if (!string.IsNullOrEmpty(fieldFound.Description)) { toDisplay.Append(FormatRow("Description", fieldFound.Description)); } if (!string.IsNullOrEmpty(fieldFound.Format)) { toDisplay.Append(FormatRow("Format", fieldFound.Format)); } if (!string.IsNullOrEmpty(fieldFound.InitialValue)) { toDisplay.Append(FormatRow("Initial value", fieldFound.InitialValue)); } toDisplay.Append(FormatRow("Order", fieldFound.Order.ToString())); } break; case CompletionType.Procedure: // find its parameters toDisplay.Append(FormatSubtitle("PARAMETERS")); var paramList = ParserHandler.FindProcedureParameters(data); if (paramList.Count > 0) { foreach (var parameter in paramList) { var defItem = (ParsedDefine)parameter.ParsedItem; toDisplay.Append(FormatRowParam(defItem.LcFlagString, parameter.DisplayText + " as <span class='ToolTipSubString'>" + defItem.PrimitiveType + "</span>")); } } else { toDisplay.Append("None"); } break; case CompletionType.Function: var funcItem = (ParsedFunction)data.ParsedItem; toDisplay.Append(FormatSubtitle("RETURN TYPE")); toDisplay.Append(FormatRowParam("output", "Returns " + FormatSubString(funcItem.ReturnType.ToString()))); toDisplay.Append(FormatSubtitle("PARAMETERS")); var param2List = ParserHandler.FindProcedureParameters(data); if (param2List.Count > 0) { foreach (var parameter in param2List) { var defItem = (ParsedDefine)parameter.ParsedItem; toDisplay.Append(FormatRowParam(defItem.LcFlagString, parameter.DisplayText + " as " + FormatSubString(defItem.PrimitiveType.ToString()))); } } else { toDisplay.Append("None"); } var funcImplem = data.ParsedItem as ParsedImplementation; if (funcImplem != null) { toDisplay.Append(FormatSubtitle("PROTOTYPE")); if (funcImplem.HasPrototype) { toDisplay.Append(FormatRowWithImg("Prototype", "<a class='ToolGotoDefinition' href='proto#" + funcItem.FilePath + "#" + funcImplem.PrototypeLine + "#" + funcImplem.PrototypeColumn + "'>Go to prototype</a>")); } else { toDisplay.Append("Has none"); } } else { toDisplay.Append(FormatSubtitle("DEFINED IN")); toDisplay.Append("Function defined in an external procedure or is a web service operation"); } break; case CompletionType.Keyword: case CompletionType.KeywordObject: toDisplay.Append(FormatRow("Type of keyword", FormatSubString(data.SubString))); // for abbreviations, find the complete keyword first string keyword = data.DisplayText; if (data.KeywordType == KeywordType.Abbreviation) { keyword = Keywords.GetFullKeyword(keyword); var associatedKeyword = AutoComplete.FindInCompletionData(keyword, 0); if (associatedKeyword != null && associatedKeyword.Count > 0) { data = associatedKeyword.First(); } } string keyToFind = null; // for the keywords define and create, we try to match the second keyword that goes with it if (data.KeywordType == KeywordType.Statement && (keyword.EqualsCi("define") || keyword.EqualsCi("create"))) { var lineStr = Npp.GetLine(Npp.LineFromPosition(Npp.GetPositionFromMouseLocation())).Text; var listOfSecWords = new List <string> { "ALIAS", "BROWSE", "BUFFER", "BUTTON", "CALL", "CLIENT-PRINCIPAL", "DATA-SOURCE", "DATABASE", "DATASET", "EVENT", "FRAME", "IMAGE", "MENU", "PARAMETER", "PROPERTY", "QUERY", "RECTANGLE", "SAX-ATTRIBUTES", "SAX-READER", "SAX-WRITER", "SERVER", "SERVER-SOCKET", "SOAP-HEADER", "SOAP-HEADER-ENTRYREF", "SOCKET", "STREAM", "SUB-MENU", "TEMP-TABLE", "VARIABLE", "WIDGET-POOL", "WORK-TABLE", "WORKFILE", "X-DOCUMENT", "X-NODEREF" }; foreach (var word in listOfSecWords) { if (lineStr.ContainsFast(word)) { keyToFind = string.Join(" ", keyword, word, data.SubString); break; } } } if (keyToFind == null) { keyToFind = string.Join(" ", keyword, data.SubString); } var dataHelp = Keywords.GetKeywordHelp(keyToFind); if (dataHelp != null) { toDisplay.Append(FormatSubtitle("DESCRIPTION")); toDisplay.Append(dataHelp.Description); // synthax if (dataHelp.Synthax.Count >= 1 && !string.IsNullOrEmpty(dataHelp.Synthax[0])) { toDisplay.Append(FormatSubtitle("SYNTAX")); toDisplay.Append(@"<div class='ToolTipcodeSnippet'>"); var i = 0; foreach (var synthax in dataHelp.Synthax) { if (i > 0) { toDisplay.Append(@"<br>"); } toDisplay.Append(synthax); i++; } toDisplay.Append(@"</div>"); } } else { toDisplay.Append(FormatSubtitle("404 NOT FOUND")); if (data.KeywordType == KeywordType.Option) { toDisplay.Append("<i><b>Sorry, this keyword doesn't have any help associated</b><br>Since this keyword is an option, try to hover the first keyword of the statement or refer to the 4GL help</i>"); } else { toDisplay.Append("<i><b>Sorry, this keyword doesn't have any help associated</b><br>Please refer to the 4GL help</i>"); } } CurrentWord = keyToFind; break; case CompletionType.Label: break; case CompletionType.Preprocessed: var preprocItem = (ParsedPreProc)data.ParsedItem; if (preprocItem.UndefinedLine > 0) { toDisplay.Append(FormatRow("Undefined line", preprocItem.UndefinedLine.ToString())); } toDisplay.Append(FormatSubtitle("VALUE")); toDisplay.Append(@"<div class='ToolTipcodeSnippet'>"); toDisplay.Append(preprocItem.Value); toDisplay.Append(@"</div>"); break; case CompletionType.Snippet: // TODO break; case CompletionType.VariableComplex: case CompletionType.VariablePrimitive: case CompletionType.Widget: var varItem = (ParsedDefine)data.ParsedItem; toDisplay.Append(FormatRow("Define type", FormatSubString(varItem.Type.ToString()))); if (!string.IsNullOrEmpty(varItem.TempPrimitiveType)) { toDisplay.Append(FormatRow("Variable type", FormatSubString(varItem.PrimitiveType.ToString()))); } if (varItem.AsLike == ParsedAsLike.Like) { toDisplay.Append(FormatRow("Is LIKE", varItem.TempPrimitiveType)); } if (!string.IsNullOrEmpty(varItem.ViewAs)) { toDisplay.Append(FormatRow("Screen representation", varItem.ViewAs)); } if (!string.IsNullOrEmpty(varItem.LcFlagString)) { toDisplay.Append(FormatRow("Define flags", varItem.LcFlagString)); } if (!string.IsNullOrEmpty(varItem.Left)) { toDisplay.Append(FormatSubtitle("END OF DECLARATION")); toDisplay.Append(@"<div class='ToolTipcodeSnippet'>"); toDisplay.Append(varItem.Left); toDisplay.Append(@"</div>"); } break; } } catch (Exception e) { toDisplay.Append("Error when appending info :<br>" + e + "<br>"); } // parsed item? if (data.FromParser) { toDisplay.Append(FormatSubtitle("ORIGINS")); toDisplay.Append(FormatRow("Scope name", data.ParsedItem.Scope.Name)); if (!Plug.CurrentFilePath.Equals(data.ParsedItem.FilePath)) { toDisplay.Append(FormatRow("Owner file", "<a class='ToolGotoDefinition' href='gotoownerfile#" + data.ParsedItem.FilePath + "'>" + data.ParsedItem.FilePath + "</a>")); } } // Flags var flagStrBuilder = new StringBuilder(); data.DoForEachFlag((name, flag) => { flagStrBuilder.Append(FormatRowWithImg(name, "<b>" + name + "</b>")); }); if (flagStrBuilder.Length > 0) { toDisplay.Append(FormatSubtitle("FLAGS")); toDisplay.Append(flagStrBuilder); } toDisplay.Append(@"<div class='ToolTipBottomGoTo'> [HIT CTRL ONCE] Prevent auto-close"); // parsed item? if (data.FromParser) { toDisplay.Append(@"<br>[" + Config.Instance.GetShortcutSpecFromName("Go_To_Definition").ToUpper() + "] <a class='ToolGotoDefinition' href='gotodefinition'>Go to definition</a>"); GoToDefinitionPoint = new Point(data.ParsedItem.Line, data.ParsedItem.Column); GoToDefinitionFile = data.ParsedItem.FilePath; } if (_currentCompletionList.Count > 1) { toDisplay.Append("<br>[CTRL + <span class='ToolTipDownArrow'>" + (char)242 + "</span>] <a class='ToolGotoDefinition' href='nexttooltip'>Read next tooltip</a>"); } toDisplay.Append("</div>"); toDisplay.Append("</div>"); _form.SetText(toDisplay.ToString(), popupMinWidth); }