Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2015-09

Desktops and multiple source editors

36 messages · 6 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Juha Manninen

Martin Friebe noticed a problem with desktops and multiple source editor windows.
In fact I also noticed that a second source editor is not restored correctly when changing desktops.
Now I realized the 2nd, 3rd etc. editor windows are project specific, while other layout settings are global. This is not very logical. How to solve it?
I think all layout settings should be global for the sake of consistency.

Juha

Reply by email

Martin Frb
to Juha Manninen
Juha Manninen wrote 9 lines
Martin Friebe noticed a problem with desktops and multiple source editor windows. In fact I also noticed that a second source editor is not restored correctly when changing desktops. Now I realized the 2nd, 3rd etc. editor windows are project specific, while other layout settings are global. This is not very logical. How to solve it? I think all layout settings should be global for the sake of consistency.

IMHO global is ok. Maybe an option to add project specific layouts?

In any case SourceEditors. The layout should store the positions and sizes. The project defines which of them to use.
But that needs decision what to do, if a layout was created with 2 editors, but a project has 3 open. Where to get the initial pos for the new source editor?
- default pos
- pos from global "default" layout (if it specifies such a pos)
- pos from hidden layout "last pos of any window by name"
- have a parent mode (layout was created as "child" of other mode)
- search the mast similar one (probably not)
....

Also does it affect design forms? Then that would have similar issues....

position of open package windows...
At first similar to the source edit issue, only projects are more likely to have different packages.
[pos from hidden layout "last pos of any window by name"] might help here.

Reply by email

Ondrej Pokorny
to Juha Manninen: Martin Friebe noticed a problem with desktops and multiple source editor windows. In fact…
Juha Manninen wrote 10 lines
Martin Friebe noticed a problem with desktops and multiple source editor windows. In fact I also noticed that a second source editor is not restored correctly when changing desktops. Now I realized the 2nd, 3rd etc. editor windows are project specific, while other layout settings are global. This is not very logical. How to solve it? I think all layout settings should be global for the sake of consistency. Juha

The settings are saved correctly in the environment settings. Try to save a desktop with 2 editor windows, move something (including the editor windows) and then load the desktop. Both editor windows are positioned correctly.

Actually, from the principal point of view, the code is correct. Editor windows are normal nonmodal windows and so they are restored/closed on desktop change like any other window. If you stored a desktop without a secondary editor window, it is closed when you apply the desktop.

But I see that this is not wanted and expected from the user's point of view ->
That means secondary editor windows need special treatment in *TEnvironmentOptions.UseDesktop/TIDEWindowCreatorList.RestoreSimpleLayout*. It should not change visibility of editor windows. It should only change their position.

I fixed this in the undocked environment. See the patch. Please test/comment. The special windows that should not be closed/shown on desktop change have to be registered in the
*IDEWindowsDontChangeVisibility* list (names of the forms). Currently only editor windows are added into the list.
Important: if you save a desktop with a secondary editor and use it, the position of the secondary editor is restored. If you save a desktop with no secondary editors and you apply the desktop when there is a secondary editor window visible, it won't change its position. This is correct behavior.

+ Please don't report bugs like "I created a desktop with no editor window. But when I apply it, the editor window isn't closed." This is the requested behavior now (there is no difference between secondary/primary editor window).

Ondrej
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20150909/daa1df1a/attachment.html>
-------------- next part --------------
Index: components/ideintf/idewindowintf.pas
===================================================================
--- components/ideintf/idewindowintf.pas	(revision 49796)
+++ components/ideintf/idewindowintf.pas	(working copy)
@@ -233,6 +233,7 @@
     procedure LoadFromConfig(Config: TConfigStorage; const Path: string);
     procedure SaveToConfig(Config: TConfigStorage; const Path: string);
     function CustomCoordinatesAreValid: boolean;
+    function DefaultCoordinatesAreValid: boolean;
     procedure CloseForm;
     function ValidateAndSetCoordinates(const aForce: Boolean = False): Boolean;
     procedure SetDefaultPosition(const AForm: TCustomForm);
@@ -483,6 +484,7 @@
 procedure MakeIDEWindowDockable(AControl: TWinControl);
 procedure MakeIDEWindowDockSite(AForm: TCustomForm);
 procedure CloseAllForms;
+function IDEWindowsDontChangeVisibility: TStringList;
 procedure Register;

@@ -491,6 +493,9 @@
uses

   LazIDEIntf;
+var
+  FIDEWindowsDontChangeVisibility: TStringList = nil;
+
 function StrToIDEWindowPlacement(const s: string): TIDEWindowPlacement;
 begin
   for Result:=Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do
@@ -551,6 +556,16 @@
   end;
 end;
+function IDEWindowsDontChangeVisibility: TStringList;
+begin
+  if not Assigned(FIDEWindowsDontChangeVisibility) then
+  begin
+    FIDEWindowsDontChangeVisibility := TStringList.Create;
+    FIDEWindowsDontChangeVisibility.Sorted := True;
+  end;
+  Result := FIDEWindowsDontChangeVisibility;
+end;
+
 procedure Register;
 begin
   RegisterComponents('Misc',[TIDEDialogLayoutStorage]);
@@ -1199,6 +1214,11 @@
   Result:=(Width>0) and (Height>0); // and (Left>10-Width) and (Top>10-Height);
 end;
+function TSimpleWindowLayout.DefaultCoordinatesAreValid: boolean;
+begin
+  Result:=(DefaultWidth>0) and (DefaultHeight>0);
+end;
+
 procedure TSimpleWindowLayout.CloseForm;
 begin
   GetCurrentPosition;
@@ -1214,8 +1234,11 @@
   Result := False;
   if aForce or CustomCoordinatesAreValid then begin
     if not CustomCoordinatesAreValid then//default position
+    begin
+      if not DefaultCoordinatesAreValid then//don't change the coordinates if default position is invalid
+        Exit;
       NewBounds := Bounds(DefaultLeft, DefaultTop, DefaultWidth, DefaultHeight)
-    else// explicit position
+    end else// explicit position
       NewBounds := Bounds(Left, Top, Width, Height);
     // set minimum size
@@ -2239,6 +2262,7 @@
   i: Integer;
   ALayout: TSimpleWindowLayout;
   AForm: TCustomForm;
+  AChangeVisibility: Boolean;
 begin
   if IDEDockMaster=nil then
   begin
@@ -2245,13 +2269,21 @@
     for i:=SimpleLayoutStorage.Count-1 downto 0 do//loop down in order to keep z-order of the forms
     begin
       ALayout:=SimpleLayoutStorage[i];
-      AForm:=GetForm(ALayout.FormID,ALayout.Visible);
+      AChangeVisibility := (IDEWindowsDontChangeVisibility.IndexOf(ALayout.FormID) = -1);
+      AForm:=GetForm(ALayout.FormID,AChangeVisibility and ALayout.Visible);
       if AForm=nil then Continue;
-      ALayout.Apply(True);
-      if ALayout.Visible or (AForm=Application.MainForm) then
-        ShowForm(AForm,true)
-      else if AForm.Visible then
-        AForm.Close;
+      ALayout.Apply(AChangeVisibility);
+      if AChangeVisibility then
+      begin
+        if ALayout.Visible or (AForm=Application.MainForm) then
+          ShowForm(AForm,true)
+        else if AForm.Visible then
+          AForm.Close;
+      end else
+      begin//do not change visibility
+        if AForm.Visible then//Only make sure their z-index is OK if they are already visible
+          ShowForm(AForm,true)
+      end;
     end;
   end;
   LayoutChanged;
@@ -2294,6 +2326,7 @@
 finalization
   FreeAndNil(IDEWindowCreators);
   FreeAndNil(IDEDialogLayoutList);
+  FreeAndNil(FIDEWindowsDontChangeVisibility);
 end.

Index: ide/sourceeditor.pp
=================================================================== --- ide/sourceeditor.pp (revision 49796)
+++ ide/sourceeditor.pp (working copy)
@@ -5740,6 +5740,7 @@

     Name := NonModalIDEWindowNames[nmiwSourceNoteBookName] + IntToStr(AWindowID+1)
   else
     Name := NonModalIDEWindowNames[nmiwSourceNoteBookName];

+ IDEWindowsDontChangeVisibility.Add(Name);

   if AWindowID > 0 then
     FBaseCaption := locWndSrcEditor + ' (' + IntToStr(AWindowID+1) + ')'

Reply by email

Ondrej Pokorny
to Ondrej Pokorny
Ondrej Pokorny wrote 47 lines
On 09.09.2015 12:58, Juha Manninen wrote: > Martin Friebe noticed a problem with desktops and multiple source > editor windows. > In fact I also noticed that a second source editor is not restored > correctly when changing desktops. > Now I realized the 2nd, 3rd etc. editor windows are project specific, > while other layout settings are global. This is not very logical. How > to solve it? > I think all layout settings should be global for the sake of consistency. > > Juha The settings are saved correctly in the environment settings. Try to save a desktop with 2 editor windows, move something (including the editor windows) and then load the desktop. Both editor windows are positioned correctly. Actually, from the principal point of view, the code is correct. Editor windows are normal nonmodal windows and so they are restored/closed on desktop change like any other window. If you stored a desktop without a secondary editor window, it is closed when you apply the desktop. But I see that this is not wanted and expected from the user's point of view -> That means secondary editor windows need special treatment in *TEnvironmentOptions.UseDesktop/TIDEWindowCreatorList.RestoreSimpleLayout*. It should not change visibility of editor windows. It should only change their position. I fixed this in the undocked environment. See the patch. Please test/comment. The special windows that should not be closed/shown on desktop change have to be registered in the *IDEWindowsDontChangeVisibility* list (names of the forms). Currently only editor windows are added into the list. Important: if you save a desktop with a secondary editor and use it, the position of the secondary editor is restored. If you save a desktop with no secondary editors and you apply the desktop when there is a secondary editor window visible, it won't change its position. This is correct behavior. + Please don't report bugs like "I created a desktop with no editor window. But when I apply it, the editor window isn't closed." This is the requested behavior now (there is no difference between secondary/primary editor window). Ondrej

