[Lazarus] Desktops and multiple source editors

Ondrej Pokorny lazarus at kluug.net
Thu Sep 10 09:30:00 CEST 2015


On 10.09.2015 01:32, Mattias Gaertner wrote:
> Speaking for myself:
> When I close the IDE with some packages open, it should
> reopen them on next start.
> I have no preference if switching between editing/debug view should
> keep packages open or hide and restore them.
>
> Mattias
In this case, it should be handled outside the desktops feature the same 
like a project gets reopened.
And it completely fits to my "package is a project" philosophy - project 
is optionally reopened at ide start, packages should be as well 
(optionally).

Please test the attached patch. It adds the "Open packages" checkbox to 
environment options -> files. If checked, packages get reopened at 
startup. The setting is true by default, which changes the default IDE 
behavior. But IMO the most users will want it. If you don't think so, 
change the "Open packages" default value to false.

Desktop change doesn't reopen/close packages (at least in undocked 
environment), which is correct IMO.

Ondrej
-------------- next part --------------
Index: components/ideintf/lazideintf.pas
===================================================================
--- components/ideintf/lazideintf.pas	(revision 49803)
+++ components/ideintf/lazideintf.pas	(working copy)
@@ -198,6 +198,7 @@
     FLazarusIDEHandlers: array[TLazarusIDEHandlerType] of TMethodList;
     FOwningComponent: TComponent;
     FIDEStarted: boolean;
+    FIDEIsClosing: Boolean;
     FLastActivatedWindows: TFPList;
     // used to find the last form so you can display the correct tab
     FLastFormActivated: TCustomForm;
@@ -418,6 +419,7 @@
                                const OnShowSourceOfActiveDesignerForm: TNotifyEvent);
 
     property IDEStarted: boolean read FIDEStarted;
+    property IDEIsClosing: boolean read FIDEIsClosing;
     property LastActivatedWindows: TFPList read FLastActivatedWindows;
     property LastFormActivated: TCustomForm read FLastFormActivated write FLastFormActivated;
   end;
Index: ide/environmentopts.pp
===================================================================
--- ide/environmentopts.pp	(revision 49803)
+++ ide/environmentopts.pp	(working copy)
@@ -252,6 +252,12 @@
 
 type
 
+  TLastOpenPackagesList = class(TStringList)
+  public
+    function Remove(const aString: string): Boolean;
+    constructor Create;
+  end;
+
   { TDesktopOpt }
 
   TDesktopOpt = class
@@ -369,6 +375,7 @@
     FAutoSaveProject: boolean;
     FAutoSaveIntervalInSecs: integer;
     FLastSavedProjectFile: string;
+    FLastOpenPackages: TLastOpenPackagesList;//list of filenames with open packages
 
     // designer
     FCreateComponentFocusNameProperty: boolean;
@@ -468,6 +475,7 @@
     FRecentPackageFiles: TStringList;
     FMaxRecentPackageFiles: integer;
     FOpenLastProjectAtStart: boolean;
+    FOpenPackagesAtStart: boolean;
     // Prevent repopulating Recent project files menu with example projects if it was already cleared up.
     FAlreadyPopulatedRecentFiles : Boolean;
 
@@ -718,8 +726,11 @@
     property LastSavedProjectFile: string read FLastSavedProjectFile
                      write FLastSavedProjectFile; { if empty then create new project,
                                                     if '-' then do not load/create any project }
+    property LastOpenPackages: TLastOpenPackagesList read FLastOpenPackages;
     property OpenLastProjectAtStart: boolean read FOpenLastProjectAtStart
                                              write FOpenLastProjectAtStart;
+    property OpenPackagesAtStart: boolean read FOpenPackagesAtStart
+                                             write FOpenPackagesAtStart;
     property FileDialogFilter: string read FFileDialogFilter write FFileDialogFilter;
 
     // backup
@@ -897,6 +908,25 @@
   WriteStr(Result, u);
 end;
 
+{ TLastOpenPackagesList }
+
+constructor TLastOpenPackagesList.Create;
+begin
+  inherited Create;
+  Sorted:=true;
+  Duplicates:=dupIgnore;
+end;
+
+function TLastOpenPackagesList.Remove(const aString: string): Boolean;
+var
+  xIndex: Integer;
+begin
+  xIndex := IndexOf(aString);
+  Result := xIndex >= 0;
+  if Result then
+    Delete(xIndex);
+end;
+
 { TDesktopOptList }
 
 constructor TDesktopOptList.Create(aEnvOpts: TEnvironmentOptions);
@@ -1193,6 +1223,7 @@
   FAutoSaveProject:=true;
   FAutoSaveIntervalInSecs:=300; // 5 minutes
   FLastSavedProjectFile:='';
