mirror of
https://github.com/HeidiSQL/HeidiSQL.git
synced 2025-08-06 18:24:26 +08:00
Issue #2137: enable automatic tab restore
This commit is contained in:
@ -15,7 +15,6 @@ type
|
||||
// Sync with main branch and Delphi structures
|
||||
TSynMemo = TSynEdit;
|
||||
TVirtualStringTree = TLazVirtualStringTree;
|
||||
TExtFileSaveDialog = class(TSaveDialog);
|
||||
TImageIndex = Integer;
|
||||
PInt = ^Integer;
|
||||
TProgressBarState = (pbsNormal, pbsError, pbsPaused);
|
||||
@ -441,7 +440,7 @@ type
|
||||
//function GetCurrentPackageFullName(out Len: Cardinal; Name: PWideChar): Integer; stdcall; external kernel32 delayed;
|
||||
function GetThemeColor(Color: TColor): TColor;
|
||||
function ThemeIsDark(ThemeName: String=''): Boolean;
|
||||
//function ProcessExists(pid: Cardinal; ExeNamePattern: String): Boolean;
|
||||
function ProcessExists(pid: Cardinal; ExeNamePattern: String): Boolean;
|
||||
//procedure ToggleCheckBoxWithoutClick(chk: TCheckBox; State: Boolean);
|
||||
function SynCompletionProposalPrettyText(ImageIndex: Integer; LeftText, CenterText, RightText: String; LeftColor: TColor=-1; CenterColor: TColor=-1; RightColor: TColor=-1): String;
|
||||
function PopupComponent(Sender: TObject): TComponent;
|
||||
@ -663,15 +662,9 @@ end;
|
||||
|
||||
|
||||
function DeleteFileWithUndo(sFileName: string): Boolean;
|
||||
//var
|
||||
// fos: TSHFileOpStruct;
|
||||
begin
|
||||
{FillChar(fos, SizeOf(fos), 0);
|
||||
fos.wFunc := FO_DELETE;
|
||||
fos.pFrom := PChar(sFileName + #0);
|
||||
fos.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION or FOF_SILENT;
|
||||
Result := (0 = ShFileOperation(fos));}
|
||||
Beep;
|
||||
// Todo: move to trash, cross-platform
|
||||
Result := DeleteFile(sFileName);
|
||||
end;
|
||||
|
||||
|
||||
@ -2767,6 +2760,7 @@ var
|
||||
hFile: DWORD;
|
||||
begin
|
||||
// Check if file is writable
|
||||
// replaced through LazFileUtils.FileIsWritable
|
||||
if not FileExists(FilePath) then begin
|
||||
// Return true if file does not exist
|
||||
Result := True;
|
||||
@ -2792,14 +2786,16 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{function ProcessExists(pid: Cardinal; ExeNamePattern: String): Boolean;
|
||||
var
|
||||
function ProcessExists(pid: Cardinal; ExeNamePattern: String): Boolean;
|
||||
{var
|
||||
Proc: TProcessEntry32;
|
||||
SnapShot: THandle;
|
||||
ContinueLoop: Boolean;
|
||||
ContinueLoop: Boolean;}
|
||||
begin
|
||||
// Check if a given process id exists
|
||||
SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
|
||||
// Todo: convert code for cross-platforming
|
||||
Result := False;
|
||||
{SnapShot := CreateToolhelp32Snapshot(TH32CS_SnapProcess, 0);
|
||||
Proc.dwSize := Sizeof(Proc);
|
||||
Result := False;
|
||||
ContinueLoop := Process32First(SnapShot, Proc);
|
||||
@ -2809,8 +2805,8 @@ begin
|
||||
Break;
|
||||
ContinueLoop := Process32Next(SnapShot, Proc);
|
||||
end;
|
||||
CloseHandle(Snapshot);
|
||||
end;}
|
||||
CloseHandle(Snapshot);}
|
||||
end;
|
||||
|
||||
|
||||
{procedure ToggleCheckBoxWithoutClick(chk: TCheckBox; State: Boolean);
|
||||
|
@ -59,22 +59,23 @@ type
|
||||
property EncodingIndex: Cardinal read FEncodingIndex write FEncodingIndex;
|
||||
end;
|
||||
|
||||
{TExtFileSaveDialog = class(TFileSaveDialog)
|
||||
TExtFileSaveDialog = class(TSaveDialog)
|
||||
private
|
||||
FFilters: TStringList;
|
||||
FLineBreaks: TStringList;
|
||||
FLineBreakIndex: TLineBreaks;
|
||||
const idLineBreakCombo = 1;
|
||||
procedure FileOkClickNoOp(Sender: TObject; var CanClose: Boolean);
|
||||
protected
|
||||
procedure DoOnExecute; override;
|
||||
function DoOnFileOkClick: Boolean; override;
|
||||
//procedure DoOnExecute; override;
|
||||
//function DoOnFileOkClick: Boolean; override;
|
||||
public
|
||||
constructor Create(AOwner: TComponent); override;
|
||||
destructor Destroy; override;
|
||||
procedure AddFileType(FileMask, DisplayName: String);
|
||||
property LineBreaks: TStringList read FLineBreaks;
|
||||
property LineBreakIndex: TLineBreaks read FLineBreakIndex write FLineBreakIndex;
|
||||
end;}
|
||||
end;
|
||||
|
||||
{TExtSynHotKey = class(TSynHotKey)
|
||||
private
|
||||
@ -502,14 +503,10 @@ end;
|
||||
|
||||
procedure TExtFileOpenDialog.AddFileType(FileMask, DisplayName: String);
|
||||
var
|
||||
//FileType: TFileTypeItem;
|
||||
i: Integer;
|
||||
NewFilter: String;
|
||||
begin
|
||||
// Shorthand for callers
|
||||
{FileType := FileTypes.Add;
|
||||
FileType.DisplayName := DisplayName;
|
||||
FileType.FileMask := FileMask;}
|
||||
FFilters.Values[DisplayName] := FileMask;
|
||||
NewFilter := '';
|
||||
for i:=FFilters.Count-1 downto 0 do begin
|
||||
@ -567,7 +564,7 @@ end;}
|
||||
|
||||
{ TExtFileSaveDialog }
|
||||
|
||||
{constructor TExtFileSaveDialog.Create(AOwner: TComponent);
|
||||
constructor TExtFileSaveDialog.Create(AOwner: TComponent);
|
||||
begin
|
||||
inherited Create(AOwner);
|
||||
FLineBreaks := TStringList.Create;
|
||||
@ -575,6 +572,7 @@ begin
|
||||
FLineBreaks.Add(_('UNIX linebreaks'));
|
||||
FLineBreaks.Add(_('Mac OS linebreaks'));
|
||||
FLineBreakIndex := lbsWindows;
|
||||
FFilters := TStringList.Create;
|
||||
end;
|
||||
|
||||
|
||||
@ -587,16 +585,22 @@ end;
|
||||
|
||||
procedure TExtFileSaveDialog.AddFileType(FileMask, DisplayName: String);
|
||||
var
|
||||
FileType: TFileTypeItem;
|
||||
i: Integer;
|
||||
NewFilter: String;
|
||||
begin
|
||||
// Shorthand for callers
|
||||
FileType := FileTypes.Add;
|
||||
FileType.DisplayName := DisplayName;
|
||||
FileType.FileMask := FileMask;
|
||||
FFilters.Values[DisplayName] := FileMask;
|
||||
NewFilter := '';
|
||||
for i:=FFilters.Count-1 downto 0 do begin
|
||||
NewFilter := NewFilter + Format('%s (%s)|%s', [FFilters.Names[i], FFilters.ValueFromIndex[i], FFilters.ValueFromIndex[i]]);
|
||||
if i > 0 then
|
||||
NewFilter := NewFilter + '|';
|
||||
end;
|
||||
Filter := NewFilter;
|
||||
end;
|
||||
|
||||
|
||||
procedure TExtFileSaveDialog.DoOnExecute;
|
||||
{procedure TExtFileSaveDialog.DoOnExecute;
|
||||
var
|
||||
iCustomize: IFileDialogCustomize;
|
||||
i, ComboIndex: Integer;
|
||||
@ -622,7 +626,7 @@ begin
|
||||
iCustomize.EndVisualGroup;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;}
|
||||
|
||||
|
||||
procedure TExtFileSaveDialog.FileOkClickNoOp(Sender: TObject; var CanClose: Boolean);
|
||||
@ -631,7 +635,7 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function TExtFileSaveDialog.DoOnFileOkClick: Boolean;
|
||||
{function TExtFileSaveDialog.DoOnFileOkClick: Boolean;
|
||||
var
|
||||
iCustomize: IFileDialogCustomize;
|
||||
ComboIndex: Cardinal;
|
||||
|
@ -1089,12 +1089,12 @@ object MainForm: TMainForm
|
||||
Height = 315
|
||||
Top = 0
|
||||
Width = 780
|
||||
ActivePage = tabData
|
||||
ActivePage = tabQuery
|
||||
Align = alClient
|
||||
HotTrack = True
|
||||
Images = ImageListIcons8
|
||||
PopupMenu = popupMainTabs
|
||||
TabIndex = 3
|
||||
TabIndex = 4
|
||||
TabOrder = 1
|
||||
OnChange = PageControlMainChange
|
||||
OnChanging = PageControlMainChanging
|
||||
@ -3019,7 +3019,7 @@ object MainForm: TMainForm
|
||||
OnDragOver = SynMemoQueryDragOver
|
||||
OnKeyPress = SynMemoQueryKeyPress
|
||||
OnMouseWheel = AnySynMemoMouseWheel
|
||||
Gutter.Width = 30
|
||||
Gutter.Width = 68
|
||||
Gutter.MouseActions = <>
|
||||
RightGutter.Width = 0
|
||||
RightGutter.MouseActions = <>
|
||||
@ -3473,6 +3473,10 @@ object MainForm: TMainForm
|
||||
OnSpecialLineColors = SynMemoQuerySpecialLineColors
|
||||
OnStatusChange = SynMemoQueryStatusChange
|
||||
inline SynLeftGutterPartList1: TSynGutterPartList
|
||||
object SynGutterMarks1: TSynGutterMarks
|
||||
Width = 30
|
||||
MouseActions = <>
|
||||
end
|
||||
object SynGutterLineNumber1: TSynGutterLineNumber
|
||||
Width = 17
|
||||
MouseActions = <>
|
||||
@ -3483,6 +3487,18 @@ object MainForm: TMainForm
|
||||
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 = <>
|
||||
|
@ -14,7 +14,7 @@ uses
|
||||
Generics.Defaults, opensslsockets, StdActns, Clipbrd, Types, LCLType, EditBtn,
|
||||
FileUtil, LMessages, jsonconf, dbconnection, dbstructures, dbstructures.mysql,
|
||||
generic_types, apphelpers, extra_controls, createdatabase,
|
||||
SynEditMarkupSpecialLine, searchreplace, ImgList;
|
||||
SynEditMarkupSpecialLine, searchreplace, ImgList, IniFiles, LazFileUtils;
|
||||
|
||||
|
||||
type
|
||||
@ -1298,9 +1298,9 @@ type
|
||||
//procedure SetLogToFile(Value: Boolean);
|
||||
procedure StoreLastSessions;
|
||||
function HandleUnixTimestampColumn(Sender: TBaseVirtualTree; Column: TColumnIndex): Boolean;
|
||||
//function InitTabsIniFile: TIniFile;
|
||||
//procedure StoreTabs;
|
||||
//function RestoreTabs: Boolean;
|
||||
function InitTabsIniFile: TIniFile;
|
||||
procedure StoreTabs;
|
||||
function RestoreTabs: Boolean;
|
||||
procedure SetHintFontByControl(Control: TWinControl=nil);
|
||||
public
|
||||
QueryTabs: TQueryTabList;
|
||||
@ -2331,10 +2331,10 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
{// Restore backup'ed query tabs
|
||||
// Restore backup'ed query tabs
|
||||
if AppSettings.RestoreTabsInitValue then begin
|
||||
TimerStoreTabs.Enabled := RestoreTabs;
|
||||
end;}
|
||||
end;
|
||||
|
||||
// Load SQL file(s) by command line
|
||||
if not RunQueryFiles(FileNames, nil, false) then begin
|
||||
@ -2353,10 +2353,10 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
{function TMainForm.InitTabsIniFile: TIniFile;
|
||||
function TMainForm.InitTabsIniFile: TIniFile;
|
||||
var
|
||||
WaitingSince: UInt64;
|
||||
Attempts: Integer;
|
||||
//WaitingSince: UInt64;
|
||||
//Attempts: Integer;
|
||||
TabsIniFilename: String;
|
||||
begin
|
||||
// Try to open tabs.ini for writing or reading
|
||||
@ -2365,7 +2365,7 @@ begin
|
||||
TabsIniFilename := ExtractFilePath(Application.ExeName) + 'tabs.ini'
|
||||
else
|
||||
TabsIniFilename := AppSettings.DirnameUserAppData + 'tabs.ini';
|
||||
WaitingSince := GetTickCount64;
|
||||
{WaitingSince := GetTickCount64;
|
||||
Attempts := 0;
|
||||
while not FileIsWritable(TabsIniFilename) do begin
|
||||
if GetTickCount64 - WaitingSince > 3000 then
|
||||
@ -2375,16 +2375,16 @@ begin
|
||||
end;
|
||||
if Attempts > 0 then begin
|
||||
LogSQL(Format('Had to wait %d ms before opening %s', [GetTickCount64 - WaitingSince, TabsIniFilename]), lcDebug);
|
||||
end;
|
||||
end;}
|
||||
// Catch errors when file cannot be created
|
||||
if not FileExists(TabsIniFilename) then begin
|
||||
SaveUnicodeFile(TabsIniFilename, '', UTF8NoBOMEncoding);
|
||||
end;
|
||||
Result := TIniFile.Create(TabsIniFilename);
|
||||
end;}
|
||||
end;
|
||||
|
||||
|
||||
{procedure TMainForm.StoreTabs;
|
||||
procedure TMainForm.StoreTabs;
|
||||
var
|
||||
Tab: TQueryTab;
|
||||
Section, TabCaption: String;
|
||||
@ -2413,8 +2413,8 @@ begin
|
||||
TabsIni.WriteString(Section, TQueryTab.IdentFilename, Tab.MemoFilename);
|
||||
if TabsIni.ReadString(Section, TQueryTab.IdentCaption, '') <> TabCaption then
|
||||
TabsIni.WriteString(Section, TQueryTab.IdentCaption, TabCaption);
|
||||
if TabsIni.ReadInteger(Section, TQueryTab.IdentPid, 0) <> Integer(GetCurrentProcessId) then
|
||||
TabsIni.WriteInteger(Section, TQueryTab.IdentPid, Integer(GetCurrentProcessId));
|
||||
if TabsIni.ReadInteger(Section, TQueryTab.IdentPid, 0) <> Integer(GetProcessId) then
|
||||
TabsIni.WriteInteger(Section, TQueryTab.IdentPid, Integer(GetProcessId));
|
||||
if TabsIni.ReadInteger(Section, TQueryTab.IdentEditorHeight, 0) <> Tab.pnlMemo.Height then
|
||||
TabsIni.WriteInteger(Section, TQueryTab.IdentEditorHeight, Tab.pnlMemo.Height);
|
||||
if TabsIni.ReadInteger(Section, TQueryTab.IdentHelpersWidth, 0) <> Tab.pnlHelpers.Width then
|
||||
@ -2444,7 +2444,7 @@ begin
|
||||
end;
|
||||
// Delete tab section if tab was closed and section belongs to this app instance
|
||||
pid := Cardinal(TabsIni.ReadInteger(Section, TQueryTab.IdentPid, 0));
|
||||
if (not SectionTabExists) and (pid = GetCurrentProcessId) then begin
|
||||
if (not SectionTabExists) and (pid = GetProcessId) then begin
|
||||
TabsIni.EraseSection(Section);
|
||||
end;
|
||||
end;
|
||||
@ -2457,14 +2457,14 @@ begin
|
||||
ErrorDialog(_('Storing tab setup failed'),
|
||||
'Tabs won''t be stored in this session.' + CRLF + CRLF +
|
||||
E.Message + CRLF + CRLF +
|
||||
SysErrorMessage(GetLastError)
|
||||
SysErrorMessage(GetLastOSError)
|
||||
);
|
||||
end;
|
||||
end;
|
||||
end;}
|
||||
end;
|
||||
|
||||
|
||||
{function TMainForm.RestoreTabs: Boolean;
|
||||
function TMainForm.RestoreTabs: Boolean;
|
||||
var
|
||||
Tab: TQueryTab;
|
||||
Sections, SlowTabs: TStringList;
|
||||
@ -2513,7 +2513,7 @@ begin
|
||||
Encoding := GetEncodingByName(TabsIni.ReadString(Section, TQueryTab.IdentFileEncoding, 'UTF-8'));
|
||||
|
||||
// Don't restore this tab if it belongs to a different running Heidi process
|
||||
if (pid > 0) and (pid <> GetCurrentProcessId) and ProcessExists(pid, APPNAME) then begin
|
||||
if (pid > 0) and (pid <> GetProcessId) and ProcessExists(pid, APPNAME) then begin
|
||||
LogSQL(IfThen(BackupFilename.IsEmpty, Filename, BackupFilename)+' loaded in process #'+pid.ToString);
|
||||
Continue;
|
||||
end;
|
||||
@ -2590,11 +2590,11 @@ begin
|
||||
ErrorDialog(_('Restoring tab setup failed'),
|
||||
'Tabs won''t be stored in this session.' + CRLF + CRLF +
|
||||
E.Message + CRLF + CRLF +
|
||||
SysErrorMessage(GetLastError)
|
||||
SysErrorMessage(GetLastOSError)
|
||||
);
|
||||
end;
|
||||
end;
|
||||
end;}
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.SetHintFontByControl(Control: TWinControl=nil);
|
||||
@ -2614,7 +2614,7 @@ end;
|
||||
procedure TMainForm.TimerStoreTabsTimer(Sender: TObject);
|
||||
begin
|
||||
// Backup unsaved content every 10 seconds
|
||||
//StoreTabs;
|
||||
StoreTabs;
|
||||
end;
|
||||
|
||||
|
||||
@ -2627,6 +2627,7 @@ begin
|
||||
Dialog.Free;
|
||||
end;
|
||||
|
||||
|
||||
procedure TMainForm.actDisconnectExecute(Sender: TObject);
|
||||
var
|
||||
Connection: TDBConnection;
|
||||
@ -12328,7 +12329,19 @@ begin
|
||||
QueryTab.Memo.RightEdge := SynMemoQuery.RightEdge;
|
||||
QueryTab.Memo.WantTabs := SynMemoQuery.WantTabs;
|
||||
QueryTab.Memo.Highlighter := SynMemoQuery.Highlighter;
|
||||
QueryTab.Memo.Gutter.Assign(SynMemoQuery.Gutter);
|
||||
QueryTab.Memo.Gutter.Width := SynMemoQuery.Gutter.Width;
|
||||
// Todo: adding and gutter part results in EAccessviolation's when closing a query tab.
|
||||
// Fix that and use the same gutter as in mother query tab
|
||||
// In the meantime we let SynEdit use TSynGutter.CreateDefaultGutterParts
|
||||
//for GutterPartIndex:=0 to SynMemoQuery.Gutter.Parts.Count-1 do begin
|
||||
// QueryTab.Memo.Gutter.Parts.Add(SynMemoQuery.Gutter.Parts[GutterPartIndex].ClassType.Create(QueryTab.Memo.Gutter.Parts));
|
||||
// QueryTab.Memo.Gutter.Parts[GutterPartIndex].Width := SynMemoQuery.Gutter.Parts[GutterPartIndex].Width;
|
||||
//end;
|
||||
//QueryTab.Memo.Gutter.Parts.Clear;
|
||||
//QueryTab.Memo.Gutter.Parts.Add(TSynGutterLineNumber.Create(QueryTab.Memo.Gutter.Parts));
|
||||
//QueryTab.Memo.Gutter.Parts[0].Width := SynMemoQuery.Gutter.Parts[0].Width;
|
||||
//QueryTab.Memo.Gutter.Parts.Add(TSynGutterCodeFolding.Create(QueryTab.Memo.Gutter.Parts));
|
||||
//QueryTab.Memo.Gutter.Parts[1].Width := SynMemoQuery.Gutter.Parts[1].Width;
|
||||
QueryTab.Memo.Font.Assign(SynMemoQuery.Font);
|
||||
//QueryTab.Memo.ActiveLineColor := SynMemoQuery.ActiveLineColor;
|
||||
QueryTab.Memo.OnStatusChange := SynMemoQuery.OnStatusChange;
|
||||
@ -13123,7 +13136,7 @@ begin
|
||||
end;
|
||||
end;
|
||||
// Leave space for close button on closable query tabs
|
||||
Text := Text + ' ';
|
||||
//Text := Text + ' ';
|
||||
end;
|
||||
PageControlMain.Pages[PageIndex].Caption := Text;
|
||||
FixQueryTabCloseButtons;
|
||||
@ -13186,8 +13199,8 @@ begin
|
||||
else begin
|
||||
Dialog := TExtFileSaveDialog.Create(Self);
|
||||
Dialog.Options := Dialog.Options + [ofOverwritePrompt];
|
||||
//Dialog.AddFileType('*.sql', _('SQL files'));
|
||||
//Dialog.AddFileType('*.*', _('All files'));
|
||||
Dialog.AddFileType('*.sql', _('SQL files'));
|
||||
Dialog.AddFileType('*.*', _('All files'));
|
||||
Dialog.DefaultExt := 'sql';
|
||||
//Dialog.LineBreakIndex := Tab.MemoLineBreaks;
|
||||
if Dialog.Execute then begin
|
||||
|
Reference in New Issue
Block a user