+ Maybe package windows should be treated the same way as editor windows? They are closed/opened on desktop change as well (the same problem).

Ondrej
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20150909/fafdde37/attachment-0001.html>

Reply by email

Mattias Gaertner
to Ondrej Pokorny
[...] + Maybe package windows should be treated the same way as editor windows? They are closed/opened on desktop change as well (the same problem).

About package windows: I just got the following exception on startup of the IDE when recreating a package editor:

TApplication.HandleException TControl.EnableAutoSizing PackageEditor_ToDoListLaz:TPackageEditorForm: missing DisableAutoSizing Stack trace:
$000000000072A9B8 line 5447 of include/control.inc $000000000157CD63 line 1946 of anchordocking.pas
$000000000157D55D line 2045 of anchordocking.pas
$000000000163CB2B line 232 of anchordesktopoptions.pas $0000000000DDFFFC line 2111 of environmentopts.pp
$00000000004AF4D8 line 2336 of main.pp
$00000000004A9011 line 1548 of main.pp
$000000000041FE0D line 123 of lazarus.pp

DisableAutoSizing and EnableAutoSizing calls must be balanced.

Mattias

Reply by email

Ondrej Pokorny
to Mattias Gaertner
Mattias Gaertner wrote 19 lines
About package windows: I just got the following exception on startup of the IDE when recreating a package editor: TApplication.HandleException TControl.EnableAutoSizing PackageEditor_ToDoListLaz:TPackageEditorForm: missing DisableAutoSizing Stack trace: $000000000072A9B8 line 5447 of include/control.inc $000000000157CD63 line 1946 of anchordocking.pas $000000000157D55D line 2045 of anchordocking.pas $000000000163CB2B line 232 of anchordesktopoptions.pas $0000000000DDFFFC line 2111 of environmentopts.pp $00000000004AF4D8 line 2336 of main.pp $00000000004A9011 line 1548 of main.pp $000000000041FE0D line 123 of lazarus.pp DisableAutoSizing and EnableAutoSizing calls must be balanced. Mattias

This is strange. I tested and debugged it and package windows are not recreated at IDE start with the current code (???) This is due to the over-complicated TSimpleWindowLayoutList.Assign which I have to refactor. Let's see after the refactoring.

Ondrej

Reply by email

Martin Frb
to Ondrej Pokorny: The settings are saved correctly in the environment settings. Try to save a desktop with…
Ondrej Pokorny wrote 16 lines
On 09.09.2015 12:58, Juha Manninen wrote: > Martin Friebe noticed a problem with desktops and multiple source > editor windows. > In fact I also noticed that a second source editor is not restored > correctly when changing desktops. > Now I realized the 2nd, 3rd etc. editor windows are project specific, > while other layout settings are global. This is not very logical. How > to solve it? > I think all layout settings should be global for the sake of consistency. > > Juha The settings are saved correctly in the environment settings. Try to save a desktop with 2 editor windows, move something (including the editor windows) and then load the desktop. Both editor windows are positioned correctly.

I have 2 source editors open. Always. In all projects, since forever.

Now I updated the ide, while 2 SrcEd are open, I checked that the desktop settings were:
- one layout named "default" (set as default)
- autosave desktop.

Both SE are open
I have 2 monitors, both are on the left, with negative x-coordinate

After an IDE restart, I find this in environmentopts.

<Desktops Count="1" ActiveDesktop="default">
<Desktop1 Name="default">
...
<SourceNotebook2>
<Caption Value="SourceNotebook2"/>
<WindowPlacement Value="RestoreWindowGeometry"/>
<CustomPosition Left="-879" Width="862" Height="996"/> <WindowState Value="Normal"/>
</SourceNotebook2>
<SourceNotebook>
<Caption Value="SourceNotebook"/>
<WindowPlacement Value="RestoreWindowGeometry"/>
<CustomPosition Left="-1680" Width="823" Height="991"/> <WindowState Value="Normal"/>
</SourceNotebook>

Those values are ok. Sometimes the order is SourceNotebook2 first

So I debug it.
The first sourcenotebook is created in
TIDEWindowCreatorList.RestoreSimpleLayout;
#0 RESTORESIMPLELAYOUT(0x11a7f988) at idewindowintf.pas:2248 #1 RESTOREDESKTOP(0x156848) at environmentopts.pp:2109 #2 RESTOREIDEWINDOWS(0x11a50548) at main.pp:2336
#3 STARTIDE(0x11a50548) at main.pp:1548
#4 :127

But the 2nd is NOT !

It is created later (when it is actually needed):
#0 CREATE(0x15b023c0, 0x1, 0x12b3c1b0, 1) at sourceeditor.pp:5733 #1 CREATENEWWINDOW(0x12b3c1b0, false, false, 1) at sourceeditor.pp:10554 #2 SOURCEWINDOWWITHID(0x12b3c1b0, 1) at sourceeditor.pp:9403 #3 OPENFILEINSOURCEEDITOR(0x1383a078, 0x154d5d20) at sourcefilemanager.pas:410
#4 OPENEDITORFILE(0x1383a078, -1, 1, 0x154d5d20,
[OFPROJECTLOADING..OFONLYIFEXISTS, OFMULTIOPEN]) at sourcefilemanager.pas:1173
#5 OPENEDITORFILE(0x154c6528
'B:\lazarus_latest\ide\sourcefilemanager.pas', -1, 1, 0x154d5d20, [OFPROJECTLOADING..OFONLYIFEXISTS, OFMULTIOPEN], true) at sourcefilemanager.pas:338
#6 INITOPENEDPROJECTFILE(0x147c1e48, 0x15244d60
'B:\lazarus_latest\ide\lazarus.lpi', []) at sourcefilemanager.pas:3424 #7 DOOPENPROJECTFILE(0x11a50548, 0x15244d60
'B:\lazarus_latest\ide\lazarus.lpi', []) at main.pp:6022 #8 SETUPSTARTPROJECT(0x11a50548) at main.pp:2219
#9 STARTIDE(0x11a50548) at main.pp:1553
#10 :127

And so the desktop is not applied.

------------------------
Opening the second SE-win in RestoreSimpleLayout wil only partly fix issues.

Because a desktop may have positions for 10 SE-win. A project may load with just one or two then more get open while working on the project (I often open a 3rd or 4th temporarily). When they get opened they need to be placed according to the active desktop.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20150909/dd8b6f38/attachment.html>

Reply by email

Martin Frb
to Ondrej Pokorny: The settings are saved correctly in the environment settings. Try to save a desktop with…

Sorry didnt see the patch / so no feedback on it.

Ondrej Pokorny wrote 7 lines
But I see that this is not wanted and expected from the user's point of view -> That means secondary editor windows need special treatment in *TEnvironmentOptions.UseDesktop/TIDEWindowCreatorList.RestoreSimpleLayout*. It should not change visibility of editor windows. It should only change their position.

Yes ... no .. yes .. well
interesting point.

If a desktop layout is global (for all projects) then it can not be allowed to open close SE. Because each project can have different amount of SE.

But it may also be desirable to have layouts that toggle a specific project between different amount of SE (and maybe even with different set of files open).
But that only works, if a desktop is not global. (so no currently implemented)

And this may become worse (though not anytime soon). I have that idea, that you can open 2 or 3 watches (or stack or local) windows. One for current data, the others for debug history http://wiki.lazarus.freepascal.org/IDE_Window:_Debug_History Yet seeing my current schedule - *not* within the next 2 or 3 years ...

Ondrej Pokorny wrote
On 09.09.2015 17:16, Ondrej Pokorny wrote: + Maybe package windows should be treated the same way as editor windows? They are closed/opened on desktop change as well (the same problem).

Same as with SE, would depends on global/none global settings.

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20150909/adcb0350/attachment-0001.html>

Reply by email

Ondrej Pokorny
to Martin Frb

Now I think I got the multiple source editors handling correct: 1.) The position of editor windows is controlled by the desktop. 2.) The visibility of editor windows is controlled by the current project. This corresponds with the old pre-desktop Lazarus behavior and is also logical.

The above applies to non-docked environment.
The docked environment is more a problem because e.g. the secondary editor window doesn't get closed when you close all the tabs. Also the project doesn't handle the visibility of the secondary editor window. I assume it was the same in pre-desktop Lazarus. I don't know if it is a feature or a bug.

The Package editors:
1.) Position is controlled by the desktop for every package separately. This means if you open a package and save the desktop, the next time you open the package having the same desktop active in the IDE, it will be correctly placed.
2.) The visibility is controlled by the fact if the package is open or not. The desktop cannot reopen packages, obviously. It doesn't store the file info of the package. It is also not expected.