+  FLastOpenPackages:=TLastOpenPackagesList.Create;
 
   // EnvironmentOptionsDialog editor
   FShowGrid:=true;
@@ -1280,6 +1311,7 @@
   FRecentPackageFiles:=TStringList.Create;
   FMaxRecentPackageFiles:=DefaultMaxRecentPackageFiles;
   FOpenLastProjectAtStart:=true;
+  FOpenPackagesAtStart:=true;
 
   // backup
   with FBackupInfoProjectFiles do begin
@@ -1348,6 +1380,7 @@
   FreeAndNil(FConfigStore);
   FreeAndNil(FDbgConfigStore);
   FreeAndNil(FXMLCfg);
+  FreeAndNil(FLastOpenPackages);
   inherited Destroy;
 end;
 
@@ -1551,7 +1584,7 @@
   Path, CurPath: String;
   i, j: Integer;
   Rec: PIDEOptionsGroupRec;
-  NodeName: String;
+  NodeName, xFileName: String;
   mwc: TMsgWndColor;
   u: TMessageLineUrgency;
 begin
@@ -1583,9 +1616,21 @@
     FAutoSaveIntervalInSecs:=FXMLCfg.GetValue(Path+'AutoSave/IntervalInSecs',600);
     FLastSavedProjectFile:=FXMLCfg.GetValue(Path+'AutoSave/LastSavedProjectFile','');
     FOpenLastProjectAtStart:=FXMLCfg.GetValue(Path+'AutoSave/OpenLastProjectAtStart',true);
+    FOpenPackagesAtStart:=FXMLCfg.GetValue(Path+'AutoSave/OpenPackagesAtStart',true);
     FShowCompileDialog:=FXMLCfg.GetValue(Path+'ShowCompileDialog/Value',false);
     FAutoCloseCompileDialog:=FXMLCfg.GetValue(Path+'AutoCloseCompileDialog/Value',false);
     FAutoSaveActiveDesktop:=FXMLCfg.GetValue(Path+'AutoSave/ActiveDesktop',True);
+    FLastOpenPackages.Clear;
+    if FOpenPackagesAtStart then
+    begin
+      i := 1;
+      repeat
+        xFileName := FXMLCfg.GetValue(Path+'AutoSave/LastOpenPackages/Package'+IntToStr(i), '');
+        if FileExistsCached(xFileName) then
+          FLastOpenPackages.Add(xFileName);
+        Inc(i);
+      until xFileName='';
+    end;
 
     // form editor
     FShowGrid:=FXMLCfg.GetValue(Path+'FormEditor/ShowGrid',true);
@@ -1901,7 +1946,14 @@
     FXMLCfg.SetDeleteValue(Path+'AutoSave/IntervalInSecs',FAutoSaveIntervalInSecs,600);
     FXMLCfg.SetDeleteValue(Path+'AutoSave/LastSavedProjectFile',FLastSavedProjectFile,'');
     FXMLCfg.SetDeleteValue(Path+'AutoSave/OpenLastProjectAtStart',FOpenLastProjectAtStart,true);
+    FXMLCfg.SetDeleteValue(Path+'AutoSave/OpenPackagesAtStart',FOpenPackagesAtStart,true);
     FXMLCfg.SetDeleteValue(Path+'AutoSave/ActiveDesktop', FAutoSaveActiveDesktop, True);
+    if FOpenPackagesAtStart and (FLastOpenPackages.Count > 0) then
+    begin
+      for i := 0 to FLastOpenPackages.Count-1 do
+        FXMLCfg.SetValue(Path+'AutoSave/LastOpenPackages/Package'+IntToStr(i+1), FLastOpenPackages[i]);
+    end else
+      FXMLCfg.DeletePath(Path+'AutoSave/LastOpenPackages/');
 
     // form editor
     FXMLCfg.SetDeleteValue(Path+'FormEditor/ShowBorderSpacing',FShowBorderSpacing,false);
Index: ide/frames/files_options.lfm
===================================================================
--- ide/frames/files_options.lfm	(revision 49803)
+++ ide/frames/files_options.lfm	(working copy)
@@ -17,7 +17,7 @@
     Left = 2
     Height = 15
     Top = 2
-    Width = 145
+    Width = 138
     Caption = 'MaxRecentOpenFilesLabel'
     ParentColor = False
   end
@@ -27,7 +27,7 @@
     Left = 287
     Height = 15
     Top = 2
-    Width = 155
+    Width = 146
     BorderSpacing.Left = 3
     Caption = 'MaxRecentProjectFilesLabel'
     ParentColor = False
@@ -38,22 +38,24 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Side = asrBottom
     Left = 2
