mirror of
				https://gitlab.com/freepascal.org/lazarus/lazarus.git
				synced 2025-11-04 07:43:13 +01:00 
			
		
		
		
	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:
		
							parent
							
								
									374bd932f9
								
							
						
					
					
						commit
						423c43ea13
					
				@ -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'),
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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 - ';
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										36
									
								
								ide/main.pp
									
									
									
									
									
								
							
							
						
						
									
										36
									
								
								ide/main.pp
									
									
									
									
									
								
							@ -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);
 | 
			
		||||
 | 
			
		||||
@ -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
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
@ -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;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user