Again, the above applies to non-docked environment. Packages are a problem in the docked environment. When you change the desktop, there is a docked package and there is no docking information about it in the new desktop, where should it be placed? IMO, it has to be detached from the dock and placed in a window. Now it gets closed. Maybe it is easier to disable docking capabilities for packages. Then the docked environment would just ignore them.

I am not using AnchorDocking personally so somebody else should care of the problems in AnchorDocking.

---
Patch attached.
+ I tested Windows 10 only. It seems to work pretty well for me.

Ondrej
-------------- next part --------------
Index: components/ideintf/idewindowintf.pas
===================================================================
--- components/ideintf/idewindowintf.pas	(revision 49801)
+++ components/ideintf/idewindowintf.pas	(working copy)
@@ -209,16 +209,12 @@
     FDefaultWidth: integer;
     FDefaultHeight: integer;
     FWindowState: TIDEWindowState;
-    FForm: TCustomForm;
     FFormID: string;
     FDefaultWindowPlacement: TIDEWindowPlacement;
     FDividers: TSimpleWindowLayoutDividerPosList;
+    function GetForm: TCustomForm;
     function GetFormCaption: string;
-    function GetFormID: string;
-    procedure SetForm(const AValue: TCustomForm);
     procedure OnFormClose(Sender: TObject; var {%H-}CloseAction: TCloseAction);
-  protected
-    procedure Notification(AComponent: TComponent; Operation: TOperation); override;
   public
     constructor Create(AFormID: string); reintroduce;
     destructor Destroy; override;
@@ -233,11 +229,13 @@
     procedure LoadFromConfig(Config: TConfigStorage; const Path: string);
     procedure SaveToConfig(Config: TConfigStorage; const Path: string);
     function CustomCoordinatesAreValid: boolean;
+    function DefaultCoordinatesAreValid: boolean;
     procedure CloseForm;
+    procedure SetForm(const AForm: TCustomForm);
     function ValidateAndSetCoordinates(const aForce: Boolean = False): Boolean;
     procedure SetDefaultPosition(const AForm: TCustomForm);
   public
-    property FormID: string read GetFormID write FFormID;
+    property FormID: string read FFormID write FFormID;
     function FormBaseID(out SubIndex: Integer): String; // split FormID into name+number
     property FormCaption: string read GetFormCaption;
     property WindowPlacement: TIDEWindowPlacement read fWindowPlacement write FWindowPlacement;
@@ -252,7 +250,7 @@
     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 Form: TCustomForm read GetForm;
     property Visible: boolean read FVisible write FVisible;
     property Applied: boolean read FApplied write FApplied;
     property Dividers: TSimpleWindowLayoutDividerPosList read FDividers;
@@ -281,8 +279,7 @@
                            AMoveToVisbleMode: TLayoutMoveToVisbleMode = vmAlwaysMoveToVisible);
     procedure StoreWindowPositions;
     procedure SetDefaultPosition(const AForm: TCustomForm);
-    procedure Assign(SrcList: TSimpleWindowLayoutList; AssignOnlyNewlyCreated,
-      DestroyNotAssigned, AssignOrder: Boolean);
+    procedure CopyItemsFrom(SrcList: TSimpleWindowLayoutList);
     function Add(ALayout: TSimpleWindowLayout): integer;
     function CreateWindowLayout(const TheFormID: string): TSimpleWindowLayout;
     function CreateWindowLayout(const TheForm: TCustomForm): TSimpleWindowLayout;
@@ -477,6 +474,22 @@
     property HideSimpleLayoutOptions: boolean read FHideSimpleLayoutOptions;
   end;
+  TIDEWindowGlobalOption = class
+  public
+    CanSetVisibility: Boolean;
+  end;
+
+  TIDEWindowsGlobalOptions = class
+  private
+    FList: TStringList;
+  public
+    constructor Create;
+    destructor Destroy; override;
+  public
+    procedure Add(const aFormIDPrefix: string; CanSetVisibility: Boolean);
+    function CanSetVisibility(const aFormID: string): Boolean;
+  end;
+
 var
   IDEDockMaster: TIDEDockMaster = nil; // can be set by a package
@@ -483,6 +496,7 @@
 procedure MakeIDEWindowDockable(AControl: TWinControl);
 procedure MakeIDEWindowDockSite(AForm: TCustomForm);
 procedure CloseAllForms;
+function IDEWindowsGlobalOptions: TIDEWindowsGlobalOptions;
 procedure Register;

@@ -491,6 +505,9 @@
uses

   LazIDEIntf;
+var
+  FIDEWindowsGlobalOptions: TIDEWindowsGlobalOptions = nil;
+
 function StrToIDEWindowPlacement(const s: string): TIDEWindowPlacement;
 begin
   for Result:=Low(TIDEWindowPlacement) to High(TIDEWindowPlacement) do
@@ -551,11 +568,62 @@
   end;
 end;
+function IDEWindowsGlobalOptions: TIDEWindowsGlobalOptions;
+begin
+  if not Assigned(FIDEWindowsGlobalOptions) then
+    FIDEWindowsGlobalOptions := TIDEWindowsGlobalOptions.Create;
+
+  Result := FIDEWindowsGlobalOptions;
+end;
+
 procedure Register;
 begin
   RegisterComponents('Misc',[TIDEDialogLayoutStorage]);
 end;
+{ TIDEWindowsGlobalOptions }
+
+procedure TIDEWindowsGlobalOptions.Add(const aFormIDPrefix: string;
+  CanSetVisibility: Boolean);
+var
+  xIndex: Integer;
+begin
+  xIndex := FList.Add(aFormIDPrefix);
+  if FList.Objects[xIndex] = nil then
+    FList.Objects[xIndex] := TIDEWindowGlobalOption.Create;
+
+  TIDEWindowGlobalOption(FList.Objects[xIndex]).CanSetVisibility := CanSetVisibility;
+end;
+
+function TIDEWindowsGlobalOptions.CanSetVisibility(const aFormID: string
+  ): Boolean;
+var
+  I: Integer;
+begin
+  for I := 0 to FList.Count-1 do
+  if Copy(aFormID, 1, Length(FList[I])) = FList[I] then
+  begin
+    Result := TIDEWindowGlobalOption(FList.Objects[I]).CanSetVisibility;
+    Exit;
+  end;
+  Result := True;//default is true
+end;
+
+constructor TIDEWindowsGlobalOptions.Create;
+begin
+  inherited Create;
+
+  FList := TStringList.Create;
+  FList.Sorted := True;
+  FList.OwnsObjects := True;
+end;
+
+destructor TIDEWindowsGlobalOptions.Destroy;
+begin
+  FList.Free;
+  inherited Destroy;
+end;
+
 { TSimpleWindowLayoutDividerPosList }
 function TSimpleWindowLayoutDividerPosList.GetItems(Index: Integer): TSimpleWindowLayoutDividerPos;
@@ -1110,7 +1178,6 @@
 destructor TSimpleWindowLayout.Destroy;
 begin
-  Form:=nil;
   inherited Destroy;
   FDividers.Free;
 end;
@@ -1182,27 +1249,19 @@
   GetCurrentPosition;
 end;
-procedure TSimpleWindowLayout.Notification(AComponent: TComponent;
-  Operation: TOperation);
+function TSimpleWindowLayout.CustomCoordinatesAreValid: boolean;
 begin
-  inherited Notification(AComponent, Operation);
-  if Operation=opRemove then begin
-    if fForm=AComponent then begin
-      fForm:=nil;
-      Applied:=false;
-    end;
-  end;
+  Result:=(Width>0) and (Height>0); // and (Left>10-Width) and (Top>10-Height);
 end;
-function TSimpleWindowLayout.CustomCoordinatesAreValid: boolean;
+function TSimpleWindowLayout.DefaultCoordinatesAreValid: boolean;
 begin
-  Result:=(Width>0) and (Height>0); // and (Left>10-Width) and (Top>10-Height);
+  Result:=(DefaultWidth>0) and (DefaultHeight>0);
 end;
 procedure TSimpleWindowLayout.CloseForm;
 begin
   GetCurrentPosition;