-    Height = 24
-    Top = 50
-    Width = 212
+    Height = 19
+    Top = 48
+    Width = 195
     BorderSpacing.Top = 6
     Caption = 'OpenLastProjectAtStartCheckBox'
+    OnChange = OpenLastProjectAtStartCheckBoxChange
     TabOrder = 0
   end
   object ShowCompileDialogCheckBox: TCheckBox
     AnchorSideLeft.Control = Owner
-    AnchorSideTop.Control = OpenLastProjectAtStartCheckBox
+    AnchorSideTop.Control = OpenPackagesAtStartCheckBox
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Side = asrBottom
     Left = 2
-    Height = 24
-    Top = 74
-    Width = 188
+    Height = 19
+    Top = 88
+    Width = 180
+    BorderSpacing.Top = 2
     Caption = 'ShowCompileDialogCheckBox'
     OnChange = ShowCompileDialogCheckBoxChange
     TabOrder = 1
@@ -64,8 +66,8 @@
     AnchorSideTop.Side = asrBottom
     Left = 2
     Height = 15
-    Top = 132
-    Width = 87
+    Top = 136
+    Width = 82
     BorderSpacing.Top = 10
     Caption = 'LazarusDirLabel'
     ParentColor = False
@@ -78,8 +80,8 @@
     AnchorSideBottom.Control = LazarusDirComboBox
     AnchorSideBottom.Side = asrBottom
     Left = 542
-    Height = 27
-    Top = 147
+    Height = 23
+    Top = 151
     Width = 25
     Anchors = [akTop, akRight, akBottom]
     Caption = '...'
@@ -92,11 +94,11 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = LazarusDirButton
     Left = 2
-    Height = 27
-    Top = 147
+    Height = 23
+    Top = 151
     Width = 540
     Anchors = [akTop, akLeft, akRight]
-    ItemHeight = 0
+    ItemHeight = 15
     TabOrder = 3
     Text = 'LazarusDirComboBox'
   end
@@ -106,11 +108,11 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = CompilerPathButton
     Left = 2
-    Height = 27
+    Height = 23
     Top = 195
     Width = 540
     Anchors = [akTop, akLeft, akRight]
-    ItemHeight = 0
+    ItemHeight = 15
     TabOrder = 4
     Text = 'CompilerPathComboBox'
   end
@@ -121,7 +123,7 @@
     AnchorSideBottom.Control = CompilerPathComboBox
     AnchorSideBottom.Side = asrBottom
     Left = 542
-    Height = 27
+    Height = 23
     Top = 195
     Width = 25
     Anchors = [akTop, akRight, akBottom]
@@ -136,7 +138,7 @@
     Left = 2
     Height = 15
     Top = 180
-    Width = 103
+    Width = 101
     BorderSpacing.Top = 6
     Caption = 'CompilerPathLabel'
     ParentColor = False
@@ -147,11 +149,11 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = FPCSourceDirButton
     Left = 2
-    Height = 27
-    Top = 243
+    Height = 23
+    Top = 239
     Width = 540
     Anchors = [akTop, akLeft, akRight]
-    ItemHeight = 0
+    ItemHeight = 15
     TabOrder = 6
     Text = 'FPCSourceDirComboBox'
   end
@@ -162,8 +164,8 @@
     AnchorSideBottom.Control = FPCSourceDirComboBox
     AnchorSideBottom.Side = asrBottom
     Left = 542
-    Height = 27
-    Top = 243
+    Height = 23
+    Top = 239
     Width = 25
     Anchors = [akTop, akRight, akBottom]
     Caption = '...'
@@ -176,8 +178,8 @@
     AnchorSideTop.Side = asrBottom
     Left = 2
     Height = 15
-    Top = 228
-    Width = 104
+    Top = 224
+    Width = 100
     BorderSpacing.Top = 6
     Caption = 'FPCSourceDirLabel'
     ParentColor = False
@@ -188,8 +190,8 @@
     AnchorSideTop.Side = asrBottom
     Left = 2
     Height = 15
-    Top = 276
-    Width = 83
+    Top = 268
+    Width = 81
     BorderSpacing.Top = 6
     Caption = 'MakePathLabel'
     ParentColor = False
@@ -200,8 +202,8 @@
     AnchorSideTop.Side = asrBottom
     Left = 2
     Height = 15
-    Top = 324
-    Width = 97
+    Top = 312
+    Width = 91
     BorderSpacing.Top = 6
     Caption = 'TestBuildDirLabel'
     ParentColor = False
@@ -212,11 +214,11 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = MakePathButton
     Left = 2
-    Height = 27
-    Top = 291
+    Height = 23
+    Top = 283
     Width = 540
     Anchors = [akTop, akLeft, akRight]
-    ItemHeight = 0
+    ItemHeight = 15
     TabOrder = 8
     Text = 'MakePathComboBox'
   end
