mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-28 12:30:36 +01:00
636 lines
21 KiB
ObjectPascal
636 lines
21 KiB
ObjectPascal
{ Installs anchor docking manager in the Lazarus IDE.
|
|
|
|
Copyright (C) 2010 Mattias Gaertner mattias@freepascal.org
|
|
|
|
This library is free software; you can redistribute it and/or modify it
|
|
under the terms of the GNU Library General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or (at your
|
|
option) any later version with the following modification:
|
|
|
|
As a special exception, the copyright holders of this library give you
|
|
permission to link this library with independent modules to produce an
|
|
executable, regardless of the license terms of these independent modules,and
|
|
to copy and distribute the resulting executable under terms of your choice,
|
|
provided that you also meet, for each linked independent module, the terms
|
|
and conditions of the license of that module. An independent module is a
|
|
module which is not derived from or based on this library. If you modify
|
|
this library, you may extend this exception to your version of the library,
|
|
but you are not obligated to do so. If you do not wish to do so, delete this
|
|
exception statement from your version.
|
|
|
|
This program is distributed in the hope that it will be useful, but WITHOUT
|
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
|
|
for more details.
|
|
|
|
You should have received a copy of the GNU Library General Public License
|
|
along with this library; if not, write to the Free Software Foundation,
|
|
Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
|
|
ToDo:
|
|
- save settings after options dialog
|
|
- close source editor and show again
|
|
- show anchor editor => too small
|
|
- qt: focus on close page
|
|
- gtk2: focus on cancel completion box
|
|
- gtk2: focus on execute completion box
|
|
- gtk2: restore fails for mainidebar
|
|
}
|
|
unit RegisterAnchorDocking;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Math, Classes, SysUtils, LCLProc, Forms, Controls, FileUtil, Dialogs,
|
|
LazConfigStorage, XMLConf, XMLPropStorage, StdCtrls, LCLIntf,
|
|
BaseIDEIntf, ProjectIntf, MacroIntf, IDEDialogs, MenuIntf, LazIDEIntf,
|
|
IDEWindowIntf, IDEOptionsIntf,
|
|
AnchorDockStr, AnchorDocking, AnchorDockOptionsDlg;
|
|
|
|
const
|
|
DefaultConfigFileName = 'anchordocklayout.xml';
|
|
var
|
|
mnuAnchorDockSection: TIDEMenuSection;
|
|
mnuADSaveLayoutAsDefault: TIDEMenuCommand;
|
|
mnuADSaveLayoutToFile: TIDEMenuCommand;
|
|
mnuADLoadLayoutFromFile: TIDEMenuCommand;
|
|
mnuADRestoreDefaultLayout: TIDEMenuCommand;
|
|
|
|
type
|
|
|
|
{ TIDEAnchorDockMaster }
|
|
|
|
TIDEAnchorDockMaster = class(TIDEDockMaster)
|
|
private
|
|
FChangeStamp: int64;
|
|
FEnabled: boolean;
|
|
FModified: boolean;
|
|
FUserLayoutLoaded: boolean;
|
|
procedure DockMasterCreateControl(Sender: TObject; aName: string;
|
|
var AControl: TControl; DoDisableAutoSizing: boolean);
|
|
procedure GetDefaultBounds(AForm: TCustomForm; out Creator: TIDEWindowCreator;
|
|
out NewBounds: TRect; out DockSiblingName: string; out DockAlign: TAlign);
|
|
procedure SetEnabled(const AValue: boolean);
|
|
procedure SetModified(const AValue: boolean);
|
|
procedure SetUserLayoutLoaded(const AValue: boolean);
|
|
public
|
|
constructor Create;
|
|
destructor Destroy; override;
|
|
procedure MakeIDEWindowDockSite(AForm: TCustomForm; ASides: TDockSides = [alBottom]); override;
|
|
procedure MakeIDEWindowDockable(AControl: TWinControl); override;
|
|
function AddableInWindowMenu(AForm: TCustomForm): boolean; override;
|
|
function GetDefaultLayoutFilename: string;
|
|
procedure LoadDefaultLayout;
|
|
procedure LoadUserLayout;
|
|
procedure SaveUserLayout;
|
|
procedure LoadLayoutFromFile(Filename: string);
|
|
procedure SaveLayoutToFile(Filename: string);
|
|
procedure ShowForm(AForm: TCustomForm; BringToFront: boolean); override;
|
|
procedure CloseAll; override;
|
|
procedure OnIDERestoreWindows(Sender: TObject);
|
|
function OnProjectClose(Sender: TObject; AProject: TLazProject): TModalResult;
|
|
procedure RestoreDefaultLayoutClicked(Sender: TObject);
|
|
procedure LoadLayoutFromFileClicked(Sender: TObject);
|
|
procedure SaveLayoutToFileClicked(Sender: TObject);
|
|
procedure SaveLayoutAsDefaultClicked(Sender: TObject);
|
|
property UserLayoutLoaded: boolean read FUserLayoutLoaded write SetUserLayoutLoaded;
|
|
property Enabled: boolean read FEnabled write SetEnabled;
|
|
procedure IncreaseChangeStamp;
|
|
property ChangeStamp: int64 read FChangeStamp;
|
|
property Modified: boolean read FModified write SetModified;
|
|
end;
|
|
|
|
{ TAnchorDockIDEFrame }
|
|
|
|
TAnchorDockIDEFrame = class(TAbstractIDEOptionsEditor)
|
|
EnableCheckBox: TCheckBox;
|
|
NoteLabel: TLabel;
|
|
public
|
|
OptionsFrame: TAnchorDockOptionsFrame;
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
function GetTitle: String; override;
|
|
procedure Setup(ADialog: TAbstractOptionsEditorDialog); override;
|
|
procedure ReadSettings(AOptions: TAbstractIDEOptions); override;
|
|
procedure WriteSettings(AOptions: TAbstractIDEOptions); override;
|
|
class function SupportedOptionsClass: TAbstractIDEOptionsClass; override;
|
|
end;
|
|
|
|
var
|
|
IDEAnchorDockMaster: TIDEAnchorDockMaster = nil;
|
|
AnchorDockOptionsID: integer = 1000;
|
|
|
|
procedure Register;
|
|
|
|
implementation
|
|
|
|
procedure Register;
|
|
begin
|
|
if not (IDEDockMaster is TIDEAnchorDockMaster) then exit;
|
|
|
|
LazarusIDE.AddHandlerOnIDERestoreWindows(@IDEAnchorDockMaster.OnIDERestoreWindows);
|
|
LazarusIDE.AddHandlerOnProjectClose(@IDEAnchorDockMaster.OnProjectClose);
|
|
|
|
// add menu section
|
|
mnuAnchorDockSection:=RegisterIDEMenuSection(itmSecondaryTools,'AnchorDocking');
|
|
mnuADSaveLayoutAsDefault:=RegisterIDEMenuCommand(mnuAnchorDockSection,
|
|
'ADSaveLayoutAsDefault', adrsSaveWindowLayoutAsDefault,
|
|
@IDEAnchorDockMaster.SaveLayoutAsDefaultClicked);
|
|
mnuADSaveLayoutToFile:=RegisterIDEMenuCommand(mnuAnchorDockSection,
|
|
'ADSaveLayoutToFile', adrsSaveWindowLayoutToFile,
|
|
@IDEAnchorDockMaster.SaveLayoutToFileClicked);
|
|
mnuADLoadLayoutFromFile:=RegisterIDEMenuCommand(mnuAnchorDockSection,
|
|
'ADLoadLayoutFromFile', adrsLoadWindowLayoutFromFile,
|
|
@IDEAnchorDockMaster.LoadLayoutFromFileClicked);
|
|
mnuADRestoreDefaultLayout:=RegisterIDEMenuCommand(mnuAnchorDockSection,
|
|
'ADRestoreDefaultLayout', adrsRestoreDefaultLayout,
|
|
@IDEAnchorDockMaster.RestoreDefaultLayoutClicked);
|
|
|
|
// add options frame
|
|
{$R *.lfm}
|
|
AnchorDockOptionsID:=RegisterIDEOptionsEditor(GroupEnvironment,TAnchorDockIDEFrame,
|
|
AnchorDockOptionsID)^.Index;
|
|
end;
|
|
|
|
{ TIDEAnchorDockMaster }
|
|
|
|
procedure TIDEAnchorDockMaster.DockMasterCreateControl(Sender: TObject;
|
|
aName: string; var AControl: TControl; DoDisableAutoSizing: boolean);
|
|
begin
|
|
//debugln(['TIDEAnchorDockMaster.DockMasterCreateControl CtrlName="',dbgstr(AName),'"']);
|
|
AControl:=IDEWindowCreators.GetForm(aName,true,DoDisableAutoSizing);
|
|
//debugln(['TIDEAnchorDockMaster.DockMasterCreateControl Result=',DbgSName(AControl)]);
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.GetDefaultBounds(AForm: TCustomForm; out
|
|
Creator: TIDEWindowCreator; out NewBounds: TRect; out
|
|
DockSiblingName: string; out DockAlign: TAlign);
|
|
var
|
|
AControl: TControl;
|
|
begin
|
|
NewBounds:=Rect(0,0,0,0);
|
|
DockSiblingName:='';
|
|
DockAlign:=alNone;
|
|
|
|
// get the embedded control
|
|
AControl:=DockMaster.GetControl(AForm);
|
|
if not (AControl is TCustomForm) then exit;
|
|
AForm:=TCustomForm(AControl);
|
|
|
|
Creator:=IDEWindowCreators.FindWithName(AForm.Name);
|
|
if Creator=nil then exit;
|
|
if Creator.OnGetLayout<>nil then
|
|
Creator.OnGetLayout(Self,AForm.Name,NewBounds,DockSiblingName,DockAlign)
|
|
else begin
|
|
Creator.GetDefaultBounds(AForm,NewBounds);
|
|
DockSiblingName:=Creator.DockSibling;
|
|
DockAlign:=Creator.DockAlign;
|
|
end;
|
|
NewBounds.Left:=Min(10000,Max(-10000,NewBounds.Left));
|
|
NewBounds.Top:=Min(10000,Max(-10000,NewBounds.Top));
|
|
NewBounds.Right:=Max(NewBounds.Left+100,NewBounds.Right);
|
|
NewBounds.Bottom:=Max(NewBounds.Top+100,NewBounds.Bottom);
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.SetEnabled(const AValue: boolean);
|
|
begin
|
|
if FEnabled=AValue then exit;
|
|
FEnabled:=AValue;
|
|
IncreaseChangeStamp;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.SetModified(const AValue: boolean);
|
|
begin
|
|
if FModified=AValue then exit;
|
|
FModified:=AValue;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.SetUserLayoutLoaded(const AValue: boolean);
|
|
begin
|
|
if FUserLayoutLoaded=AValue then exit;
|
|
FUserLayoutLoaded:=AValue;
|
|
end;
|
|
|
|
constructor TIDEAnchorDockMaster.Create;
|
|
begin
|
|
inherited Create;
|
|
fEnabled:=true;
|
|
IDEAnchorDockMaster:=Self;
|
|
DockMaster.OnCreateControl:=@DockMasterCreateControl;
|
|
DockMaster.OnShowOptions:=@ShowAnchorDockOptions;
|
|
FHideSimpleLayoutOptions:=true;
|
|
end;
|
|
|
|
destructor TIDEAnchorDockMaster.Destroy;
|
|
begin
|
|
IDEAnchorDockMaster:=nil;
|
|
if IDEDockMaster=Self then
|
|
IDEDockMaster:=Self;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.MakeIDEWindowDockSite(AForm: TCustomForm;
|
|
ASides: TDockSides);
|
|
var
|
|
aManager: TAnchorDockManager;
|
|
begin
|
|
debugln(['TIDEAnchorDockMaster.MakeIDEWindowDockSite ',DbgSName(AForm)]);
|
|
if ASides=[] then ;
|
|
DockMaster.MakeDockSite(AForm,[akBottom],admrpChild);
|
|
if AForm.DockManager is TAnchorDockManager then begin
|
|
aManager:=TAnchorDockManager(AForm.DockManager);
|
|
aManager.PreferredSiteSizeAsSiteMinimum:=false;
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.MakeIDEWindowDockable(AControl: TWinControl);
|
|
begin
|
|
debugln(['TIDEAnchorDockMaster.MakeIDEWindowDockable ',DbgSName(AControl)]);
|
|
DockMaster.MakeDockable(AControl,false);
|
|
end;
|
|
|
|
function TIDEAnchorDockMaster.AddableInWindowMenu(AForm: TCustomForm): boolean;
|
|
begin
|
|
Result:=false;
|
|
if AForm is TAnchorDockHostSite then exit;
|
|
if (DockMaster.FindControl(AForm.Name)=nil) and (AForm.Parent<>nil) then exit;
|
|
Result:=true;
|
|
end;
|
|
|
|
function TIDEAnchorDockMaster.GetDefaultLayoutFilename: string;
|
|
begin
|
|
Result:=AppendPathDelim(LazarusIDE.GetPrimaryConfigPath)+DefaultConfigFileName;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.LoadDefaultLayout;
|
|
var
|
|
BaseDir: String;
|
|
Filename: String;
|
|
begin
|
|
BaseDir:='$PkgDir(AnchorDockingDsgn)';
|
|
IDEMacros.SubstituteMacros(BaseDir);
|
|
if (BaseDir<>'') and DirectoryExistsUTF8(BaseDir) then begin
|
|
Filename:=AppendPathDelim(BaseDir)+'ADLayoutDefault.xml';
|
|
if FileExistsUTF8(Filename) then
|
|
LoadLayoutFromFile(Filename);
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.LoadUserLayout;
|
|
var
|
|
Filename: String;
|
|
Config: TConfigStorage;
|
|
begin
|
|
Filename:=DefaultConfigFileName;
|
|
try
|
|
debugln(['TIDEAnchorDockMaster.LoadUserLayout ',Filename]);
|
|
Config:=GetIDEConfigStorage(Filename,true);
|
|
try
|
|
if not DockMaster.ConfigIsEmpty(Config) then begin
|
|
// loading last layout
|
|
debugln(['TIDEAnchorDockMaster.LoadUserLayout restoring ...']);
|
|
DockMaster.LoadSettingsFromConfig(Config);
|
|
DockMaster.LoadLayoutFromConfig(Config,true);
|
|
UserLayoutLoaded:=true;
|
|
end else begin
|
|
debugln(['TIDEAnchorDockMaster.LoadUserLayout loading default layout ...']);
|
|
LoadDefaultLayout;
|
|
end;
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
except
|
|
on E: Exception do begin
|
|
DebugLn(['TIDEAnchorDockMaster.LoadUserLayout loading ',Filename,' failed: ',E.Message]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.SaveUserLayout;
|
|
var
|
|
Filename: String;
|
|
Config: TConfigStorage;
|
|
begin
|
|
Filename:=DefaultConfigFileName;
|
|
try
|
|
debugln(['TIDEAnchorDockMaster.SaveDefaultLayout ',Filename]);
|
|
Config:=GetIDEConfigStorage(Filename,false);
|
|
try
|
|
DockMaster.SaveSettingsToConfig(Config);
|
|
DockMaster.SaveLayoutToConfig(Config);
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
except
|
|
on E: Exception do begin
|
|
DebugLn(['TIDEAnchorDockMaster.SaveDefaultLayout saving ',Filename,' failed: ',E.Message]);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.LoadLayoutFromFile(Filename: string);
|
|
var
|
|
XMLConfig: TXMLConfig;
|
|
Config: TXMLConfigStorage;
|
|
begin
|
|
//debugln(['TIDEAnchorDockMaster.LoadLayoutFromFile ',Filename]);
|
|
XMLConfig:=TXMLConfig.Create(nil);
|
|
try
|
|
XMLConfig.Filename:=Filename;
|
|
Config:=TXMLConfigStorage.Create(XMLConfig);
|
|
try
|
|
DockMaster.LoadLayoutFromConfig(Config,true);
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
XMLConfig.Flush;
|
|
finally
|
|
XMLConfig.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.SaveLayoutToFile(Filename: string);
|
|
var
|
|
XMLConfig: TXMLConfig;
|
|
Config: TXMLConfigStorage;
|
|
begin
|
|
XMLConfig:=TXMLConfig.Create(nil);
|
|
try
|
|
XMLConfig.StartEmpty:=true;
|
|
XMLConfig.Filename:=Filename;
|
|
Config:=TXMLConfigStorage.Create(XMLConfig);
|
|
try
|
|
DockMaster.SaveLayoutToConfig(Config);
|
|
finally
|
|
Config.Free;
|
|
end;
|
|
XMLConfig.Flush;
|
|
finally
|
|
XMLConfig.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.ShowForm(AForm: TCustomForm;
|
|
BringToFront: boolean);
|
|
var
|
|
Parent: TCustomForm;
|
|
Creator: TIDEWindowCreator;
|
|
NewBounds: TRect;
|
|
DockSiblingName: string;
|
|
DockAlign: TAlign;
|
|
DockSibling: TCustomForm;
|
|
NewDockSite: TCustomForm;
|
|
Site: TAnchorDockHostSite;
|
|
AControl: TControl;
|
|
NeedPlacing: Boolean;
|
|
SiteForm: TCustomForm;
|
|
OldActiveControl: TWinControl;
|
|
begin
|
|
//debugln(['TIDEAnchorDockMaster.ShowForm START ',DbgSName(AForm),' BringToFront=',BringToFront,' IsSite=',DockMaster.IsSite(AForm),' IsCustomSite=',DockMaster.IsCustomSite(AForm)]);
|
|
try
|
|
AForm.DisableAlign;
|
|
|
|
NeedPlacing:=not AForm.IsVisible;
|
|
if DockMaster.GetSite(AForm)=nil then begin
|
|
// this form was not yet docked
|
|
// => make it dockable
|
|
DockMaster.MakeDockable(AForm,false);
|
|
NeedPlacing:=true;
|
|
end;
|
|
AControl:=DockMaster.GetControl(AForm);
|
|
|
|
if not Aform.IsVisible then debugln(['TIDEAnchorDockMaster.ShowForm AControl=',DbgSName(AControl),' NeedPlacing=',NeedPlacing,' Floating=',DockMaster.IsFloating(AForm)]);
|
|
|
|
if (AControl<>nil) and NeedPlacing and DockMaster.IsFloating(AForm) then begin
|
|
// this form is not yet on the screen and is not yet docked
|
|
debugln(['TIDEAnchorDockMaster.ShowForm placing ',DbgSName(AControl),' ...']);
|
|
|
|
// ToDo: use the restore layout
|
|
|
|
// place it at a default position and/or dock it
|
|
GetDefaultBounds(AForm,Creator,NewBounds,DockSiblingName,DockAlign);
|
|
if Creator<>nil then begin
|
|
SiteForm:=GetParentForm(AForm);
|
|
SiteForm.BoundsRect:=NewBounds;
|
|
SiteForm.UndockWidth:=NewBounds.Right-NewBounds.Left;
|
|
SiteForm.UndockHeight:=NewBounds.Bottom-NewBounds.Top;
|
|
debugln(['TIDEAnchorDockMaster.ShowForm creator for ',DbgSName(AControl),' found: Left=',Creator.Left,' Top=',Creator.Top,' Right=',Creator.Right,' Bottom=',Creator.Bottom,' DockSiblingName=',DockSiblingName,' DockAlign=',dbgs(DockAlign),' ',dbgs(SiteForm.BoundsRect)]);
|
|
Site:=DockMaster.GetAnchorSite(SiteForm);
|
|
if (Site<>nil) and (DockSiblingName<>'') then begin
|
|
DockSibling:=Screen.FindForm(DockSiblingName);
|
|
debugln(['TIDEAnchorDockMaster.ShowForm DockSiblingName="',DockSiblingName,'" DockSibling=',DbgSName(DockSibling)]);
|
|
if DockSibling<>nil then begin
|
|
NewDockSite:=DockMaster.GetSite(DockSibling);
|
|
if NewDockSite<>nil then begin
|
|
debugln(['TIDEAnchorDockMaster.ShowForm NewDockSite=',DbgSName(NewDockSite),'="',NewDockSite.Caption,'"']);
|
|
DockMaster.ManualDock(Site,NewDockSite,DockAlign);
|
|
debugln(['TIDEAnchorDockMaster.ShowForm after docking: ',DbgSName(AControl),' Floating=',DockMaster.IsFloating(AControl)]);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
OldActiveControl:=AForm.ActiveControl;
|
|
if not AForm.IsVisible then debugln(['TIDEAnchorDockMaster.ShowForm MakeVisible ',DbgSName(AForm),' ',dbgs(AForm.BoundsRect),' Floating=',DockMaster.IsFloating(AForm)]);
|
|
DockMaster.MakeVisible(AForm,BringToFront);
|
|
AForm.EnableAlign;
|
|
|
|
if BringToFront then begin
|
|
if (OldActiveControl=nil)
|
|
or (not OldActiveControl.HandleAllocated)
|
|
or (FindControl(GetFocus)<>OldActiveControl) then begin
|
|
Parent:=GetParentForm(AForm);
|
|
Parent.ShowOnTop;
|
|
if (OldActiveControl<>nil) and OldActiveControl.CanFocus then
|
|
begin
|
|
Parent.ActiveControl:=OldActiveControl;
|
|
Parent.SetFocus;
|
|
end;
|
|
//debugln(['TIDEAnchorDockMaster.ShowForm AForm.ActiveControl=',dbgsname(AForm.ActiveControl),' ',DbgSName(Parent.ActiveControl),' ',DbgSName(FindControl(GetFocus))]);
|
|
end;
|
|
end;
|
|
end;
|
|
//debugln(['TIDEAnchorDockMaster.ShowForm END ',DbgSName(AForm),' ',dbgs(AForm.BoundsRect),' ',DbgSName(FindControl(GetFocus))]);
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.CloseAll;
|
|
begin
|
|
DockMaster.CloseAll;
|
|
end;
|
|
|
|
function TIDEAnchorDockMaster.OnProjectClose(Sender: TObject;
|
|
AProject: TLazProject): TModalResult;
|
|
begin
|
|
Result:=mrOk;
|
|
if AProject=nil then exit;
|
|
// do not auto save user layout, the restore is not yet stable
|
|
//SaveUserLayout;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.RestoreDefaultLayoutClicked(Sender: TObject);
|
|
begin
|
|
LoadDefaultLayout;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.OnIDERestoreWindows(Sender: TObject);
|
|
begin
|
|
LoadUserLayout;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.LoadLayoutFromFileClicked(Sender: TObject);
|
|
var
|
|
Dlg: TOpenDialog;
|
|
Filename: String;
|
|
begin
|
|
Dlg:=TOpenDialog.Create(nil);
|
|
try
|
|
InitIDEFileDialog(Dlg);
|
|
Dlg.Title:=adrsLoadWindowLayoutFromFileXml;
|
|
Dlg.Options:=Dlg.Options+[ofFileMustExist];
|
|
Dlg.Filter:=adrsAnchorDockingLayout+'|*.xml|'+adrsAllFiles+'|'+GetAllFilesMask;
|
|
if Dlg.Execute then begin
|
|
Filename:=CleanAndExpandFilename(Dlg.FileName);
|
|
try
|
|
LoadLayoutFromFile(Filename);
|
|
except
|
|
on E: Exception do begin
|
|
IDEMessageDialog(adrsError,
|
|
Format(adrsErrorLoadingWindowLayoutFromFile, [Filename, #13, E.Message]),
|
|
mtError,[mbCancel]);
|
|
end;
|
|
end;
|
|
end;
|
|
StoreIDEFileDialog(Dlg);
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.SaveLayoutToFileClicked(Sender: TObject);
|
|
var
|
|
Dlg: TSaveDialog;
|
|
Filename: String;
|
|
begin
|
|
Dlg:=TSaveDialog.Create(nil);
|
|
try
|
|
InitIDEFileDialog(Dlg);
|
|
Dlg.Title:=adrsSaveWindowLayoutToFileXml;
|
|
Dlg.Options:=Dlg.Options+[ofPathMustExist,ofNoReadOnlyReturn,ofOverwritePrompt];
|
|
Dlg.Filter:=adrsAnchorDockingLayout+'|*.xml|'+adrsAllFiles+'|'+GetAllFilesMask;
|
|
if Dlg.Execute then begin
|
|
Filename:=CleanAndExpandFilename(Dlg.FileName);
|
|
if ExtractFileExt(Filename)='' then
|
|
Filename:=Filename+'.xml';
|
|
try
|
|
SaveLayoutToFile(Filename);
|
|
except
|
|
on E: Exception do begin
|
|
IDEMessageDialog(adrsError,
|
|
Format(adrsErrorWritingWindowLayoutToFile, [Filename, #13, E.Message]),
|
|
mtError,[mbCancel]);
|
|
end;
|
|
end;
|
|
end;
|
|
StoreIDEFileDialog(Dlg);
|
|
finally
|
|
Dlg.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.SaveLayoutAsDefaultClicked(Sender: TObject);
|
|
begin
|
|
SaveUserLayout;
|
|
end;
|
|
|
|
procedure TIDEAnchorDockMaster.IncreaseChangeStamp;
|
|
begin
|
|
if FChangeStamp<High(FChangeStamp) then
|
|
inc(FChangeStamp)
|
|
else
|
|
FChangeStamp:=low(FChangeStamp);
|
|
end;
|
|
|
|
{ TAnchorDockIDEFrame }
|
|
|
|
constructor TAnchorDockIDEFrame.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
|
|
OptionsFrame:=TAnchorDockOptionsFrame.Create(Self);
|
|
with OptionsFrame do begin
|
|
Name:='OptionsFrame';
|
|
end;
|
|
end;
|
|
|
|
destructor TAnchorDockIDEFrame.Destroy;
|
|
begin
|
|
inherited Destroy;
|
|
end;
|
|
|
|
function TAnchorDockIDEFrame.GetTitle: String;
|
|
begin
|
|
Result:='Docking / Anchordocking';
|
|
end;
|
|
|
|
procedure TAnchorDockIDEFrame.Setup(ADialog: TAbstractOptionsEditorDialog);
|
|
begin
|
|
if ADialog=nil then ;
|
|
if IDEDockMaster=IDEAnchorDockMaster then begin
|
|
NoteLabel.Visible:=false;
|
|
EnableCheckBox.AnchorParallel(akTop,6,Self);
|
|
OptionsFrame.Align:=alBottom;
|
|
OptionsFrame.AnchorToNeighbour(akTop,6,EnableCheckBox);
|
|
OptionsFrame.Parent:=Self;
|
|
EnableCheckBox.Caption:=adrsDockingEnabledRequiresARestartOfTheIDE;
|
|
end else begin
|
|
NoteLabel.Visible:=true;
|
|
NoteLabel.Caption:=Format(adrsToUseAnchordockingYouMustFirstUninstall, [
|
|
DbgSName(IDEDockMaster)]);
|
|
NoteLabel.Hint:=Format(
|
|
adrsThereIsAnotherDockMasterInstalledOnlyOneDockingPac, [DbgSName(
|
|
IDEDockMaster)]);
|
|
EnableCheckBox.Visible:=false;
|
|
OptionsFrame.Parent:=nil;
|
|
end;
|
|
end;
|
|
|
|
procedure TAnchorDockIDEFrame.ReadSettings(AOptions: TAbstractIDEOptions);
|
|
begin
|
|
if not (AOptions is SupportedOptionsClass) then exit;
|
|
EnableCheckBox.Checked:=IDEAnchorDockMaster.Enabled;
|
|
OptionsFrame.Master:=DockMaster;
|
|
end;
|
|
|
|
procedure TAnchorDockIDEFrame.WriteSettings(AOptions: TAbstractIDEOptions);
|
|
begin
|
|
if not (AOptions is SupportedOptionsClass) then exit;
|
|
IDEAnchorDockMaster.Enabled:=EnableCheckBox.Checked;
|
|
OptionsFrame.SaveToMaster;
|
|
|
|
end;
|
|
|
|
class function TAnchorDockIDEFrame.
|
|
SupportedOptionsClass: TAbstractIDEOptionsClass;
|
|
begin
|
|
Result:=IDEEditorGroups.GetByIndex(GroupEnvironment)^.GroupClass;
|
|
end;
|
|
|
|
initialization
|
|
// create the dockmaster in the initialization section, so that it is ready
|
|
// when the Register procedures of the packages are called.
|
|
if IDEDockMaster<>nil then begin
|
|
debugln('WARNING: there is already another IDEDockMaster installed.');
|
|
TIDEAnchorDockMaster.Create;
|
|
end else
|
|
IDEDockMaster:=TIDEAnchorDockMaster.Create;
|
|
|
|
finalization
|
|
FreeAndNil(IDEAnchorDockMaster);
|
|
|
|
end.
|
|
|