-  Form:=nil;
 end;
 function TSimpleWindowLayout.ValidateAndSetCoordinates(const aForce: Boolean
@@ -1210,12 +1269,19 @@
 var
   i: Integer;
   NewBounds: TRect;
+  xForm: TCustomForm;
 begin
   Result := False;
-  if aForce or CustomCoordinatesAreValid then begin
+  xForm := Form;
+  if Assigned(xForm) and
+     (aForce or CustomCoordinatesAreValid) then
+  begin
     if not CustomCoordinatesAreValid then//default position
+    begin
+      if not DefaultCoordinatesAreValid then//don't change the coordinates if default position is invalid
+        Exit;
       NewBounds := Bounds(DefaultLeft, DefaultTop, DefaultWidth, DefaultHeight)
-    else// explicit position
+    end else// explicit position
       NewBounds := Bounds(Left, Top, Width, Height);
     // set minimum size
@@ -1248,7 +1314,7 @@
     end;
     // set bounds (do not use SetRestoredBounds - that flickers with the current LCL implementation)
-    FForm.SetBounds(NewBounds.Left, NewBounds.Top,
+    xForm.SetBounds(NewBounds.Left, NewBounds.Top,
                     NewBounds.Right - NewBounds.Left,
                     NewBounds.Bottom - NewBounds.Top);
     Result := True;
@@ -1270,33 +1336,17 @@
   Result := copy(Result, 1, i);
 end;
-procedure TSimpleWindowLayout.SetForm(const AValue: TCustomForm);
+procedure TSimpleWindowLayout.SetForm(const AForm: TCustomForm);
 begin
-  if fForm=AValue then exit;
-  if Assigned(Form) then
+  if Assigned(AForm) then
   begin
-    RemoveFreeNotification(Form);
-    Form.RemoveHandlerClose(@OnFormClose);
-  end;
-  fForm:=AValue;
-  if Assigned(Form) then
-  begin
-    fFormID := Form.Name;
-    FFormCaption := Form.Caption;
-    FreeNotification(Form);
-    Form.AddHandlerClose(@OnFormClose);
+    fFormID := AForm.Name;
+    FFormCaption := AForm.Caption;
+    AForm.AddHandlerClose(@OnFormClose);
     Applied:=false;
   end;
 end;
-function TSimpleWindowLayout.GetFormID: string;
-begin
-  if Form=nil then
-    Result:=fFormID
-  else
-    Result:=Form.Name;
-end;
-
 function TSimpleWindowLayout.GetFormCaption: string;
 begin
   if Formnil then
@@ -1370,10 +1420,12 @@
   i, j: Integer;
   f: Boolean;
   Creator: TIDEWindowCreator;
+  xForm: TCustomForm;
 begin
   Creator:=IDEWindowCreators.FindWithName(FormID);
   if (Creator = nil) or (Creator.OnGetDividerSize = nil) then exit;
-  if fForm = nil then exit;
+  xForm := Form;
+  if xForm = nil then exit;
   for i := 0 to FDividers.Count - 1 do begin
     if FDividers[i].FId < 0 then continue;
     f := AForce;
@@ -1385,7 +1437,7 @@
     end;
     if f then begin
       j:=-1;
-      if Creator.OnGetDividerSize(fForm, FDividers[i].Id, j) then
+      if Creator.OnGetDividerSize(xForm, FDividers[i].Id, j) then
         FDividers[i].Size := j
       else
         FDividers[i].Size := -1; // Default / Not Changed / Unavailable
@@ -1405,10 +1457,26 @@
   //debugln('TSimpleWindowLayout.GetCurrentPosition ',DbgSName(Self),' ',FormID,' Width=',dbgs(Width));
 end;
+function TSimpleWindowLayout.GetForm: TCustomForm;
+var
+  I: Integer;
+begin
+  for I := 0 to Screen.CustomFormCount-1 do
+  if Screen.CustomForms[I].Name = FFormID then
+  begin
+    Result := Screen.CustomForms[I];
+    Exit;
+  end;
+  Result := nil;
+end;
+
 function TSimpleWindowLayout.Apply(const aForce: Boolean): Boolean;
+var
+  xForm: TCustomForm;
 begin
   Result := False;
-  if fForm = nil then exit;
+  xForm := Form;
+  if xForm = nil then exit;
   Applied:=true;
   {$IFDEF VerboseIDEDocking}
   debugln(['TSimpleWindowLayoutList.ApplyAndShow restore ',
@@ -1421,8 +1489,8 @@
     begin
       //DebugLn(['TMainIDE.OnApplyWindowLayout ',IDEWindowStateNames[WindowState]]);
       case WindowState of
-        iwsMinimized: FForm.WindowState:=wsMinimized;
-        iwsMaximized: FForm.WindowState:=wsMaximized;
+        iwsMinimized: xForm.WindowState:=wsMinimized;
+        iwsMaximized: xForm.WindowState:=wsMaximized;
       end;
       Result := ValidateAndSetCoordinates(aForce);     // Adjust bounds to screen area and apply them.
       if WindowState in [iwsMinimized, iwsMaximized] then
@@ -1453,7 +1521,7 @@
           f := WindowPlacement in [iwpRestoreWindowGeometry, iwpRestoreWindowSize];
       end;
       if f then
-        Creator.OnSetDividerSize(fForm, FDividers[i].Id, FDividers[i].Size);
+        Creator.OnSetDividerSize(Form, FDividers[i].Id, FDividers[i].Size);
     end;
   end;
 end;
@@ -1504,7 +1572,7 @@
 function TSimpleWindowLayoutList.IndexOf(const FormID: string): integer;
 begin
   Result:=Count-1;
-  while (Result>=0) and (FormIDItems[Result].GetFormID) do dec(Result);
+  while (Result>=0) and (FormIDItems[Result].FormID) do dec(Result);
 end;
 function TSimpleWindowLayoutList.IndexOf(const AForm: TCustomForm): integer;
@@ -1649,7 +1717,7 @@
     ALayout:=ItemByFormID(AForm.Name);
     if ALayoutnil then
     begin
-      ALayout.Form:=AForm;
+      ALayout.SetForm(AForm);
       if ALayout.Applied then exit;
       if ALayout.Apply then exit;
     end;
@@ -1789,42 +1857,22 @@
   end;
 end;
-procedure TSimpleWindowLayoutList.Assign(SrcList: TSimpleWindowLayoutList;
-  AssignOnlyNewlyCreated, DestroyNotAssigned, AssignOrder: Boolean);
+procedure TSimpleWindowLayoutList.CopyItemsFrom(SrcList: TSimpleWindowLayoutList);
 var
-  i: integer;
-  xItemIndex: Integer;
-  xNewlyCreated: Boolean;
+  SrcI: Integer;//index in SrcList
+  SelfI: Integer;//index in Self
 begin
   if SrcList=nil then exit;
-  for i:=0 to SrcList.Count-1 do begin
-    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 (xItemIndexi) and (AssignOrder) then
-      begin
-        Self.fItems.Move(xItemIndex, i);//move it to right position
-        xItemIndex := i;
-      end;
-    end else
-      xItemIndex := i;
-    if not AssignOnlyNewlyCreated or xNewlyCreated then
-      Self.Items[xItemIndex].Assign(SrcList[i])
-  end;
-  for i := Count-1 downto 0 do
-  if SrcList.IndexOf(Items[i].FormID) = -1 then
+  //do not clear self, always copy items
+  for SrcI:=0 to SrcList.Count-1 do
   begin
-    if DestroyNotAssigned then
-      Delete(i)
-    else
-      Items[i].Clear;
+    SelfI := IndexOf(SrcList[SrcI].FormID);
+    if SelfI < 0 then
+      SelfI := Self.Add(TSimpleWindowLayout.Create(SrcList[SrcI].FormID));//not found, create
+    Self.fItems.Move(SelfI, SrcI);//move it to right position
+    SelfI := SrcI;
+    Self.Items[SelfI].Assign(SrcList[SrcI])
   end;
 end;
@@ -1850,7 +1898,7 @@
   ): TSimpleWindowLayout;
 begin
   Result:=CreateWindowLayout(TheForm.Name);
-  Result.Form:=TheForm;
+  Result.SetForm(TheForm);
 end;
 { TIDEWindowCreator }
@@ -2199,7 +2247,7 @@
       SimpleLayoutStorage.CreateWindowLayout(AForm);
   end
   else
-    Layout.Form:=AForm;
+    Layout.SetForm(AForm);
   if (IDEDockMasternil) and (not (csDesigning in AForm.ComponentState))
   and (FindWithName(AForm.Name)nil) then
@@ -2240,6 +2288,7 @@
   ALayout: TSimpleWindowLayout;
   AForm: TCustomForm;
   HasChanged: Boolean;
+  AChangeVisibility: Boolean;
 begin
   if IDEDockMaster=nil then
   begin
@@ -2247,14 +2296,22 @@
     for i:=SimpleLayoutStorage.Count-1 downto 0 do//loop down in order to keep z-order of the forms
     begin
       ALayout:=SimpleLayoutStorage[i];
-      AForm:=GetForm(ALayout.FormID,ALayout.Visible);
+      AChangeVisibility := IDEWindowsGlobalOptions.CanSetVisibility(ALayout.FormID);
+      AForm:=GetForm(ALayout.FormID,AChangeVisibility and ALayout.Visible);
       if AForm=nil then Continue;
       HasChanged:=true;
-      ALayout.Apply(True);
-      if ALayout.Visible or (AForm=Application.MainForm) then
-        ShowForm(AForm,true)
-      else if AForm.Visible then
-        AForm.Close;
+      ALayout.Apply(AChangeVisibility);
+      if AChangeVisibility then
+      begin
+        if ALayout.Visible or (AForm=Application.MainForm) then
+          ShowForm(AForm,true)
+        else if AForm.Visible then
+          AForm.Close;
+      end else
+      begin//do not change visibility
+        if AForm.Visible then//Only make sure their z-index is OK if they are already visible
+          ShowForm(AForm,true)
+      end;
     end;
     if HasChanged then
       LayoutChanged;
@@ -2298,6 +2355,7 @@
 finalization
   FreeAndNil(IDEWindowCreators);
   FreeAndNil(IDEDialogLayoutList);
+  FreeAndNil(FIDEWindowsGlobalOptions);
 end.
Index: ide/environmentopts.pp
===================================================================
--- ide/environmentopts.pp	(revision 49801)
+++ ide/environmentopts.pp	(working copy)
@@ -1009,7 +1009,7 @@
     FIDEDialogLayoutList:=TIDEDialogLayoutList.Create;
     FIDEWindowCreatorsLayoutList:=TSimpleWindowLayoutList.Create(False);
     FIDEDialogLayoutList.Assign(IDEWindowIntf.IDEDialogLayoutList);
-    FIDEWindowCreatorsLayoutList.Assign(IDEWindowIntf.IDEWindowCreators.SimpleLayoutStorage, True, True, True);
+    FIDEWindowCreatorsLayoutList.CopyItemsFrom(IDEWindowIntf.IDEWindowCreators.SimpleLayoutStorage);
   end;
 end;
@@ -1043,9 +1043,7 @@
     raise Exception.Create('Internal error: TDesktopOpt.Assign mixed docked/undocked desktops.');
   // window layout
-  if Source.FIDEWindowCreatorsLayoutList  IDEWindowCreators.SimpleLayoutStorage then
-    Source.FIDEWindowCreatorsLayoutList.Assign(IDEWindowCreators.SimpleLayoutStorage, True, True, False);
-  FIDEWindowCreatorsLayoutList.Assign(Source.FIDEWindowCreatorsLayoutList, False, False, True);
+  FIDEWindowCreatorsLayoutList.CopyItemsFrom(Source.FIDEWindowCreatorsLayoutList);
   FIDEDialogLayoutList.Assign(Source.FIDEDialogLayoutList);
   FSingleTaskBarButton := Source.FSingleTaskBarButton;
   FHideIDEOnRun := Source.FHideIDEOnRun;
Index: ide/frames/window_options.pas
===================================================================
--- ide/frames/window_options.pas	(revision 49801)
+++ ide/frames/window_options.pas	(working copy)
@@ -151,7 +151,7 @@
     ProjectDirInIdeTitleCheckBox.Checked:=IDEProjectDirectoryInIdeTitle;
   end;
-  FLayouts.Assign(IDEWindowCreators.SimpleLayoutStorage, False, True, True);
+  FLayouts.CopyItemsFrom(IDEWindowCreators.SimpleLayoutStorage);
   if FShowSimpleLayout then begin
     // Window Positions
@@ -220,8 +220,7 @@
 procedure TWindowOptionsFrame.WriteSettings(AOptions: TAbstractIDEOptions);
 begin
   SaveLayout;
-  FLayouts.Assign(IDEWindowCreators.SimpleLayoutStorage, True, True, False);
-  IDEWindowCreators.SimpleLayoutStorage.Assign(FLayouts, False, False, True);
+  IDEWindowCreators.SimpleLayoutStorage.CopyItemsFrom(FLayouts);
   with (AOptions as TEnvironmentOptions).Desktop do
   begin
Index: ide/sourceeditor.pp
===================================================================
--- ide/sourceeditor.pp	(revision 49801)
+++ ide/sourceeditor.pp	(working copy)
@@ -6710,7 +6710,7 @@
     // => disconnect first
     Layout:=IDEWindowCreators.SimpleLayoutStorage.ItemByForm(Self);
     if Layoutnil then
-      Layout.Form:=nil;
+      Layout.SetForm(nil);
     Name := Name + '___' + IntToStr({%H-}PtrUInt(Pointer(Self)));
     CloseAction := caFree;
   end
@@ -8574,6 +8574,8 @@
   SRCED_OPEN  := DebugLogger.RegisterLogGroup('SRCED_OPEN' {$IFDEF SRCED_OPEN} , True {$ENDIF} );
   SRCED_CLOSE := DebugLogger.RegisterLogGroup('SRCED_CLOSE' {$IFDEF SRCED_CLOSE} , True {$ENDIF} );
   SRCED_PAGES := DebugLogger.RegisterLogGroup('SRCED_PAGES' {$IFDEF SRCED_PAGES} , True {$ENDIF} );
+
+  IDEWindowsGlobalOptions.Add(NonModalIDEWindowNames[nmiwSourceNoteBookName], False);
 end;

procedure InternalFinal;
Index: packager/packageeditor.pas
=================================================================== --- packager/packageeditor.pas (revision 49801)
+++ packager/packageeditor.pas (working copy)
@@ -42,7 +42,7 @@
IDEImagesIntf, MenuIntf, LazIDEIntf, ProjectIntf, CodeToolsStructs, FormEditingIntf, PackageIntf, IDEHelpIntf, IDEOptionsIntf, IDEExternToolIntf,
- NewItemIntf,
+ NewItemIntf, IDEWindowIntf,

   // IDE
   IDEDialogs, IDEProcs, LazarusIDEStrConsts, IDEDefs, CompilerOptions,
   ComponentReg, UnitResources, EnvironmentOpts, DialogProcs, InputHistory,

@@ -3551,6 +3551,7 @@

 initialization
   PackageEditors:=nil;
+  IDEWindowsGlobalOptions.Add(PackageEditorWindowPrefix, False);
 end.

Reply by email

Ondrej Pokorny
to Ondrej Pokorny
Ondrej Pokorny wrote 6 lines
The Package editors: 1.) Position is controlled by the desktop for every package separately. This means if you open a package and save the desktop, the next time you open the package having the same desktop active in the IDE, it will be correctly placed.

Ok, this does not work now...
Ondrej

Reply by email

Mattias Gaertner
to Ondrej Pokorny: Now I think I got the multiple source editors handling correct: 1.) The position of…
Show quoted text 6 lines
[...] The Package editors: 1.) Position is controlled by the desktop for every package separately. This means if you open a package and save the desktop, the next time you open the package having the same desktop active in the IDE, it will be correctly placed.