@@ -227,8 +229,8 @@
     AnchorSideBottom.Control = MakePathComboBox
     AnchorSideBottom.Side = asrBottom
     Left = 542
-    Height = 27
-    Top = 291
+    Height = 23
+    Top = 283
     Width = 25
     Anchors = [akTop, akRight, akBottom]
     Caption = '...'
@@ -241,11 +243,11 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = TestBuildDirButton
     Left = 2
-    Height = 27
-    Top = 339
+    Height = 23
+    Top = 327
     Width = 540
     Anchors = [akTop, akLeft, akRight]
-    ItemHeight = 0
+    ItemHeight = 15
     TabOrder = 10
     Text = 'TestBuildDirComboBox'
   end
@@ -256,8 +258,8 @@
     AnchorSideBottom.Control = TestBuildDirComboBox
     AnchorSideBottom.Side = asrBottom
     Left = 542
-    Height = 27
-    Top = 339
+    Height = 23
+    Top = 327
     Width = 25
     Anchors = [akTop, akRight, akBottom]
     Caption = '...'
@@ -270,9 +272,9 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Side = asrBottom
     Left = 32
-    Height = 24
-    Top = 98
-    Width = 215
+    Height = 19
+    Top = 107
+    Width = 206
     BorderSpacing.Left = 30
     Caption = 'AutoCloseCompileDialogCheckBox'
     TabOrder = 12
@@ -283,8 +285,8 @@
     AnchorSideTop.Side = asrBottom
     Left = 2
     Height = 15
-    Top = 372
-    Width = 158
+    Top = 356
+    Width = 153
     Alignment = taRightJustify
     BorderSpacing.Top = 6
     Caption = 'CompilerTranslationFileLabel'
@@ -299,8 +301,8 @@
     AnchorSideBottom.Control = CompilerTranslationFileComboBox
     AnchorSideBottom.Side = asrBottom
     Left = 542
-    Height = 27
-    Top = 387
+    Height = 23
+    Top = 371
     Width = 25
     Anchors = [akTop, akRight, akBottom]
     Caption = '...'
@@ -315,11 +317,11 @@
     AnchorSideTop.Side = asrBottom
     AnchorSideRight.Control = CompilerTranslationFileButton
     Left = 2
-    Height = 27
-    Top = 387
+    Height = 23
+    Top = 371
     Width = 540
     Anchors = [akTop, akLeft, akRight]
-    ItemHeight = 0
+    ItemHeight = 15
     ParentShowHint = False
     ShowHint = True
     TabOrder = 14
@@ -341,7 +343,7 @@
     AnchorSideRight.Control = lblCenter
     AnchorSideRight.Side = asrBottom
     Left = 2
-    Height = 25
+    Height = 23
     Top = 19
     Width = 278
     Anchors = [akTop, akLeft, akRight]
@@ -356,7 +358,7 @@
     AnchorSideRight.Control = Owner
     AnchorSideRight.Side = asrBottom
     Left = 289
-    Height = 25
+    Height = 23
     Top = 19
     Width = 278
     Anchors = [akTop, akLeft, akRight]
@@ -364,4 +366,17 @@
     BorderSpacing.Around = 2
     TabOrder = 16
   end
+  object OpenPackagesAtStartCheckBox: TCheckBox
+    AnchorSideLeft.Control = OpenLastProjectAtStartCheckBox
+    AnchorSideTop.Control = OpenLastProjectAtStartCheckBox
+    AnchorSideTop.Side = asrBottom
+    AnchorSideRight.Side = asrBottom
+    Left = 32
+    Height = 19
+    Top = 67
+    Width = 186
+    BorderSpacing.Left = 30
+    Caption = 'OpenPackagesAtStartCheckBox'
+    TabOrder = 17
+  end
 end
Index: ide/frames/files_options.pas
===================================================================
--- ide/frames/files_options.pas	(revision 49803)
+++ ide/frames/files_options.pas	(working copy)
@@ -61,6 +61,7 @@
     MaxRecentProjectFilesSpin: TSpinEdit;
     MaxRecentProjectFilesLabel: TLabel;
     OpenLastProjectAtStartCheckBox: TCheckBox;
+    OpenPackagesAtStartCheckBox: TCheckBox;
     ShowCompileDialogCheckBox: TCheckBox;
     TestBuildDirButton:TButton;
     TestBuildDirComboBox:TComboBox;
@@ -68,6 +69,7 @@
     procedure CompilerTranslationFileButtonClick(Sender:TObject);
     procedure FilesButtonClick(Sender: TObject);
     procedure DirectoriesButtonClick(Sender: TObject);
+    procedure OpenLastProjectAtStartCheckBoxChange(Sender: TObject);
     procedure ShowCompileDialogCheckBoxChange(Sender: TObject);
   private
     FOldLazarusDir: string;
