IDE: Fully implement saving/loading desktops and the GUI for it. Modified patch from Ondrej Pokorny.

git-svn-id: trunk@49514 -
This commit is contained in:
juha 2015-07-09 19:05:29 +00:00
parent 374bd932f9
commit 423c43ea13
13 changed files with 600 additions and 188 deletions

View File

@ -1225,7 +1225,7 @@ begin
end;
const
IDEEditorCommandStrs: array[0..307] of TIdentMapEntry = (
IDEEditorCommandStrs: array[0..308] of TIdentMapEntry = (
// search
(Value: ecFind; Name: 'ecFind'),
(Value: ecFindAgain; Name: 'ecFindAgain'),
@ -1488,6 +1488,7 @@ const
// tools menu
(Value: ecEnvironmentOptions; Name: 'ecEnvironmentOptions'),
(Value: ecManageDesktops; Name: 'ecManageDesktops'),
(Value: ecRescanFPCSrcDir; Name: 'ecRescanFPCSrcDir'),
(Value: ecEditCodeTemplates; Name: 'ecEditCodeTemplates'),
(Value: ecCodeToolsDefinesEd; Name: 'ecCodeToolsDefinesEd'),

View File

@ -204,6 +204,10 @@ type
FTop: integer;
FWidth: integer;
FHeight: integer;
FDefaultLeft: integer;
FDefaultTop: integer;
FDefaultWidth: integer;
FDefaultHeight: integer;
FWindowState: TIDEWindowState;
FForm: TCustomForm;
FFormID: string;
@ -218,10 +222,9 @@ type
public
constructor Create(AFormID: string); reintroduce;
destructor Destroy; override;
function CreateCopy: TSimpleWindowLayout;
procedure Clear;
procedure GetCurrentPosition;
function Apply: Boolean;
function Apply(const aForce: Boolean = False): Boolean;
procedure ApplyDivider(AForce: Boolean = False);
procedure Assign(Layout: TSimpleWindowLayout); reintroduce;
procedure ReadCurrentDividers(AForce: Boolean = False);
@ -231,7 +234,8 @@ type
procedure SaveToConfig(Config: TConfigStorage; const Path: string);
function CustomCoordinatesAreValid: boolean;
procedure CloseForm;
function ValidateAndSetCoordinates: Boolean;
function ValidateAndSetCoordinates(const aForce: Boolean = False): Boolean;
procedure SetDefaultPosition(const AForm: TCustomForm);
public
property FormID: string read GetFormID write FFormID;
function FormBaseID(out SubIndex: Integer): String; // split FormID into name+number
@ -243,6 +247,10 @@ type
property Top: integer read FTop write FTop;
property Width: integer read FWidth write FWidth;
property Height: integer read FHeight write FHeight;
property DefaultLeft: integer read FDefaultLeft write FDefaultLeft;
property DefaultTop: integer read FDefaultTop write FDefaultTop;
property DefaultWidth: integer read FDefaultWidth write FDefaultWidth;
property DefaultHeight: integer read FDefaultHeight write FDefaultHeight;
property WindowState: TIDEWindowState read FWindowState write FWindowState;
property Form: TCustomForm read FForm write SetForm;
property Visible: boolean read FVisible write FVisible;
@ -260,10 +268,11 @@ type
TSimpleWindowLayoutList = class
private
fItems: TFPList;
fRegisterEventHandlers: Boolean;
function GetItems(Index: Integer): TSimpleWindowLayout;
procedure OnScreenRemoveForm(Sender: TObject; AForm: TCustomForm);
public
constructor Create;
constructor Create(ARegisterEventHandlers: Boolean);
destructor Destroy; override;
procedure Clear;
procedure Delete(Index: Integer);
@ -271,7 +280,9 @@ type
BringToFront: boolean;
AMoveToVisbleMode: TLayoutMoveToVisbleMode = vmAlwaysMoveToVisible);
procedure StoreWindowPositions;
procedure Assign(SrcList: TSimpleWindowLayoutList);
procedure SetDefaultPosition(const AForm: TCustomForm);
procedure Assign(SrcList: TSimpleWindowLayoutList; AssignOnlyNewlyCreated,
DestroyNotAssigned: Boolean);
function Add(ALayout: TSimpleWindowLayout): integer;
function CreateWindowLayout(const TheFormID: string): TSimpleWindowLayout;
function CreateWindowLayout(const TheForm: TCustomForm): TSimpleWindowLayout;
@ -397,6 +408,8 @@ type
fItems: TFPList; // list of TIDEWindowCreator
FScreenMaxSizeForDefaults: TPoint;
FSimpleLayoutStorage: TSimpleWindowLayoutList;
FOnLayoutChanged: TMethodList;
procedure LayoutChanged;
function GetItems(Index: integer): TIDEWindowCreator;
procedure ErrorIfFormExists(FormName: string);
public
@ -431,6 +444,8 @@ type
property SimpleLayoutStorage: TSimpleWindowLayoutList read FSimpleLayoutStorage;
procedure RestoreSimpleLayout;
procedure AddLayoutChangedHandler(const aEvent: TNotifyEvent);
procedure RemoveLayoutChangedHandler(const aEvent: TNotifyEvent);
property ScreenMaxSizeForDefaults: TPoint read FScreenMaxSizeForDefaults
write FScreenMaxSizeForDefaults; // on big screens: do not span the whole screen
@ -1095,12 +1110,6 @@ begin
FDividers.Free;
end;
function TSimpleWindowLayout.CreateCopy: TSimpleWindowLayout;
begin
Result := TSimpleWindowLayout.Create(FFormID);
Result.Assign(Self);
end;
procedure TSimpleWindowLayout.LoadFromConfig(Config: TConfigStorage; const Path: string);
var
P: string;
@ -1154,6 +1163,14 @@ begin
FDividers.SaveToConfig(Config, P + 'Divider/');
end;
procedure TSimpleWindowLayout.SetDefaultPosition(const AForm: TCustomForm);
begin
FDefaultLeft := AForm.Left;
FDefaultTop := AForm.Top;
FDefaultWidth := AForm.Width;
FDefaultHeight := AForm.Height;
end;
procedure TSimpleWindowLayout.OnFormClose(Sender: TObject;
var CloseAction: TCloseAction);
begin
@ -1183,15 +1200,19 @@ begin
Form:=nil;
end;
function TSimpleWindowLayout.ValidateAndSetCoordinates: Boolean;
function TSimpleWindowLayout.ValidateAndSetCoordinates(const aForce: Boolean
): Boolean;
var
i: Integer;
NewBounds: TRect;
begin
Result := False;
if CustomCoordinatesAreValid then begin
// explicit position
NewBounds := Bounds(Left, Top, Width, Height);
if aForce or CustomCoordinatesAreValid then begin
if not CustomCoordinatesAreValid then//default position
NewBounds := Bounds(DefaultLeft, DefaultTop, DefaultWidth, DefaultHeight)
else// explicit position
NewBounds := Bounds(Left, Top, Width, Height);
// set minimum size
if NewBounds.Right - NewBounds.Left < 60 then
NewBounds.Right := NewBounds.Left + 60;
@ -1283,6 +1304,8 @@ end;
procedure TSimpleWindowLayout.Clear;
begin
//debugln(['TSimpleWindowLayout.Clear ',FormID]);
fApplied := False;
fVisible := False;
fWindowPlacement:=fDefaultWindowPlacement;
fLeft:=0;
fTop:=0;
@ -1324,15 +1347,15 @@ end;
procedure TSimpleWindowLayout.Assign(Layout: TSimpleWindowLayout);
begin
Clear;
FApplied:=Layout.Applied;
FForm:=Layout.FForm;
Assert(FFormID = Layout.FFormID);
//IMPORTANT: do not assign FForm and FFormID!
FVisible:=Layout.FVisible;
FWindowPlacement:=Layout.FWindowPlacement;
FLeft:=Layout.FLeft;
FTop:=Layout.FTop;
FWidth:=Layout.FWidth;
FHeight:=Layout.FHeight;
FWindowState:=Layout.FWindowState;
FFormID:=Layout.FFormID;
FDefaultWindowPlacement:=Layout.FDefaultWindowPlacement;
FDividers.Assign(Layout.FDividers);
end;
@ -1377,7 +1400,7 @@ begin
//debugln('TSimpleWindowLayout.GetCurrentPosition ',DbgSName(Self),' ',FormID,' Width=',dbgs(Width));
end;
function TSimpleWindowLayout.Apply: Boolean;
function TSimpleWindowLayout.Apply(const aForce: Boolean): Boolean;
begin
Result := False;
if fForm = nil then exit;
@ -1396,7 +1419,7 @@ begin
iwsMinimized: FForm.WindowState:=wsMinimized;
iwsMaximized: FForm.WindowState:=wsMaximized;
end;
Result := ValidateAndSetCoordinates; // Adjust bounds to screen area and apply them.
Result := ValidateAndSetCoordinates(aForce); // Adjust bounds to screen area and apply them.
if WindowState in [iwsMinimized, iwsMaximized] then
Result := True;
end;
@ -1404,7 +1427,7 @@ begin
Result := True;
end;
ApplyDivider;
ApplyDivider(aForce);
end;
procedure TSimpleWindowLayout.ApplyDivider(AForce: Boolean = False);
@ -1457,10 +1480,12 @@ begin
CloseForm(AForm);
end;
constructor TSimpleWindowLayoutList.Create;
constructor TSimpleWindowLayoutList.Create(ARegisterEventHandlers: Boolean);
begin
fItems:=TFPList.Create;
Screen.AddHandlerRemoveForm(@OnScreenRemoveForm);
fRegisterEventHandlers := ARegisterEventHandlers;
if ARegisterEventHandlers then
Screen.AddHandlerRemoveForm(@OnScreenRemoveForm);
end;
destructor TSimpleWindowLayoutList.Destroy;
@ -1511,6 +1536,18 @@ begin
end;
end;
procedure TSimpleWindowLayoutList.SetDefaultPosition(const AForm: TCustomForm);
var
xLayout: TSimpleWindowLayout;
begin
if AForm.Name <> '' then
begin
xLayout:=ItemByFormID(AForm.Name);
if xLayout<>nil then
xLayout.SetDefaultPosition(AForm);
end;
end;
function TSimpleWindowLayoutList.Count: integer;
begin
Result:=fItems.Count;
@ -1724,15 +1761,37 @@ begin
Items[i].GetCurrentPosition;
end;
procedure TSimpleWindowLayoutList.Assign(SrcList: TSimpleWindowLayoutList);
procedure TSimpleWindowLayoutList.Assign(SrcList: TSimpleWindowLayoutList;
AssignOnlyNewlyCreated, DestroyNotAssigned: Boolean);
var
i: integer;
xItemIndex: Integer;
xNewlyCreated: Boolean;
begin
Clear;
if SrcList=nil then exit;
for i:=0 to SrcList.Count-1 do begin
Add(SrcList[i].CreateCopy);
xNewlyCreated := False;
if (i >= Self.Count) or (Self.Items[i].FormID <> SrcList[i].FormID) then
begin//the target item has not the same index, find it!
xItemIndex := IndexOf(SrcList[i].FormID);
if xItemIndex < 0 then
begin
xItemIndex := Self.Add(TSimpleWindowLayout.Create(SrcList[i].FormID));//not found, create
xNewlyCreated := True;
end;
if xItemIndex<>i then
Self.fItems.Move(xItemIndex, i);//move it to right position
xItemIndex := i;
end;
if not AssignOnlyNewlyCreated or xNewlyCreated then
Self.Items[i].Assign(SrcList[i])
end;
for i := Count-1 downto xItemIndex+1 do
if DestroyNotAssigned then
Delete(i)
else
Items[i].Clear;
end;
function TSimpleWindowLayoutList.Add(ALayout: TSimpleWindowLayout): integer;
@ -1955,8 +2014,9 @@ end;
constructor TIDEWindowCreatorList.Create;
begin
fItems:=TFPList.Create;
FSimpleLayoutStorage:=TSimpleWindowLayoutList.Create;
FSimpleLayoutStorage:=TSimpleWindowLayoutList.Create(True);
FScreenMaxSizeForDefaults:=Point(1200,900);
FOnLayoutChanged:=TMethodList.Create;
end;
destructor TIDEWindowCreatorList.Destroy;
@ -1964,6 +2024,7 @@ begin
Clear;
FreeAndNil(fItems);
FreeAndNil(FSimpleLayoutStorage);
FOnLayoutChanged.Free;
inherited Destroy;
end;
@ -1987,6 +2048,12 @@ begin
Result:=fItems.Add(aLayout);
end;
procedure TIDEWindowCreatorList.AddLayoutChangedHandler(
const aEvent: TNotifyEvent);
begin
FOnLayoutChanged.Add(TMethod(aEvent));
end;
function TIDEWindowCreatorList.Add(aFormName: string
): TIDEWindowCreator;
begin
@ -2021,6 +2088,24 @@ begin
dec(Result);
end;
procedure TIDEWindowCreatorList.LayoutChanged;
var
I: Integer;
xEvent: TNotifyEvent;
begin
for I := 0 to FOnLayoutChanged.Count-1 do
begin
xEvent := TNotifyEvent(FOnLayoutChanged[I]);
xEvent(Self);
end;
end;
procedure TIDEWindowCreatorList.RemoveLayoutChangedHandler(
const aEvent: TNotifyEvent);
begin
FOnLayoutChanged.Remove(TMethod(aEvent));
end;
function TIDEWindowCreatorList.FindWithName(FormName: string): TIDEWindowCreator;
var
i: LongInt;
@ -2061,6 +2146,7 @@ begin
debugln(['TIDEWindowCreatorList.GetForm create failed for ',aFormName]);
exit;
end;
SimpleLayoutStorage.SetDefaultPosition(Result);
end;
end;
@ -2107,6 +2193,7 @@ begin
TCustomForm(AForm).Create(TheOwner);
if not DoDisableAutoSizing then
TCustomForm(AForm).EnableAutoSizing;
SimpleLayoutStorage.SetDefaultPosition(TCustomForm(AForm));
end else if DoDisableAutoSizing then
TCustomForm(AForm).DisableAutoSizing;
end;
@ -2117,13 +2204,24 @@ var
ALayout: TSimpleWindowLayout;
AForm: TCustomForm;
begin
for i:=0 to SimpleLayoutStorage.Count-1 do begin
ALayout:=SimpleLayoutStorage[i];
if not ALayout.Visible then continue;
AForm:=GetForm(ALayout.FormID,true);
if AForm=nil then continue;
ShowForm(AForm,false);
if IDEDockMaster=nil then
begin
for i:=0 to SimpleLayoutStorage.Count-1 do begin
ALayout:=SimpleLayoutStorage[i];
AForm:=GetForm(ALayout.FormID,ALayout.Visible);
if AForm=nil then Continue;
ALayout.Apply(True);
if ALayout.Visible then
ShowForm(AForm,false)
else
begin
//ALayout.Apply;
if AForm.Visible then
AForm.Close;
end;
end;
end;
LayoutChanged;
end;
function TIDEWindowCreatorList.GetScreenrectForDefaults: TRect;
@ -2159,8 +2257,10 @@ end;
initialization
IDEWindowCreators:=TIDEWindowCreatorList.Create;
IDEDialogLayoutList:=TIDEDialogLayoutList.Create;
finalization
FreeAndNil(IDEWindowCreators);
FreeAndNil(IDEDialogLayoutList);
end.

View File

@ -1,53 +1,94 @@
object DesktopForm: TDesktopForm
Left = 463
Height = 159
Top = 670
Width = 394
Left = 472
Height = 202
Top = 431
Width = 432
BorderIcons = [biSystemMenu]
Caption = 'DesktopForm'
ClientHeight = 159
ClientWidth = 394
ClientHeight = 202
ClientWidth = 432
OnCreate = FormCreate
Position = poScreenCenter
LCLVersion = '1.5'
object DesktopComboBox: TComboBox
Left = 6
Height = 23
Top = 12
Width = 212
ItemHeight = 17
OnSelect = DesktopComboBoxSelect
TabOrder = 0
Text = 'DesktopComboBox'
end
object SaveBitBtn: TBitBtn
AnchorSideLeft.Control = DesktopComboBox
AnchorSideLeft.Side = asrBottom
AnchorSideTop.Control = DesktopComboBox
AnchorSideTop.Side = asrCenter
Left = 229
Height = 29
Top = 9
Width = 133
AutoSize = True
BorderSpacing.Left = 11
AnchorSideLeft.Control = DeleteBitBtn
AnchorSideTop.Control = DesktopListBox
AnchorSideRight.Control = DeleteBitBtn
AnchorSideRight.Side = asrBottom
Left = 237
Height = 23
Top = 14
Width = 189
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
Caption = 'Save current desktop'
OnClick = SaveBitBtnClick
TabOrder = 1
end
object ButtonPanel1: TButtonPanel
Left = 6
Height = 37
Top = 116
Width = 382
Height = 34
Top = 162
Width = 420
OKButton.Name = 'OKButton'
OKButton.DefaultCaption = True
OKButton.Caption = 'Close and use selected desktop'
OKButton.DefaultCaption = False
HelpButton.Name = 'HelpButton'
HelpButton.DefaultCaption = True
CloseButton.Name = 'CloseButton'
CloseButton.DefaultCaption = True
CancelButton.Name = 'CancelButton'
CancelButton.DefaultCaption = True
TabOrder = 2
CancelButton.Caption = 'Close'
CancelButton.DefaultCaption = False
TabOrder = 4
ShowButtons = [pbOK, pbCancel]
ShowGlyphs = [pbOK, pbClose, pbHelp]
end
object DesktopListBox: TListBox
AnchorSideRight.Control = SaveBitBtn
Left = 11
Height = 147
Top = 8
Width = 216
Anchors = [akTop, akLeft, akRight, akBottom]
BorderSpacing.Right = 10
ItemHeight = 0
OnDblClick = DesktopListBoxDblClick
OnDrawItem = DesktopListBoxDrawItem
OnKeyPress = DesktopListBoxKeyPress
OnSelectionChange = DesktopListBoxSelectionChange
Style = lbOwnerDrawFixed
TabOrder = 0
end
object DeleteBitBtn: TBitBtn
AnchorSideLeft.Control = SetDebugDesktopBitBtn
AnchorSideTop.Control = SaveBitBtn
AnchorSideTop.Side = asrBottom
AnchorSideRight.Control = SetDebugDesktopBitBtn
AnchorSideRight.Side = asrBottom
Left = 237
Height = 23
Top = 43
Width = 189
Anchors = [akTop, akLeft, akRight]
BorderSpacing.Top = 6
Caption = 'Delete selected desktop'
OnClick = DeleteBitBtnClick
TabOrder = 2
end
object SetDebugDesktopBitBtn: TBitBtn
AnchorSideTop.Control = DeleteBitBtn
AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 237
Height = 23
Top = 86
Width = 189
Anchors = [akTop, akRight]
AutoSize = True
BorderSpacing.Top = 20
Caption = 'Toggle selected as debug desktop'
OnClick = SetDebugDesktopBitBtnClick
TabOrder = 3
end
end

View File

@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, StdCtrls,
Buttons, ButtonPanel,
Buttons, ButtonPanel, LCLType,
LazarusIDEStrConsts, LCLProc, EnvironmentOpts;
type
@ -15,13 +15,21 @@ type
TDesktopForm = class(TForm)
ButtonPanel1: TButtonPanel;
DesktopComboBox: TComboBox;
SetDebugDesktopBitBtn: TBitBtn;
DesktopListBox: TListBox;
SaveBitBtn: TBitBtn;
DeleteBitBtn: TBitBtn;
procedure DeleteBitBtnClick(Sender: TObject);
procedure DesktopListBoxDblClick(Sender: TObject);
procedure DesktopListBoxDrawItem(Control: TWinControl; Index: Integer;
ARect: TRect; State: TOwnerDrawState);
procedure DesktopListBoxKeyPress(Sender: TObject; var Key: char);
procedure DesktopListBoxSelectionChange(Sender: TObject; {%H-}User: boolean);
procedure FormCreate(Sender: TObject);
procedure DesktopComboBoxSelect(Sender: TObject);
procedure SaveBitBtnClick(Sender: TObject);
procedure SetDebugDesktopBitBtnClick(Sender: TObject);
private
procedure RefreshList(const SelectName: string = '');
public
end;
@ -32,69 +40,214 @@ function ShowDesktopManagerDlg: TModalResult;
implementation
uses
IDEWindowIntf, IDEOptionsIntf;
{$R *.lfm}
function ShowDesktopManagerDlg: TModalResult;
var
theForm: TDesktopForm;
xDesktopName: String;
xDesktop: TDesktopOpt;
begin
Result:=mrCancel;
xDesktopName := '';
theForm:=TDesktopForm.Create(Nil);
try
Result:=theForm.ShowModal;
if Result=mrYes then begin
debugln(['ShowDesktopManagerDlg: Selecting ', theForm.DesktopComboBox.Text]);
EnvironmentOptions.Desktops.Select(theForm.DesktopComboBox.Text);
end;
Result := theForm.ShowModal;
if (Result = mrOK) and (theForm.DesktopListBox.ItemIndex >= 0) then
xDesktopName := theForm.DesktopListBox.Items[theForm.DesktopListBox.ItemIndex];
finally
theForm.Free;
end;
end;
{$R *.lfm}
if xDesktopName <> '' then
with EnvironmentOptions do
begin
xDesktop := Desktops.Find(xDesktopName);
if xDesktop<>nil then
EnvironmentOptions.UseDesktop(xDesktop);
end;
end;
{ TDesktopForm }
procedure TDesktopForm.FormCreate(Sender: TObject);
var
i, ActiveInd: Integer;
begin
// Saved desktops
ActiveInd := 0;
with EnvironmentOptions do
for i:=0 to Desktops.Count-1 do
begin
if Desktops[i] = Desktop then
ActiveInd := i;
DesktopComboBox.Items.Add(Desktops[i].Name);
end;
DesktopComboBox.ItemIndex := ActiveInd;
// Save button
RefreshList;
// buttons captions & text
Caption := dlgManageDesktops;
SaveBitBtn.Caption := dlgSaveCurrentDesktop;
SaveBitBtn.LoadGlyphFromResourceName(HInstance, 'laz_save');
DeleteBitBtn.Caption := dlgDeleteSelectedDesktop;
DeleteBitBtn.LoadGlyphFromResourceName(HInstance, 'laz_delete');
SetDebugDesktopBitBtn.Caption := dlgToggleSelectedDebugDesktop;
SetDebugDesktopBitBtn.LoadGlyphFromResourceName(HInstance, 'menu_run');
ButtonPanel1.OKButton.Caption := dlgCloseAndUseSelectedDesktop;
ButtonPanel1.CancelButton.Caption := lisClose;
end;
procedure TDesktopForm.DesktopComboBoxSelect(Sender: TObject);
procedure TDesktopForm.RefreshList(const SelectName: string);
var
i: Integer;
begin
debugln(['TDesktopForm.DesktopComboBoxSelect: ', DesktopComboBox.Text]);
DesktopListBox.Clear;
// Saved desktops
with EnvironmentOptions do
for i:=0 to Desktops.Count-1 do
DesktopListBox.Items.Add(Desktops[i].Name);
DesktopListBox.ItemIndex := DesktopListBox.Items.IndexOf(SelectName);
DesktopListBoxSelectionChange(DesktopListBox, False);
end;
procedure TDesktopForm.DeleteBitBtnClick(Sender: TObject);
var
xDesktopName: String;
dskIndex: Integer;
begin
if DesktopListBox.ItemIndex = -1 then
Exit;
xDesktopName := DesktopListBox.Items[DesktopListBox.ItemIndex];
if MessageDlg(Format(dlgReallyDeleteDesktop, [xDesktopName]), mtConfirmation, mbYesNo, 0) <> mrYes then
Exit;
with EnvironmentOptions do
begin
dskIndex := Desktops.IndexOf(xDesktopName);
if dskIndex >= 0 then
begin
debugln(['TDesktopForm.SaveBitBtnClick: Deleting ', xDesktopName]);
Desktops.Delete(dskIndex);
if DesktopListBox.ItemIndex+1 < DesktopListBox.Count then
xDesktopName := DesktopListBox.Items[DesktopListBox.ItemIndex+1]
else if DesktopListBox.ItemIndex > 0 then
xDesktopName := DesktopListBox.Items[DesktopListBox.ItemIndex-1]
else
xDesktopName := '';
RefreshList(xDesktopName);
end;
end;
end;
procedure TDesktopForm.DesktopListBoxDblClick(Sender: TObject);
begin
if ButtonPanel1.OKButton.Enabled then
ButtonPanel1.OKButton.Click;
end;
procedure TDesktopForm.DesktopListBoxDrawItem(Control: TWinControl;
Index: Integer; ARect: TRect; State: TOwnerDrawState);
var
xLB: TListBox;
xName: string;
OldBrushStyle: TBrushStyle;
OldTextStyle: TTextStyle;
NewTextStyle: TTextStyle;
OldFontStyle: TFontStyles;
begin
xLB := Control as TListBox;
if (Index < 0) or (Index >= xLB.Count) then
Exit;
xLB.Canvas.FillRect(ARect);
OldBrushStyle := xLB.Canvas.Brush.Style;
xLB.Canvas.Brush.Style := bsClear;
OldFontStyle := xLB.Canvas.Font.Style;
OldTextStyle := xLB.Canvas.TextStyle;
NewTextStyle := OldTextStyle;
NewTextStyle.Layout := tlCenter;
NewTextStyle.RightToLeft := Control.UseRightToLeftReading;
if Control.UseRightToLeftAlignment then
begin
NewTextStyle.Alignment := taRightJustify;
ARect.Right := ARect.Right - 2;
end
else
begin
NewTextStyle.Alignment := taLeftJustify;
ARect.Left := ARect.Left + 2;
end;
xLB.Canvas.TextStyle := NewTextStyle;
xName := xLB.Items[Index];
if (xName <> '') and (EnvironmentOptions.DebugDesktopName = xName) then
begin
xName := xName + ' ('+dlgDebugDesktop+')';
xLB.Canvas.Font.Style := xLB.Canvas.Font.Style + [fsItalic];
end;
xLB.Canvas.TextRect(ARect, ARect.Left, ARect.Top, xName);
xLB.Canvas.Brush.Style := OldBrushStyle;
xLB.Canvas.TextStyle := OldTextStyle;
xLB.Canvas.Font.Style := OldFontStyle;
end;
procedure TDesktopForm.DesktopListBoxKeyPress(Sender: TObject; var Key: char);
begin
if Key = Char(VK_RETURN) then
DesktopListBoxDblClick(Sender);
end;
procedure TDesktopForm.DesktopListBoxSelectionChange(Sender: TObject;
User: boolean);
begin
DeleteBitBtn.Enabled := DesktopListBox.ItemIndex>=0;
SetDebugDesktopBitBtn.Enabled := DeleteBitBtn.Enabled;
ButtonPanel1.OKButton.Enabled := DeleteBitBtn.Enabled;
end;
procedure TDesktopForm.SaveBitBtnClick(Sender: TObject);
var
dsk: TDesktopOpt;
xDesktopName: string;
begin
if DesktopListBox.ItemIndex >= 0 then
xDesktopName := DesktopListBox.Items[DesktopListBox.ItemIndex]
else
xDesktopName := '';
if not InputQuery(dlgSaveCurrentDesktop, dlgDesktopNameWillBeOverwritten, xDesktopName)
or (xDesktopName = '') // xDesktopName MUST NOT BE EMPTY !!!
then
Exit;
with EnvironmentOptions do
begin
dsk := Desktops.Find(DesktopComboBox.Text);
dsk := Desktops.Find(xDesktopName);
if not Assigned(dsk) then
begin
debugln(['TDesktopForm.SaveBitBtnClick: Adding ', DesktopComboBox.Text]);
dsk := TDesktopOpt.Create(DesktopComboBox.Text);
debugln(['TDesktopForm.SaveBitBtnClick: Adding ', xDesktopName]);
dsk := TDesktopOpt.Create(xDesktopName, False);
Desktops.Add(dsk);
end;
debugln(['TDesktopForm.SaveBitBtnClick: Assign from ', Desktop.Name, ' to ', dsk.Name]);
Desktop.IDEWindowCreatorsLayoutList.StoreWindowPositions;
dsk.Assign(Desktop);
Desktops.Select(DesktopComboBox.Text);
RefreshList(xDesktopName);
end;
end;
procedure TDesktopForm.SetDebugDesktopBitBtnClick(Sender: TObject);
var
xDesktopName: String;
begin
if DesktopListBox.ItemIndex = -1 then
Exit;
xDesktopName := DesktopListBox.Items[DesktopListBox.ItemIndex];
if EnvironmentOptions.DebugDesktopName = xDesktopName then
EnvironmentOptions.DebugDesktopName := ''
else
EnvironmentOptions.DebugDesktopName := xDesktopName;
RefreshList(xDesktopName);
end;
end.

View File

@ -37,7 +37,7 @@ uses
{$ifdef Windows}
ShlObj,
{$endif}
Classes, SysUtils, TypInfo, strutils, fgl, Graphics, Controls, Forms, Dialogs,
Classes, SysUtils, TypInfo, contnrs, Graphics, Controls, Forms, Dialogs,
LCLProc, FileProcs, LazFileUtils, LazFileCache, LazConfigStorage,
Laz2_XMLCfg, LazUTF8,
// IDEIntf
@ -260,6 +260,8 @@ type
FXMLCfg: TRttiXMLConfig;
FConfigStore: TXMLOptionsStorage;
// window layout
FUseIDELayouts: Boolean;
FIDEWindowCreatorsLayoutList: TSimpleWindowLayoutList;
FIDEDialogLayoutList: TIDEDialogLayoutList;
FSingleTaskBarButton: boolean;
FHideIDEOnRun: boolean;
@ -286,12 +288,12 @@ type
procedure Load(Path: String);
procedure Save(Path: String);
public
constructor Create;
constructor Create(aName: String);
constructor Create(aName: String; const aUseIDELayouts: Boolean);
destructor Destroy; override;
procedure Assign(Source: TDesktopOpt);
property Name: String read FName write FName;
property IDEWindowCreatorsLayoutList: TSimpleWindowLayoutList read FIDEWindowCreatorsLayoutList write FIDEWindowCreatorsLayoutList;
property IDEDialogLayoutList: TIDEDialogLayoutList read FIDEDialogLayoutList;
property SingleTaskBarButton: boolean read FSingleTaskBarButton write FSingleTaskBarButton;
property HideIDEOnRun: boolean read FHideIDEOnRun write FHideIDEOnRun;
@ -317,12 +319,12 @@ type
{ TDesktopOptList }
dtol = specialize TFPGObjectList<TDesktopOpt>;
TDesktopOptList = class (dtol)
TDesktopOptList = class(TObjectList)
private
FXMLCfg: TRttiXMLConfig;
FConfigStore: TXMLOptionsStorage;
FEnvOpts: TEnvironmentOptions;
function GetItem(Index: Integer): TDesktopOpt;
procedure SetConfig(aXMLCfg: TRttiXMLConfig; aConfigStore: TXMLOptionsStorage);
public
constructor Create(aEnvOpts: TEnvironmentOptions);
@ -330,7 +332,7 @@ type
procedure AddFromCfg(Path: String);
function IndexOf(aName: string): integer;
function Find(aName: string): TDesktopOpt;
function Select(aName: string): Boolean;
property Items[Index: Integer]: TDesktopOpt read GetItem; default;
end;
{ TEnvironmentOptions - class for storing environment options }
@ -484,14 +486,17 @@ type
// Desktop
FDesktops: TDesktopOptList;
FDesktop: TDesktopOpt; // Active desktop
FDesktop: TDesktopOpt;
FLastDesktopBeforeDebug: TDesktopOpt;
FDebugDesktopName: string;
function GetCompilerFilename: string;
function GetCompilerMessagesFilename: string;
function GetDebugDesktop: TDesktopOpt;
function GetDebuggerEventLogColors(AIndex: TDBGEventType): TDebuggerEventLogColor;
function GetDebuggerFilename: string;
function GetDebuggerSearchPath: string;
function GetDesktop: TDesktopOpt;
function GetFPCSourceDirectory: string;
function GetFPDocPaths: string;
function GetLazarusDirectory: string;
@ -562,6 +567,11 @@ type
var {%H-}Abort: boolean): string;
function MacroFuncConfDir(const {%H-}s:string; const {%H-}Data: PtrInt;
var {%H-}Abort: boolean): string;
procedure UseDesktop(ADesktop: TDesktopOpt);
procedure EnableDebugDesktop;
procedure DisableDebugDesktop;
// auto save
// ask even if only project session needs saving
property AskSaveSessionOnly: boolean read FAskSaveSessionOnly write FAskSaveSessionOnly;
@ -753,7 +763,9 @@ type
property NewFormTemplate: string read FNewFormTemplate write FNewFormTemplate;
// Desktop
property Desktops: TDesktopOptList read FDesktops;
property Desktop: TDesktopOpt read GetDesktop;
property Desktop: TDesktopOpt read FDesktop;
property DebugDesktopName: string read FDebugDesktopName write FDebugDesktopName;
property DebugDesktop: TDesktopOpt read GetDebugDesktop;
end;
var
@ -890,11 +902,16 @@ end;
procedure TDesktopOptList.AddFromCfg(Path: String);
var
dsk: TDesktopOpt;
dskName: String;
begin
dsk := TDesktopOpt.Create;
dsk.SetConfig(FXMLCfg, FConfigStore);
dsk.Load(Path);
Add(dsk);
dskName := FXMLCfg.GetValue(Path+'Name', 'default');
if Find(dskName)=nil then
begin
dsk := TDesktopOpt.Create(dskName, False);
dsk.SetConfig(FXMLCfg, FConfigStore);
dsk.Load(Path);
Add(dsk);
end;
end;
function TDesktopOptList.IndexOf(aName: string): integer;
@ -916,22 +933,18 @@ begin
Result:=nil;
end;
function TDesktopOptList.Select(aName: string): Boolean;
var
dsk: TDesktopOpt;
function TDesktopOptList.GetItem(Index: Integer): TDesktopOpt;
begin
dsk := Find(aName);
Result := Assigned(dsk);
if Result then
FEnvOpts.FDesktop := dsk;
Result := TDesktopOpt(inherited Items[Index]);
end;
{ TDesktopOpt }
constructor TDesktopOpt.Create;
constructor TDesktopOpt.Create(aName: String; const aUseIDELayouts: Boolean);
begin
inherited Create;
FName:=aName;
FSingleTaskBarButton:=false;
FHideIDEOnRun:=false;
FAutoAdjustIDEHeight:=true;
@ -953,25 +966,35 @@ begin
FComponentPaletteOptions:=TCompPaletteOptions.Create;
// Windows layout
InitLayoutList;
FIDEDialogLayoutList:=TIDEDialogLayoutList.Create;
if IDEWindowIntf.IDEDialogLayoutList=nil then
IDEWindowIntf.IDEDialogLayoutList:=FIDEDialogLayoutList;
end;
constructor TDesktopOpt.Create(aName: String);
begin
Create; // constructor above.
FName:=aName;
FUseIDELayouts := aUseIDELayouts;
if FUseIDELayouts then
begin
//default desktop - use IDE storage objects!
FIDEDialogLayoutList:=IDEWindowIntf.IDEDialogLayoutList;
FIDEWindowCreatorsLayoutList := IDEWindowIntf.IDEWindowCreators.SimpleLayoutStorage;
end else
begin
//saved desktops - use own layout storage objects
FIDEDialogLayoutList:=TIDEDialogLayoutList.Create;
FIDEWindowCreatorsLayoutList:=TSimpleWindowLayoutList.Create(False);
FIDEDialogLayoutList.Assign(IDEWindowIntf.IDEDialogLayoutList);
FIDEWindowCreatorsLayoutList.Assign(IDEWindowIntf.IDEWindowCreators.SimpleLayoutStorage, True, True);
end;
end;
destructor TDesktopOpt.Destroy;
begin
if IDEWindowIntf.IDEDialogLayoutList=FIDEDialogLayoutList then
IDEWindowIntf.IDEDialogLayoutList:=nil;
FreeAndNil(FIDEDialogLayoutList);
FreeAndNil(FComponentPaletteOptions);
FreeAndNil(FEditorToolBarOptions);
FreeAndNil(FIDECoolBarOptions);
if not FUseIDELayouts then
begin
FreeAndNil(FIDEDialogLayoutList);
FreeAndNil(FIDEWindowCreatorsLayoutList);
end;
inherited Destroy;
end;
@ -983,6 +1006,9 @@ begin
//FConfigStore.Assign(Source.FConfigStore);
// window layout
if Source.FIDEWindowCreatorsLayoutList <> IDEWindowCreators.SimpleLayoutStorage then
Source.FIDEWindowCreatorsLayoutList.Assign(IDEWindowCreators.SimpleLayoutStorage, True, True);
FIDEWindowCreatorsLayoutList.Assign(Source.FIDEWindowCreatorsLayoutList, False, False);
FIDEDialogLayoutList.Assign(Source.FIDEDialogLayoutList);
FSingleTaskBarButton := Source.FSingleTaskBarButton;
FHideIDEOnRun := Source.FHideIDEOnRun;
@ -1007,9 +1033,8 @@ end;
procedure TDesktopOpt.Load(Path: String);
begin
FName:=FXMLCfg.GetValue(Path+'Name', 'default');
// Windows layout
IDEWindowCreators.SimpleLayoutStorage.LoadFromConfig(FConfigStore,Path);
FIDEWindowCreatorsLayoutList.LoadFromConfig(FConfigStore, Path);
FIDEDialogLayoutList.LoadFromConfig(FConfigStore, Path+'Dialogs/');
FSingleTaskBarButton:=FXMLCfg.GetValue(Path+'SingleTaskBarButton/Value', False);
@ -1026,7 +1051,7 @@ begin
FCompletionWindowWidth:=FXMLCfg.GetValue(Path+'CompletionWindowWidth/Value', 320);
FCompletionWindowHeight:=FXMLCfg.GetValue(Path+'CompletionWindowHeight/Value', 6);
if AnsiStartsStr('EnvironmentOptions', Path) then
if not FXMLCfg.HasPath(Path+'IDECoolBarOptions/', True) then
Path := ''; // Toolbars and palette were at the top level in XML.
// IDE Coolbar
FIDECoolBarOptions.Load(FXMLCfg, Path);
@ -1040,7 +1065,7 @@ procedure TDesktopOpt.Save(Path: String);
begin
// windows
FXMLCfg.SetDeleteValue(Path+'Name', FName, '');
IDEWindowCreators.SimpleLayoutStorage.SaveToConfig(FConfigStore,Path);
FIDEWindowCreatorsLayoutList.SaveToConfig(FConfigStore, Path);
FIDEDialogLayoutList.SaveToConfig(FConfigStore,Path+'Dialogs/');
FXMLCfg.SetDeleteValue(Path+'SingleTaskBarButton/Value',FSingleTaskBarButton, False);
@ -1231,8 +1256,10 @@ begin
// global build options
FBuildMatrixOptions:=TBuildMatrixOptions.Create;
// Desktop collection (FDesktop will point to the active desktop).
// Desktop collection
FDesktops := TDesktopOptList.Create(Self);
// FDesktop points to the IDE properties
FDesktop := TDesktopOpt.Create('', True);
end;
destructor TEnvironmentOptions.Destroy;
@ -1240,6 +1267,8 @@ var
i: Integer;
begin
FreeAndNil(FDesktops);
FreeAndNil(FDesktop);
FreeAndNil(FLastDesktopBeforeDebug);
FreeAndNil(FBuildMatrixOptions);
FreeAndNil(FMsgViewFilters);
FreeAndNil(fExternalUserTools);
@ -1264,6 +1293,17 @@ begin
inherited Destroy;
end;
procedure TEnvironmentOptions.DisableDebugDesktop;
begin
if (FLastDesktopBeforeDebug=nil) or (FDesktop=nil) then
Exit;
try
UseDesktop(FLastDesktopBeforeDebug);
finally
FreeAndNil(FLastDesktopBeforeDebug);
end;
end;
class function TEnvironmentOptions.GetGroupCaption: string;
begin
Result := dlgGroupEnvironment;
@ -1282,6 +1322,16 @@ begin
inherited DoAfterWrite(Restore);
end;
procedure TEnvironmentOptions.EnableDebugDesktop;
begin
if not Assigned(FLastDesktopBeforeDebug) and Assigned(DebugDesktop) then
begin
FLastDesktopBeforeDebug := TDesktopOpt.Create('', False);
FLastDesktopBeforeDebug.Assign(Desktop);
EnvironmentOptions.UseDesktop(DebugDesktop);
end;
end;
procedure TEnvironmentOptions.CreateConfig;
var
ConfFileName: string;
@ -1426,7 +1476,7 @@ procedure TEnvironmentOptions.Load(OnlyDesktop: boolean);
end;
var
Path, CurPath, ActiveDsk: String;
Path, CurPath: String;
i, j: Integer;
Rec: PIDEOptionsGroupRec;
NodeName: String;
@ -1435,6 +1485,8 @@ var
begin
try
InitXMLCfg(false);
// ToDo: Get rid of EnvironmentOptions/ path. The whole file is about
// environment options. Many section are not under it any more.
Path:='EnvironmentOptions/';
FFileVersion:=FXMLCfg.GetValue(Path+'Version/Value',0);
FOldLazarusVersion:=FXMLCfg.GetValue(Path+'Version/Lazarus','');
@ -1594,14 +1646,14 @@ begin
FObjectInspectorOptions.SaveBounds:=false;
// IDEEditorGroups
for i := 0 to IDEEditorGroups.Count - 1 do
for i := 0 to IDEEditorGroups.Count-1 do
begin
Rec := IDEEditorGroups[i];
NodeName := Rec^.GroupClass.ClassName;
Rec^.Collapsed := FXMLCfg.GetValue(Path+'OptionDialog/Tree/' + NodeName + '/Value',
Rec^.DefaultCollapsed);
if Rec^.Items <> nil then begin
for j := 0 to Rec^.Items.Count - 1 do begin
for j := 0 to Rec^.Items.Count-1 do begin
Rec^.Items[j]^.Collapsed := FXMLCfg.GetValue(Path+'OptionDialog/Tree/' + NodeName
+ '/' + Rec^.Items[j]^.EditorClass.ClassName + '/Value',
Rec^.Items[j]^.DefaultCollapsed);
@ -1612,25 +1664,20 @@ begin
// The user can define many desktops. They are saved under path Desktops/.
FDesktops.Clear;
FDesktops.SetConfig(FXMLCfg, FConfigStore);
CurPath:='Desktops/';
CurPath := 'Desktops/';
if FXMLCfg.HasPath(CurPath, True) then
begin
// New path under Desktops/. Default=1 forces reading default values always.
j := FXMLCfg.GetValue(CurPath+'Count/', 1);
FDebugDesktopName := FXMLCfg.GetValue(CurPath+'DebugDesktop', '');
j := FXMLCfg.GetValue(CurPath+'Count', 1);
for i := 0 to j-1 do
FDesktops.AddFromCfg(CurPath+'Desktop'+IntToStr(i+1)+'/');
Assert(FDesktops.Count>0, 'FDesktops.Count=0');
// Find active desktop
ActiveDsk := FXMLCfg.GetValue(CurPath+'Active','default');
FDesktop:=FDesktops.Find(ActiveDsk);
DebugLn(['TEnvironmentOptions.Load: New desktop, Count=',j,', Active=', ActiveDsk, ', Dsk name=', FDesktop.Name]);
end
else begin // Old path was under EnvironmentOptions/.
FDesktops.AddFromCfg(Path+'Desktop/');
FDesktop := nil;
end;
if FDesktop=nil then
FDesktop:=FDesktops[0];
FDesktop.SetConfig(FXMLCfg, FConfigStore);
CurPath := 'Desktop/'; // New place: Desktop/
if not FXMLCfg.HasPath(CurPath, True) then
CurPath := Path+'Desktop/'; // Old place: EnvironmentOptions/Desktop/
FDesktop.Load(CurPath);
FileUpdated;
except
@ -1747,9 +1794,12 @@ var
Rec: PIDEOptionsGroupRec;
mwc: TMsgWndColor;
u: TMessageLineUrgency;
xSaveDesktop: TDesktopOpt;
begin
try
InitXMLCfg(true);
// ToDo: Get rid of EnvironmentOptions/ path. The whole file is about
// environment options. Many section are not under it any more.
Path:='EnvironmentOptions/';
FXMLCfg.SetValue(Path+'Version/Value',EnvOptsVersion);
@ -1875,7 +1925,7 @@ begin
FObjectInspectorOptions.Save;
// IDEEditorGroups
for i := 0 to IDEEditorGroups.Count - 1 do
for i := 0 to IDEEditorGroups.Count-1 do
begin
Rec := IDEEditorGroups[i];
NodeName := Rec^.GroupClass.ClassName;
@ -1883,7 +1933,7 @@ begin
Rec^.Collapsed,
Rec^.DefaultCollapsed);
if Rec^.Items <> nil then begin
for j := 0 to Rec^.Items.Count - 1 do begin
for j := 0 to Rec^.Items.Count-1 do begin
FXMLCfg.SetDeleteValue(Path+'OptionDialog/Tree/' + NodeName
+ '/' + Rec^.Items[j]^.EditorClass.ClassName + '/Value',
Rec^.Items[j]^.Collapsed,
@ -1895,13 +1945,20 @@ begin
// The user can define many desktops. They are saved under path Desktops/.
CurPath:='Desktops/';
FXMLCfg.SetDeleteValue(CurPath+'Count', FDesktops.Count, 0);
FXMLCfg.SetDeleteValue(CurPath+'Active', FDesktop.Name, '');
FXMLCfg.SetDeleteValue(CurPath+'DebugDesktop', FDebugDesktopName, '');
for i := 0 to FDesktops.Count-1 do
begin
FDesktops[i].SetConfig(FXMLCfg, FConfigStore);
FDesktops[i].Save(CurPath+'Desktop'+IntToStr(i+1)+'/');
end;
if Assigned(FLastDesktopBeforeDebug) then
xSaveDesktop := FLastDesktopBeforeDebug
else
xSaveDesktop := FDesktop;
xSaveDesktop.SetConfig(FXMLCfg, FConfigStore);
xSaveDesktop.Save('Desktop/');
FXMLCfg.Flush;
FileUpdated;
except
@ -2258,6 +2315,36 @@ begin
SetParseValue(eopTestBuildDirectory,NewValue);
end;
procedure TEnvironmentOptions.UseDesktop(ADesktop: TDesktopOpt);
procedure _UpdateEditorOptions(const aAfter: Boolean);
var
i: Integer;
Rec: PIDEOptionsGroupRec;
Instance: TAbstractIDEOptions;
begin
for i := 0 to IDEEditorGroups.Count - 1 do
begin
Rec := IDEEditorGroups[i];
if Assigned(Rec^.Items) and Assigned(Rec^.GroupClass) then
begin
Instance := Rec^.GroupClass.GetInstance;
if Assigned(Instance) then
begin
if aAfter then
Instance.DoAfterWrite(False)
else
Instance.DoBeforeWrite(False)
end;
end;
end;
end;
begin
_UpdateEditorOptions(False);
Desktop.Assign(ADesktop);
_UpdateEditorOptions(True);
IDEWindowCreators.RestoreSimpleLayout;
end;
procedure TEnvironmentOptions.SetLazarusDirectory(const AValue: string);
var
NewValue: String;
@ -2317,17 +2404,6 @@ begin
Result:=FParseValues[eopDebuggerSearchPath].UnparsedValue;
end;
function TEnvironmentOptions.GetDesktop: TDesktopOpt;
begin
// Can be Nil if desktops are not read from config files -> create a default desktop.
if not Assigned(FDesktop) then
begin
FDesktop := TDesktopOpt.Create('default');
FDesktops.Add(FDesktop);
end;
Result := FDesktop;
end;
function TEnvironmentOptions.GetCompilerFilename: string;
begin
Result:=FParseValues[eopCompilerFilename].UnparsedValue;
@ -2338,6 +2414,14 @@ begin
Result:=FParseValues[eopCompilerMessagesFilename].UnparsedValue;
end;
function TEnvironmentOptions.GetDebugDesktop: TDesktopOpt;
begin
if FDebugDesktopName<>'' then
Result := FDesktops.Find(FDebugDesktopName)
else
Result := nil;
end;
function TEnvironmentOptions.GetFPCSourceDirectory: string;
begin
Result:=FParseValues[eopFPCSourceDirectory].UnparsedValue;

View File

@ -290,8 +290,7 @@ begin
AnEnvironmentOptions.Filename := OpenDialog.Filename;
AnEnvironmentOptions.Load(true);
DoLoadSettings(AnEnvironmentOptions);
if IDEDockMaster=nil then
IDEWindowCreators.RestoreSimpleLayout;
IDEWindowCreators.RestoreSimpleLayout;
ShowMessageFmt(lisSuccessfullyImported, [OpenDialog.Filename]);
finally
AnEnvironmentOptions.Free;

View File

@ -150,7 +150,7 @@ begin
ProjectDirInIdeTitleCheckBox.Checked:=IDEProjectDirectoryInIdeTitle;
end;
FLayouts.Assign(IDEWindowCreators.SimpleLayoutStorage);
FLayouts.Assign(IDEWindowCreators.SimpleLayoutStorage, False, True);
if FShowSimpleLayout then begin
// Window Positions
@ -217,7 +217,8 @@ end;
procedure TWindowOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions);
begin
SaveLayout;
IDEWindowCreators.SimpleLayoutStorage.Assign(FLayouts);
FLayouts.Assign(IDEWindowCreators.SimpleLayoutStorage, True, True);
IDEWindowCreators.SimpleLayoutStorage.Assign(FLayouts, False, False);
with (AOptions as TEnvironmentOptions).Desktop do
begin
@ -231,6 +232,8 @@ begin
AutoAdjustIDEHeightFullCompPal := AutoAdjustIDEHeightFullCompPalCheckBox.Checked;
IDEProjectDirectoryInIdeTitle:=ProjectDirInIdeTitleCheckBox.Checked;
end;
IDEWindowCreators.RestoreSimpleLayout;
end;
function TWindowOptionsFrame.GetPlacementRadioButtons(
@ -483,7 +486,7 @@ end;
constructor TWindowOptionsFrame.Create(TheOwner: TComponent);
begin
inherited Create(TheOwner);
FLayouts:=TSimpleWindowLayoutList.Create;
FLayouts:=TSimpleWindowLayoutList.Create(False);
FShowSimpleLayout:=(IDEDockMaster=nil) or (not IDEDockMaster.HideSimpleLayoutOptions);
end;

View File

@ -682,6 +682,7 @@ begin
ecRescanFPCSrcDir : Result:= lisMenuRescanFPCSourceDirectory;
ecEditCodeTemplates : Result:= lisMenuEditCodeTemplates;
ecCodeToolsDefinesEd : Result:= lisKMCodeToolsDefinesEditor;
ecManageDesktops : Result:= lisDesktops;
ecExtToolSettings : Result:= srkmecExtToolSettings;
ecManageExamples : Result:= lisMenuExampleProjects;
@ -3006,6 +3007,7 @@ begin
AddDefault(C, 'Rescan FPC source directory', lisMenuRescanFPCSourceDirectory, ecRescanFPCSrcDir);
AddDefault(C, 'Edit Code Templates', lisKMEditCodeTemplates, ecEditCodeTemplates);
AddDefault(C, 'CodeTools defines editor', lisKMCodeToolsDefinesEditor, ecCodeToolsDefinesEd);
AddDefault(C, 'Manage desktops', dlgManageDesktops, ecManageDesktops);
AddDefault(C, 'External Tools settings', lisKMExternalToolsSettings, ecExtToolSettings);
AddDefault(C, 'Example Projects', lisKMExampleProjects, ecManageExamples);

View File

@ -1234,7 +1234,14 @@ resourcestring
dlgIntvInSec = 'Interval in secs';
dlgExportDesktop = 'Export desktop';
dlgImportDesktop = 'Import desktop';
dlgManageDesktops = 'Manage desktops';
dlgSaveCurrentDesktop = 'Save current desktop';
dlgCloseAndUseSelectedDesktop = 'Close and use selected desktop';
dlgDeleteSelectedDesktop = 'Delete selected desktop';
dlgReallyDeleteDesktop = 'Really delete desktop "%s"?';
dlgToggleSelectedDebugDesktop = 'Toggle selected as debug desktop';
dlgDesktopNameWillBeOverwritten = 'Desktop name (old entry will be overwritten):';
dlgDebugDesktop = 'debug desktop';
dlgDesktopHints = 'Hints';
dlgDesktopButtons = 'Buttons - ';
dlgDesktopMenus = 'Menus - ';

View File

@ -171,6 +171,8 @@ type
TMainIDE = class(TMainIDEBase)
private
IDEIsClosing: Boolean;
// event handlers
procedure MainIDEFormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
procedure MainIDEFormCloseQuery(Sender: TObject; var CanClose: boolean);
@ -409,6 +411,7 @@ type
function HandleIDEQuestionDialog(const aCaption, aMsg: string;
DlgType: TMsgDlgType; Buttons: array of const;
const HelpKeyword: string): Integer;
procedure HandleLayoutChanged(Sender: TObject);
public
// Environment options dialog events
procedure DoLoadIDEOptions(Sender: TObject; AOptions: TAbstractIDEOptions);
@ -1541,6 +1544,7 @@ begin
MainIDEBar.SetupHints;
SetupIDEWindowsLayout;
RestoreIDEWindows;
IDEWindowCreators.AddLayoutChangedHandler(@HandleLayoutChanged);
// make sure the main IDE bar is always shown
IDEWindowCreators.ShowForm(MainIDEBar,false);
DebugBoss.UpdateButtonsAndMenuItems; // Disable Stop-button (and some others).
@ -1957,11 +1961,10 @@ begin
end;
procedure TMainIDE.MainIDEFormCloseQuery(Sender: TObject; var CanClose: boolean);
const IsClosing: Boolean = False;
begin
CanClose := True;
if IsClosing then Exit;
IsClosing := True;
if IDEIsClosing then Exit;
IDEIsClosing := True;
CanClose := False;
SourceFileMgr.CheckingFilesOnDisk := True;
try
@ -1983,7 +1986,7 @@ begin
CanClose:=(DoCloseProject <> mrAbort);
finally
IsClosing := False;
IDEIsClosing := CanClose;
SourceFileMgr.CheckingFilesOnDisk:=false;
if not CanClose then
DoCheckFilesOnDisk(false);
@ -2328,8 +2331,7 @@ end;
procedure TMainIDE.RestoreIDEWindows;
begin
DoCallNotifyHandler(lihtIDERestoreWindows);
if IDEDockMaster=nil then
IDEWindowCreators.RestoreSimpleLayout;
IDEWindowCreators.RestoreSimpleLayout;
end;
procedure TMainIDE.FreeIDEWindows;
@ -2665,9 +2667,6 @@ begin
itmToolConfigure.OnClick := @mnuToolConfigureUserExtToolsClicked;
itmToolManageDesktops.OnClick := @mnuToolManageDesktopsClicked;
{$IFnDEF EnableDesktops}
itmToolManageDesktops.Visible := False;
{$ENDIF}
itmToolManageExamples.OnClick := @mnuToolManageExamplesClicked;
itmToolDiff.OnClick := @mnuToolDiffClicked;
@ -3557,6 +3556,14 @@ begin
FWaitForClose := False;
MainIDEBar.Close;
end;
if not IDEIsClosing then
begin
if (ToolStatus = itDebugger) then
EnvironmentOptions.EnableDebugDesktop
else if (ToolStatus <> itExiting) then
EnvironmentOptions.DisableDebugDesktop;
end;
end;
function TMainIDE.DoResetToolStatus(AFlags: TResetToolFlags): boolean;
@ -4474,9 +4481,6 @@ procedure TMainIDE.SaveDesktopSettings(TheEnvironmentOptions: TEnvironmentOption
begin
DebugLn(['* TMainIDE.SaveDesktopSettings']);
IDEWindowCreators.SimpleLayoutStorage.StoreWindowPositions;
// do not auto show the search results view
IDEWindowCreators.SimpleLayoutStorage.ItemByFormID(
NonModalIDEWindowNames[nmiwSearchResultsViewName]).Visible:=false;
if ObjectInspector1<>nil then
TheEnvironmentOptions.ObjectInspectorOptions.Assign(ObjectInspector1);
@ -6813,6 +6817,14 @@ begin
end;
end;
procedure TMainIDE.HandleLayoutChanged(Sender: TObject);
begin
MainIDEBar.RefreshCoolbar;
MainIDEBar.DoSetViewComponentPalette(EnvironmentOptions.Desktop.ComponentPaletteOptions.Visible);
MainIDEBar.DoSetMainIDEHeight(MainIDEBar.WindowState = wsMaximized, 55);
MainIDEBar.SetMainIDEHeight;
end;
procedure TMainIDE.DoExecuteRemoteControl;
procedure OpenFiles(Files: TStrings);

View File

@ -512,9 +512,10 @@ begin
if ANewHeight <> Constraints.MaxHeight then
begin
Constraints.MaxHeight := ANewHeight;
Constraints.MinHeight := Constraints.MaxHeight;
ClientHeight := Constraints.MaxHeight;
end;
Constraints.MinHeight := ANewHeight;
ClientHeight := ANewHeight;
end else if ClientHeight <> ANewHeight then
ClientHeight := ANewHeight;
end else
if Constraints.MaxHeight <> 0 then
begin

View File

@ -2630,7 +2630,10 @@ end;
class function TProjectIDEOptions.GetInstance: TAbstractIDEOptions;
begin
Result := Project1.IDEOptions;
if Project1<>nil then
Result := Project1.IDEOptions
else
Result := nil;
end;
class function TProjectIDEOptions.GetGroupCaption: string;

View File

@ -2161,7 +2161,10 @@ end;
class function TPackageIDEOptions.GetInstance: TAbstractIDEOptions;
begin
Result := Package1.IDEOptions;
if Package1<>nil then
Result := Package1.IDEOptions
else
Result := nil;
end;
class function TPackageIDEOptions.GetGroupCaption: string;
@ -4116,7 +4119,10 @@ end;
class function TPkgCompilerOptions.GetInstance: TAbstractIDEOptions;
begin
Result := Package1.CompilerOptions;
if Package1<>nil then
Result := Package1.CompilerOptions
else
Result := nil;
end;
function TPkgCompilerOptions.IsActive: boolean;