Good.

2.) The visibility is controlled by the fact if the package is open or not. The desktop cannot reopen packages, obviously.It doesn't store the file info of the package. It is also not expected.

Why not?
The window has the name PackageEditor_ToDoListLaz, so you have the package name. That is all you need to load the package.

Show quoted text 5 lines
Again, the above applies to non-docked environment. Packages are a problem in the docked environment. When you change the desktop, there is a docked package and there is no docking information about it in the new desktop, where should it be placed? IMO, it has to be detached from the dock and placed in a window.

Yes.

Now it gets closed.

What if the package was modified?

Show quoted text 6 lines
Maybe it is easier to disable docking capabilities for packages. Then the docked environment would just ignore them. I am not using AnchorDocking personally so somebody else should care of the problems in AnchorDocking.

I will wait til the dust has settled.

--- Patch attached. + I tested Windows 10 only. It seems to work pretty well for me.

Thanks, applied.

Mattias

Reply by email

Ondrej Pokorny
to Mattias Gaertner
Mattias Gaertner wrote 8 lines
On Thu, 10 Sep 2015 00:13:24 +0200 Ondrej Pokorny wrote: > 2.) The visibility is controlled by the fact if the package is open or > not. The desktop cannot reopen packages, obviously.It doesn't store the file info of the package. It is also not expected. Why not? The window has the name PackageEditor_ToDoListLaz, so you have the package name. That is all you need to load the package.

Ok, then it is possible to reopen a package. But still I don't think reopening/closing of packages on desktop change is a good idea. A package is kind of "project" and should be completely independent on desktop, the same like the active LPR project is.
Imagine e.g. that you (accidentally) save a debug desktop with a package. Should it be reopened every time you start debugging?

Show quoted text 11 lines
> Again, the above applies to non-docked environment. Packages are a > problem in the docked environment. When you change the desktop, there is > a docked package and there is no docking information about it in the new > desktop, where should it be placed? IMO, it has to be detached from the > dock and placed in a window. Yes. > Now it gets closed. What if the package was modified?

I don't know what happens now with the closed package but the fact is that it should not get closed.

This problem was always there. Saving/loading of the docked environment wasn't changed. The missing functionality just came up now because the desktops are going to be used much more often than the save/load function from AnchorDocking.

Show quoted text 9 lines
> Maybe it is easier to > disable docking capabilities for packages. Then the docked environment > would just ignore them. > > I am not using AnchorDocking personally so somebody else should care of > the problems in AnchorDocking. I will wait til the dust has settled.

Great, thanks!

Ondrej

Reply by email

Martin Frb
to Ondrej Pokorny
Ondrej Pokorny wrote 16 lines
On 10.09.2015 00:26, Mattias Gaertner wrote: > On Thu, 10 Sep 2015 00:13:24 +0200 > Ondrej Pokorny wrote: > >> 2.) The visibility is controlled by the fact if the package is open or >> not. The desktop cannot reopen packages, obviously.It doesn't store >> the file info of the package. It is also not expected. > Why not? > The window has the name PackageEditor_ToDoListLaz, so you have the > package name. That is all you need to load the package. Ok, then it is possible to reopen a package. But still I don't think reopening/closing of packages on desktop change is a good idea. A package is kind of "project" and should be completely independent on desktop, the same like the active LPR project is. Imagine e.g. that you (accidentally) save a debug desktop with a package. Should it be reopened every time you start debugging?

Worse, since desktops/layouts are global (apply to all projects), if you:
- save one of your desktops with a package open,
- switch to another desktop
- change project
- switch to the first desktop
it would open that package again, even if that package is not used by the course, in a way you already have that: If a package is open, it stays open, even when you change the project. But at least the you see it immediately. with desktops it may be on a inactive desktop.

Yet in terms of a debug desktop, it may be practical, to be able to close all packages, and restore them after debugging.

Maybe desktops could have some per-project info?

Reply by email