@@ -220,6 +222,7 @@
   MaxRecentOpenFilesLabel.Caption:=dlgMaxRecentFiles;
   MaxRecentProjectFilesLabel.Caption:=dlgMaxRecentProjs;
   OpenLastProjectAtStartCheckBox.Caption:=dlgQOpenLastPrj;
+  OpenPackagesAtStartCheckBox.Caption:=dlgQOpenPackages;
   ShowCompileDialogCheckBox.Visible:=false;
   AutoCloseCompileDialogCheckBox.Visible:=false;
   LazarusDirLabel.Caption:=dlgLazarusDir;
@@ -272,6 +275,12 @@
   Result := dlgEnvFiles;
 end;
 
+procedure TFilesOptionsFrame.OpenLastProjectAtStartCheckBoxChange(
+  Sender: TObject);
+begin
+  OpenPackagesAtStartCheckBox.Enabled := OpenLastProjectAtStartCheckBox.Checked;
+end;
+
 function TFilesOptionsFrame.Check: Boolean;
 begin
   Result := False;
@@ -360,6 +369,7 @@
 
     // open last project at start
     OpenLastProjectAtStartCheckBox.Checked:=OpenLastProjectAtStart;
+    OpenPackagesAtStartCheckBox.Checked:=OpenPackagesAtStart;
 
     // compile dialog
     fOldShowCompileDialog:=ShowCompileDialog;
@@ -391,6 +401,7 @@
     MaxRecentOpenFiles := MaxRecentOpenFilesSpin.Value;
     MaxRecentProjectFiles := MaxRecentProjectFilesSpin.Value;
     OpenLastProjectAtStart:=OpenLastProjectAtStartCheckBox.Checked;
+    OpenPackagesAtStart:=OpenPackagesAtStartCheckBox.Checked;
     ShowCompileDialog := ShowCompileDialogCheckBox.Checked;
     AutoCloseCompileDialog := AutoCloseCompileDialogCheckBox.Checked;
   end;
Index: ide/lazarusidestrconsts.pas
===================================================================
--- ide/lazarusidestrconsts.pas	(revision 49803)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -1339,6 +1339,7 @@
   dlgMaxRecentFiles = 'Max recent files';
   dlgMaxRecentProjs = 'Max recent project files';
   dlgQOpenLastPrj = 'Open last project at start';
+  dlgQOpenPackages = 'Open packages';
   dlgLazarusDir = 'Lazarus directory (default for all projects)';
   dlgFpcExecutable = 'Compiler executable (e.g. %s)';
   dlgFpcSrcPath = 'FPC source directory';
@@ -3989,6 +3990,7 @@
     +'%s%s'
     +'%slazbuild is non interactive, aborting now.';
   lisPkgMangSavePackageLpk = 'Save Package %s (*.lpk)';
+  lisPkgMangSaveAsAlreadyOpenedPackage = 'The package %s is already open in the IDE.'+sLineBreak+'You cannot save a package with the same name.';
   lisPkgMangInvalidPackageFileExtension = 'Invalid package file extension';
   lisPkgMangPackagesMustHaveTheExtensionLpk = 'Packages must have the '
     +'extension .lpk';
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 49803)
+++ ide/main.pp	(working copy)
@@ -171,8 +171,6 @@
 
   TMainIDE = class(TMainIDEBase)
   private
-    IDEIsClosing: Boolean;
-
     // event handlers
     procedure MainIDEFormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
     procedure MainIDEFormCloseQuery(Sender: TObject; var CanClose: boolean);
@@ -1966,7 +1964,7 @@
 begin
   CanClose := True;
   if IDEIsClosing then Exit;
-  IDEIsClosing := True;
+  FIDEIsClosing := True;
   CanClose := False;
   SourceFileMgr.CheckingFilesOnDisk := True;
   try
@@ -1988,7 +1986,7 @@
 
     CanClose:=(DoCloseProject <> mrAbort);
   finally
-    IDEIsClosing := CanClose;
+    FIDEIsClosing := CanClose;
     SourceFileMgr.CheckingFilesOnDisk:=false;
     if not CanClose then
       DoCheckFilesOnDisk(false);
@@ -2175,6 +2173,7 @@
   i: Integer;
   OpenFlags: TOpenFlags;
   AFilename: String;
+  PkgOpenFlags: TPkgOpenFlags;
 begin
   {$IFDEF IDE_DEBUG}
   debugln('TMainIDE.SetupStartProject A ***********');
@@ -2220,7 +2219,27 @@
         // protocol that the IDE was able to open the project without crashing
         IDEProtocolOpts.LastProjectLoadingCrashed := false;
         IDEProtocolOpts.Save;
