mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-26 11:17:57 +08:00
Implement query helpers: Columns, SQL functions and SQL keywords, presented in a listbox where they can be doubleclicked or dragged to insert into query-memo.
As a benefit, function.txt is read into 3 stringlists at startup now: Names, Declarations and Descriptions. Used in SynCompletionProposal and to fill the above mentioned helpers-list. Also fixes a minor issue in SynMemoQueryDragOver using an unset "Accept" var.
This commit is contained in:
@ -908,7 +908,7 @@ object MDIChild: TMDIChild
|
||||
object SynMemoQuery: TSynMemo
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 496
|
||||
Width = 336
|
||||
Height = 96
|
||||
SingleLineMode = False
|
||||
Align = alClient
|
||||
@ -959,6 +959,48 @@ object MDIChild: TMDIChild
|
||||
end>
|
||||
AddedKeystrokes = <>
|
||||
end
|
||||
object pnlQueryHelpers: TPanel
|
||||
Left = 336
|
||||
Top = 0
|
||||
Width = 160
|
||||
Height = 96
|
||||
Align = alRight
|
||||
BevelOuter = bvNone
|
||||
TabOrder = 1
|
||||
object tabsetQueryHelpers: TTabSet
|
||||
Left = 0
|
||||
Top = 72
|
||||
Width = 160
|
||||
Height = 24
|
||||
Align = alBottom
|
||||
AutoScroll = False
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = []
|
||||
ParentShowHint = False
|
||||
ShowHint = False
|
||||
Style = tsModernTabs
|
||||
Tabs.Strings = (
|
||||
'Cols'
|
||||
'SQL fn'
|
||||
'SQL kw')
|
||||
TabIndex = 0
|
||||
OnChange = tabsetQueryHelpersChange
|
||||
end
|
||||
object lboxQueryHelpers: TListBox
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 160
|
||||
Height = 72
|
||||
Align = alClient
|
||||
DragMode = dmAutomatic
|
||||
ItemHeight = 13
|
||||
TabOrder = 1
|
||||
OnDblClick = lboxQueryHelpersDblClick
|
||||
end
|
||||
end
|
||||
end
|
||||
object gridQuery: TSMDBGrid
|
||||
Left = 0
|
||||
|
@ -21,7 +21,7 @@ uses
|
||||
ZAbstractRODataset, ZConnection,
|
||||
ZSqlMonitor, ZPlainMySqlDriver, EDBImage, ZAbstractDataset, ZDbcLogging,
|
||||
SynCompletionProposal, HeidiComp, SynEditMiscClasses, MysqlQuery,
|
||||
MysqlQueryThread, queryprogress, communication, MysqlConn, smdbgrid;
|
||||
MysqlQueryThread, queryprogress, communication, MysqlConn, smdbgrid, Tabs;
|
||||
|
||||
|
||||
type
|
||||
@ -267,6 +267,12 @@ type
|
||||
btnUnsafeEdit: TToolButton;
|
||||
btnColumnSelection: TSpeedButton;
|
||||
btnAltTerminator: TToolButton;
|
||||
pnlQueryHelpers: TPanel;
|
||||
tabsetQueryHelpers: TTabSet;
|
||||
lboxQueryHelpers: TListBox;
|
||||
procedure lboxQueryHelpersDblClick(Sender: TObject);
|
||||
procedure tabsetQueryHelpersChange(Sender: TObject; NewTab: Integer;
|
||||
var AllowChange: Boolean);
|
||||
procedure btnTableViewDataClick(Sender: TObject);
|
||||
procedure btnDbViewDataClick(Sender: TObject);
|
||||
procedure btnColumnSelectionClick(Sender: TObject);
|
||||
@ -1730,6 +1736,8 @@ end;
|
||||
Occurs when active tab has changed.
|
||||
}
|
||||
procedure TMDIChild.pcChange(Sender: TObject);
|
||||
var
|
||||
dummy : Boolean;
|
||||
begin
|
||||
tabFilter.tabVisible := (PageControlMain.ActivePage = tabData);
|
||||
|
||||
@ -1739,10 +1747,14 @@ begin
|
||||
if (PageControlMain.ActivePage = tabData) and (not dataselected) then
|
||||
viewdata(self);
|
||||
if PageControlMain.ActivePage = tabQuery then
|
||||
begin
|
||||
if ActualDatabase <> '' then
|
||||
pnlQueryTop.Caption := 'SQL-Query on Database ' + ActualDatabase + ':'
|
||||
else
|
||||
pnlQueryTop.Caption := 'SQL-Query on Host ' + FConn.MysqlParams.Host + ':';
|
||||
// Manually invoke OnChange event of tabset to fill helper list with data
|
||||
tabsetQueryHelpers.OnChange( Sender, tabsetQueryHelpers.TabIndex, dummy);
|
||||
end;
|
||||
|
||||
// Move focus to relevant controls in order for them to receive keyboard events.
|
||||
if PageControlMain.ActivePage = tabDatabase then ListTables.SetFocus;
|
||||
@ -2905,8 +2917,6 @@ procedure TMDIChild.SynCompletionProposal1Execute(Kind: TSynCompletionType;
|
||||
var CanExecute: Boolean);
|
||||
var
|
||||
i,j,c,t : Integer;
|
||||
functionname : String;
|
||||
functiondecl : String;
|
||||
tn, child : TTreeNode;
|
||||
sql, tmpsql, kw : String;
|
||||
keywords, tables : TStringList;
|
||||
@ -3069,15 +3079,10 @@ begin
|
||||
end;
|
||||
|
||||
// Add functions
|
||||
for i := 0 to MainForm.sqlfunctionlist.Count - 1 do
|
||||
for i := 0 to MainForm.SQLFunctionNames.Count - 1 do
|
||||
begin
|
||||
functionname := Copy(MainForm.sqlfunctionlist[i], 0, Pos('(', MainForm.sqlfunctionlist[i])-1);
|
||||
if Pos( '|', MainForm.sqlfunctionlist[i] ) > 0 then
|
||||
functiondecl := Copy(MainForm.sqlfunctionlist[i], Length(functionname)+1, Pos( '|', MainForm.sqlfunctionlist[i] )-Length(functionname)-1)
|
||||
else
|
||||
functiondecl := Copy(MainForm.sqlfunctionlist[i], Length(functionname)+1, Length(MainForm.sqlfunctionlist[i]) );
|
||||
SynCompletionProposal1.InsertList.Add( functionname + functiondecl );
|
||||
SynCompletionProposal1.ItemList.Add( '\hspace{2}\color{'+ColorToString(SynSQLSyn1.FunctionAttri.Foreground)+'}function\color{clWindowText}\column{}' + functionname + '\style{-B}' + functiondecl );
|
||||
SynCompletionProposal1.InsertList.Add( MainForm.SQLFunctionNames[i] + MainForm.SQLFunctionDeclarations[i] );
|
||||
SynCompletionProposal1.ItemList.Add( '\hspace{2}\color{'+ColorToString(SynSQLSyn1.FunctionAttri.Foreground)+'}function\color{clWindowText}\column{}' + MainForm.SQLFunctionNames[i] + '\style{-B}' + MainForm.SQLFunctionDeclarations[i] );
|
||||
end;
|
||||
|
||||
// Add keywords
|
||||
@ -4099,10 +4104,13 @@ end;
|
||||
|
||||
procedure TMDIChild.SynMemoQueryDragOver(Sender, Source: TObject; X,
|
||||
Y: Integer; State: TDragState; var Accept: Boolean);
|
||||
var
|
||||
src : TControl;
|
||||
begin
|
||||
// dragging an object over the query-memo
|
||||
if (Source as TControl).Parent = DBTree then
|
||||
accept := true;
|
||||
src := Source as TControl;
|
||||
// Accepting drag's from DBTree and QueryHelpers
|
||||
Accept := (src = DBTree) or (src = lboxQueryHelpers);
|
||||
// set x-position of cursor
|
||||
SynMemoQuery.CaretX := (x - SynMemoQuery.Gutter.Width) div SynMemoQuery.CharWidth - 1 + SynMemoQuery.LeftChar;
|
||||
// set y-position of cursor
|
||||
@ -4114,10 +4122,24 @@ end;
|
||||
|
||||
procedure TMDIChild.SynMemoQueryDragDrop(Sender, Source: TObject; X,
|
||||
Y: Integer);
|
||||
var
|
||||
src : TControl;
|
||||
Text : String;
|
||||
begin
|
||||
// dropping a TTreeNode into the query-memo
|
||||
SynMemoQuery.UndoList.AddGroupBreak;
|
||||
SynMemoQuery.SelText := DBTree.Selected.Text;
|
||||
src := Source as TControl;
|
||||
// Check for allowed controls as source has already
|
||||
// been performed in OnDragOver. So, only do typecasting here.
|
||||
if src is TTreeView then
|
||||
begin
|
||||
Text := (src as TTreeView).Selected.Text;
|
||||
end
|
||||
else if src is TListBox then
|
||||
begin
|
||||
Text := (src as TListBox).Items[(src as TListBox).ItemIndex];
|
||||
end;
|
||||
SynMemoQuery.SelText := Text;
|
||||
SynMemoQuery.UndoList.AddGroupBreak;
|
||||
end;
|
||||
|
||||
@ -5320,6 +5342,68 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{**
|
||||
Tabset right to query-memo was clicked
|
||||
}
|
||||
procedure TMDIChild.tabsetQueryHelpersChange(Sender: TObject; NewTab: Integer;
|
||||
var AllowChange: Boolean);
|
||||
var
|
||||
i : Integer;
|
||||
begin
|
||||
// Leaving early if method was invoked manually without changing
|
||||
// the tabIndex while listbox is already filled
|
||||
if (NewTab = tabsetQueryHelpers.TabIndex) and (lboxQueryHelpers.Items.Count > 0) then
|
||||
exit;
|
||||
|
||||
lboxQueryHelpers.Items.BeginUpdate;
|
||||
lboxQueryHelpers.Items.Clear;
|
||||
// By default sorted alpabetically
|
||||
lboxQueryHelpers.Sorted := True;
|
||||
|
||||
case NewTab of
|
||||
0: // Cols
|
||||
begin
|
||||
// Keep native order of columns
|
||||
lboxQueryHelpers.Sorted := False;
|
||||
for i := 0 to ListColumns.Items.Count - 1 do
|
||||
begin
|
||||
lboxQueryHelpers.Items.Add(ListColumns.Items[i].Caption);
|
||||
end;
|
||||
end;
|
||||
|
||||
1: // SQL functions
|
||||
begin
|
||||
for i := 0 to Mainform.SQLFunctionNames.Count - 1 do
|
||||
begin
|
||||
lboxQueryHelpers.Items.Add( Mainform.SQLFunctionNames[i] + Mainform.SQLFunctionDeclarations[i] );
|
||||
end;
|
||||
end;
|
||||
|
||||
2: // SQL keywords
|
||||
begin
|
||||
lboxQueryHelpers.Items := MYSQL_KEYWORDS;
|
||||
lboxQueryHelpers.Sorted := True;
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
lboxQueryHelpers.Items.EndUpdate;
|
||||
|
||||
end;
|
||||
|
||||
|
||||
|
||||
{**
|
||||
Insert string from listbox with query helpers into SQL
|
||||
memo at doubleclick
|
||||
}
|
||||
procedure TMDIChild.lboxQueryHelpersDblClick(Sender: TObject);
|
||||
begin
|
||||
SynMemoQuery.SelText := lboxQueryHelpers.Items[lboxQueryHelpers.ItemIndex];
|
||||
end;
|
||||
|
||||
|
||||
|
||||
end.
|
||||
|
||||
|
||||
|
@ -229,7 +229,9 @@ type
|
||||
NativeFieldTypes : Boolean;
|
||||
LanguageOffset : Integer;
|
||||
DataNullBackground : TColor;
|
||||
sqlfunctionlist : TStringList;
|
||||
SQLFunctionNames,
|
||||
SQLFunctionDeclarations,
|
||||
SQLFunctionDescriptions : TStringList;
|
||||
function GetRegValue( valueName: String; defaultValue: Integer; key: String = '' ) : Integer; Overload;
|
||||
function GetRegValue( valueName: String; defaultValue: Boolean; key: String = '' ) : Boolean; Overload;
|
||||
procedure SaveRegValue( valueName: String; value: Integer; key: String = '' ); Overload;
|
||||
@ -432,7 +434,10 @@ var
|
||||
ws : String;
|
||||
mi : TMenuItem;
|
||||
f : TextFile;
|
||||
functionname, functionhint : String;
|
||||
FunctionLine,
|
||||
FunctionName,
|
||||
FunctionDeclaration,
|
||||
FunctionDescription : String;
|
||||
i, pipeposition : Integer;
|
||||
begin
|
||||
caption := APPNAME;
|
||||
@ -499,28 +504,40 @@ begin
|
||||
AssignFile(f, ExtractFilePath(paramstr(0)) + 'function.txt');
|
||||
Reset(f);
|
||||
i := 1;
|
||||
SQLFunctionNames := TStringList.Create;
|
||||
SQLFunctionDeclarations := TStringList.Create;
|
||||
SQLFunctionDescriptions := TStringList.Create;
|
||||
|
||||
while not eof(f) do
|
||||
begin
|
||||
functionname := '';
|
||||
Readln(f, functionname);
|
||||
pipeposition := pos('|', functionname);
|
||||
if pipeposition > 0 then // read hint
|
||||
begin
|
||||
if sqlfunctionlist = nil then
|
||||
sqlfunctionlist := TStringList.Create;
|
||||
sqlfunctionlist.Add( trim(functionname) );
|
||||
functionhint := copy(functionname, 0, pipeposition-1) + ' - ' + copy(functionname, pipeposition+1, length(functionname)-1);
|
||||
functionname := copy(functionname, 0, pos('(', functionname)-1);
|
||||
end else
|
||||
functionhint := '';
|
||||
if (functionname[1] <> '#') and (length(trim(functionname)) > 0) then
|
||||
FunctionName := '';
|
||||
FunctionDeclaration := '';
|
||||
FunctionDescription := '';
|
||||
Readln(f, FunctionLine);
|
||||
|
||||
if (length(FunctionLine) > 0) and (FunctionLine[1] <> '#') then
|
||||
begin
|
||||
FunctionName := FunctionLine;
|
||||
if pos('(', FunctionName) > 0 then
|
||||
FunctionName := copy(FunctionName, 0, pos('(', FunctionName)-1);
|
||||
FunctionName := trim(FunctionName);
|
||||
|
||||
FunctionDeclaration := Copy(FunctionLine, 0, Pos( ')', FunctionLine ) );
|
||||
FunctionDeclaration := Copy(FunctionDeclaration, Pos( '(', FunctionDeclaration ), Length(FunctionDeclaration) );
|
||||
|
||||
pipeposition := pos('|', FunctionLine);
|
||||
if pipeposition > 0 then // read hint
|
||||
begin
|
||||
FunctionDescription := copy(FunctionLine, 0, pipeposition-1) + ' - ' + copy(FunctionLine, pipeposition+1, length(FunctionLine)-1);
|
||||
FunctionDescription := trim(FunctionDescription);
|
||||
end;
|
||||
|
||||
mi := TMenuItem.Create(self);
|
||||
mi.Caption := trim(functionname);
|
||||
mi.Hint := trim(functionhint);
|
||||
mi.Caption := FunctionName;
|
||||
mi.Hint := FunctionDescription;
|
||||
mi.OnClick := insertFunction;
|
||||
if functionname[1] <> ' ' then // build submenu
|
||||
|
||||
if FunctionLine[1] <> ' ' then // build submenu
|
||||
begin
|
||||
SQLfunctions.Items.add(mi);
|
||||
inc(i);
|
||||
@ -528,6 +545,9 @@ begin
|
||||
begin
|
||||
SQLfunctions.Items[i+11].OnClick := nil; // deactivate parent Menuitem
|
||||
SQLfunctions.Items[i+11].Add(mi);
|
||||
SQLFunctionNames.Add(FunctionName);
|
||||
SQLFunctionDeclarations.Add(FunctionDeclaration);
|
||||
SQLFunctionDescriptions.Add(FunctionDescription);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
Reference in New Issue
Block a user