Ondrej Pokorny
to Ondrej Pokorny: Ok, this does not work now... Ondrej
Ondrej Pokorny wrote 9 lines
On 10.09.2015 00:13, Ondrej Pokorny wrote: > > The Package editors: > 1.) Position is controlled by the desktop for every package > separately. This means if you open a package and save the desktop, > the next time you open the package having the same desktop active in > the IDE, it will be correctly placed. Ok, this does not work now... Ondrej

There was Position=poScreenCenter set for the package editor window in the LFM. It overrides any position change. I forgot about it. Now it behaves like it should - the position is restored from the desktop. Small patch included.

Thanks, Ondrej
-------------- next part --------------
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

Reply by email

Ondrej Pokorny
to Martin Frb: Worse, since desktops/layouts are global (apply to all projects), if you: - save one of…
Martin Frb wrote 34 lines
On 09/09/2015 23:42, Ondrej Pokorny wrote: > On 10.09.2015 00:26, Mattias Gaertner wrote: >> On Thu, 10 Sep 2015 00:13:24 +0200 >> Ondrej Pokorny wrote: >> >>> 2.) The visibility is controlled by the fact if the package is open or >>> not. The desktop cannot reopen packages, obviously.It doesn't store >>> the file info of the package. It is also not expected. >> Why not? >> The window has the name PackageEditor_ToDoListLaz, so you have the >> package name. That is all you need to load the package. > Ok, then it is possible to reopen a package. But still I don't think > reopening/closing of packages on desktop change is a good idea. A > package is kind of "project" and should be completely independent on > desktop, the same like the active LPR project is. > Imagine e.g. that you (accidentally) save a debug desktop with a > package. Should it be reopened every time you start debugging? Worse, since desktops/layouts are global (apply to all projects), if you: - save one of your desktops with a package open, - switch to another desktop - change project - switch to the first desktop it would open that package again, even if that package is not used by the project at all. Of course, in a way you already have that: If a package is open, it stays open, even when you change the project. But at least the you see it immediately. with desktops it may be on a inactive desktop. Yet in terms of a debug desktop, it may be practical, to be able to close all packages, and restore them after debugging. Maybe desktops could have some per-project info?

Let's keep it easy and don't reopen/close package windows in desktop change. Package is something like an independent project so let's handle them the same as editor windows.

BTW. I heard some rumours that project groups should be supported at some point (?) - the same modern Delphi has. If it is so, the package editor will be deleted anyway and replaced by the project group window.

Ondrej

Reply by email

Mattias Gaertner
to Martin Frb: Worse, since desktops/layouts are global (apply to all projects), if you: - save one of…
Show quoted text 8 lines
[...] Worse, since desktops/layouts are global (apply to all projects), if you: - save one of your desktops with a package open, - switch to another desktop - change project - switch to the first desktop it would open that package again, even if that package is not used by the would like that. Maybe make reopening package windows optional?

Mattias

Reply by email

Mattias Gaertner
to Ondrej Pokorny: Ok, then it is possible to reopen a package. But still I don't think reopening/closing of…
Show quoted text 15 lines
On 10.09.2015 00:26, Mattias Gaertner wrote: > On Thu, 10 Sep 2015 00:13:24 +0200 > Ondrej Pokorny wrote: > >> 2.) The visibility is controlled by the fact if the package is open or >> not. The desktop cannot reopen packages, obviously.It doesn't store the file info of the package. It is also not expected. > Why not? > The window has the name PackageEditor_ToDoListLaz, so you have the > package name. That is all you need to load the package. Ok, then it is possible to reopen a package. But still I don't think reopening/closing of packages on desktop change is a good idea. A package is kind of "project" and should be completely independent on desktop, the same like the active LPR project is. Imagine e.g. that you (accidentally) save a debug desktop with a package. Should it be reopened every time you start debugging?

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

Reply by email

Michael Van Canneyt
to Ondrej Pokorny: Let's keep it easy and don't reopen/close package windows in desktop change. Package is…
Ondrej Pokorny wrote 9 lines
> > Maybe desktops could have some per-project info? Let's keep it easy and don't reopen/close package windows in desktop change. Package is something like an independent project so let's handle them the same as editor windows. BTW. I heard some rumours that project groups should be supported at some point (?) - the same modern Delphi has. If it is so, the package editor will be deleted anyway and replaced by the project group window.

That is not correct.
They will remain independent, at least it is so in the implementation I submitted to Mattias.

The need in Delphi to always open a package in a project group is terribly annoying, so Lazarus should definitely not make the same mistake.

Michael.

Reply by email

Ondrej Pokorny
to Mattias Gaertner: On Thu, 10 Sep 2015 00:42:55 +0200 Speaking for myself: When I close the IDE with some…
Mattias Gaertner wrote 7 lines
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 (LazPackagenil) 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 (LazPackagenil) 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 FLazPackagenil then FLazPackage.Editor:=nil;
+  if (FLazPackage=AValue) and
+     not(Assigned(AValue) and (NamePackageEditorWindowPrefix+AValue.Name))//force editor name change when package name changed!
+  then
+    exit;
+  if FLazPackagenil 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

Reply by email

Ondrej Pokorny
to Michael Van Canneyt: That is not correct. They will remain independent, at least it is so in the…
Michael Van Canneyt wrote 6 lines
The need in Delphi to always open a package in a project group is terribly annoying, so Lazarus should definitely not make the same mistake. Michael.

Then you are probably using project group wrongly. The packages are saved in the project group. So if you open a project group, the packages from the project group are opened and all others are closed. I keep packages that are relevant for the project in the project group. I find this useful. But it depends on the work flow, of course.

Ondrej

Reply by email

Michael Van Canneyt
to Ondrej Pokorny
Ondrej Pokorny wrote 10 lines
On 10.09.2015 08:34, Michael Van Canneyt wrote: > > The need in Delphi to always open a package in a project group is terribly > annoying, so Lazarus should definitely not make the same mistake. > > Michael. Then you are probably using project group wrongly. The packages are saved in the project group. So if you open a project group, the packages from the project group are opened and all others are closed. I keep packages that are relevant for the project in the project group.

For small numbers, I agree. I do the same.

But there are over 200 relevant packages (400 if I take third-party ones as well) in my typical project.

This is simply impossible to work with in a single project group. So the packages are divided over "logical" project groups, but then the project groeps do not contain all relevant packages.

I find this useful. But it depends on the work flow, of course.

I understand why they did it, but it is misguided.

Another example:

For instance, you will usually not add the synapse package to the project group. But you want to open it occasionally without adding it to the project group or losing the current project group.

So no, Lazarus should not do this.

Michael.

Reply by email

Ondrej Pokorny
to Michael Van Canneyt
Michael Van Canneyt wrote 11 lines
Another example: For instance, you will usually not add the synapse package to the project group. But you want to open it occasionally without adding it to the project group or losing the current project group. So no, Lazarus should not do this. Michael.

Yes this is true. Please also test the latest patch for package reopening at ide startup if you think Lazarus should do it. I am actually quite happy that you are against the Delphi group-package design because that would make my last patch useless in the future :)

Ondrej

Reply by email

Michael Van Canneyt
to Ondrej Pokorny
Ondrej Pokorny wrote 16 lines
On 10.09.2015 09:57, Michael Van Canneyt wrote: > > Another example: > > For instance, you will usually not add the synapse package to the project > group. > But you want to open it occasionally without adding it to the project group > or losing the current project group. > > So no, Lazarus should not do this. > > Michael. Yes this is true. Please also test the latest patch for package reopening at ide startup if you think Lazarus should do it. I am actually quite happy that you are against the Delphi group-package design because that would make my last patch useless in the future :)

I am glad we agree :-)

In general, I think this should also be settable on a per project basis.

For the project session you can currently specify that only forms belonging to the project should be included in the session.
(I always set this to on, because opening 100+ units at startup is really counter-productive).

I think the same should be done for packages: packages that are in the project dependencies and were open the last time the project was open, should be opened again.

Or all packages should be opened.

Anyway, I will test your patch in the weekend (presumably there will still be some changes by then).

Michael.

Reply by email

Ondrej Pokorny
to Michael Van Canneyt
Michael Van Canneyt wrote 16 lines
I am glad we agree :-) In general, I think this should also be settable on a per project basis. For the project session you can currently specify that only forms belonging to the project should be included in the session. (I always set this to on, because opening 100+ units at startup is really counter-productive). I think the same should be done for packages: packages that are in the project dependencies and were open the last time the project was open, should be opened again. Or all packages should be opened.

Are you refering to the Project Options -> Session -> -> Save editor info only for project files.
?

Yes, I think packages should behave the same - but IMO they should have the same but independent option
-> Reopen packages only for project dependencies.

Ondrej

Reply by email

Michael Van Canneyt
to Ondrej Pokorny
Ondrej Pokorny wrote 21 lines
On 10.09.2015 10:25, Michael Van Canneyt wrote: > > > I am glad we agree :-) > > In general, I think this should also be settable on a per project basis. > > For the project session you can currently specify that only forms belonging > to the project should be included in the session. > (I always set this to on, because opening 100+ units at startup is really > counter-productive). > > I think the same should be done for packages: packages that are in the > project dependencies > and were open the last time the project was open, should be opened again. > > Or all packages should be opened. Are you refering to the Project Options -> Session -> -> Save editor info only for project files. ?