-        if not ProjectLoaded then begin
+        if ProjectLoaded then
+        begin
+          if EnvironmentOptions.OpenPackagesAtStart then
+          begin
+            PkgOpenFlags:=[pofAddToRecent];
+            for I := 0 to EnvironmentOptions.LastOpenPackages.Count-1 do
+            begin
+              AFilename:=EnvironmentOptions.LastOpenPackages[I];
+              if AFilename='' then
+                continue;
+              if i<EnvironmentOptions.LastOpenPackages.Count-1 then
+                Include(PkgOpenFlags,pofMultiOpen)
+              else
+                Exclude(PkgOpenFlags,pofMultiOpen);
+              if PkgBoss.DoOpenPackageFile(AFilename,PkgOpenFlags,true)=mrAbort then begin
+                break;
+              end;
+            end;
+          end;
+        end else
+        begin
           DoCloseProject;
         end;
       end;
Index: packager/packageeditor.lfm
===================================================================
--- packager/packageeditor.lfm	(revision 49803)
+++ packager/packageeditor.lfm	(working copy)
@@ -15,7 +15,6 @@
   OnCreate = FormCreate
   OnDestroy = FormDestroy
   OnDropFiles = FormDropFiles
-  Position = poScreenCenter
   LCLVersion = '1.5'
   object ToolBar: TToolBar
     Left = 0
@@ -30,18 +29,18 @@
   object PropsGroupBox: TGroupBox
     Left = 0
     Height = 118
-    Top = 315
+    Top = 314
     Width = 464
     Align = alBottom
     Caption = 'PropsGroupBox'
-    ClientHeight = 97
+    ClientHeight = 98
     ClientWidth = 460
     TabOrder = 3
     object CallRegisterProcCheckBox: TCheckBox
       Left = 0
-      Height = 22
+      Height = 19
       Top = 0
-      Width = 174
+      Width = 158
       Caption = 'CallRegisterProcCheckBox'
       OnChange = CallRegisterProcCheckBoxChange
       ParentShowHint = False
@@ -51,10 +50,10 @@
     object AddToUsesPkgSectionCheckBox: TCheckBox
       AnchorSideLeft.Control = CallRegisterProcCheckBox
       AnchorSideLeft.Side = asrBottom
-      Left = 184
-      Height = 22
+      Left = 168
+      Height = 19
       Top = 0
-      Width = 207
+      Width = 191
       BorderSpacing.Left = 10
       Caption = 'AddToUsesPkgSectionCheckBox'
       OnChange = AddToUsesPkgSectionCheckBoxChange
@@ -67,9 +66,9 @@
       AnchorSideTop.Control = MinVersionEdit
       AnchorSideTop.Side = asrCenter
       Left = 0
-      Height = 22
-      Top = 0
-      Width = 167
+      Height = 19
+      Top = 2
+      Width = 151
       Caption = 'UseMinVersionCheckBox'
       OnChange = UseMinVersionCheckBoxChange
       TabOrder = 2
@@ -78,7 +77,7 @@
       AnchorSideLeft.Control = UseMinVersionCheckBox
       AnchorSideLeft.Side = asrBottom
       AnchorSideTop.Control = PropsGroupBox
-      Left = 177
+      Left = 161
       Height = 23
       Top = 0
       Width = 100
@@ -92,9 +91,9 @@
       AnchorSideTop.Control = MaxVersionEdit
       AnchorSideTop.Side = asrCenter
       Left = 0
-      Height = 22
-      Top = 25
-      Width = 169
+      Height = 19
+      Top = 27
+      Width = 152
       Caption = 'UseMaxVersionCheckBox'
       OnChange = UseMaxVersionCheckBoxChange
       TabOrder = 4
@@ -104,7 +103,7 @@
       AnchorSideLeft.Side = asrBottom
       AnchorSideTop.Control = MinVersionEdit
       AnchorSideTop.Side = asrBottom
-      Left = 179
+      Left = 162
       Height = 23
       Top = 25
       Width = 100
@@ -119,9 +118,9 @@
       AnchorSideTop.Control = MaxVersionEdit
       AnchorSideTop.Side = asrBottom
       Left = 0
-      Height = 29
+      Height = 25
       Top = 54
-      Width = 153
+      Width = 159
       AutoSize = True
       BorderSpacing.Top = 6
       Caption = 'ApplyDependencyButton'
@@ -132,19 +131,19 @@
       AnchorSideTop.Control = CallRegisterProcCheckBox
       AnchorSideTop.Side = asrBottom
       Left = 0
-      Height = 69
-      Top = 28
+      Height = 73
+      Top = 25
       Width = 460
       Align = alBottom
       Anchors = [akTop, akLeft, akRight, akBottom]
       BorderSpacing.Top = 6
       Caption = 'RegisteredPluginsGroupBox'
