mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2026-03-13 09:24:25 +08:00
Issue #1525: remove project manager feature with all its unrelated changes
This commit is contained in:
@@ -6768,95 +6768,3 @@ msgstr "Select top %s rows"
|
||||
|
||||
msgid "Selects the first %s rows in a new query tab"
|
||||
msgstr "Selects the first %s rows in a new query tab"
|
||||
|
||||
#. Project Manager
|
||||
msgid "Project Manager"
|
||||
msgstr "Project Manager"
|
||||
|
||||
msgid "Project &Manager"
|
||||
msgstr "Project &Manager"
|
||||
|
||||
msgid "Toggle Project Manager tab in query helpers (F11)"
|
||||
msgstr "Toggle Project Manager tab in query helpers (F11)"
|
||||
|
||||
#. Project Manager - Button hints
|
||||
msgid "Add Project Folder"
|
||||
msgstr "Add Project Folder"
|
||||
|
||||
msgid "Remove Project Folder"
|
||||
msgstr "Remove Project Folder"
|
||||
|
||||
msgid "Rename Project"
|
||||
msgstr "Rename Project"
|
||||
|
||||
msgid "Refresh Projects"
|
||||
msgstr "Refresh Projects"
|
||||
|
||||
#. Project Manager - Context menu
|
||||
msgid "Open File"
|
||||
msgstr "Open File"
|
||||
|
||||
msgid "Open with System Editor"
|
||||
msgstr "Open with System Editor"
|
||||
|
||||
msgid "Open Folder"
|
||||
msgstr "Open Folder"
|
||||
|
||||
msgid "Copy Path"
|
||||
msgstr "Copy Path"
|
||||
|
||||
msgid "Add Project Folder..."
|
||||
msgstr "Add Project Folder..."
|
||||
|
||||
msgid "Remove Project"
|
||||
msgstr "Remove Project"
|
||||
|
||||
#. Project Manager - Dialogs
|
||||
msgid "Select Project Folder"
|
||||
msgstr "Select Project Folder"
|
||||
|
||||
msgid "Root"
|
||||
msgstr "Root"
|
||||
|
||||
msgid "Project Name"
|
||||
msgstr "Project Name"
|
||||
|
||||
msgid "Enter a name for this project:"
|
||||
msgstr "Enter a name for this project:"
|
||||
|
||||
#. Project Manager - Error messages
|
||||
msgid "Error in CreateWnd: "
|
||||
msgstr "Error in CreateWnd: "
|
||||
|
||||
msgid "Project name cannot be empty!"
|
||||
msgstr "Project name cannot be empty!"
|
||||
|
||||
msgid "A project with this name already exists!"
|
||||
msgstr "A project with this name already exists!"
|
||||
|
||||
msgid "This folder is already added as a project!"
|
||||
msgstr "This folder is already added as a project!"
|
||||
|
||||
msgid "Please select a project to remove."
|
||||
msgstr "Please select a project to remove."
|
||||
|
||||
msgid "Project not found in list."
|
||||
msgstr "Project not found in list."
|
||||
|
||||
msgid "Please select a project to rename."
|
||||
msgstr "Please select a project to rename."
|
||||
|
||||
msgid "Database files should be opened via the connection manager."
|
||||
msgstr "Database files should be opened via the connection manager."
|
||||
|
||||
msgid "Use File > Connect to Database to open this SQLite database."
|
||||
msgstr "Use File > Connect to Database to open this SQLite database."
|
||||
|
||||
msgid "Failed to copy path to clipboard: "
|
||||
msgstr "Failed to copy path to clipboard: "
|
||||
|
||||
msgid "Error saving projects: "
|
||||
msgstr "Error saving projects: "
|
||||
|
||||
msgid "Error opening file: "
|
||||
msgstr "Error opening file: "
|
||||
|
||||
3
packages/Delphi12.1/heidisql.dpr
vendored
3
packages/Delphi12.1/heidisql.dpr
vendored
@@ -58,8 +58,7 @@ uses
|
||||
customize_highlighter in '..\..\source\customize_highlighter.pas' {frmCustomizeHighlighter},
|
||||
Xml.VerySimple in '..\..\source\Xml.VerySimple.pas',
|
||||
Sequal.Suggest in '..\..\source\Sequal.Suggest.pas' {SequalSuggestForm},
|
||||
reformatter in '..\..\source\reformatter.pas' {frmReformatter},
|
||||
projectmanager in '..\..\source\projectmanager.pas';
|
||||
reformatter in '..\..\source\reformatter.pas' {frmReformatter};
|
||||
|
||||
{.$R *.RES}
|
||||
{$R ..\..\res\icon.RES}
|
||||
|
||||
1
packages/Delphi12.1/heidisql.dproj
vendored
1
packages/Delphi12.1/heidisql.dproj
vendored
@@ -265,7 +265,6 @@
|
||||
<Form>frmReformatter</Form>
|
||||
<FormType>dfm</FormType>
|
||||
</DCCReference>
|
||||
<DCCReference Include="..\..\source\projectmanager.pas"/>
|
||||
<None Include="..\..\source\const.inc"/>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
|
||||
3
packages/Delphi12.3/heidisql.dpr
vendored
3
packages/Delphi12.3/heidisql.dpr
vendored
@@ -58,8 +58,7 @@ uses
|
||||
customize_highlighter in '..\..\source\customize_highlighter.pas' {frmCustomizeHighlighter},
|
||||
Xml.VerySimple in '..\..\source\Xml.VerySimple.pas',
|
||||
Sequal.Suggest in '..\..\source\Sequal.Suggest.pas' {SequalSuggestForm},
|
||||
reformatter in '..\..\source\reformatter.pas' {frmReformatter},
|
||||
projectmanager in '..\..\source\projectmanager.pas';
|
||||
reformatter in '..\..\source\reformatter.pas' {frmReformatter};
|
||||
|
||||
{.$R *.RES}
|
||||
{$R ..\..\res\icon.RES}
|
||||
|
||||
1
packages/Delphi12.3/heidisql.dproj
vendored
1
packages/Delphi12.3/heidisql.dproj
vendored
@@ -267,7 +267,6 @@
|
||||
<Form>frmReformatter</Form>
|
||||
<FormType>dfm</FormType>
|
||||
</DCCReference>
|
||||
<DCCReference Include="..\..\source\projectmanager.pas"/>
|
||||
<None Include="..\..\source\const.inc"/>
|
||||
<BuildConfiguration Include="Base">
|
||||
<Key>Base</Key>
|
||||
|
||||
@@ -182,7 +182,7 @@ type
|
||||
asMaxColWidth, asDatagridMaximumRows, asDatagridRowsPerStep, asGridRowLineCount, asColumnHeaderClick, asReuseEditorConfiguration,
|
||||
asLogToFile, asMainWinMaximized, asMainWinLeft, asMainWinTop, asMainWinWidth,
|
||||
asMainWinHeight, asMainWinOnMonitor, asCoolBandIndex, asCoolBandBreak, asCoolBandWidth, asToolbarShowCaptions, asQuerymemoheight, asDbtreewidth,
|
||||
asDataPreviewHeight, asDataPreviewEnabled, asLogHeight, asQueryhelperswidth, asProjectManagerWidth, asProjectManagerVisible, asProjectManagerTabActive, asStopOnErrorsInBatchMode,
|
||||
asDataPreviewHeight, asDataPreviewEnabled, asLogHeight, asQueryhelperswidth, asStopOnErrorsInBatchMode,
|
||||
asWrapLongLines, asCodeFolding, asDisplayBLOBsAsText, asSingleQueries, asMemoEditorWidth, asMemoEditorHeight, asMemoEditorMaximized,
|
||||
asMemoEditorWrap, asMemoEditorHighlighter, asMemoEditorAlwaysFormatCode, asDelimiter, asSQLHelpWindowLeft, asSQLHelpWindowTop, asSQLHelpWindowWidth,
|
||||
asSQLHelpWindowHeight, asSQLHelpPnlLeftWidth, asSQLHelpPnlRightTopHeight, asHost,
|
||||
@@ -236,7 +236,6 @@ type
|
||||
asSequalSuggestWindowWidth, asSequalSuggestWindowHeight, asSequalSuggestPrompt, asSequalSuggestRecentPrompts,
|
||||
asReformatter, asReformatterNoDialog, asAlwaysGenerateFilter,
|
||||
asGenerateDataNumRows, asGenerateDataNullAmount, asWebOnceAction,
|
||||
asProjectManagerHeight,
|
||||
asUnused);
|
||||
TAppSetting = record
|
||||
Name: String;
|
||||
@@ -528,10 +527,10 @@ begin
|
||||
Exit;
|
||||
if FromLeft then begin
|
||||
SetLength(Result, MaxLen);
|
||||
Result[MaxLen] := '.';
|
||||
Result[MaxLen] := '<EFBFBD>';
|
||||
end else begin
|
||||
Result := Copy(Result, Length(Result)-MaxLen, Length(Result));
|
||||
Result := '…' + Result;
|
||||
Result := '<EFBFBD>' + Result;
|
||||
end;
|
||||
end;
|
||||
|
||||
@@ -854,7 +853,7 @@ end;
|
||||
|
||||
function RoundCommercial(e: Extended): Int64;
|
||||
begin
|
||||
// "Kaufmännisch runden"
|
||||
// "Kaufm<EFBFBD>nnisch runden"
|
||||
// In contrast to Delphi's Round() which rounds *.5 to the next even number
|
||||
Result := Trunc(e);
|
||||
if Frac(e) >= 0.5 then
|
||||
@@ -3793,9 +3792,6 @@ begin
|
||||
InitSetting(asDataPreviewEnabled, 'DataPreviewEnabled', 0, False);
|
||||
InitSetting(asLogHeight, 'sqloutheight', 80);
|
||||
InitSetting(asQueryhelperswidth, 'queryhelperswidth', 200);
|
||||
InitSetting(asProjectManagerWidth, 'projectmanagerwidth', 260);
|
||||
InitSetting(asProjectManagerVisible, 'projectmanagervisible', 0, True);
|
||||
InitSetting(asProjectManagerTabActive, 'projectmanagertabactive', 0, False);
|
||||
InitSetting(asStopOnErrorsInBatchMode, 'StopOnErrorsInBatchMode', 0, True);
|
||||
InitSetting(asWrapLongLines, 'WrapLongLines', 0, False);
|
||||
InitSetting(asCodeFolding, 'CodeFolding', 0, True);
|
||||
@@ -4056,7 +4052,6 @@ begin
|
||||
InitSetting(asCreateDbCollation, 'CreateDbCollation', 0, False, '');
|
||||
InitSetting(asRealTrailingZeros, 'RealTrailingZeros', 1);
|
||||
InitSetting(asWebOnceAction, 'WebOnceAction', 0, False, DateToStr(DateTimeNever));
|
||||
InitSetting(asProjectManagerHeight, 'ProjectManagerHeight', 200);
|
||||
|
||||
// Initialization values
|
||||
FRestoreTabsInitValue := ReadBool(asRestoreTabs);
|
||||
|
||||
@@ -155,7 +155,6 @@ object MainForm: TMainForm
|
||||
DragMode = dmAutomatic
|
||||
DragType = dtVCL
|
||||
Header.AutoSizeIndex = 0
|
||||
Header.Height = 18
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDrag]
|
||||
HintMode = hmTooltip
|
||||
HotCursor = crHandPoint
|
||||
@@ -191,7 +190,7 @@ object MainForm: TMainForm
|
||||
item
|
||||
Position = 0
|
||||
Text = 'Name'
|
||||
Width = 169
|
||||
Width = 165
|
||||
end
|
||||
item
|
||||
Alignment = taRightJustify
|
||||
@@ -432,7 +431,6 @@ object MainForm: TMainForm
|
||||
Height = 195
|
||||
Align = alClient
|
||||
Header.AutoSizeIndex = 0
|
||||
Header.Height = 18
|
||||
Header.Options = [hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoShowSortGlyphs, hoVisible, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
Header.PopupMenu = popupListHeader
|
||||
Header.SortColumn = 0
|
||||
@@ -516,7 +514,7 @@ object MainForm: TMainForm
|
||||
Align = alClient
|
||||
DragOperations = []
|
||||
Header.AutoSizeIndex = 2
|
||||
Header.Height = 18
|
||||
Header.Height = 20
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoShowSortGlyphs, hoVisible, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
Header.PopupMenu = popupListHeader
|
||||
Header.SortColumn = 0
|
||||
@@ -559,7 +557,7 @@ object MainForm: TMainForm
|
||||
item
|
||||
Position = 2
|
||||
Text = 'Global'
|
||||
Width = 316
|
||||
Width = 312
|
||||
end>
|
||||
end
|
||||
end
|
||||
@@ -574,7 +572,7 @@ object MainForm: TMainForm
|
||||
Align = alClient
|
||||
DragOperations = []
|
||||
Header.AutoSizeIndex = 1
|
||||
Header.Height = 18
|
||||
Header.Height = 20
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoShowSortGlyphs, hoVisible, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
Header.PopupMenu = popupListHeader
|
||||
Header.SortColumn = 0
|
||||
@@ -611,7 +609,7 @@ object MainForm: TMainForm
|
||||
Alignment = taRightJustify
|
||||
Position = 1
|
||||
Text = 'Value'
|
||||
Width = 316
|
||||
Width = 312
|
||||
end
|
||||
item
|
||||
Alignment = taRightJustify
|
||||
@@ -646,7 +644,7 @@ object MainForm: TMainForm
|
||||
Height = 122
|
||||
Align = alClient
|
||||
Header.AutoSizeIndex = 7
|
||||
Header.Height = 18
|
||||
Header.Height = 20
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoShowSortGlyphs, hoVisible, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
Header.PopupMenu = popupListHeader
|
||||
Header.SortColumn = 0
|
||||
@@ -713,7 +711,7 @@ object MainForm: TMainForm
|
||||
item
|
||||
Position = 7
|
||||
Text = 'Info'
|
||||
Width = 186
|
||||
Width = 182
|
||||
end>
|
||||
end
|
||||
object pnlProcessViewBox: TPanel
|
||||
@@ -795,7 +793,7 @@ object MainForm: TMainForm
|
||||
Height = 195
|
||||
Align = alClient
|
||||
Header.AutoSizeIndex = 4
|
||||
Header.Height = 18
|
||||
Header.Height = 20
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoShowSortGlyphs, hoVisible, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
Header.PopupMenu = popupListHeader
|
||||
Header.SortColumn = 1
|
||||
@@ -850,7 +848,7 @@ object MainForm: TMainForm
|
||||
item
|
||||
Position = 4
|
||||
Text = 'Percentage'
|
||||
Width = 256
|
||||
Width = 252
|
||||
end>
|
||||
end
|
||||
end
|
||||
@@ -867,7 +865,7 @@ object MainForm: TMainForm
|
||||
Align = alClient
|
||||
EditDelay = 500
|
||||
Header.AutoSizeIndex = -1
|
||||
Header.Height = 18
|
||||
Header.Height = 20
|
||||
Header.Options = [hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoShowSortGlyphs, hoVisible, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
Header.PopupMenu = popupListHeader
|
||||
Header.SortColumn = 0
|
||||
@@ -1029,8 +1027,6 @@ object MainForm: TMainForm
|
||||
Caption = 'No data available for this item.'
|
||||
Layout = tlCenter
|
||||
WordWrap = True
|
||||
ExplicitWidth = 165
|
||||
ExplicitHeight = 14
|
||||
end
|
||||
object pnlDataTop: TPanel
|
||||
Left = 0
|
||||
@@ -1242,7 +1238,7 @@ object MainForm: TMainForm
|
||||
AutoScrollDelay = 50
|
||||
EditDelay = 0
|
||||
Header.AutoSizeIndex = -1
|
||||
Header.Height = 14
|
||||
Header.Height = 20
|
||||
Header.Images = VirtualImageListMain
|
||||
Header.MainColumn = -1
|
||||
Header.Options = [hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoOwnerDraw, hoShowHint, hoShowImages, hoVisible, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
@@ -1404,7 +1400,6 @@ object MainForm: TMainForm
|
||||
DragMode = dmAutomatic
|
||||
DragType = dtVCL
|
||||
Header.AutoSizeIndex = 0
|
||||
Header.Height = 18
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs]
|
||||
Images = VirtualImageListMain
|
||||
IncrementalSearch = isVisibleOnly
|
||||
@@ -1437,7 +1432,7 @@ object MainForm: TMainForm
|
||||
item
|
||||
Position = 0
|
||||
Text = 'Main column'
|
||||
Width = 85
|
||||
Width = 64
|
||||
end
|
||||
item
|
||||
Position = 1
|
||||
@@ -1471,7 +1466,7 @@ object MainForm: TMainForm
|
||||
AutoScrollDelay = 50
|
||||
EditDelay = 0
|
||||
Header.AutoSizeIndex = -1
|
||||
Header.Height = 14
|
||||
Header.Height = 20
|
||||
Header.Images = VirtualImageListMain
|
||||
Header.MainColumn = -1
|
||||
Header.Options = [hoColumnResize, hoDblClickResize, hoDrag, hoHotTrack, hoOwnerDraw, hoShowHint, hoShowImages, hoDisableAnimatedResize, hoAutoResizeInclCaption]
|
||||
|
||||
506
source/main.pas
506
source/main.pas
@@ -16,7 +16,7 @@ uses
|
||||
Winapi.CommCtrl, System.Contnrs, System.Generics.Collections, System.Generics.Defaults, SynEditExport, SynExportHTML, SynExportRTF, System.Math, Vcl.ExtDlgs, System.Win.Registry, Vcl.AppEvnts,
|
||||
routine_editor, trigger_editor, event_editor, preferences, EditVar, apphelpers, createdatabase, table_editor,
|
||||
TableTools, View, Usermanager, SelectDBObject, connections, sqlhelp, dbconnection,
|
||||
insertfiles, searchreplace, loaddata, copytable, csv_detector, Cromis.DirectoryWatch, SyncDB, gnugettext, projectmanager,
|
||||
insertfiles, searchreplace, loaddata, copytable, csv_detector, Cromis.DirectoryWatch, SyncDB, gnugettext,
|
||||
VirtualTrees, VirtualTrees.HeaderPopup, VirtualTrees.Utils, VirtualTrees.Types,
|
||||
JumpList, System.Actions, System.UITypes, Vcl.Imaging.pngimage,
|
||||
System.ImageList, Vcl.Styles.Utils.Forms,
|
||||
@@ -102,10 +102,6 @@ type
|
||||
pnlMemo: TPanel;
|
||||
Memo: TSynMemo;
|
||||
pnlHelpers: TPanel;
|
||||
pcHelpers: TPageControl; // PageControl for Helpers and Project Manager
|
||||
tabHelpers: TTabSheet; // Tab for the original Helpers
|
||||
tabProjectManager: TTabSheet; // Tab for the Project Manager
|
||||
projectManagerPanel: TProjectManagerPanel; // Project Manager Instance pro Tab
|
||||
filterHelpers: TButtonedEdit;
|
||||
treeHelpers: TVirtualStringTree;
|
||||
MemoFileRenamed: Boolean;
|
||||
@@ -507,7 +503,6 @@ type
|
||||
pnlRight: TPanel;
|
||||
btnCloseFilterPanel: TSpeedButton;
|
||||
actFilterPanel: TAction;
|
||||
actProjectManager: TAction;
|
||||
actFindInVT1: TMenuItem;
|
||||
TimerFilterVT: TTimer;
|
||||
actFindTextOnServer: TAction;
|
||||
@@ -800,7 +795,6 @@ type
|
||||
actGenerateData: TAction;
|
||||
Generatedata1: TMenuItem;
|
||||
Generatedata2: TMenuItem;
|
||||
menuProjectManager: TMenuItem;
|
||||
actCopyGridNodes: TAction;
|
||||
actCopyGridNodes1: TMenuItem;
|
||||
actQueryTable: TAction;
|
||||
@@ -1003,9 +997,6 @@ type
|
||||
procedure actCloseQueryTabExecute(Sender: TObject);
|
||||
procedure menuCloseQueryTabClick(Sender: TObject);
|
||||
procedure CloseQueryTab(PageIndex: Integer);
|
||||
function GetQueryTabBackupFilename(Tab: TQueryTab): String;
|
||||
procedure SaveQueryTabBackupToIni(Tab: TQueryTab; const BackupFilename: String);
|
||||
function ShouldCreateQueryTabBackup(Tab: TQueryTab): Boolean;
|
||||
procedure CloseButtonOnMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
procedure CloseButtonOnMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer);
|
||||
function GetMainTabAt(X, Y: Integer): Integer;
|
||||
@@ -1016,7 +1007,6 @@ type
|
||||
procedure popupMainTabsPopup(Sender: TObject);
|
||||
procedure FormCloseQuery(Sender: TObject; var CanClose: Boolean);
|
||||
procedure actFilterPanelExecute(Sender: TObject);
|
||||
procedure actProjectManagerExecute(Sender: TObject);
|
||||
procedure TimerFilterVTTimer(Sender: TObject);
|
||||
procedure PageControlMainContextPopup(Sender: TObject; MousePos: TPoint; var Handled: Boolean);
|
||||
procedure menuQueryHelpersGenerateStatementClick(Sender: TObject);
|
||||
@@ -1212,14 +1202,7 @@ type
|
||||
var HintText: string);
|
||||
procedure actCopyGridNodesExecute(Sender: TObject);
|
||||
procedure actQueryTableExecute(Sender: TObject);
|
||||
procedure ToggleProjectManager; // Toggle Project Manager Panel visibility
|
||||
procedure ApplyProjectManagerStateToActiveTab; // Apply global Project Manager state to active tab
|
||||
procedure HelpersPageControlChange(Sender: TObject); // Handle manual tab changes in helpers PageControl
|
||||
procedure SynchronizeAllQueryTabsToGlobalState(ExcludeTab: TQueryTab = nil); // Sync all tabs to global state
|
||||
private
|
||||
// Project Manager global state
|
||||
FProjectManagerTabActive: Boolean; // Global state: should Project Manager tab be active?
|
||||
|
||||
// Executable file details
|
||||
FAppVerMajor: Integer;
|
||||
FAppVerMinor: Integer;
|
||||
@@ -1328,7 +1311,6 @@ type
|
||||
procedure StoreTabs;
|
||||
function RestoreTabs: Boolean;
|
||||
procedure SetHintFontByControl(Control: TWinControl=nil);
|
||||
private
|
||||
public
|
||||
QueryTabs: TQueryTabList;
|
||||
ActiveObjectEditor: TDBObjectEditor;
|
||||
@@ -1870,7 +1852,6 @@ begin
|
||||
AppSettings.WriteBool(asDataPreviewEnabled, actDataPreview.Checked);
|
||||
AppSettings.WriteInt(asLogHeight, SynMemoSQLLog.Height);
|
||||
AppSettings.WriteBool(asFilterPanel, actFilterPanel.Checked);
|
||||
AppSettings.WriteBool(asProjectManagerTabActive, FProjectManagerTabActive);
|
||||
AppSettings.WriteBool(asWrapLongLines, actQueryWordWrap.Checked);
|
||||
AppSettings.WriteBool(asCodeFolding, actCodeFolding.Checked);
|
||||
AppSettings.WriteBool(asSingleQueries, actSingleQueries.Checked);
|
||||
@@ -2027,54 +2008,6 @@ begin
|
||||
QueryTab.Uid := TQueryTab.GenerateUid;
|
||||
QueryTab.pnlMemo := pnlQueryMemo;
|
||||
QueryTab.pnlHelpers := pnlQueryHelpers;
|
||||
|
||||
// Convert the first tab to use the new PageControl system
|
||||
// Create PageControl for the existing pnlQueryHelpers
|
||||
QueryTab.pcHelpers := TPageControl.Create(QueryTab.pnlHelpers);
|
||||
QueryTab.pcHelpers.Name := 'pcHelpers0';
|
||||
QueryTab.pcHelpers.Parent := QueryTab.pnlHelpers;
|
||||
QueryTab.pcHelpers.Align := alClient;
|
||||
QueryTab.pcHelpers.TabPosition := tpTop;
|
||||
QueryTab.pcHelpers.Style := tsButtons;
|
||||
QueryTab.pcHelpers.OnChange := HelpersPageControlChange; // Event handler for tab changes
|
||||
|
||||
// Create "Helpers" tab and move existing components
|
||||
QueryTab.tabHelpers := TTabSheet.Create(QueryTab.pcHelpers);
|
||||
QueryTab.tabHelpers.Name := 'tabHelpers0';
|
||||
QueryTab.tabHelpers.Caption := 'Helpers';
|
||||
QueryTab.tabHelpers.PageControl := QueryTab.pcHelpers;
|
||||
|
||||
// Move existing components to the Helpers tab
|
||||
filterQueryHelpers.Parent := QueryTab.tabHelpers;
|
||||
treeQueryHelpers.Parent := QueryTab.tabHelpers;
|
||||
|
||||
// Create "Project Manager" tab
|
||||
QueryTab.tabProjectManager := TTabSheet.Create(QueryTab.pcHelpers);
|
||||
QueryTab.tabProjectManager.Name := 'tabProjectManager0';
|
||||
QueryTab.tabProjectManager.Caption := 'Project Manager';
|
||||
QueryTab.tabProjectManager.PageControl := QueryTab.pcHelpers;
|
||||
|
||||
// Create Project Manager in the Project Manager tab
|
||||
try
|
||||
QueryTab.projectManagerPanel := TProjectManagerPanel.Create(QueryTab.tabProjectManager);
|
||||
QueryTab.projectManagerPanel.Parent := QueryTab.tabProjectManager;
|
||||
QueryTab.projectManagerPanel.Align := alClient;
|
||||
LogSQL('Project Manager panel created successfully in main query tab', lcDebug);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
LogSQL('Error creating Project Manager in main query tab: ' + E.Message, lcError);
|
||||
QueryTab.projectManagerPanel := nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Set initial active tab based on global Project Manager state (loaded from settings)
|
||||
FProjectManagerTabActive := AppSettings.ReadBool(asProjectManagerTabActive, '', False);
|
||||
if FProjectManagerTabActive then
|
||||
QueryTab.pcHelpers.ActivePage := QueryTab.tabProjectManager
|
||||
else
|
||||
QueryTab.pcHelpers.ActivePage := QueryTab.tabHelpers;
|
||||
|
||||
QueryTab.filterHelpers := filterQueryHelpers;
|
||||
QueryTab.treeHelpers := treeQueryHelpers;
|
||||
QueryTab.Memo := SynMemoQuery;
|
||||
@@ -2255,33 +2188,6 @@ begin
|
||||
LogSQL(f_('Theme: "%s"', [TStyleManager.ActiveStyle.Name]), lcDebug);
|
||||
LogSQL(f_('Pixels per inch on current monitor: %d', [Monitor.PixelsPerInch]), lcDebug);
|
||||
LogSQL(f_('Timezone offset: %d', [FTimeZoneOffset]), lcDebug);
|
||||
|
||||
// Create and configure Project Manager action for tab switching
|
||||
try
|
||||
if not Assigned(actProjectManager) then
|
||||
begin
|
||||
actProjectManager := TAction.Create(Self);
|
||||
actProjectManager.ActionList := ActionList1;
|
||||
actProjectManager.Category := 'View';
|
||||
actProjectManager.Name := 'actProjectManager';
|
||||
end;
|
||||
|
||||
if Assigned(actProjectManager) then
|
||||
begin
|
||||
actProjectManager.Caption := _('Project &Manager');
|
||||
actProjectManager.Hint := _('Toggle Project Manager tab in query helpers (F11)');
|
||||
actProjectManager.ShortCut := VK_F11;
|
||||
actProjectManager.OnExecute := actProjectManagerExecute;
|
||||
actProjectManager.Checked := FProjectManagerTabActive; // Reflect global state
|
||||
|
||||
LogSQL('Project Manager action configured for tab switching', lcDebug);
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
LogSQL('Error creating Project Manager action: ' + E.Message, lcError);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
@@ -6455,11 +6361,6 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
// Apply global Project Manager state to newly active query tab (always, not just on manual clicks)
|
||||
if IsQueryTab(tab.PageIndex, True) then begin
|
||||
ApplyProjectManagerStateToActiveTab;
|
||||
end;
|
||||
|
||||
// Filter panel has one text per tab, which we need to update
|
||||
UpdateFilterPanel(Sender);
|
||||
|
||||
@@ -11969,29 +11870,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.ToggleProjectManager;
|
||||
begin
|
||||
// Toggle global Project Manager state
|
||||
FProjectManagerTabActive := not FProjectManagerTabActive;
|
||||
|
||||
{$IFDEF DEBUG}
|
||||
LogSQL(Format('Toggled Project Manager state to: %s', [BoolToStr(FProjectManagerTabActive, True)]), lcDebug);
|
||||
{$ENDIF}
|
||||
|
||||
// Apply the state to all existing query tabs
|
||||
SynchronizeAllQueryTabsToGlobalState;
|
||||
|
||||
// Update action checked state
|
||||
if Assigned(actProjectManager) then
|
||||
actProjectManager.Checked := FProjectManagerTabActive;
|
||||
|
||||
// Show status message
|
||||
if FProjectManagerTabActive then
|
||||
ShowStatusMsg('Project Manager activated for all query tabs')
|
||||
else
|
||||
ShowStatusMsg('Helpers activated for all query tabs');
|
||||
end;
|
||||
|
||||
procedure TMainForm.actCopyGridNodesExecute(Sender: TObject);
|
||||
var
|
||||
SenderControl: TComponent;
|
||||
@@ -12575,32 +12453,10 @@ begin
|
||||
else
|
||||
QueryTab.pnlHelpers.Width := AppSettings.GetDefaultInt(asQueryhelperswidth);
|
||||
|
||||
// Create PageControl for Helpers and Project Manager tabs
|
||||
QueryTab.pcHelpers := TPageControl.Create(QueryTab.pnlHelpers);
|
||||
QueryTab.pcHelpers.Name := 'pcHelpers' + i.ToString;
|
||||
QueryTab.pcHelpers.Parent := QueryTab.pnlHelpers;
|
||||
QueryTab.pcHelpers.Align := alClient;
|
||||
QueryTab.pcHelpers.TabPosition := tpTop;
|
||||
QueryTab.pcHelpers.Style := tsButtons;
|
||||
QueryTab.pcHelpers.OnChange := HelpersPageControlChange; // Event handler for tab changes
|
||||
|
||||
// Create "Helpers" tab
|
||||
QueryTab.tabHelpers := TTabSheet.Create(QueryTab.pcHelpers);
|
||||
QueryTab.tabHelpers.Name := 'tabHelpers' + i.ToString;
|
||||
QueryTab.tabHelpers.Caption := 'Helpers';
|
||||
QueryTab.tabHelpers.PageControl := QueryTab.pcHelpers;
|
||||
|
||||
// Create "Project Manager" tab
|
||||
QueryTab.tabProjectManager := TTabSheet.Create(QueryTab.pcHelpers);
|
||||
QueryTab.tabProjectManager.Name := 'tabProjectManager' + i.ToString;
|
||||
QueryTab.tabProjectManager.Caption := 'Project Manager';
|
||||
QueryTab.tabProjectManager.PageControl := QueryTab.pcHelpers;
|
||||
|
||||
// Move filter and tree to Helpers tab
|
||||
QueryTab.filterHelpers := TButtonedEdit.Create(QueryTab.tabHelpers);
|
||||
QueryTab.filterHelpers := TButtonedEdit.Create(QueryTab.pnlHelpers);
|
||||
QueryTab.filterHelpers.Name := filterQueryHelpers.Name + i.ToString;
|
||||
QueryTab.filterHelpers.Text := '';
|
||||
QueryTab.filterHelpers.Parent := QueryTab.tabHelpers;
|
||||
QueryTab.filterHelpers.Parent := QueryTab.pnlHelpers;
|
||||
QueryTab.filterHelpers.Align := filterQueryHelpers.Align;
|
||||
QueryTab.filterHelpers.TextHint := filterQueryHelpers.TextHint;
|
||||
QueryTab.filterHelpers.Images := filterQueryHelpers.Images;
|
||||
@@ -12611,9 +12467,9 @@ begin
|
||||
QueryTab.filterHelpers.OnChange := filterQueryHelpers.OnChange;
|
||||
QueryTab.filterHelpers.OnRightButtonClick := filterQueryHelpers.OnRightButtonClick;
|
||||
|
||||
QueryTab.treeHelpers := TVirtualStringTree.Create(QueryTab.tabHelpers);
|
||||
QueryTab.treeHelpers := TVirtualStringTree.Create(QueryTab.pnlHelpers);
|
||||
QueryTab.treeHelpers.Name := treeQueryHelpers.Name + i.ToString;
|
||||
QueryTab.treeHelpers.Parent := QueryTab.tabHelpers;
|
||||
QueryTab.treeHelpers.Parent := QueryTab.pnlHelpers;
|
||||
QueryTab.treeHelpers.Align := treeQueryHelpers.Align;
|
||||
QueryTab.treeHelpers.Left := treeQueryHelpers.Left;
|
||||
QueryTab.treeHelpers.Constraints.MinWidth := treeQueryHelpers.Constraints.MinWidth;
|
||||
@@ -12649,28 +12505,6 @@ begin
|
||||
QueryTab.treeHelpers.TextMargin := treeQueryHelpers.TextMargin;
|
||||
FixVT(QueryTab.treeHelpers);
|
||||
|
||||
// Create Project Manager in Project Manager tab
|
||||
try
|
||||
QueryTab.projectManagerPanel := TProjectManagerPanel.Create(QueryTab.tabProjectManager);
|
||||
QueryTab.projectManagerPanel.Parent := QueryTab.tabProjectManager;
|
||||
QueryTab.projectManagerPanel.Align := alClient;
|
||||
|
||||
// Initialize Project Manager if needed
|
||||
LogSQL('Project Manager panel created successfully in query tab ' + i.ToString, lcDebug);
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
LogSQL('Error creating Project Manager in query tab: ' + E.Message, lcError);
|
||||
QueryTab.projectManagerPanel := nil;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Set active tab based on global Project Manager state
|
||||
if FProjectManagerTabActive then
|
||||
QueryTab.pcHelpers.ActivePage := QueryTab.tabProjectManager
|
||||
else
|
||||
QueryTab.pcHelpers.ActivePage := QueryTab.tabHelpers;
|
||||
|
||||
QueryTab.spltQuery := TSplitter.Create(QueryTab.TabSheet);
|
||||
QueryTab.spltQuery.Parent := QueryTab.TabSheet;
|
||||
QueryTab.spltQuery.Top := spltQuery.Top; // Important to get it below the editor, not above. See #439
|
||||
@@ -12868,8 +12702,6 @@ procedure TMainForm.CloseQueryTab(PageIndex: Integer);
|
||||
var
|
||||
NewPageIndex: Integer;
|
||||
Grid: TVirtualStringTree;
|
||||
QueryTab: TQueryTab;
|
||||
BackupFilename: String;
|
||||
begin
|
||||
// Special case: the very first tab gets cleared but not closed
|
||||
if PageIndex = tabQuery.PageIndex then begin
|
||||
@@ -12878,30 +12710,6 @@ begin
|
||||
end;
|
||||
if not IsQueryTab(PageIndex, False) then
|
||||
Exit;
|
||||
|
||||
// Get the query tab before we destroy it
|
||||
QueryTab := QueryTabs.TabByControl(PageControlMain.Pages[PageIndex]);
|
||||
|
||||
// Create automatic backup if needed
|
||||
if Assigned(QueryTab) and ShouldCreateQueryTabBackup(QueryTab) then
|
||||
begin
|
||||
try
|
||||
BackupFilename := GetQueryTabBackupFilename(QueryTab);
|
||||
if BackupFilename <> '' then
|
||||
begin
|
||||
QueryTab.Memo.Lines.SaveToFile(BackupFilename, TEncoding.UTF8);
|
||||
SaveQueryTabBackupToIni(QueryTab, BackupFilename);
|
||||
LogSQL(f_('Query tab content backed up to: %s', [BackupFilename]), lcInfo);
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
// Don't prevent tab closing due to backup errors, but log them
|
||||
LogSQL(f_('Error creating query tab backup: %s', [E.Message]), lcError);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
// Cancel cell editor if active, preventing crash. See issue #2040
|
||||
Grid := ActiveGrid;
|
||||
if Assigned(Grid) and Grid.IsEditing then
|
||||
@@ -12917,14 +12725,11 @@ begin
|
||||
Dec(NewPageIndex);
|
||||
// Avoid excessive flicker:
|
||||
LockWindowUpdate(PageControlMain.Handle);
|
||||
try
|
||||
PageControlMain.Pages[PageIndex].Free;
|
||||
QueryTabs.Delete(PageIndex-tabQuery.PageIndex);
|
||||
PageControlMain.ActivePageIndex := NewPageIndex;
|
||||
FixQueryTabCloseButtons;
|
||||
finally
|
||||
LockWindowUpdate(0);
|
||||
end;
|
||||
PageControlMain.Pages[PageIndex].Free;
|
||||
QueryTabs.Delete(PageIndex-tabQuery.PageIndex);
|
||||
PageControlMain.ActivePageIndex := NewPageIndex;
|
||||
FixQueryTabCloseButtons;
|
||||
LockWindowUpdate(0);
|
||||
PageControlMain.OnChange(PageControlMain);
|
||||
end;
|
||||
|
||||
@@ -13157,23 +12962,10 @@ var
|
||||
begin
|
||||
// Asynchronous timer for mousedown event on query tab close button
|
||||
TimerCloseTabByButton.Enabled := False;
|
||||
|
||||
try
|
||||
for i:=0 to QueryTabs.Count-1 do begin
|
||||
if QueryTabs[i].CloseButton = FLastMouseDownCloseButton then begin
|
||||
CloseQueryTab(QueryTabs[i].TabSheet.PageIndex);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
// Stop timer on errors to prevent cascading issues
|
||||
TimerCloseTabByButton.Enabled := False;
|
||||
LogSQL(f_('Error in TimerCloseTabByButtonTimer: %s', [E.Message]), lcError);
|
||||
|
||||
// Reset the close button reference to prevent further issues
|
||||
FLastMouseDownCloseButton := nil;
|
||||
for i:=0 to QueryTabs.Count-1 do begin
|
||||
if QueryTabs[i].CloseButton = FLastMouseDownCloseButton then begin
|
||||
CloseQueryTab(QueryTabs[i].TabSheet.PageIndex);
|
||||
break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@@ -13528,13 +13320,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.actProjectManagerExecute(Sender: TObject);
|
||||
begin
|
||||
// Toggle Project Manager tab visibility in current query tab
|
||||
ToggleProjectManager;
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.UpdateFilterPanel(Sender: TObject);
|
||||
var
|
||||
tab: TTabSheet;
|
||||
@@ -15292,68 +15077,11 @@ end;
|
||||
|
||||
destructor TQueryTab.Destroy;
|
||||
begin
|
||||
try
|
||||
// Clean up Project Manager if it exists
|
||||
if Assigned(projectManagerPanel) then
|
||||
begin
|
||||
try
|
||||
projectManagerPanel.PrepareForShutdown;
|
||||
except
|
||||
// Ignore exceptions during shutdown preparation
|
||||
end;
|
||||
FreeAndNil(projectManagerPanel);
|
||||
end;
|
||||
|
||||
// Clean up tab components safely
|
||||
if Assigned(ResultTabs) then
|
||||
begin
|
||||
ResultTabs.Clear;
|
||||
FreeAndNil(ResultTabs);
|
||||
end;
|
||||
|
||||
// Free other components with error handling
|
||||
try
|
||||
if Assigned(DirectoryWatch) then
|
||||
FreeAndNil(DirectoryWatch);
|
||||
except
|
||||
// Ignore DirectoryWatch cleanup errors
|
||||
end;
|
||||
|
||||
if Assigned(ListBindParams) then
|
||||
FreeAndNil(ListBindParams);
|
||||
|
||||
if Assigned(TimerLastChange) then
|
||||
begin
|
||||
TimerLastChange.Enabled := False;
|
||||
FreeAndNil(TimerLastChange);
|
||||
end;
|
||||
|
||||
if Assigned(TimerStatusUpdate) then
|
||||
begin
|
||||
TimerStatusUpdate.Enabled := False;
|
||||
FreeAndNil(TimerStatusUpdate);
|
||||
end;
|
||||
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
// Log but don't re-raise exceptions during destruction
|
||||
{$IFDEF DEBUG}
|
||||
OutputDebugString(PChar('Error in TQueryTab.Destroy: ' + E.Message));
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
|
||||
try
|
||||
inherited Destroy;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
{$IFDEF DEBUG}
|
||||
OutputDebugString(PChar('Error in TQueryTab.inherited Destroy: ' + E.Message));
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
ResultTabs.Clear;
|
||||
DirectoryWatch.Free;
|
||||
ListBindParams.Free;
|
||||
TimerLastChange.Free;
|
||||
TimerStatusUpdate.Free;
|
||||
end;
|
||||
|
||||
|
||||
@@ -16018,201 +15746,5 @@ begin
|
||||
Result := CompareText(Left.Name, Right.Name);
|
||||
end;
|
||||
|
||||
|
||||
{ TMainForm - Query Tab Backup Methods }
|
||||
|
||||
function TMainForm.GetQueryTabBackupFilename(Tab: TQueryTab): String;
|
||||
var
|
||||
BackupDir, Timestamp, SafeCaption: String;
|
||||
begin
|
||||
Result := '';
|
||||
if not Assigned(Tab) then
|
||||
Exit;
|
||||
|
||||
try
|
||||
// Create backup directory if it doesn't exist
|
||||
if AppSettings.PortableMode then
|
||||
BackupDir := ExtractFilePath(Application.ExeName) + 'Backups\'
|
||||
else
|
||||
BackupDir := AppSettings.DirnameUserAppData + 'Backups\';
|
||||
|
||||
if not DirectoryExists(BackupDir) then
|
||||
ForceDirectories(BackupDir);
|
||||
|
||||
// Create safe filename from tab caption
|
||||
SafeCaption := Tab.TabSheet.Caption;
|
||||
SafeCaption := StringReplace(SafeCaption, ' ', '_', [rfReplaceAll]);
|
||||
SafeCaption := StringReplace(SafeCaption, '*', '', [rfReplaceAll]);
|
||||
// Remove non-alphanumeric characters
|
||||
SafeCaption := ReplaceRegExpr('[^\w]', SafeCaption, '_', True);
|
||||
|
||||
// Generate unique filename with timestamp
|
||||
Timestamp := FormatDateTime('yyyymmdd_hhnnss', Now);
|
||||
Result := BackupDir + 'query_' + SafeCaption + '_' + Timestamp + '_' + IntToStr(GetTickCount64) + '.sql';
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
LogSQL(f_('Error generating backup filename: %s', [E.Message]), lcError);
|
||||
Result := '';
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SaveQueryTabBackupToIni(Tab: TQueryTab; const BackupFilename: String);
|
||||
var
|
||||
TabsIni: TIniFile;
|
||||
TabSection: String;
|
||||
begin
|
||||
if not Assigned(Tab) or (BackupFilename = '') then
|
||||
Exit;
|
||||
|
||||
try
|
||||
TabsIni := InitTabsIniFile;
|
||||
try
|
||||
TabSection := 'Tab' + IntToStr(Tab.Number);
|
||||
TabsIni.WriteString(TabSection, 'BackupFile', BackupFilename);
|
||||
TabsIni.WriteString(TabSection, 'BackupTimestamp', DateTimeToStr(Now));
|
||||
TabsIni.WriteString(TabSection, 'BackupReason', 'AutoBackupOnClose');
|
||||
finally
|
||||
TabsIni.Free;
|
||||
end;
|
||||
except
|
||||
on E: Exception do
|
||||
begin
|
||||
LogSQL(f_('Error saving backup info to tabs.ini: %s', [E.Message]), lcError);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TMainForm.ShouldCreateQueryTabBackup(Tab: TQueryTab): Boolean;
|
||||
var
|
||||
QueryText: String;
|
||||
begin
|
||||
Result := False;
|
||||
|
||||
if not Assigned(Tab) or not Assigned(Tab.Memo) then
|
||||
Exit;
|
||||
|
||||
// Only backup if content has been modified and is not empty
|
||||
if not Tab.Memo.Modified then
|
||||
Exit;
|
||||
|
||||
QueryText := Trim(Tab.Memo.Text);
|
||||
if Length(QueryText) = 0 then
|
||||
Exit;
|
||||
|
||||
// Don't backup very short queries (probably just typos)
|
||||
if Length(QueryText) < 10 then
|
||||
Exit;
|
||||
|
||||
// Don't backup if it's just whitespace or common single commands
|
||||
if (Pos(#13#10, QueryText) = 0) and
|
||||
(LowerCase(QueryText) = 'select') or
|
||||
(LowerCase(QueryText) = 'show') or
|
||||
(LowerCase(QueryText) = 'desc') or
|
||||
(LowerCase(QueryText) = 'describe') then
|
||||
Exit;
|
||||
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
procedure TMainForm.ApplyProjectManagerStateToActiveTab;
|
||||
var
|
||||
CurrentTab: TQueryTab;
|
||||
begin
|
||||
// Apply global Project Manager state to the currently active query tab
|
||||
if QueryTabs.HasActiveTab then
|
||||
begin
|
||||
CurrentTab := QueryTabs.ActiveTab;
|
||||
if Assigned(CurrentTab.pcHelpers) then
|
||||
begin
|
||||
// Only change if different from current state to avoid unnecessary updates
|
||||
if FProjectManagerTabActive and (CurrentTab.pcHelpers.ActivePage <> CurrentTab.tabProjectManager) then
|
||||
begin
|
||||
CurrentTab.pcHelpers.ActivePage := CurrentTab.tabProjectManager;
|
||||
{$IFDEF DEBUG}
|
||||
LogSQL('Applied Project Manager tab state to query tab', lcDebug);
|
||||
{$ENDIF}
|
||||
end
|
||||
else if not FProjectManagerTabActive and (CurrentTab.pcHelpers.ActivePage <> CurrentTab.tabHelpers) then
|
||||
begin
|
||||
CurrentTab.pcHelpers.ActivePage := CurrentTab.tabHelpers;
|
||||
{$IFDEF DEBUG}
|
||||
LogSQL('Applied Helpers tab state to query tab', lcDebug);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.HelpersPageControlChange(Sender: TObject);
|
||||
var
|
||||
PageControl: TPageControl;
|
||||
CurrentTab: TQueryTab;
|
||||
begin
|
||||
// Handle manual tab changes in helpers PageControl
|
||||
PageControl := Sender as TPageControl;
|
||||
|
||||
// Find which query tab this PageControl belongs to
|
||||
CurrentTab := nil;
|
||||
if QueryTabs.HasActiveTab then
|
||||
CurrentTab := QueryTabs.ActiveTab;
|
||||
|
||||
// Only update global state if this is the active query tab
|
||||
if Assigned(CurrentTab) and (CurrentTab.pcHelpers = PageControl) then
|
||||
begin
|
||||
// Update global state based on which tab is now active
|
||||
if PageControl.ActivePage = CurrentTab.tabProjectManager then
|
||||
begin
|
||||
if not FProjectManagerTabActive then
|
||||
begin
|
||||
FProjectManagerTabActive := True;
|
||||
// Apply to all other query tabs
|
||||
SynchronizeAllQueryTabsToGlobalState(CurrentTab);
|
||||
// Update action state
|
||||
if Assigned(actProjectManager) then
|
||||
actProjectManager.Checked := True;
|
||||
{$IFDEF DEBUG}
|
||||
LogSQL('Project Manager manually activated - synchronized to all tabs', lcDebug);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end
|
||||
else if PageControl.ActivePage = CurrentTab.tabHelpers then
|
||||
begin
|
||||
if FProjectManagerTabActive then
|
||||
begin
|
||||
FProjectManagerTabActive := False;
|
||||
// Apply to all other query tabs
|
||||
SynchronizeAllQueryTabsToGlobalState(CurrentTab);
|
||||
// Update action state
|
||||
if Assigned(actProjectManager) then
|
||||
actProjectManager.Checked := False;
|
||||
{$IFDEF DEBUG}
|
||||
LogSQL('Helpers manually activated - synchronized to all tabs', lcDebug);
|
||||
{$ENDIF}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure TMainForm.SynchronizeAllQueryTabsToGlobalState(ExcludeTab: TQueryTab);
|
||||
var
|
||||
i: Integer;
|
||||
Tab: TQueryTab;
|
||||
begin
|
||||
// Apply global state to all query tabs except the one that triggered the change
|
||||
for i := 0 to QueryTabs.Count - 1 do
|
||||
begin
|
||||
Tab := QueryTabs[i];
|
||||
if (Tab <> ExcludeTab) and Assigned(Tab.pcHelpers) then
|
||||
begin
|
||||
if FProjectManagerTabActive then
|
||||
Tab.pcHelpers.ActivePage := Tab.tabProjectManager
|
||||
else
|
||||
Tab.pcHelpers.ActivePage := Tab.tabHelpers;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
object ProjectManagerPanel: TProjectManagerPanel
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 250
|
||||
Height = 400
|
||||
Caption = 'Project Manager'
|
||||
TabOrder = 0
|
||||
object pnlHeader: TPanel
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 250
|
||||
Height = 30
|
||||
Align = alTop
|
||||
BevelOuter = bvNone
|
||||
TabOrder = 0
|
||||
object lblProjectTitle: TLabel
|
||||
Left = 8
|
||||
Top = 8
|
||||
Width = 43
|
||||
Height = 13
|
||||
Caption = 'Projects'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -11
|
||||
Font.Name = 'Tahoma'
|
||||
Font.Style = [fsBold]
|
||||
ParentFont = False
|
||||
end
|
||||
object ToolBarProjects: TToolBar
|
||||
Left = 72
|
||||
Top = 0
|
||||
Width = 178
|
||||
Height = 30
|
||||
Align = alRight
|
||||
AutoSize = True
|
||||
ButtonHeight = 21
|
||||
ButtonWidth = 22
|
||||
Caption = 'ToolBarProjects'
|
||||
Images = MainForm.VirtualImageListMain
|
||||
ShowHint = True
|
||||
TabOrder = 0
|
||||
object btnAddProject: TToolButton
|
||||
Left = 0
|
||||
Top = 0
|
||||
Hint = 'Add project folder'
|
||||
ImageIndex = 45
|
||||
ImageName = 'icons8-add'
|
||||
OnClick = menuAddProjectClick
|
||||
end
|
||||
object btnRemoveProject: TToolButton
|
||||
Left = 22
|
||||
Top = 0
|
||||
Hint = 'Remove project folder'
|
||||
ImageIndex = 46
|
||||
ImageName = 'icons8-delete-button'
|
||||
OnClick = menuRemoveProjectClick
|
||||
end
|
||||
object btnSeparator1: TToolButton
|
||||
Left = 44
|
||||
Top = 0
|
||||
Width = 8
|
||||
Style = tbsSeparator
|
||||
end
|
||||
object btnRefreshProject: TToolButton
|
||||
Left = 52
|
||||
Top = 0
|
||||
Hint = 'Refresh projects'
|
||||
ImageIndex = 16
|
||||
ImageName = 'icons8-refresh'
|
||||
OnClick = menuRefreshProjectClick
|
||||
end
|
||||
end
|
||||
end
|
||||
object pnlTree: TPanel
|
||||
Left = 0
|
||||
Top = 30
|
||||
Width = 250
|
||||
Height = 370
|
||||
Align = alClient
|
||||
BevelOuter = bvNone
|
||||
TabOrder = 1
|
||||
object TreeProjects: TVirtualStringTree
|
||||
Left = 0
|
||||
Top = 0
|
||||
Width = 250
|
||||
Height = 370
|
||||
Align = alClient
|
||||
Header.AutoSizeIndex = 0
|
||||
Header.Options = [hoAutoResize, hoColumnResize, hoDrag, hoShowSortGlyphs, hoVisible]
|
||||
Images = MainForm.VirtualImageListMain
|
||||
PopupMenu = PopupProjects
|
||||
TabOrder = 0
|
||||
TreeOptions.MiscOptions = [toAcceptOLEDrop, toFullRepaintOnResize, toInitOnSave, toToggleOnDblClick, toWheelPanning, toEditOnClick]
|
||||
TreeOptions.PaintOptions = [toShowButtons, toShowDropmark, toShowTreeLines, toThemeAware, toUseBlendedImages, toShowRoot]
|
||||
TreeOptions.SelectionOptions = [toFullRowSelect]
|
||||
OnBeforeExpansion = TreeProjectsBeforeExpansion
|
||||
OnCollapsed = TreeProjectsCollapsed
|
||||
OnDblClick = TreeProjectsDblClick
|
||||
OnExpanded = TreeProjectsExpanded
|
||||
OnGetImageIndex = TreeProjectsGetImageIndex
|
||||
OnGetNodeDataSize = TreeProjectsGetNodeDataSize
|
||||
OnGetText = TreeProjectsGetText
|
||||
OnInitChildren = TreeProjectsInitChildren
|
||||
OnInitNode = TreeProjectsInitNode
|
||||
Columns = <
|
||||
item
|
||||
Position = 0
|
||||
Text = 'Name'
|
||||
Width = 246
|
||||
end>
|
||||
end
|
||||
end
|
||||
object PopupProjects: TPopupMenu
|
||||
OnPopup = PopupProjectsPopup
|
||||
Left = 104
|
||||
Top = 168
|
||||
object menuAddProject: TMenuItem
|
||||
Caption = 'Add Project Folder...'
|
||||
ImageIndex = 45
|
||||
ImageName = 'icons8-add'
|
||||
OnClick = menuAddProjectClick
|
||||
end
|
||||
object menuRemoveProject: TMenuItem
|
||||
Caption = 'Remove Project'
|
||||
ImageIndex = 46
|
||||
ImageName = 'icons8-delete-button'
|
||||
OnClick = menuRemoveProjectClick
|
||||
end
|
||||
object menuSeparator1: TMenuItem
|
||||
Caption = '-'
|
||||
end
|
||||
object menuOpenFile: TMenuItem
|
||||
Caption = 'Open File'
|
||||
Default = True
|
||||
ImageIndex = 8
|
||||
ImageName = 'icons8-opened-folder'
|
||||
OnClick = menuOpenFileClick
|
||||
end
|
||||
object menuOpenInExplorer: TMenuItem
|
||||
Caption = 'Open in Explorer'
|
||||
ImageIndex = 71
|
||||
ImageName = 'icons8-folder'
|
||||
OnClick = menuOpenInExplorerClick
|
||||
end
|
||||
object menuRefreshProject: TMenuItem
|
||||
Caption = 'Refresh'
|
||||
ImageIndex = 16
|
||||
ImageName = 'icons8-refresh'
|
||||
OnClick = menuRefreshProjectClick
|
||||
end
|
||||
end
|
||||
end
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user