mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Issue #1482: enable SQL help window
This commit is contained in:
@ -229,6 +229,13 @@
|
|||||||
<Filename Value="source\jsonregistry.pas"/>
|
<Filename Value="source\jsonregistry.pas"/>
|
||||||
<IsPartOfProject Value="True"/>
|
<IsPartOfProject Value="True"/>
|
||||||
</Unit>
|
</Unit>
|
||||||
|
<Unit>
|
||||||
|
<Filename Value="source\sqlhelp.pas"/>
|
||||||
|
<IsPartOfProject Value="True"/>
|
||||||
|
<ComponentName Value="frmSQLhelp"/>
|
||||||
|
<HasResources Value="True"/>
|
||||||
|
<ResourceBaseClass Value="Form"/>
|
||||||
|
</Unit>
|
||||||
</Units>
|
</Units>
|
||||||
</ProjectOptions>
|
</ProjectOptions>
|
||||||
<CompilerOptions>
|
<CompilerOptions>
|
||||||
|
@ -19,7 +19,7 @@ uses
|
|||||||
dbstructures.sqlite, change_password, loginform, data_sorting, extra_controls,
|
dbstructures.sqlite, change_password, loginform, data_sorting, extra_controls,
|
||||||
column_selection, loaddata, csv_detector, createdatabase, editvar, copytable,
|
column_selection, loaddata, csv_detector, createdatabase, editvar, copytable,
|
||||||
exportgrid, usermanager, selectdbobject, reformatter, searchreplace,
|
exportgrid, usermanager, selectdbobject, reformatter, searchreplace,
|
||||||
connections, jsonregistry {, printlist (EnablePrint not defined) }
|
connections, jsonregistry, sqlhelp {, printlist (EnablePrint not defined) }
|
||||||
;
|
;
|
||||||
|
|
||||||
{$R *.res}
|
{$R *.res}
|
||||||
|
@ -1415,7 +1415,7 @@ implementation
|
|||||||
|
|
||||||
uses
|
uses
|
||||||
FileInfo, winpeimagereader, elfreader, machoreader, About, data_sorting, column_selection, loaddata, editvar,
|
FileInfo, winpeimagereader, elfreader, machoreader, About, data_sorting, column_selection, loaddata, editvar,
|
||||||
copytable, csv_detector, exportgrid, usermanager, selectdbobject, reformatter, connections;
|
copytable, csv_detector, exportgrid, usermanager, selectdbobject, reformatter, connections, sqlhelp;
|
||||||
|
|
||||||
{$R *.lfm}
|
{$R *.lfm}
|
||||||
|
|
||||||
@ -4903,10 +4903,10 @@ end;
|
|||||||
procedure TMainform.CallSQLHelpWithKeyword( keyword: String );
|
procedure TMainform.CallSQLHelpWithKeyword( keyword: String );
|
||||||
begin
|
begin
|
||||||
if FActiveDbObj.Connection.Has(frHelpKeyword) then begin
|
if FActiveDbObj.Connection.Has(frHelpKeyword) then begin
|
||||||
{if not Assigned(SqlHelpDialog) then
|
if not Assigned(SqlHelpDialog) then
|
||||||
SqlHelpDialog := TfrmSQLhelp.Create(Self);
|
SqlHelpDialog := TfrmSQLhelp.Create(Self);
|
||||||
SqlHelpDialog.Show;
|
SqlHelpDialog.Show;
|
||||||
SqlHelpDialog.Keyword := keyword;}
|
SqlHelpDialog.Keyword := keyword;
|
||||||
end else
|
end else
|
||||||
ErrorDialog(_('SQL help not available.'), f_('HELP <keyword> requires %s or newer.', ['MySQL 4.1']));
|
ErrorDialog(_('SQL help not available.'), f_('HELP <keyword> requires %s or newer.', ['MySQL 4.1']));
|
||||||
end;
|
end;
|
||||||
@ -13273,10 +13273,10 @@ begin
|
|||||||
Editors.Add(frmPreferences.SynMemoSQLSample);}
|
Editors.Add(frmPreferences.SynMemoSQLSample);}
|
||||||
if Assigned(FCreateDatabaseDialog) then
|
if Assigned(FCreateDatabaseDialog) then
|
||||||
Editors.Add(FCreateDatabaseDialog.SynMemoCreateCode);
|
Editors.Add(FCreateDatabaseDialog.SynMemoCreateCode);
|
||||||
{if SqlHelpDialog <> nil then begin
|
if SqlHelpDialog <> nil then begin
|
||||||
Editors.Add(SqlHelpDialog.memoDescription);
|
Editors.Add(SqlHelpDialog.memoDescription);
|
||||||
Editors.Add(SqlHelpDialog.MemoExample);
|
Editors.Add(SqlHelpDialog.MemoExample);
|
||||||
end;}
|
end;
|
||||||
{if Assigned(FTableToolsDialog) then
|
{if Assigned(FTableToolsDialog) then
|
||||||
Editors.Add(FTableToolsDialog.SynMemoFindText);}
|
Editors.Add(FTableToolsDialog.SynMemoFindText);}
|
||||||
if Assigned(frmCsvDetector) then
|
if Assigned(frmCsvDetector) then
|
||||||
|
339
source/sqlhelp.lfm
Normal file
339
source/sqlhelp.lfm
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
object frmSQLhelp: TfrmSQLhelp
|
||||||
|
Left = 0
|
||||||
|
Height = 444
|
||||||
|
Top = 0
|
||||||
|
Width = 728
|
||||||
|
BorderWidth = 10
|
||||||
|
Caption = 'Integrated SQL-help'
|
||||||
|
ClientHeight = 444
|
||||||
|
ClientWidth = 728
|
||||||
|
Color = clBtnFace
|
||||||
|
DesignTimePPI = 120
|
||||||
|
FormStyle = fsStayOnTop
|
||||||
|
OnClose = FormClose
|
||||||
|
OnCreate = FormCreate
|
||||||
|
OnShow = FormShow
|
||||||
|
object pnlMain: TPanel
|
||||||
|
Left = 10
|
||||||
|
Height = 382
|
||||||
|
Top = 10
|
||||||
|
Width = 708
|
||||||
|
Align = alClient
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 382
|
||||||
|
ClientWidth = 708
|
||||||
|
ParentBackground = False
|
||||||
|
TabOrder = 0
|
||||||
|
object Splitter1: TSplitter
|
||||||
|
Cursor = crSizeWE
|
||||||
|
Left = 191
|
||||||
|
Height = 382
|
||||||
|
Top = 0
|
||||||
|
Width = 10
|
||||||
|
end
|
||||||
|
object pnlLeft: TPanel
|
||||||
|
Left = 0
|
||||||
|
Height = 382
|
||||||
|
Top = 0
|
||||||
|
Width = 191
|
||||||
|
Align = alLeft
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 382
|
||||||
|
ClientWidth = 191
|
||||||
|
ParentBackground = False
|
||||||
|
TabOrder = 0
|
||||||
|
object editFilter: TEditButton
|
||||||
|
Left = 0
|
||||||
|
Height = 28
|
||||||
|
Top = 0
|
||||||
|
Width = 191
|
||||||
|
Align = alTop
|
||||||
|
ButtonWidth = 29
|
||||||
|
Images = MainForm.ImageListIcons8
|
||||||
|
ImageIndex = 193
|
||||||
|
MaxLength = 0
|
||||||
|
NumGlyphs = 1
|
||||||
|
OnButtonClick = editFilterRightButtonClick
|
||||||
|
OnChange = editFilterChange
|
||||||
|
PasswordChar = #0
|
||||||
|
TabOrder = 0
|
||||||
|
TextHint = 'Filter'
|
||||||
|
end
|
||||||
|
object treeTopics: TLazVirtualStringTree
|
||||||
|
Left = 0
|
||||||
|
Height = 354
|
||||||
|
Top = 28
|
||||||
|
Width = 191
|
||||||
|
Align = alClient
|
||||||
|
Constraints.MinWidth = 38
|
||||||
|
Header.AutoSizeIndex = 0
|
||||||
|
Header.Columns = <>
|
||||||
|
Header.MainColumn = -1
|
||||||
|
Images = MainForm.ImageListIcons8
|
||||||
|
TabOrder = 1
|
||||||
|
TreeOptions.PaintOptions = [toHotTrack, toShowButtons, toShowDropmark, toShowRoot, toShowTreeLines, toThemeAware, toUseBlendedImages, toUseExplorerTheme, toHideTreeLinesIfThemed]
|
||||||
|
OnFocusChanged = treeTopicsFocusChanged
|
||||||
|
OnFreeNode = treeTopicsFreeNode
|
||||||
|
OnGetText = treeTopicsGetText
|
||||||
|
OnGetImageIndex = treeTopicsGetImageIndex
|
||||||
|
OnGetNodeDataSize = treeTopicsGetNodeDataSize
|
||||||
|
OnInitChildren = treeTopicsInitChildren
|
||||||
|
OnInitNode = treeTopicsInitNode
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object pnlRight: TPanel
|
||||||
|
Left = 201
|
||||||
|
Height = 382
|
||||||
|
Top = 0
|
||||||
|
Width = 507
|
||||||
|
Align = alClient
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 382
|
||||||
|
ClientWidth = 507
|
||||||
|
ParentBackground = False
|
||||||
|
TabOrder = 1
|
||||||
|
object Splitter2: TSplitter
|
||||||
|
Cursor = crVSplit
|
||||||
|
Left = 0
|
||||||
|
Height = 10
|
||||||
|
Top = 212
|
||||||
|
Width = 507
|
||||||
|
Align = alTop
|
||||||
|
ResizeAnchor = akTop
|
||||||
|
end
|
||||||
|
object lblDescription: TLabel
|
||||||
|
Left = 0
|
||||||
|
Height = 20
|
||||||
|
Top = 1
|
||||||
|
Width = 507
|
||||||
|
Align = alTop
|
||||||
|
Caption = 'Description:'
|
||||||
|
end
|
||||||
|
object lblKeyword: TLabel
|
||||||
|
Left = 0
|
||||||
|
Height = 1
|
||||||
|
Top = 0
|
||||||
|
Width = 507
|
||||||
|
Align = alTop
|
||||||
|
ShowAccelChar = False
|
||||||
|
end
|
||||||
|
object lblExample: TLabel
|
||||||
|
Left = 0
|
||||||
|
Height = 20
|
||||||
|
Top = 222
|
||||||
|
Width = 507
|
||||||
|
Align = alTop
|
||||||
|
Caption = 'Example:'
|
||||||
|
end
|
||||||
|
inline memoDescription: TSynEdit
|
||||||
|
Left = 0
|
||||||
|
Height = 191
|
||||||
|
Top = 21
|
||||||
|
Width = 507
|
||||||
|
Align = alTop
|
||||||
|
Constraints.MinHeight = 38
|
||||||
|
Font.Height = -16
|
||||||
|
Font.Name = 'Courier New'
|
||||||
|
Font.Pitch = fpFixed
|
||||||
|
Font.Quality = fqNonAntialiased
|
||||||
|
ParentColor = False
|
||||||
|
ParentFont = False
|
||||||
|
TabOrder = 0
|
||||||
|
OnKeyDown = memosKeyDown
|
||||||
|
Gutter.Visible = False
|
||||||
|
Gutter.Width = 72
|
||||||
|
Gutter.MouseActions = <>
|
||||||
|
RightGutter.Width = 0
|
||||||
|
RightGutter.MouseActions = <>
|
||||||
|
Keystrokes = <>
|
||||||
|
MouseActions = <>
|
||||||
|
MouseTextActions = <>
|
||||||
|
MouseSelActions = <>
|
||||||
|
Options = [eoAutoIndent, eoGroupUndo, eoShowScrollHint, eoSmartTabs, eoTabsToSpaces, eoDragDropEditing]
|
||||||
|
MouseOptions = [emDragDropEditing]
|
||||||
|
VisibleSpecialChars = [vscSpace, vscTabAtLast]
|
||||||
|
ReadOnly = True
|
||||||
|
RightEdge = 0
|
||||||
|
SelectedColor.BackPriority = 50
|
||||||
|
SelectedColor.ForePriority = 50
|
||||||
|
SelectedColor.FramePriority = 50
|
||||||
|
SelectedColor.BoldPriority = 50
|
||||||
|
SelectedColor.ItalicPriority = 50
|
||||||
|
SelectedColor.UnderlinePriority = 50
|
||||||
|
SelectedColor.StrikeOutPriority = 50
|
||||||
|
BracketHighlightStyle = sbhsBoth
|
||||||
|
BracketMatchColor.Background = clNone
|
||||||
|
BracketMatchColor.Foreground = clNone
|
||||||
|
BracketMatchColor.Style = [fsBold]
|
||||||
|
FoldedCodeColor.Background = clNone
|
||||||
|
FoldedCodeColor.Foreground = clGray
|
||||||
|
FoldedCodeColor.FrameColor = clGray
|
||||||
|
MouseLinkColor.Background = clNone
|
||||||
|
MouseLinkColor.Foreground = clBlue
|
||||||
|
LineHighlightColor.Background = clNone
|
||||||
|
LineHighlightColor.Foreground = clNone
|
||||||
|
inline SynLeftGutterPartList1: TSynGutterPartList
|
||||||
|
object SynGutterMarks1: TSynGutterMarks
|
||||||
|
Width = 30
|
||||||
|
MouseActions = <>
|
||||||
|
end
|
||||||
|
object SynGutterLineNumber1: TSynGutterLineNumber
|
||||||
|
Width = 21
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clBtnFace
|
||||||
|
MarkupInfo.Foreground = clNone
|
||||||
|
DigitCount = 2
|
||||||
|
ShowOnlyLineNumbersMultiplesOf = 1
|
||||||
|
ZeroStart = False
|
||||||
|
LeadingZeros = False
|
||||||
|
end
|
||||||
|
object SynGutterChanges1: TSynGutterChanges
|
||||||
|
Width = 5
|
||||||
|
MouseActions = <>
|
||||||
|
ModifiedColor = 59900
|
||||||
|
SavedColor = clGreen
|
||||||
|
end
|
||||||
|
object SynGutterSeparator1: TSynGutterSeparator
|
||||||
|
Width = 3
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clWhite
|
||||||
|
MarkupInfo.Foreground = clGray
|
||||||
|
end
|
||||||
|
object SynGutterCodeFolding1: TSynGutterCodeFolding
|
||||||
|
Width = 13
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clNone
|
||||||
|
MarkupInfo.Foreground = clGray
|
||||||
|
MouseActionsExpanded = <>
|
||||||
|
MouseActionsCollapsed = <>
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
inline MemoExample: TSynEdit
|
||||||
|
Left = 0
|
||||||
|
Height = 140
|
||||||
|
Top = 242
|
||||||
|
Width = 507
|
||||||
|
Align = alClient
|
||||||
|
Constraints.MinHeight = 38
|
||||||
|
Font.Height = -16
|
||||||
|
Font.Name = 'Courier New'
|
||||||
|
Font.Pitch = fpFixed
|
||||||
|
Font.Quality = fqNonAntialiased
|
||||||
|
ParentColor = False
|
||||||
|
ParentFont = False
|
||||||
|
TabOrder = 1
|
||||||
|
OnKeyDown = memosKeyDown
|
||||||
|
Gutter.Visible = False
|
||||||
|
Gutter.Width = 72
|
||||||
|
Gutter.MouseActions = <>
|
||||||
|
RightGutter.Width = 0
|
||||||
|
RightGutter.MouseActions = <>
|
||||||
|
Keystrokes = <>
|
||||||
|
MouseActions = <>
|
||||||
|
MouseTextActions = <>
|
||||||
|
MouseSelActions = <>
|
||||||
|
Options = [eoAutoIndent, eoGroupUndo, eoShowScrollHint, eoSmartTabs, eoTabsToSpaces, eoDragDropEditing]
|
||||||
|
MouseOptions = [emDragDropEditing]
|
||||||
|
VisibleSpecialChars = [vscSpace, vscTabAtLast]
|
||||||
|
ReadOnly = True
|
||||||
|
RightEdge = 0
|
||||||
|
SelectedColor.BackPriority = 50
|
||||||
|
SelectedColor.ForePriority = 50
|
||||||
|
SelectedColor.FramePriority = 50
|
||||||
|
SelectedColor.BoldPriority = 50
|
||||||
|
SelectedColor.ItalicPriority = 50
|
||||||
|
SelectedColor.UnderlinePriority = 50
|
||||||
|
SelectedColor.StrikeOutPriority = 50
|
||||||
|
BracketHighlightStyle = sbhsBoth
|
||||||
|
BracketMatchColor.Background = clNone
|
||||||
|
BracketMatchColor.Foreground = clNone
|
||||||
|
BracketMatchColor.Style = [fsBold]
|
||||||
|
FoldedCodeColor.Background = clNone
|
||||||
|
FoldedCodeColor.Foreground = clGray
|
||||||
|
FoldedCodeColor.FrameColor = clGray
|
||||||
|
MouseLinkColor.Background = clNone
|
||||||
|
MouseLinkColor.Foreground = clBlue
|
||||||
|
LineHighlightColor.Background = clNone
|
||||||
|
LineHighlightColor.Foreground = clNone
|
||||||
|
inline SynLeftGutterPartList1: TSynGutterPartList
|
||||||
|
object SynGutterMarks1: TSynGutterMarks
|
||||||
|
Width = 30
|
||||||
|
MouseActions = <>
|
||||||
|
end
|
||||||
|
object SynGutterLineNumber1: TSynGutterLineNumber
|
||||||
|
Width = 21
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clBtnFace
|
||||||
|
MarkupInfo.Foreground = clNone
|
||||||
|
DigitCount = 2
|
||||||
|
ShowOnlyLineNumbersMultiplesOf = 1
|
||||||
|
ZeroStart = False
|
||||||
|
LeadingZeros = False
|
||||||
|
end
|
||||||
|
object SynGutterChanges1: TSynGutterChanges
|
||||||
|
Width = 5
|
||||||
|
MouseActions = <>
|
||||||
|
ModifiedColor = 59900
|
||||||
|
SavedColor = clGreen
|
||||||
|
end
|
||||||
|
object SynGutterSeparator1: TSynGutterSeparator
|
||||||
|
Width = 3
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clWhite
|
||||||
|
MarkupInfo.Foreground = clGray
|
||||||
|
end
|
||||||
|
object SynGutterCodeFolding1: TSynGutterCodeFolding
|
||||||
|
Width = 13
|
||||||
|
MouseActions = <>
|
||||||
|
MarkupInfo.Background = clNone
|
||||||
|
MarkupInfo.Foreground = clGray
|
||||||
|
MouseActionsExpanded = <>
|
||||||
|
MouseActionsCollapsed = <>
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object pnlBottom: TPanel
|
||||||
|
Left = 10
|
||||||
|
Height = 42
|
||||||
|
Top = 392
|
||||||
|
Width = 708
|
||||||
|
Align = alBottom
|
||||||
|
BevelOuter = bvNone
|
||||||
|
ClientHeight = 42
|
||||||
|
ClientWidth = 708
|
||||||
|
ParentBackground = False
|
||||||
|
TabOrder = 1
|
||||||
|
object btnSearchOnline: TSpeedButton
|
||||||
|
Left = 444
|
||||||
|
Height = 31
|
||||||
|
Top = 8
|
||||||
|
Width = 129
|
||||||
|
Anchors = [akTop, akRight]
|
||||||
|
Caption = 'Search online'
|
||||||
|
Images = MainForm.ImageListIcons8
|
||||||
|
ImageIndex = 69
|
||||||
|
OnClick = ButtonOnlinehelpClick
|
||||||
|
end
|
||||||
|
object ButtonClose: TButton
|
||||||
|
Left = 580
|
||||||
|
Height = 31
|
||||||
|
Top = 8
|
||||||
|
Width = 128
|
||||||
|
Anchors = [akTop, akRight]
|
||||||
|
Cancel = True
|
||||||
|
Caption = 'Close'
|
||||||
|
Default = True
|
||||||
|
TabOrder = 0
|
||||||
|
OnClick = ButtonCloseClick
|
||||||
|
end
|
||||||
|
end
|
||||||
|
object timerSearch: TTimer
|
||||||
|
Interval = 500
|
||||||
|
OnTimer = DoSearch
|
||||||
|
Left = 10
|
||||||
|
Top = 400
|
||||||
|
end
|
||||||
|
end
|
427
source/sqlhelp.pas
Normal file
427
source/sqlhelp.pas
Normal file
@ -0,0 +1,427 @@
|
|||||||
|
unit sqlhelp;
|
||||||
|
|
||||||
|
{$mode delphi}{$H+}
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
uses
|
||||||
|
SysUtils, Classes, Controls, Forms, Dialogs, StdCtrls, ComCtrls, ExtCtrls,
|
||||||
|
Buttons, SynEdit, SynEditHighlighter, extra_controls,
|
||||||
|
laz.VirtualTrees, Graphics, EditBtn,
|
||||||
|
dbconnection;
|
||||||
|
|
||||||
|
type
|
||||||
|
|
||||||
|
{ TfrmSQLhelp }
|
||||||
|
|
||||||
|
TfrmSQLhelp = class(TExtForm)
|
||||||
|
//URIOpenerDescription: TSynURIOpener;
|
||||||
|
//URIHighlighter: TSynURISyn;
|
||||||
|
//URIOpenerExample: TSynURIOpener;
|
||||||
|
btnSearchOnline: TSpeedButton;
|
||||||
|
ButtonClose: TButton;
|
||||||
|
pnlBottom: TPanel;
|
||||||
|
pnlMain: TPanel;
|
||||||
|
pnlLeft: TPanel;
|
||||||
|
treeTopics: TLazVirtualStringTree;
|
||||||
|
editFilter: TEditButton;
|
||||||
|
pnlRight: TPanel;
|
||||||
|
Splitter2: TSplitter;
|
||||||
|
Splitter1: TSplitter;
|
||||||
|
lblDescription: TLabel;
|
||||||
|
lblKeyword: TLabel;
|
||||||
|
memoDescription: TSynEdit;
|
||||||
|
lblExample: TLabel;
|
||||||
|
MemoExample: TSynEdit;
|
||||||
|
timerSearch: TTimer;
|
||||||
|
procedure FormCreate(Sender: TObject);
|
||||||
|
procedure memosKeyDown(Sender: TObject; var Key: Word;
|
||||||
|
Shift: TShiftState);
|
||||||
|
procedure ButtonOnlinehelpClick(Sender: TObject);
|
||||||
|
procedure ButtonCloseClick(Sender: TObject);
|
||||||
|
procedure DoSearch(Sender: TObject);
|
||||||
|
procedure treeTopicsGetNodeDataSize(Sender: TBaseVirtualTree; var NodeDataSize: Integer);
|
||||||
|
procedure treeTopicsInitNode(Sender: TBaseVirtualTree; ParentNode, Node: PVirtualNode;
|
||||||
|
var InitialStates: TVirtualNodeInitStates);
|
||||||
|
procedure treeTopicsInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
var ChildCount: Cardinal);
|
||||||
|
procedure treeTopicsGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: Integer);
|
||||||
|
procedure treeTopicsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
|
||||||
|
procedure treeTopicsFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
||||||
|
procedure treeTopicsFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
Column: TColumnIndex);
|
||||||
|
procedure editFilterChange(Sender: TObject);
|
||||||
|
procedure editFilterRightButtonClick(Sender: TObject);
|
||||||
|
procedure FormClose(Sender: TObject; var Action: TCloseAction);
|
||||||
|
procedure FormShow(Sender: TObject);
|
||||||
|
|
||||||
|
private
|
||||||
|
{ Private declarations }
|
||||||
|
FConnection: TDBConnection;
|
||||||
|
FKeyword: String;
|
||||||
|
FRootTopics: TDBQuery;
|
||||||
|
function GetHelpResult(Node: PVirtualNode): TDBQuery;
|
||||||
|
procedure SetKeyword(Value: String);
|
||||||
|
public
|
||||||
|
{ Public declarations }
|
||||||
|
property Keyword: String read FKeyword write SetKeyword;
|
||||||
|
end;
|
||||||
|
|
||||||
|
var
|
||||||
|
SqlHelpDialog: TfrmSQLhelp; // global var, so we can apply settings via SetupSynEditors
|
||||||
|
|
||||||
|
const
|
||||||
|
DEFAULT_WINDOW_CAPTION : String = 'Integrated SQL-help' ;
|
||||||
|
ICONINDEX_CATEGORY_CLOSED : Integer = 66;
|
||||||
|
ICONINDEX_CATEGORY_OPENED : Integer = 67;
|
||||||
|
ICONINDEX_HELPITEM : Integer = 68;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
uses apphelpers, main;
|
||||||
|
|
||||||
|
{$I const.inc}
|
||||||
|
|
||||||
|
{$R *.lfm}
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.FormCreate(Sender: TObject);
|
||||||
|
begin
|
||||||
|
// Set window-layout
|
||||||
|
lblKeyword.Font.Style := [fsBold];
|
||||||
|
Caption := DEFAULT_WINDOW_CAPTION;
|
||||||
|
FixVT(treeTopics);
|
||||||
|
HasSizeGrip := True;
|
||||||
|
|
||||||
|
treeTopics.Clear;
|
||||||
|
FreeAndNil(FRootTopics);
|
||||||
|
FConnection := MainForm.ActiveConnection;
|
||||||
|
FRootTopics := FConnection.GetResults('HELP '+FConnection.EscapeString('CONTENTS'));
|
||||||
|
treeTopics.RootNodeCount := FRootTopics.RecordCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.FormClose(Sender: TObject; var Action: TCloseAction);
|
||||||
|
begin
|
||||||
|
AppSettings.WriteInt(asSQLHelpWindowLeft, Left );
|
||||||
|
AppSettings.WriteInt(asSQLHelpWindowTop, Top );
|
||||||
|
AppSettings.WriteIntDpiAware(asSQLHelpWindowWidth, Self, Width);
|
||||||
|
AppSettings.WriteIntDpiAware(asSQLHelpWindowHeight, Self, Height);
|
||||||
|
AppSettings.WriteIntDpiAware(asSQLHelpPnlLeftWidth, Self, pnlLeft.Width);
|
||||||
|
AppSettings.WriteIntDpiAware(asSQLHelpPnlRightTopHeight, Self, memoDescription.Height);
|
||||||
|
Action := caFree;
|
||||||
|
SqlHelpDialog := nil;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.treeTopicsFocusChanged(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
Column: TColumnIndex);
|
||||||
|
var
|
||||||
|
Results: TDBQuery;
|
||||||
|
VT: TVirtualStringTree;
|
||||||
|
begin
|
||||||
|
// Topic selected
|
||||||
|
VT := Sender as TVirtualStringTree;
|
||||||
|
if not Assigned(VT.FocusedNode) then
|
||||||
|
Exit;
|
||||||
|
if VT.HasChildren[VT.FocusedNode] then
|
||||||
|
Exit;
|
||||||
|
FKeyword := VT.Text[VT.FocusedNode, VT.FocusedColumn];
|
||||||
|
lblKeyword.Caption := Copy(FKeyword, 0, 100);
|
||||||
|
MemoDescription.Lines.Clear;
|
||||||
|
MemoExample.Lines.Clear;
|
||||||
|
Caption := DEFAULT_WINDOW_CAPTION;
|
||||||
|
|
||||||
|
if FKeyword <> '' then try
|
||||||
|
Screen.Cursor := crHourglass;
|
||||||
|
Results := FConnection.GetResults('HELP '+FConnection.EscapeString(FKeyword));
|
||||||
|
Caption := Caption + ' - ' + FKeyword;
|
||||||
|
MemoDescription.Text := fixNewlines(Results.Col('description', True));
|
||||||
|
MemoExample.Text := fixNewlines(Results.Col('example', True));
|
||||||
|
finally
|
||||||
|
FreeAndNil(Results);
|
||||||
|
Screen.Cursor := crDefault;
|
||||||
|
end;
|
||||||
|
|
||||||
|
// Show the user if topic is (not) available
|
||||||
|
if memoDescription.GetTextLen = 0 then
|
||||||
|
memoDescription.Text := _('No help available for this keyword or no keyword was selected.');
|
||||||
|
if memoExample.GetTextLen = 0 then
|
||||||
|
memoExample.Text := _('No example available or no keyword was selected.');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.treeTopicsFreeNode(Sender: TBaseVirtualTree; Node: PVirtualNode);
|
||||||
|
var
|
||||||
|
Results: PDBQuery;
|
||||||
|
begin
|
||||||
|
// Node gets destroyed - free memory used for bound SQL result
|
||||||
|
Results := Sender.GetNodeData(Node);
|
||||||
|
if Assigned(Results^) then
|
||||||
|
Results^.Free;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.treeTopicsGetImageIndex(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
Kind: TVTImageKind; Column: TColumnIndex; var Ghosted: Boolean; var ImageIndex: TImageIndex);
|
||||||
|
begin
|
||||||
|
// Return open or closed book icon for folders, or document icon for topics
|
||||||
|
if not (Kind in [ikNormal, ikSelected]) then
|
||||||
|
Exit;
|
||||||
|
if Sender.HasChildren[Node] then begin
|
||||||
|
if Sender.Expanded[Node] then
|
||||||
|
ImageIndex := ICONINDEX_CATEGORY_OPENED
|
||||||
|
else
|
||||||
|
ImageIndex := ICONINDEX_CATEGORY_CLOSED;
|
||||||
|
end else
|
||||||
|
ImageIndex := ICONINDEX_HELPITEM;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.treeTopicsGetNodeDataSize(Sender: TBaseVirtualTree;
|
||||||
|
var NodeDataSize: Integer);
|
||||||
|
begin
|
||||||
|
// We bind one TDBQuery to a node
|
||||||
|
NodeDataSize := SizeOf(TDBQuery);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function TfrmSQLhelp.GetHelpResult(Node: PVirtualNode): TDBQuery;
|
||||||
|
var
|
||||||
|
P: PDBQuery;
|
||||||
|
begin
|
||||||
|
// Find right result set for given node
|
||||||
|
if treeTopics.GetNodeLevel(Node) = 0 then
|
||||||
|
Result := FRootTopics
|
||||||
|
else begin
|
||||||
|
P := treeTopics.GetNodeData(Node.Parent);
|
||||||
|
Result := P^;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.treeTopicsGetText(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
Column: TColumnIndex; TextType: TVSTTextType; var CellText: string);
|
||||||
|
var
|
||||||
|
Results: TDBQuery;
|
||||||
|
begin
|
||||||
|
// Ask result set for node text
|
||||||
|
Results := GetHelpResult(Node);
|
||||||
|
Results.RecNo := Node.Index;
|
||||||
|
CellText := Results.Col('name');
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.treeTopicsInitChildren(Sender: TBaseVirtualTree; Node: PVirtualNode;
|
||||||
|
var ChildCount: Cardinal);
|
||||||
|
var
|
||||||
|
Results: PDBQuery;
|
||||||
|
VT: TVirtualStringTree;
|
||||||
|
begin
|
||||||
|
// Return number of children for folder
|
||||||
|
VT := Sender as TVirtualStringTree;
|
||||||
|
Results := VT.GetNodeData(Node);
|
||||||
|
Results^ := FConnection.GetResults('HELP '+FConnection.EscapeString(VT.Text[Node, VT.Header.MainColumn]));
|
||||||
|
ChildCount := Results.RecordCount;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.treeTopicsInitNode(Sender: TBaseVirtualTree; ParentNode,
|
||||||
|
Node: PVirtualNode; var InitialStates: TVirtualNodeInitStates);
|
||||||
|
var
|
||||||
|
Results: TDBQuery;
|
||||||
|
ThisFolder, PrevFolder: String;
|
||||||
|
N: PVirtualNode;
|
||||||
|
VT: TVirtualStringTree;
|
||||||
|
RecursionAlarm: Boolean;
|
||||||
|
begin
|
||||||
|
// Display plus button for nodes which are folders
|
||||||
|
VT := Sender as TVirtualStringTree;
|
||||||
|
Results := GetHelpResult(Node);
|
||||||
|
Results.RecNo := Node.Index;
|
||||||
|
if Results.Col('is_it_category', True) = 'Y' then begin
|
||||||
|
// Some random server versions have duplicated category names in help tables, which would cause
|
||||||
|
// infinite tree recursion, e.g. for "Polygon properties" > "Contents". Do not display these
|
||||||
|
// duplicates as folder
|
||||||
|
RecursionAlarm := False;
|
||||||
|
ThisFolder := Results.Col('name');
|
||||||
|
N := VT.GetPreviousInitialized(Node);
|
||||||
|
while Assigned(N) do begin
|
||||||
|
PrevFolder := VT.Text[N, VT.Header.MainColumn];
|
||||||
|
if VT.HasChildren[N] and ((ThisFolder=PrevFolder) or (ThisFolder='Contents')) then begin
|
||||||
|
RecursionAlarm := True;
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
N := VT.GetPreviousInitialized(N);
|
||||||
|
end;
|
||||||
|
if not RecursionAlarm then
|
||||||
|
Include(InitialStates, ivsHasChildren);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.ButtonCloseClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Close;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.FormShow(Sender: TObject);
|
||||||
|
begin
|
||||||
|
Top := AppSettings.ReadInt(asSQLHelpWindowTop);
|
||||||
|
Left := AppSettings.ReadInt(asSQLHelpWindowLeft);
|
||||||
|
Width := AppSettings.ReadIntDpiAware(asSQLHelpWindowWidth, Self);
|
||||||
|
Height := AppSettings.ReadIntDpiAware(asSQLHelpWindowHeight, Self);
|
||||||
|
MakeFullyVisible;
|
||||||
|
|
||||||
|
pnlLeft.Width := AppSettings.ReadIntDpiAware(asSQLHelpPnlLeftWidth, Self);
|
||||||
|
memoDescription.Height := AppSettings.ReadIntDpiAware(asSQLHelpPnlRightTopHeight, Self);
|
||||||
|
// Apply themed colors in OnShow, not OnCreate, as a check with <> nil returns false otherwise
|
||||||
|
MainForm.SetupSynEditors(Self);
|
||||||
|
// These SynMemo's don't have any (SQL) highligher, so we have to assign correct colors for basic text
|
||||||
|
memoDescription.Font.Color := GetThemeColor(clWindowText);
|
||||||
|
MemoExample.Font.Color := GetThemeColor(clWindowText);
|
||||||
|
editFilter.SetFocus;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.ButtonOnlinehelpClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
// Link/redirect to mysql.com for further help
|
||||||
|
ShellExec(APPDOMAIN + 'sqlhelp.php?mysqlversion='+inttostr(FConnection.ServerVersionInt)+
|
||||||
|
'&keyword='+EncodeURLParam(keyword));
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.memosKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
|
||||||
|
begin
|
||||||
|
// Esc pressed - close form.
|
||||||
|
// Seems that if we're in a memo, the ButtonClose.Cancel=True doesn't have an effect
|
||||||
|
//if Key = VK_ESCAPE then
|
||||||
|
// Close;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.SetKeyword(Value: string);
|
||||||
|
var
|
||||||
|
VT: TVirtualStringTree;
|
||||||
|
Node: PVirtualNode;
|
||||||
|
Results: TDBQuery;
|
||||||
|
SearchNoInit: Boolean;
|
||||||
|
begin
|
||||||
|
// Find keyword in tree
|
||||||
|
FKeyword := Value;
|
||||||
|
if FKeyword = '' then
|
||||||
|
Exit;
|
||||||
|
Results := FConnection.GetResults('HELP '+FConnection.EscapeString(FKeyword));
|
||||||
|
while not Results.Eof do begin
|
||||||
|
if Results.Col('is_it_category', true) = 'N' then begin
|
||||||
|
FKeyword := Results.Col('name');
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
Results.Next;
|
||||||
|
end;
|
||||||
|
FreeAndNil(Results);
|
||||||
|
|
||||||
|
VT := treeTopics;
|
||||||
|
if (not Assigned(VT.FocusedNode)) // No node selected
|
||||||
|
or VT.HasChildren[VT.FocusedNode] // Selected node is a folder, not a document
|
||||||
|
or (VT.Text[VT.FocusedNode, VT.Header.MainColumn] <> FKeyword) // Node is not the right one
|
||||||
|
then begin
|
||||||
|
// Start searching in initialized nodes, to minimize number of "HELP xyz" queries in certain cases
|
||||||
|
Node := VT.GetFirst;
|
||||||
|
SearchNoInit := False;
|
||||||
|
while Assigned(Node) do begin
|
||||||
|
if (not VT.HasChildren[Node]) and (UpperCase(VT.Text[Node, VT.Header.MainColumn]) = UpperCase(FKeyword)) then begin
|
||||||
|
SelectNode(VT, Node);
|
||||||
|
break;
|
||||||
|
end;
|
||||||
|
if not SearchNoInit then begin
|
||||||
|
Node := VT.GetNextInitialized(Node);
|
||||||
|
if not Assigned(Node) then begin
|
||||||
|
SearchNoInit := True;
|
||||||
|
Node := VT.GetFirst;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
if SearchNoInit then
|
||||||
|
Node := VT.GetNext(Node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.editFilterChange(Sender: TObject);
|
||||||
|
begin
|
||||||
|
timerSearch.Enabled := False;
|
||||||
|
timerSearch.Enabled := True;
|
||||||
|
editFilter.Button.Enabled := Trim(editFilter.Text) <> '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.editFilterRightButtonClick(Sender: TObject);
|
||||||
|
begin
|
||||||
|
editFilter.Clear;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
procedure TfrmSQLhelp.DoSearch(Sender: TObject);
|
||||||
|
var
|
||||||
|
Node: PVirtualNode;
|
||||||
|
Search: String;
|
||||||
|
Vis: Boolean;
|
||||||
|
|
||||||
|
function HasVisibleChildItems(Node: PVirtualNode): Boolean;
|
||||||
|
var
|
||||||
|
N: PVirtualNode;
|
||||||
|
begin
|
||||||
|
N := treeTopics.GetFirstChild(Node);
|
||||||
|
Result := False;
|
||||||
|
while Assigned(N) do begin
|
||||||
|
if treeTopics.HasChildren[N] then
|
||||||
|
Result := HasVisibleChildItems(N)
|
||||||
|
else
|
||||||
|
Result := treeTopics.IsVisible[N];
|
||||||
|
if Result then
|
||||||
|
Exit;
|
||||||
|
N := treeTopics.GetNextSibling(N);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
begin
|
||||||
|
// Apply filter text
|
||||||
|
Screen.Cursor := crHourglass;
|
||||||
|
treeTopics.BeginUpdate;
|
||||||
|
timerSearch.Enabled := False;
|
||||||
|
Search := Trim(editFilter.Text);
|
||||||
|
if Search = '' then begin
|
||||||
|
// Show all items
|
||||||
|
Node := treeTopics.GetFirstInitialized;
|
||||||
|
while Assigned(Node) do begin
|
||||||
|
treeTopics.IsVisible[Node] := True;
|
||||||
|
Node := treeTopics.GetNextInitialized(Node);
|
||||||
|
end;
|
||||||
|
end else begin
|
||||||
|
// Hide non matching child items
|
||||||
|
Node := treeTopics.GetFirst;
|
||||||
|
while Assigned(Node) do begin
|
||||||
|
if not treeTopics.HasChildren[Node] then
|
||||||
|
treeTopics.IsVisible[Node] := Pos(UpperCase(Search), UpperCase(treeTopics.Text[Node, treeTopics.Header.MainColumn])) > 0;
|
||||||
|
Node := treeTopics.GetNext(Node);
|
||||||
|
end;
|
||||||
|
// Hide empty folders
|
||||||
|
Node := treeTopics.GetFirst;
|
||||||
|
while Assigned(Node) do begin
|
||||||
|
if treeTopics.HasChildren[Node] then begin
|
||||||
|
Vis := HasVisibleChildItems(Node);
|
||||||
|
treeTopics.Expanded[Node] := Vis;
|
||||||
|
treeTopics.IsVisible[Node] := Vis;
|
||||||
|
end;
|
||||||
|
Node := treeTopics.GetNext(Node);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
treeTopics.EndUpdate;
|
||||||
|
Screen.Cursor := crDefault;
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
Reference in New Issue
Block a user