-      ClientHeight = 48
+      ClientHeight = 53
       ClientWidth = 456
       TabOrder = 7
       object RegisteredListBox: TListBox
         Left = 0
-        Height = 48
+        Height = 53
         Top = 0
         Width = 456
         Align = alClient
@@ -158,10 +157,10 @@
       AnchorSideLeft.Control = AddToUsesPkgSectionCheckBox
       AnchorSideLeft.Side = asrBottom
       AnchorSideTop.Control = AddToUsesPkgSectionCheckBox
-      Left = 397
-      Height = 22
+      Left = 365
+      Height = 19
       Top = 0
-      Width = 192
+      Width = 174
       BorderSpacing.Left = 6
       Caption = 'DisableI18NForLFMCheckBox'
       OnChange = DisableI18NForLFMCheckBoxChange
@@ -172,8 +171,8 @@
   end
   object StatusBar: TStatusBar
     Left = 0
-    Height = 22
-    Top = 433
+    Height = 23
+    Top = 432
     Width = 464
     Panels = <>
   end
@@ -181,7 +180,7 @@
     Cursor = crVSplit
     Left = 0
     Height = 5
-    Top = 310
+    Top = 309
     Width = 464
     Align = alBottom
     ResizeAnchor = akBottom
@@ -314,11 +313,12 @@
   end
   object ItemsTreeView: TTreeView
     Left = 0
-    Height = 233
+    Height = 232
     Top = 77
     Width = 464
     Align = alClient
     BorderSpacing.Top = 1
+    DefaultItemHeight = 18
     DragMode = dmAutomatic
     MultiSelect = True
     PopupMenu = ItemsPopupMenu
Index: packager/packageeditor.pas
===================================================================
--- packager/packageeditor.pas	(revision 49803)
+++ packager/packageeditor.pas	(working copy)
@@ -47,7 +47,7 @@
   IDEDialogs, IDEProcs, LazarusIDEStrConsts, IDEDefs, CompilerOptions,
   ComponentReg, UnitResources, EnvironmentOpts, DialogProcs, InputHistory,
   PackageDefs, AddToPackageDlg, PkgVirtualUnitEditor, MissingPkgFilesDlg,
-  PackageSystem, CleanPkgDeps;
+  PackageSystem, CleanPkgDeps, MainBase;
   
 const
   PackageEditorMenuRootName = 'PackageEditor';
@@ -435,7 +435,9 @@
     procedure Clear;
     procedure Remove(Editor: TPackageEditorForm);
     function IndexOfPackage(Pkg: TLazPackage): integer;
-    function FindEditor(Pkg: TLazPackage): TPackageEditorForm;
+    function IndexOfPackage(const PkgName: string): integer;
+    function FindEditor(Pkg: TLazPackage): TPackageEditorForm; overload;
+    function FindEditor(const PkgName: string): TPackageEditorForm; overload;
     function OpenEditor(Pkg: TLazPackage): TPackageEditorForm;
     function OpenFile(Sender: TObject; const Filename: string): TModalResult;
     function OpenPkgFile(Sender: TObject; PkgFile: TPkgFile): TModalResult;
@@ -1182,20 +1184,27 @@
   MsgResult: Integer;
 begin
   //debugln(['TPackageEditorForm.PackageEditorFormCloseQuery ',Caption]);
-  if (LazPackage<>nil) and (not (lpfDestroying in LazPackage.Flags))
-  and (not LazPackage.ReadOnly) and LazPackage.Modified then begin
-
-    MsgResult:=MessageDlg(lisPkgMangSavePackage,
-      Format(lisPckEditPackageHasChangedSavePackage, [LazPackage.IDAsString, LineEnding]),
-      mtConfirmation,[mbYes,mbNo,mbAbort],0);
-    case MsgResult of
-      mrYes:
-        MsgResult:=PackageEditors.SavePackage(LazPackage,false);
-      mrNo:
-        LazPackage.UserIgnoreChangeStamp:=LazPackage.ChangeStamp;
+  if (LazPackage<>nil) and (not (lpfDestroying in LazPackage.Flags)) then
+  begin
+    if (not LazPackage.ReadOnly) and LazPackage.Modified then
+    begin
+      MsgResult:=MessageDlg(lisPkgMangSavePackage,
+        Format(lisPckEditPackageHasChangedSavePackage, [LazPackage.IDAsString, LineEnding]),
+        mtConfirmation,[mbYes,mbNo,mbAbort],0);
+      case MsgResult of
+        mrYes:
+          MsgResult:=PackageEditors.SavePackage(LazPackage,false);
+        mrNo:
+          LazPackage.UserIgnoreChangeStamp:=LazPackage.ChangeStamp;
+      end;
+      if MsgResult=mrAbort then CanClose:=false;
+      LazPackage.Modified:=false; // clear modified flag, so that it will be closed
     end;