Yes.

Yes, I think packages should behave the same - but IMO they should have the same but independent option -> Reopen packages only for project dependencies.

Exactly.

Michael.

Reply by email

Mattias Gaertner
to Ondrej Pokorny: In this case, it should be handled outside the desktops feature the same like a project…
Show quoted text 6 lines
[...] 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).

Well, since a project has more than a package (e.g. session and macro values) it would be more "a project is a package".

Please test the attached patch.

Thanks. Applied.

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.

The "most users" argument is seldom good.
There are basically two groups of users. Those who want a fresh IDE when starting and those who want to continue where they stopped working. I don't think we need another option. Keep it simple and stupid and change "Open last project on start" to "Open last project and packages at start".
When project groups arrive this option will probably become "Open last project, groups and packages at start."

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.

Fine with me.

Mattias

Reply by email

Mattias Gaertner
to Michael Van Canneyt: I am glad we agree :-) In general, I think this should also be settable on a per project…
[...] For the project session you can currently specify that only forms belonging to the project should be included in the session. (I always set this to on, because opening 100+ units at startup is really counter-productive).

I'm not sure if you are mixing things up or if you found a bug. The IDE only reopens what you had open.
The global option "Open designer when open unit" automatically opens the designer form when opening a form unit.
The project option "Save editor info only for project files" stores for non project files the editor position (e.g. caret, bookmarks, foldings) and if the file was open in the source editor.

I think the same should be done for packages: packages that are in the project dependencies and were open the last time the project was open, should be opened again. Or all packages should be opened.

I fail to imagine that someone wants to open all package editors.

Mattias

Reply by email

Michael Van Canneyt
to Mattias Gaertner
Mattias Gaertner wrote 10 lines
On Thu, 10 Sep 2015 10:25:15 +0200 (CEST) Michael Van Canneyt wrote: > [...] > For the project session you can currently specify that only forms belonging > to the project should be included in the session. > (I always set this to on, because opening 100+ units at startup is really counter-productive). I'm not sure if you are mixing things up or if you found a bug. The IDE only reopens what you had open.

Not if "Save editor info only for project files" was set ? I just tested.
1. Project open: some files are loaded.
2. open some additional files.
3. Reopen project: only files opened in step 1 are re-opened.

This is as it should be IMHO.

Show quoted text 14 lines
The global option "Open designer when open unit" automatically opens the designer form when opening a form unit. The project option "Save editor info only for project files" stores for non project files the editor position (e.g. caret, bookmarks, foldings) and if the file was open in the source editor. > I think the same should be done for packages: packages that are in the project dependencies > and were open the last time the project was open, should be opened again. > > Or all packages should be opened. I fail to imagine that someone wants to open all package editors.

Me too :)
I was imprecise, it should have been: 'all previously opened packages should be opened'

Michael.

Reply by email

Ondrej Pokorny
to Mattias Gaertner: On Thu, 10 Sep 2015 09:30:00 +0200 Well, since a project has more than a package (e.g.…
Mattias Gaertner wrote 17 lines
Please test the attached patch. Thanks. Applied. > 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. The "most users" argument is seldom good. There are basically two groups of users. Those who want a fresh IDE when starting and those who want to continue where they stopped working. I don't think we need another option. Keep it simple and stupid and change "Open last project on start" to "Open last project and packages at start". When project groups arrive this option will probably become "Open last project, groups and packages at start."

You are right. Let's not blow up the settings with unnecessary options. I'll revert this back and use the same option for both editor files and packages.
You can wait with the commit if you have objections in order not to have a lot of commits about one patch.

I'll also take the Project Environment setting into account as Michael suggested (but rename it and use only one for that).

Ondrej

Reply by email

Graeme Geldenhuys
to Ondrej Pokorny: Let's keep it easy and don't reopen/close package windows in desktop change. Package is…
Ondrej Pokorny wrote
BTW. I heard some rumours that project groups should be supported at some point (?) - the same modern Delphi has.

Modern Delphi? Project Groups have been in Delphi since Delphi 5 (circa
1999) days I believe. It definitely is available in my Delphi 7 (circa
2002) which I still use on occasion.

Project Groups in Lazarus IDE is a top wishlist item of mine. I work with huge projects (multiple packages and projects) all the time, and no project groups is a huge downside of both Lazarus and MSEide.

Regards,
- Graeme -

Reply by email

Mattias Gaertner
to Michael Van Canneyt: Not if "Save editor info only for project files" was set ? I just tested. 1. Project…
Show quoted text 16 lines
On Thu, 10 Sep 2015, Mattias Gaertner wrote: > On Thu, 10 Sep 2015 10:25:15 +0200 (CEST) > Michael Van Canneyt wrote: > >> [...] >> For the project session you can currently specify that only forms belonging >> to the project should be included in the session. >> (I always set this to on, because opening 100+ units at startup is really counter-productive). > > I'm not sure if you are mixing things up or if you found a bug. > The IDE only reopens what you had open. Not if "Save editor info only for project files" was set ?

I should word more carefully:
The IDE reopens no more than what you had open. It can be less.

Show quoted text 5 lines
I just tested. 1. Project open: some files are loaded. 2. open some additional files. 3. Reopen project: only files opened in step 1 are re-opened. This is as it should be IMHO.

Yes.
When you wrote about "counter productive" opening 100+ units I was worried it opens the wrong files.

Mattias

Reply by email

Ondrej Pokorny
to Michael Van Canneyt: I am glad we agree :-) In general, I think this should also be settable on a per project…
Michael Van Canneyt wrote 11 lines
I think the same should be done for packages: packages that are in the project dependencies and were open the last time the project was open, should be opened again. Or all packages should be opened. Anyway, I will test your patch in the weekend (presumably there will still be some changes by then). Michael.

I checked into this and I don't think now it is possible/reasonable. Because:
*Packages are independent of the current project. When you open another project, the package editors don't change.*

So they should be independent of the project during the IDE startup as well.

If you create a link between packages and project, it's about the same as the link project group <-> packages that you don't like at all, as you stated.

Ondrej
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus.freepascal.org/pipermail/lazarus/attachments/20150910/9348cb95/attachment.html>

Reply by email

Michael Van Canneyt
to Mattias Gaertner: On Thu, 10 Sep 2015 11:23:37 +0200 (CEST) I should word more carefully: The IDE reopens…
Mattias Gaertner wrote 22 lines
On Thu, 10 Sep 2015 11:23:37 +0200 (CEST) Michael Van Canneyt wrote: > > > On Thu, 10 Sep 2015, Mattias Gaertner wrote: > >> On Thu, 10 Sep 2015 10:25:15 +0200 (CEST) >> Michael Van Canneyt wrote: >> >>> [...] >>> For the project session you can currently specify that only forms belonging >>> to the project should be included in the session. >>> (I always set this to on, because opening 100+ units at startup is really counter-productive). >> >> I'm not sure if you are mixing things up or if you found a bug. >> The IDE only reopens what you had open. > > Not if "Save editor info only for project files" was set ? I should word more carefully: The IDE reopens no more than what you had open. It can be less.

That seems an accurate statement :)

Show quoted text 10 lines
> I just tested. > 1. Project open: some files are loaded. > 2. open some additional files. > 3. Reopen project: only files opened in step 1 are re-opened. > This is as it should be IMHO. Yes. When you wrote about "counter productive" opening 100+ units I was worried it opens the wrong files.

Nono.
Sorry if it was interpreted that way. During the course of a debug/develop session, I sometimes have 100 units open. It's not uncommon, and I simply don't want them all reloaded the next session...

Michael.

Reply by email

Ondrej Pokorny
to Mattias Gaertner: On Thu, 10 Sep 2015 09:30:00 +0200 Well, since a project has more than a package (e.g.…
Mattias Gaertner wrote 7 lines
The "most users" argument is seldom good. There are basically two groups of users. Those who want a fresh IDE when starting and those who want to continue where they stopped working. I don't think we need another option. Keep it simple and stupid and change "Open last project on start" to "Open last project and packages at start". When project groups arrive this option will probably become "Open last project, groups and packages at start."

I removed the extra settings as you suggested. I decided not to rename the variable/check box. I only changed the caption. See patch. If you think the OpenLastProjectAtStart variable should be renamed as well, I am sure you can do it easily.

Ondrej
-------------- next part --------------
Index: ide/environmentopts.pp
=================================================================== --- ide/environmentopts.pp (revision 49804)
+++ ide/environmentopts.pp (working copy)
@@ -475,7 +475,6 @@

     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;
@@ -729,8 +728,6 @@
     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
@@ -1311,7 +1308,6 @@
   FRecentPackageFiles:=TStringList.Create;
   FMaxRecentPackageFiles:=DefaultMaxRecentPackageFiles;
   FOpenLastProjectAtStart:=true;
-  FOpenPackagesAtStart:=true;
   // backup
   with FBackupInfoProjectFiles do begin

@@ -1616,12 +1612,11 @@

     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
+ if FOpenLastProjectAtStart then

     begin
       i := 1;
       repeat

@@ -1946,9 +1941,8 @@

     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
+ if FOpenLastProjectAtStart 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]);