-    if MsgResult=mrAbort then CanClose:=false;
-    LazPackage.Modified:=false; // clear modified flag, so that it will be closed
+    if CanClose and not MainIDE.IDEIsClosing then
+    begin
+      EnvironmentOptions.LastOpenPackages.Remove(LazPackage.Filename);
+      MainIDE.SaveEnvironment;
+    end;
   end;
   //debugln(['TPackageEditorForm.PackageEditorFormCloseQuery CanClose=',CanClose,' ',Caption]);
   if CanClose then
@@ -1845,13 +1854,23 @@
 
 procedure TPackageEditorForm.SetLazPackage(const AValue: TLazPackage);
 begin
-  if FLazPackage=AValue then exit;
-  if FLazPackage<>nil then FLazPackage.Editor:=nil;
+  if (FLazPackage=AValue) and
+     not(Assigned(AValue) and (Name<>PackageEditorWindowPrefix+AValue.Name))//force editor name change when package name changed!
+  then
+    exit;
+  if FLazPackage<>nil then
+  begin
+    FLazPackage.Editor:=nil;
+    if EnvironmentOptions.LastOpenPackages.Remove(FLazPackage.Filename) then
+      MainIDE.SaveEnvironment;
+  end;
   FLazPackage:=AValue;
   if FLazPackage=nil then begin
     Name:=Name+'___off___';
     exit;
   end;
+  EnvironmentOptions.LastOpenPackages.Add(FLazPackage.Filename);
+  MainIDE.SaveEnvironment;
   Name:=PackageEditorWindowPrefix+LazPackage.Name;
   FLazPackage.Editor:=Self;
   // update components
@@ -3304,6 +3323,19 @@
   Result:=TPackageEditorForm(FItems[Index]);
 end;
 
+function TPackageEditors.IndexOfPackage(const PkgName: string): integer;
+var
+  I: Integer;
+begin
+  for I := 0 to Count-1 do
+    if Assigned(Editors[I].LazPackage) and
+      SameText(ExtractFileNameOnly(Editors[I].LazPackage.Filename), PkgName)
+    then
+      Exit(I);
+
+  Result := -1;
+end;
+
 constructor TPackageEditors.Create;
 begin
   FItems:=TFPList.Create;
@@ -3395,6 +3427,17 @@
   if Assigned(OnFreeEditor) then OnFreeEditor(Pkg);
 end;
 
+function TPackageEditors.FindEditor(const PkgName: string): TPackageEditorForm;
+var
+  i: Integer;
+begin
+  i:=IndexOfPackage(PkgName);
+  if i>=0 then
+    Result:=Editors[i]
+  else
+    Result:=nil;
+end;
+
 function TPackageEditors.CreateNewFile(Sender: TObject;
   Params: TAddToPkgResult): TModalResult;
 begin
Index: packager/pkgmanager.pas
===================================================================
--- packager/pkgmanager.pas	(revision 49803)
+++ packager/pkgmanager.pas	(working copy)
@@ -1155,6 +1155,15 @@
         NewMainUnitFileName:=ChangeFileExt(NewFileName,'.pas')
       else
         NewMainUnitFileName:='';
+
+      if PackageEditors.FindEditor(NewPkgName) <> nil then
+      begin
+        Result:=IDEMessageDialog(lisPkgMangInvalidPackageName,
+          Format(lisPkgMangSaveAsAlreadyOpenedPackage, [NewPkgName]),
+          mtInformation,[mbRetry,mbAbort]);
+        if Result=mrAbort then exit;
+        continue; // try again
+      end;
       
       // check file extension
       if ExtractFileExt(NewFilename)='' then begin
@@ -1291,6 +1300,8 @@
   
   // set filename
   APackage.Filename:=NewFilename;
+  if Assigned(APackage.Editor) then
+    APackage.Editor.LazPackage := APackage;//force package editor name change!
   
   // rename package
   PackageGraph.ChangePackageID(APackage,NewPkgName,APackage.Version,
@@ -1298,6 +1309,11 @@
   SaveAutoInstallDependencies;
   RenamePackageInProject;
 
+  //update LastOpenPackages list
+  EnvironmentOptions.LastOpenPackages.Remove(OldPkgFilename);
+  EnvironmentOptions.LastOpenPackages.Add(NewFileName);
+  MainIDE.SaveEnvironment;
+
   // clean up old package file to reduce ambiguousities
   if FileExistsUTF8(OldPkgFilename)
   and (CompareFilenames(OldPkgFilename,NewFilename)<>0) then begin


More information about the Lazarus mailing list