Index: ide/frames/files_options.lfm
=================================================================== --- ide/frames/files_options.lfm (revision 49804)
+++ ide/frames/files_options.lfm (working copy)
@@ -43,17 +43,16 @@
Width = 195
BorderSpacing.Top = 6
Caption = 'OpenLastProjectAtStartCheckBox'
- OnChange = OpenLastProjectAtStartCheckBoxChange TabOrder = 0

   end
   object ShowCompileDialogCheckBox: TCheckBox
     AnchorSideLeft.Control = Owner

- AnchorSideTop.Control = OpenPackagesAtStartCheckBox
+ AnchorSideTop.Control = OpenLastProjectAtStartCheckBox AnchorSideTop.Side = asrBottom
AnchorSideRight.Side = asrBottom
Left = 2
Height = 19
- Top = 88
+ Top = 69
Width = 180
BorderSpacing.Top = 2
Caption = 'ShowCompileDialogCheckBox'
@@ -66,7 +65,7 @@
AnchorSideTop.Side = asrBottom
Left = 2
Height = 15
- Top = 136
+ Top = 117
Width = 82
BorderSpacing.Top = 10
Caption = 'LazarusDirLabel'
@@ -81,7 +80,7 @@
AnchorSideBottom.Side = asrBottom
Left = 542
Height = 23
- Top = 151
+ Top = 132
Width = 25
Anchors = [akTop, akRight, akBottom]
Caption = '...'
@@ -95,7 +94,7 @@
AnchorSideRight.Control = LazarusDirButton
Left = 2
Height = 23
- Top = 151
+ Top = 132
Width = 540
Anchors = [akTop, akLeft, akRight]
ItemHeight = 15
@@ -109,7 +108,7 @@
AnchorSideRight.Control = CompilerPathButton
Left = 2
Height = 23
- Top = 195
+ Top = 176
Width = 540
Anchors = [akTop, akLeft, akRight]
ItemHeight = 15
@@ -124,7 +123,7 @@
AnchorSideBottom.Side = asrBottom
Left = 542
Height = 23
- Top = 195
+ Top = 176
Width = 25
Anchors = [akTop, akRight, akBottom]
Caption = '...'
@@ -137,7 +136,7 @@
AnchorSideTop.Side = asrBottom
Left = 2
Height = 15
- Top = 180
+ Top = 161
Width = 101
BorderSpacing.Top = 6
Caption = 'CompilerPathLabel'
@@ -150,7 +149,7 @@
AnchorSideRight.Control = FPCSourceDirButton
Left = 2
Height = 23
- Top = 239
+ Top = 220
Width = 540
Anchors = [akTop, akLeft, akRight]
ItemHeight = 15
@@ -165,7 +164,7 @@
AnchorSideBottom.Side = asrBottom
Left = 542
Height = 23
- Top = 239
+ Top = 220
Width = 25
Anchors = [akTop, akRight, akBottom]
Caption = '...'
@@ -178,7 +177,7 @@
AnchorSideTop.Side = asrBottom
Left = 2
Height = 15
- Top = 224
+ Top = 205
Width = 100
BorderSpacing.Top = 6
Caption = 'FPCSourceDirLabel'
@@ -190,7 +189,7 @@
AnchorSideTop.Side = asrBottom
Left = 2
Height = 15
- Top = 268
+ Top = 249
Width = 81
BorderSpacing.Top = 6
Caption = 'MakePathLabel'
@@ -202,7 +201,7 @@
AnchorSideTop.Side = asrBottom
Left = 2
Height = 15
- Top = 312
+ Top = 293
Width = 91
BorderSpacing.Top = 6
Caption = 'TestBuildDirLabel'
@@ -215,7 +214,7 @@
AnchorSideRight.Control = MakePathButton
Left = 2
Height = 23
- Top = 283
+ Top = 264
Width = 540
Anchors = [akTop, akLeft, akRight]
ItemHeight = 15
@@ -230,7 +229,7 @@
AnchorSideBottom.Side = asrBottom
Left = 542
Height = 23
- Top = 283
+ Top = 264
Width = 25
Anchors = [akTop, akRight, akBottom]
Caption = '...'
@@ -244,7 +243,7 @@
AnchorSideRight.Control = TestBuildDirButton
Left = 2
Height = 23
- Top = 327
+ Top = 308
Width = 540
Anchors = [akTop, akLeft, akRight]
ItemHeight = 15
@@ -259,7 +258,7 @@
AnchorSideBottom.Side = asrBottom
Left = 542
Height = 23
- Top = 327
+ Top = 308
Width = 25
Anchors = [akTop, akRight, akBottom]
Caption = '...'
@@ -273,7 +272,7 @@
AnchorSideRight.Side = asrBottom
Left = 32
Height = 19
- Top = 107
+ Top = 88
Width = 206
BorderSpacing.Left = 30
Caption = 'AutoCloseCompileDialogCheckBox'
@@ -285,7 +284,7 @@
AnchorSideTop.Side = asrBottom
Left = 2
Height = 15
- Top = 356
+ Top = 337
Width = 153
Alignment = taRightJustify
BorderSpacing.Top = 6
@@ -302,7 +301,7 @@
AnchorSideBottom.Side = asrBottom
Left = 542
Height = 23
- Top = 371
+ Top = 352
Width = 25
Anchors = [akTop, akRight, akBottom]
Caption = '...'
@@ -318,7 +317,7 @@
AnchorSideRight.Control = CompilerTranslationFileButton Left = 2
Height = 23
- Top = 371
+ Top = 352
Width = 540
Anchors = [akTop, akLeft, akRight]
ItemHeight = 15
@@ -366,17 +365,4 @@
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 49804)
+++ ide/frames/files_options.pas (working copy)
@@ -61,7 +61,6 @@

     MaxRecentProjectFilesSpin: TSpinEdit;
     MaxRecentProjectFilesLabel: TLabel;
     OpenLastProjectAtStartCheckBox: TCheckBox;

- OpenPackagesAtStartCheckBox: TCheckBox;

     ShowCompileDialogCheckBox: TCheckBox;
     TestBuildDirButton:TButton;
     TestBuildDirComboBox:TComboBox;

@@ -69,7 +68,6 @@

     procedure CompilerTranslationFileButtonClick(Sender:TObject);
     procedure FilesButtonClick(Sender: TObject);
     procedure DirectoriesButtonClick(Sender: TObject);

- procedure OpenLastProjectAtStartCheckBoxChange(Sender: TObject);

     procedure ShowCompileDialogCheckBoxChange(Sender: TObject);
   private
     FOldLazarusDir: string;

@@ -222,7 +220,6 @@

   MaxRecentOpenFilesLabel.Caption:=dlgMaxRecentFiles;
   MaxRecentProjectFilesLabel.Caption:=dlgMaxRecentProjs;
   OpenLastProjectAtStartCheckBox.Caption:=dlgQOpenLastPrj;

- OpenPackagesAtStartCheckBox.Caption:=dlgQOpenPackages;

   ShowCompileDialogCheckBox.Visible:=false;
   AutoCloseCompileDialogCheckBox.Visible:=false;
   LazarusDirLabel.Caption:=dlgLazarusDir;

@@ -275,12 +272,6 @@

   Result := dlgEnvFiles;

end;

-procedure TFilesOptionsFrame.OpenLastProjectAtStartCheckBoxChange(
-  Sender: TObject);
-begin
-  OpenPackagesAtStartCheckBox.Enabled := OpenLastProjectAtStartCheckBox.Checked;
-end;
-
 function TFilesOptionsFrame.Check: Boolean;
 begin
   Result := False;
@@ -369,7 +360,6 @@
     // open last project at start
     OpenLastProjectAtStartCheckBox.Checked:=OpenLastProjectAtStart;
-    OpenPackagesAtStartCheckBox.Checked:=OpenPackagesAtStart;
     // compile dialog
     fOldShowCompileDialog:=ShowCompileDialog;
@@ -401,7 +391,6 @@
     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 49804)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -1338,8 +1338,7 @@
   dlgEnvOtherFiles = 'Other Files';
   dlgMaxRecentFiles = 'Max recent files';
   dlgMaxRecentProjs = 'Max recent project files';
-  dlgQOpenLastPrj = 'Open last project at start';
-  dlgQOpenPackages = 'Open packages';
+  dlgQOpenLastPrj = 'Open last project and packages at start';
   dlgLazarusDir = 'Lazarus directory (default for all projects)';
   dlgFpcExecutable = 'Compiler executable (e.g. %s)';
   dlgFpcSrcPath = 'FPC source directory';
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 49804)
+++ ide/main.pp	(working copy)
@@ -2221,21 +2221,18 @@
         IDEProtocolOpts.Save;
         if ProjectLoaded then
         begin
-          if EnvironmentOptions.OpenPackagesAtStart then
+          PkgOpenFlags:=[pofAddToRecent];
+          for I := 0 to EnvironmentOptions.LastOpenPackages.Count-1 do
           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;
+            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 else

Reply by email

Mattias Gaertner
to Ondrej Pokorny
Show quoted text 11 lines
On 10.09.2015 11:03, Mattias Gaertner wrote: > The "most users" argument is seldom good. There are basically two > groups of users. Those who want a fresh IDE when starting and those > who want to continue where they stopped working. I don't think we need > another option. Keep it simple and stupid and change "Open last > project on start" to "Open last project and packages at start". When > project groups arrive this option will probably become "Open last > project, groups and packages at start." I removed the extra settings as you suggested. I decided not to rename the variable/check box. I only changed the caption. See patch.

Thanks.

Mattias

Reply by email