View Issue Details

IDProjectCategoryView StatusLast Update
0035883PatchesPatchpublic2019-09-11 20:15
ReporterFTurtleAssigned To 
PrioritynormalSeverityminorReproducibilityN/A
Status newResolutionopen 
Product Version2.1 (SVN)Product Build61618 
Target VersionFixed in Version 
Summary0035883: New toolbutton command "Open Recent Project"
Description1. New toolbutton command "Open Recent Project"
2. Section with arrow for toolbutton "Open Project"
3. Separate popup menu by shortcut (shortcut not assigned by default)
4. Few new classes which later will replace some number of old classes.
TagsNo tags attached.
Fixed in Revision
LazTarget
Widgetset
Attached Files
  • patch.diff (10,114 bytes)
    Index: components/ideintf/idecommands.pas
    ===================================================================
    --- components/ideintf/idecommands.pas	(revision 61618)
    +++ components/ideintf/idecommands.pas	(working copy)
    @@ -302,19 +302,20 @@
       ecNewProject              = ecFirstLazarus + 500;
       ecNewProjectFromFile      = ecFirstLazarus + 501;
       ecOpenProject             = ecFirstLazarus + 502;
    -  ecCloseProject            = ecFirstLazarus + 503;
    -  ecSaveProject             = ecFirstLazarus + 504;
    -  ecSaveProjectAs           = ecFirstLazarus + 505;
    -  ecPublishProject          = ecFirstLazarus + 506;
    -  ecProjectInspector        = ecFirstLazarus + 507;
    -  ecAddCurUnitToProj        = ecFirstLazarus + 508;
    -  ecRemoveFromProj          = ecFirstLazarus + 509;
    -  ecViewProjectUnits        = ecFirstLazarus + 510;
    -  ecViewProjectForms        = ecFirstLazarus + 511;
    -  ecViewProjectSource       = ecFirstLazarus + 512;
    -  ecProjectOptions          = ecFirstLazarus + 513;
    -  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
    -  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
    +  ecOpenRecentProject       = ecFirstLazarus + 503;
    +  ecCloseProject            = ecFirstLazarus + 504;
    +  ecSaveProject             = ecFirstLazarus + 505;
    +  ecSaveProjectAs           = ecFirstLazarus + 506;
    +  ecPublishProject          = ecFirstLazarus + 507;
    +  ecProjectInspector        = ecFirstLazarus + 508;
    +  ecAddCurUnitToProj        = ecFirstLazarus + 509;
    +  ecRemoveFromProj          = ecFirstLazarus + 510;
    +  ecViewProjectUnits        = ecFirstLazarus + 511;
    +  ecViewProjectForms        = ecFirstLazarus + 512;
    +  ecViewProjectSource       = ecFirstLazarus + 513;
    +  ecProjectOptions          = ecFirstLazarus + 514;
    +  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
    +  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
     
       // package menu
       ecOpenPackage             = ecFirstLazarus + 600;
    Index: components/ideintf/toolbarintf.pas
    ===================================================================
    --- components/ideintf/toolbarintf.pas	(revision 61618)
    +++ components/ideintf/toolbarintf.pas	(working copy)
    @@ -18,7 +18,7 @@
     uses
       Classes, SysUtils,
       // LCL
    -  Controls, ComCtrls, Menus, Forms,
    +  Controls, ComCtrls, Menus, Forms, LCLType,
       // IdeIntf
       IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
     
    @@ -29,6 +29,7 @@
     
       TIDEButtonCommand = class(TIDESpecialCommand)
       private
    +    FTag: PtrInt;
         FToolButtonClass: TIDEToolButtonClass;
         FToolButtons: TIDEToolButtons;
       protected
    @@ -46,6 +47,7 @@
         constructor Create(const TheName: string); override;
         destructor Destroy; override;
       public
    +    property Tag: PtrInt read FTag write FTag;
         property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
         property ToolButtons: TIDEToolButtons read FToolButtons;
       end;
    @@ -64,7 +66,7 @@
         property Item: TIDEButtonCommand read FItem write FItem;
       end;
     
    -  { TIDEToolButtonWithArrow }
    +{ TIDEToolButtonWithArrow }  // will be removed with descendants after complete switching on use TIDEToolButton_WithArrow
     
       TIDEToolButtonWithArrow = class(TIDEToolButton)
       protected
    @@ -93,7 +95,39 @@
         procedure DoOnAdded; override;
       end;
     
    +  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
    +  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButtonButtonDrop;
    +  TIDEToolButton_DropDown_Class = class of TIDEToolButtonDropDown;
     
    +  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
    +
    +  TIDEToolButton_WithArrow = class(TIDEToolButton)
    +  private
    +    function GetSection: TIDEMenuSection;
    +  protected
    +    procedure DoOnMenuPopup(Sender: TObject);
    +    procedure RefreshMenu; virtual;
    +    property Section: TIDEMenuSection read GetSection;
    +  public
    +    constructor Create(AOwner: TComponent); override;
    +  end;
    +
    +  { TIDEToolButtonDropDown }    // [  ][▼]
    +
    +  TIDEToolButtonDropDown = class(TIDEToolButton_WithArrow)
    +  public
    +    procedure DoOnAdded; override;
    +  end;
    +
    +  { TIDEToolButtonButtonDrop }    // [ ▼]
    +
    +  TIDEToolButtonButtonDrop = class(TIDEToolButton_WithArrow)
    +  protected
    +    procedure PopUpAloneMenu(Sender: TObject);
    +  public
    +    procedure DoOnAdded; override;
    +  end;
    +
       TIDEToolButtonCategory = class
       private
         FButtons: TFPList;
    @@ -171,6 +205,7 @@
       const aCommand: TIDECommand): TIDEButtonCommand;
     function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
     
    +
     implementation
     
     function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
    @@ -276,6 +311,65 @@
       Style := tbsDropDown;  // not in constructor
     end;
     
    +{ TIDEToolButton_WithArrow }
    +
    +constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
    +begin
    +  inherited Create(AOwner);
    +  DropdownMenu := TPopupMenu.Create(Self);
    +  DropdownMenu.Images := IDEImages.Images_16;
    +  DropdownMenu.OnPopup := @DoOnMenuPopup;
    +end;
    +
    +function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
    +begin
    +  Result:=nil;
    +  if (Item<>nil) then
    +    if (Item.Command<>nil) then
    +      Result:=TIDEMenuSection(Item.Tag);
    +end;
    +
    +procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
    +begin
    +  DropdownMenu.Items.Clear;
    +  RefreshMenu;
    +end;
    +
    +procedure TIDEToolButton_WithArrow.RefreshMenu;
    +begin
    +  if Section<>nil then
    +    DropdownMenu.Items.Assign(Section.MenuItem);
    +end;
    +
    +{ TIDEToolButtonDropDown }
    +
    +procedure TIDEToolButtonDropDown.DoOnAdded;
    +begin
    +  Style := tbsDropDown;  // not in constructor
    +end;
    +
    +{ TIDEToolButtonButtonDrop }
    +
    +procedure TIDEToolButtonButtonDrop.DoOnAdded;
    +begin
    +  Style := tbsButtonDrop;  // not in constructor
    +  if (Item<>nil) then
    +    if (Item.Command<>nil) then
    +      Item.Command.OnExecute:=@PopUpAloneMenu;
    +end;
    +
    +procedure TIDEToolButtonButtonDrop.PopUpAloneMenu(Sender: TObject);
    +var
    +  ActiveEditor: TSourceEditorInterface;
    +  ScreenXY: TPoint;
    +begin
    +  ActiveEditor := SourceEditorManagerIntf.ActiveEditor;
    +  if ActiveEditor=nil then
    +    Exit;
    +  ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
    +  DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
    +end;
    +
     { TIDEToolButtonsEnumerator }
     
     constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
    Index: ide/keymapping.pp
    ===================================================================
    --- ide/keymapping.pp	(revision 61618)
    +++ ide/keymapping.pp	(working copy)
    @@ -652,6 +652,7 @@
         ecNewProject              : Result:= lisMenuNewProject;
         ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
         ecOpenProject             : Result:= lisMenuOpenProject;
    +    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
         ecCloseProject            : Result:= lisMenuCloseProject;
         ecSaveProject             : Result:= lisMenuSaveProject;
         ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
    @@ -3074,6 +3075,7 @@
       AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
       AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
       AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
    +  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
       AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
       AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
       AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
    Index: ide/lazarusidestrconsts.pas
    ===================================================================
    --- ide/lazarusidestrconsts.pas	(revision 61618)
    +++ ide/lazarusidestrconsts.pas	(working copy)
    @@ -252,6 +252,7 @@
       lisPathOfTheMakeUtility = 'Path of the make utility';
       lisProjectMacroProperties = 'Project macro properties';
       lisOpenProject2 = 'Open project';
    +  lisKMOpenRecentProject = 'Open recent project';
       lisFileHasNoProject = 'File has no project';
       lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
          'The file "%s" is not a Lazarus project.'
    Index: ide/main.pp
    ===================================================================
    --- ide/main.pp	(revision 61618)
    +++ ide/main.pp	(working copy)
    @@ -2891,6 +2891,37 @@
           ToolButton.ToolButtonClass := ToolButtonClass;
       end;
     
    +  function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;
    +             AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
    +  var
    +    ButtonCommand: TIDEButtonCommand;
    +  begin
    +    Result:=IDECommandList.FindIDECommand(ACommand);
    +    if Result=nil then
    +      Exit(nil);
    +    ButtonCommand:=RegisterIDEButtonCommand(Result);
    +    ButtonCommand.ToolButtonClass:=AButtonClass;
    +    if AButtonClass.InheritsFrom(TIDEToolButtonButtonDrop) then
    +      ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
    +    ButtonCommand.Tag:=PtrInt(AMenuSection);
    +  end;
    +
    +  function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
    +      AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
    +  begin
    +    if AButtonClass=nil then
    +      AButtonClass:=TIDEToolButtonDropDown;
    +    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +  end;
    +
    +  function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
    +      AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
    +  begin
    +    if AButtonClass=nil then
    +      AButtonClass:=TIDEToolButtonButtonDrop;
    +    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +  end;
    +
     var
       xBtnItem: TIDEButtonCommand;
     begin
    @@ -3045,7 +3076,8 @@
         // project menu
         itmProjectNew.Command:=GetCommand(ecNewProject);
         itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
    -    itmProjectOpen.Command:=GetCommand(ecOpenProject);
    +    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
    +    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
         itmProjectClose.Command:=GetCommand(ecCloseProject);
         itmProjectSave.Command:=GetCommand(ecSaveProject);
         itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
    
    patch.diff (10,114 bytes)
  • pic1.png (17,593 bytes)
    pic1.png (17,593 bytes)
  • pic2.png (19,058 bytes)
    pic2.png (19,058 bytes)
  • pic3.png (16,646 bytes)
    pic3.png (16,646 bytes)
  • patch2.diff (15,122 bytes)
    Index: components/ideintf/idecommands.pas
    ===================================================================
    --- components/ideintf/idecommands.pas	(revision 61618)
    +++ components/ideintf/idecommands.pas	(working copy)
    @@ -302,31 +302,33 @@
       ecNewProject              = ecFirstLazarus + 500;
       ecNewProjectFromFile      = ecFirstLazarus + 501;
       ecOpenProject             = ecFirstLazarus + 502;
    -  ecCloseProject            = ecFirstLazarus + 503;
    -  ecSaveProject             = ecFirstLazarus + 504;
    -  ecSaveProjectAs           = ecFirstLazarus + 505;
    -  ecPublishProject          = ecFirstLazarus + 506;
    -  ecProjectInspector        = ecFirstLazarus + 507;
    -  ecAddCurUnitToProj        = ecFirstLazarus + 508;
    -  ecRemoveFromProj          = ecFirstLazarus + 509;
    -  ecViewProjectUnits        = ecFirstLazarus + 510;
    -  ecViewProjectForms        = ecFirstLazarus + 511;
    -  ecViewProjectSource       = ecFirstLazarus + 512;
    -  ecProjectOptions          = ecFirstLazarus + 513;
    -  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
    -  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
    +  ecOpenRecentProject       = ecFirstLazarus + 503;
    +  ecCloseProject            = ecFirstLazarus + 504;
    +  ecSaveProject             = ecFirstLazarus + 505;
    +  ecSaveProjectAs           = ecFirstLazarus + 506;
    +  ecPublishProject          = ecFirstLazarus + 507;
    +  ecProjectInspector        = ecFirstLazarus + 508;
    +  ecAddCurUnitToProj        = ecFirstLazarus + 509;
    +  ecRemoveFromProj          = ecFirstLazarus + 510;
    +  ecViewProjectUnits        = ecFirstLazarus + 511;
    +  ecViewProjectForms        = ecFirstLazarus + 512;
    +  ecViewProjectSource       = ecFirstLazarus + 513;
    +  ecProjectOptions          = ecFirstLazarus + 514;
    +  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
    +  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
     
       // package menu
       ecOpenPackage             = ecFirstLazarus + 600;
       ecOpenPackageFile         = ecFirstLazarus + 601;
       ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
    -  ecAddCurFileToPkg         = ecFirstLazarus + 603;
    -  ecNewPkgComponent         = ecFirstLazarus + 604;
    -  ecPackageGraph            = ecFirstLazarus + 605;
    -  ecPackageLinks            = ecFirstLazarus + 606;
    -  ecEditInstallPkgs         = ecFirstLazarus + 607;
    -  ecConfigCustomComps       = ecFirstLazarus + 608;
    -  ecNewPackage              = ecFirstLazarus + 609;
    +  ecOpenRecentPackage       = ecFirstLazarus + 603;
    +  ecAddCurFileToPkg         = ecFirstLazarus + 604;
    +  ecNewPkgComponent         = ecFirstLazarus + 605;
    +  ecPackageGraph            = ecFirstLazarus + 606;
    +  ecPackageLinks            = ecFirstLazarus + 607;
    +  ecEditInstallPkgs         = ecFirstLazarus + 608;
    +  ecConfigCustomComps       = ecFirstLazarus + 609;
    +  ecNewPackage              = ecFirstLazarus + 610;
     
       // custom tools menu
       ecExtToolFirst            = ecFirstLazarus + 700;
    Index: components/ideintf/toolbarintf.pas
    ===================================================================
    --- components/ideintf/toolbarintf.pas	(revision 61618)
    +++ components/ideintf/toolbarintf.pas	(working copy)
    @@ -18,7 +18,7 @@
     uses
       Classes, SysUtils,
       // LCL
    -  Controls, ComCtrls, Menus, Forms,
    +  Controls, ComCtrls, Menus, Forms, LCLType,
       // IdeIntf
       IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
     
    @@ -29,6 +29,7 @@
     
       TIDEButtonCommand = class(TIDESpecialCommand)
       private
    +    FTag: PtrInt;
         FToolButtonClass: TIDEToolButtonClass;
         FToolButtons: TIDEToolButtons;
       protected
    @@ -46,6 +47,7 @@
         constructor Create(const TheName: string); override;
         destructor Destroy; override;
       public
    +    property Tag: PtrInt read FTag write FTag;
         property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
         property ToolButtons: TIDEToolButtons read FToolButtons;
       end;
    @@ -64,7 +66,7 @@
         property Item: TIDEButtonCommand read FItem write FItem;
       end;
     
    -  { TIDEToolButtonWithArrow }
    +{ TIDEToolButtonWithArrow }  // will be removed with descendants after complete switching on use TIDEToolButton_WithArrow
     
       TIDEToolButtonWithArrow = class(TIDEToolButton)
       protected
    @@ -93,7 +95,39 @@
         procedure DoOnAdded; override;
       end;
     
    +  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
    +  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButtonButtonDrop;
    +  TIDEToolButton_DropDown_Class = class of TIDEToolButtonDropDown;
     
    +  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
    +
    +  TIDEToolButton_WithArrow = class(TIDEToolButton)
    +  private
    +    function GetSection: TIDEMenuSection;
    +  protected
    +    procedure DoOnMenuPopup(Sender: TObject);
    +    procedure RefreshMenu; virtual;
    +    property Section: TIDEMenuSection read GetSection;
    +  public
    +    constructor Create(AOwner: TComponent); override;
    +  end;
    +
    +  { TIDEToolButtonDropDown }    // [  ][▼]
    +
    +  TIDEToolButtonDropDown = class(TIDEToolButton_WithArrow)
    +  public
    +    procedure DoOnAdded; override;
    +  end;
    +
    +  { TIDEToolButtonButtonDrop }    // [ ▼]
    +
    +  TIDEToolButtonButtonDrop = class(TIDEToolButton_WithArrow)
    +  protected
    +    procedure PopUpAloneMenu(Sender: TObject);
    +  public
    +    procedure DoOnAdded; override;
    +  end;
    +
       TIDEToolButtonCategory = class
       private
         FButtons: TFPList;
    @@ -171,6 +205,7 @@
       const aCommand: TIDECommand): TIDEButtonCommand;
     function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
     
    +
     implementation
     
     function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
    @@ -276,6 +311,65 @@
       Style := tbsDropDown;  // not in constructor
     end;
     
    +{ TIDEToolButton_WithArrow }
    +
    +constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
    +begin
    +  inherited Create(AOwner);
    +  DropdownMenu := TPopupMenu.Create(Self);
    +  DropdownMenu.Images := IDEImages.Images_16;
    +  DropdownMenu.OnPopup := @DoOnMenuPopup;
    +end;
    +
    +function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
    +begin
    +  Result:=nil;
    +  if (Item<>nil) then
    +    if (Item.Command<>nil) then
    +      Result:=TIDEMenuSection(Item.Tag);
    +end;
    +
    +procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
    +begin
    +  DropdownMenu.Items.Clear;
    +  RefreshMenu;
    +end;
    +
    +procedure TIDEToolButton_WithArrow.RefreshMenu;
    +begin
    +  if Section<>nil then
    +    DropdownMenu.Items.Assign(Section.MenuItem);
    +end;
    +
    +{ TIDEToolButtonDropDown }
    +
    +procedure TIDEToolButtonDropDown.DoOnAdded;
    +begin
    +  Style := tbsDropDown;  // not in constructor
    +end;
    +
    +{ TIDEToolButtonButtonDrop }
    +
    +procedure TIDEToolButtonButtonDrop.DoOnAdded;
    +begin
    +  Style := tbsButtonDrop;  // not in constructor
    +  if (Item<>nil) then
    +    if (Item.Command<>nil) then
    +      Item.Command.OnExecute:=@PopUpAloneMenu;
    +end;
    +
    +procedure TIDEToolButtonButtonDrop.PopUpAloneMenu(Sender: TObject);
    +var
    +  ActiveEditor: TSourceEditorInterface;
    +  ScreenXY: TPoint;
    +begin
    +  ActiveEditor := SourceEditorManagerIntf.ActiveEditor;
    +  if ActiveEditor=nil then
    +    Exit;
    +  ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
    +  DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
    +end;
    +
     { TIDEToolButtonsEnumerator }
     
     constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
    Index: ide/keymapping.pp
    ===================================================================
    --- ide/keymapping.pp	(revision 61618)
    +++ ide/keymapping.pp	(working copy)
    @@ -652,6 +652,7 @@
         ecNewProject              : Result:= lisMenuNewProject;
         ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
         ecOpenProject             : Result:= lisMenuOpenProject;
    +    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
         ecCloseProject            : Result:= lisMenuCloseProject;
         ecSaveProject             : Result:= lisMenuSaveProject;
         ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
    @@ -705,6 +706,7 @@
         ecOpenPackage             : Result:= lisMenuOpenPackage;
         ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
         ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
    +    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
         ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
         ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
         ecPackageGraph            : Result:= lisMenuPackageGraph;
    @@ -3074,6 +3076,7 @@
       AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
       AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
       AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
    +  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
       AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
       AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
       AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
    @@ -3129,6 +3132,7 @@
       AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
       AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
       AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
    +  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
       AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
       AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
       AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
    Index: ide/lazarusidestrconsts.pas
    ===================================================================
    --- ide/lazarusidestrconsts.pas	(revision 61618)
    +++ ide/lazarusidestrconsts.pas	(working copy)
    @@ -252,6 +252,7 @@
       lisPathOfTheMakeUtility = 'Path of the make utility';
       lisProjectMacroProperties = 'Project macro properties';
       lisOpenProject2 = 'Open project';
    +  lisKMOpenRecentProject = 'Open recent project';
       lisFileHasNoProject = 'File has no project';
       lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
          'The file "%s" is not a Lazarus project.'
    @@ -4129,6 +4130,7 @@
       lisKMNewPackage = 'New package';
       lisCompPalOpenPackage = 'Open package';
       lisKMOpenPackageFile = 'Open package file';
    +  lisKMOpenRecentPackage = 'Open recent package';
       lisCPOpenPackage = 'Open Package %s';
       lisFilterAllMessagesOfType = 'Filter all messages of type %s';
       lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
    Index: ide/main.pp
    ===================================================================
    --- ide/main.pp	(revision 61618)
    +++ ide/main.pp	(working copy)
    @@ -2891,6 +2891,37 @@
           ToolButton.ToolButtonClass := ToolButtonClass;
       end;
     
    +  function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;
    +             AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
    +  var
    +    ButtonCommand: TIDEButtonCommand;
    +  begin
    +    Result:=IDECommandList.FindIDECommand(ACommand);
    +    if Result=nil then
    +      Exit(nil);
    +    ButtonCommand:=RegisterIDEButtonCommand(Result);
    +    ButtonCommand.ToolButtonClass:=AButtonClass;
    +    if AButtonClass.InheritsFrom(TIDEToolButtonButtonDrop) then
    +      ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
    +    ButtonCommand.Tag:=PtrInt(AMenuSection);
    +  end;
    +
    +  function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
    +      AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
    +  begin
    +    if AButtonClass=nil then
    +      AButtonClass:=TIDEToolButtonDropDown;
    +    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +  end;
    +
    +  function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
    +      AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
    +  begin
    +    if AButtonClass=nil then
    +      AButtonClass:=TIDEToolButtonButtonDrop;
    +    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +  end;
    +
     var
       xBtnItem: TIDEButtonCommand;
     begin
    @@ -3045,7 +3076,8 @@
         // project menu
         itmProjectNew.Command:=GetCommand(ecNewProject);
         itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
    -    itmProjectOpen.Command:=GetCommand(ecOpenProject);
    +    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
    +    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
         itmProjectClose.Command:=GetCommand(ecCloseProject);
         itmProjectSave.Command:=GetCommand(ecSaveProject);
         itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
    @@ -3091,8 +3123,9 @@
         // package menu
         itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
         itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
    -    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
    +    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
         itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
    +    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
         itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
         itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
         itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
    Index: ide/mainbase.pas
    ===================================================================
    --- ide/mainbase.pas	(revision 61618)
    +++ ide/mainbase.pas	(working copy)
    @@ -1409,7 +1409,7 @@
         CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
         CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
         CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
    -    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
    +    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
     
         CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
         ParentMI:=itmPkgUnits;
    Index: images/copyright.txt
    ===================================================================
    --- images/copyright.txt	(revision 61618)
    +++ images/copyright.txt	(working copy)
    @@ -169,6 +169,9 @@
     	state_warning_150.png
     	state_warning_200.png
     
    +packages directory
    +	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
    +
     --------------------------------------------------------------------------------
     
     The following component palette and menu/toolbar icons (including equally named
    Index: images/laz_images_list.txt
    ===================================================================
    --- images/laz_images_list.txt	(revision 61618)
    +++ images/laz_images_list.txt	(working copy)
    @@ -945,6 +945,9 @@
     packages/pkg_open.png
     packages/pkg_open_150.png
     packages/pkg_open_200.png
    +packages/pkg_open_recent.png
    +packages/pkg_open_recent_150.png
    +packages/pkg_open_recent_200.png
     packages/pkg_package_autoinstall.png
     packages/pkg_package_autoinstall_150.png
     packages/pkg_package_autoinstall_200.png
    
    patch2.diff (15,122 bytes)
  • images.zip (4,037 bytes)
  • patch3.diff (21,340 bytes)
    Index: components/ideintf/idecommands.pas
    ===================================================================
    --- components/ideintf/idecommands.pas	(revision 61623)
    +++ components/ideintf/idecommands.pas	(working copy)
    @@ -81,13 +81,14 @@
       ecFindBlockStart          = ecFirstLazarus + 22;
       ecOpenFileAtCursor        = ecFirstLazarus + 23;
       ecGotoIncludeDirective    = ecFirstLazarus + 24;
    -  ecJumpToInterface         = ecFirstLazarus + 25;
    -  ecJumpToInterfaceUses     = ecFirstLazarus + 26;
    -  ecJumpToImplementation    = ecFirstLazarus + 27;
    -  ecJumpToImplementationUses= ecFirstLazarus + 28;
    -  ecJumpToInitialization    = ecFirstLazarus + 29;
    -  ecJumpToProcedureHeader   = ecFirstLazarus + 30;
    -  ecJumpToProcedureBegin    = ecFirstLazarus + 31;
    +  ecJumpToSection           = ecFirstLazarus + 25;
    +  ecJumpToInterface         = ecFirstLazarus + 26;
    +  ecJumpToInterfaceUses     = ecFirstLazarus + 27;
    +  ecJumpToImplementation    = ecFirstLazarus + 28;
    +  ecJumpToImplementationUses= ecFirstLazarus + 29;
    +  ecJumpToInitialization    = ecFirstLazarus + 30;
    +  ecJumpToProcedureHeader   = ecFirstLazarus + 31;
    +  ecJumpToProcedureBegin    = ecFirstLazarus + 32;
     
       // edit selection
       ecSelectionUpperCase      = ecFirstLazarus + 50;
    @@ -302,31 +303,33 @@
       ecNewProject              = ecFirstLazarus + 500;
       ecNewProjectFromFile      = ecFirstLazarus + 501;
       ecOpenProject             = ecFirstLazarus + 502;
    -  ecCloseProject            = ecFirstLazarus + 503;
    -  ecSaveProject             = ecFirstLazarus + 504;
    -  ecSaveProjectAs           = ecFirstLazarus + 505;
    -  ecPublishProject          = ecFirstLazarus + 506;
    -  ecProjectInspector        = ecFirstLazarus + 507;
    -  ecAddCurUnitToProj        = ecFirstLazarus + 508;
    -  ecRemoveFromProj          = ecFirstLazarus + 509;
    -  ecViewProjectUnits        = ecFirstLazarus + 510;
    -  ecViewProjectForms        = ecFirstLazarus + 511;
    -  ecViewProjectSource       = ecFirstLazarus + 512;
    -  ecProjectOptions          = ecFirstLazarus + 513;
    -  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
    -  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
    +  ecOpenRecentProject       = ecFirstLazarus + 503;
    +  ecCloseProject            = ecFirstLazarus + 504;
    +  ecSaveProject             = ecFirstLazarus + 505;
    +  ecSaveProjectAs           = ecFirstLazarus + 506;
    +  ecPublishProject          = ecFirstLazarus + 507;
    +  ecProjectInspector        = ecFirstLazarus + 508;
    +  ecAddCurUnitToProj        = ecFirstLazarus + 509;
    +  ecRemoveFromProj          = ecFirstLazarus + 510;
    +  ecViewProjectUnits        = ecFirstLazarus + 511;
    +  ecViewProjectForms        = ecFirstLazarus + 512;
    +  ecViewProjectSource       = ecFirstLazarus + 513;
    +  ecProjectOptions          = ecFirstLazarus + 514;
    +  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
    +  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
     
       // package menu
       ecOpenPackage             = ecFirstLazarus + 600;
       ecOpenPackageFile         = ecFirstLazarus + 601;
       ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
    -  ecAddCurFileToPkg         = ecFirstLazarus + 603;
    -  ecNewPkgComponent         = ecFirstLazarus + 604;
    -  ecPackageGraph            = ecFirstLazarus + 605;
    -  ecPackageLinks            = ecFirstLazarus + 606;
    -  ecEditInstallPkgs         = ecFirstLazarus + 607;
    -  ecConfigCustomComps       = ecFirstLazarus + 608;
    -  ecNewPackage              = ecFirstLazarus + 609;
    +  ecOpenRecentPackage       = ecFirstLazarus + 603;
    +  ecAddCurFileToPkg         = ecFirstLazarus + 604;
    +  ecNewPkgComponent         = ecFirstLazarus + 605;
    +  ecPackageGraph            = ecFirstLazarus + 606;
    +  ecPackageLinks            = ecFirstLazarus + 607;
    +  ecEditInstallPkgs         = ecFirstLazarus + 608;
    +  ecConfigCustomComps       = ecFirstLazarus + 609;
    +  ecNewPackage              = ecFirstLazarus + 610;
     
       // custom tools menu
       ecExtToolFirst            = ecFirstLazarus + 700;
    Index: components/ideintf/toolbarintf.pas
    ===================================================================
    --- components/ideintf/toolbarintf.pas	(revision 61623)
    +++ components/ideintf/toolbarintf.pas	(working copy)
    @@ -18,7 +18,7 @@
     uses
       Classes, SysUtils,
       // LCL
    -  Controls, ComCtrls, Menus, Forms,
    +  Controls, ComCtrls, Menus, Forms, LCLType,
       // IdeIntf
       IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
     
    @@ -29,6 +29,7 @@
     
       TIDEButtonCommand = class(TIDESpecialCommand)
       private
    +    FTag: PtrInt;
         FToolButtonClass: TIDEToolButtonClass;
         FToolButtons: TIDEToolButtons;
       protected
    @@ -46,6 +47,7 @@
         constructor Create(const TheName: string); override;
         destructor Destroy; override;
       public
    +    property Tag: PtrInt read FTag write FTag;
         property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
         property ToolButtons: TIDEToolButtons read FToolButtons;
       end;
    @@ -64,7 +66,7 @@
         property Item: TIDEButtonCommand read FItem write FItem;
       end;
     
    -  { TIDEToolButtonWithArrow }
    +{ TIDEToolButtonWithArrow }  // will be removed with descendants after complete switching on use TIDEToolButton_WithArrow
     
       TIDEToolButtonWithArrow = class(TIDEToolButton)
       protected
    @@ -93,7 +95,39 @@
         procedure DoOnAdded; override;
       end;
     
    +  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
    +  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButtonButtonDrop;
    +  TIDEToolButton_DropDown_Class = class of TIDEToolButtonDropDown;
     
    +  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
    +
    +  TIDEToolButton_WithArrow = class(TIDEToolButton)
    +  private
    +    function GetSection: TIDEMenuSection;
    +  protected
    +    procedure DoOnMenuPopup(Sender: TObject);
    +    procedure RefreshMenu; virtual;
    +    property Section: TIDEMenuSection read GetSection;
    +  public
    +    constructor Create(AOwner: TComponent); override;
    +  end;
    +
    +  { TIDEToolButtonDropDown }    // [  ][▼]
    +
    +  TIDEToolButtonDropDown = class(TIDEToolButton_WithArrow)
    +  public
    +    procedure DoOnAdded; override;
    +  end;
    +
    +  { TIDEToolButtonButtonDrop }    // [ ▼]
    +
    +  TIDEToolButtonButtonDrop = class(TIDEToolButton_WithArrow)
    +  protected
    +    procedure PopUpAloneMenu(Sender: TObject);
    +  public
    +    procedure DoOnAdded; override;
    +  end;
    +
       TIDEToolButtonCategory = class
       private
         FButtons: TFPList;
    @@ -171,6 +205,7 @@
       const aCommand: TIDECommand): TIDEButtonCommand;
     function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
     
    +
     implementation
     
     function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
    @@ -276,6 +311,64 @@
       Style := tbsDropDown;  // not in constructor
     end;
     
    +{ TIDEToolButton_WithArrow }
    +
    +constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
    +begin
    +  inherited Create(AOwner);
    +  DropdownMenu := TPopupMenu.Create(Self);
    +  DropdownMenu.Images := IDEImages.Images_16;
    +  DropdownMenu.OnPopup := @DoOnMenuPopup;
    +end;
    +
    +function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
    +begin
    +  Result:=nil;
    +  if (Item<>nil) then
    +    Result:=TIDEMenuSection(Item.Tag);
    +end;
    +
    +procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
    +begin
    +  DropdownMenu.Items.Clear;
    +  RefreshMenu;
    +end;
    +
    +procedure TIDEToolButton_WithArrow.RefreshMenu;
    +begin
    +  if Section<>nil then
    +    DropdownMenu.Items.Assign(Section.MenuItem);
    +end;
    +
    +{ TIDEToolButtonDropDown }
    +
    +procedure TIDEToolButtonDropDown.DoOnAdded;
    +begin
    +  Style := tbsDropDown;  // not in constructor
    +end;
    +
    +{ TIDEToolButtonButtonDrop }
    +
    +procedure TIDEToolButtonButtonDrop.DoOnAdded;
    +begin
    +  Style := tbsButtonDrop;  // not in constructor
    +  if (Item<>nil) then
    +    if (Item.Command<>nil) then
    +      Item.Command.OnExecute:=@PopUpAloneMenu;
    +end;
    +
    +procedure TIDEToolButtonButtonDrop.PopUpAloneMenu(Sender: TObject);
    +var
    +  ActiveEditor: TSourceEditorInterface;
    +  ScreenXY: TPoint;
    +begin
    +  ActiveEditor := SourceEditorManagerIntf.ActiveEditor;
    +  if ActiveEditor=nil then
    +    Exit;
    +  ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
    +  DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
    +end;
    +
     { TIDEToolButtonsEnumerator }
     
     constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
    Index: ide/keymapping.pp
    ===================================================================
    --- ide/keymapping.pp	(revision 61623)
    +++ ide/keymapping.pp	(working copy)
    @@ -579,6 +579,7 @@
         ecJumpToNextError         : Result:= lisMenuJumpToNextError;
         ecJumpToPrevError         : Result:= lisMenuJumpToPrevError;
         ecGotoIncludeDirective    : Result:= srkmecGotoIncludeDirective;
    +    ecJumpToSection           : Result:= lisMenuJumpTo;
         ecJumpToInterface         : Result:= lisMenuJumpToInterface;
         ecJumpToInterfaceUses     : Result:= lisMenuJumpToInterfaceUses;
         ecJumpToImplementation    : Result:= lisMenuJumpToImplementation;
    @@ -652,6 +653,7 @@
         ecNewProject              : Result:= lisMenuNewProject;
         ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
         ecOpenProject             : Result:= lisMenuOpenProject;
    +    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
         ecCloseProject            : Result:= lisMenuCloseProject;
         ecSaveProject             : Result:= lisMenuSaveProject;
         ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
    @@ -705,6 +707,7 @@
         ecOpenPackage             : Result:= lisMenuOpenPackage;
         ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
         ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
    +    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
         ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
         ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
         ecPackageGraph            : Result:= lisMenuPackageGraph;
    @@ -2886,6 +2889,7 @@
       AddDefault(C, 'Find block other end', srkmecFindBlockOtherEnd, ecFindBlockOtherEnd);
       AddDefault(C, 'Find block start', srkmecFindBlockStart, ecFindBlockStart);
       AddDefault(C, 'Goto include directive', lisMenuGotoIncludeDirective, ecGotoIncludeDirective);
    +  AddDefault(C, 'Jump to Section', lisMenuJumpTo, ecJumpToSection);
       AddDefault(C, 'Jump to Interface', lisMenuJumpToInterface, ecJumpToInterface);
       AddDefault(C, 'Jump to Interface uses', lisMenuJumpToInterfaceUses, ecJumpToInterfaceUses);
       AddDefault(C, 'Jump to Implementation', lisMenuJumpToImplementation, ecJumpToImplementation);
    @@ -3074,6 +3078,7 @@
       AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
       AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
       AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
    +  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
       AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
       AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
       AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
    @@ -3129,6 +3134,7 @@
       AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
       AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
       AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
    +  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
       AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
       AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
       AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
    Index: ide/lazarusidestrconsts.pas
    ===================================================================
    --- ide/lazarusidestrconsts.pas	(revision 61623)
    +++ ide/lazarusidestrconsts.pas	(working copy)
    @@ -252,6 +252,7 @@
       lisPathOfTheMakeUtility = 'Path of the make utility';
       lisProjectMacroProperties = 'Project macro properties';
       lisOpenProject2 = 'Open project';
    +  lisKMOpenRecentProject = 'Open recent project';
       lisFileHasNoProject = 'File has no project';
       lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
          'The file "%s" is not a Lazarus project.'
    @@ -4129,6 +4130,7 @@
       lisKMNewPackage = 'New package';
       lisCompPalOpenPackage = 'Open package';
       lisKMOpenPackageFile = 'Open package file';
    +  lisKMOpenRecentPackage = 'Open recent package';
       lisCPOpenPackage = 'Open Package %s';
       lisFilterAllMessagesOfType = 'Filter all messages of type %s';
       lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
    Index: ide/main.pp
    ===================================================================
    --- ide/main.pp	(revision 61623)
    +++ ide/main.pp	(working copy)
    @@ -2891,6 +2891,37 @@
           ToolButton.ToolButtonClass := ToolButtonClass;
       end;
     
    +  function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;
    +             AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
    +  var
    +    ButtonCommand: TIDEButtonCommand;
    +  begin
    +    Result:=IDECommandList.FindIDECommand(ACommand);
    +    if Result=nil then
    +      Exit(nil);
    +    ButtonCommand:=RegisterIDEButtonCommand(Result);
    +    ButtonCommand.ToolButtonClass:=AButtonClass;
    +    if AButtonClass.InheritsFrom(TIDEToolButtonButtonDrop) then
    +      ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
    +    ButtonCommand.Tag:=PtrInt(AMenuSection);
    +  end;
    +
    +  function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
    +      AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
    +  begin
    +    if AButtonClass=nil then
    +      AButtonClass:=TIDEToolButtonDropDown;
    +    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +  end;
    +
    +  function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
    +      AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
    +  begin
    +    if AButtonClass=nil then
    +      AButtonClass:=TIDEToolButtonButtonDrop;
    +    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +  end;
    +
     var
       xBtnItem: TIDEButtonCommand;
     begin
    @@ -2953,11 +2984,12 @@
         itmSetFreeBookmark.Command:=GetCommand(ecSetFreeBookmark);
         itmJumpToNextBookmark.Command:=GetCommand(ecNextBookmark);
         itmJumpToPrevBookmark.Command:=GetCommand(ecPrevBookmark);
    -    itmJumpToInterface.Command:=GetCommand(ecJumpToInterface, nil, TJumpToSectionToolButton);
    -    itmJumpToInterfaceUses.Command:=GetCommand(ecJumpToInterfaceUses, nil, TJumpToSectionToolButton);
    -    itmJumpToImplementation.Command:=GetCommand(ecJumpToImplementation, nil, TJumpToSectionToolButton);
    -    itmJumpToImplementationUses.Command:=GetCommand(ecJumpToImplementationUses, nil, TJumpToSectionToolButton);
    -    itmJumpToInitialization.Command:=GetCommand(ecJumpToInitialization, nil, TJumpToSectionToolButton);
    +    GetCommand_ButtonDrop(ecJumpToSection, itmJumpToSection);
    +    itmJumpToInterface.Command:=GetCommand_DropDown(ecJumpToInterface, itmJumpToSection);
    +    itmJumpToInterfaceUses.Command:=GetCommand_DropDown(ecJumpToInterfaceUses, itmJumpToSection);
    +    itmJumpToImplementation.Command:=GetCommand_DropDown(ecJumpToImplementation, itmJumpToSection);
    +    itmJumpToImplementationUses.Command:=GetCommand_DropDown(ecJumpToImplementationUses, itmJumpToSection);
    +    itmJumpToInitialization.Command:=GetCommand_DropDown(ecJumpToInitialization, itmJumpToSection);
         GetCmdAndBtn(ecJumpToProcedureHeader, xBtnItem);
         xBtnItem.Caption := lisMenuJumpToProcedureHeader;
         xBtnItem.OnClick := @SourceEditorManager.JumpToProcedureHeaderClicked;
    @@ -3045,7 +3077,8 @@
         // project menu
         itmProjectNew.Command:=GetCommand(ecNewProject);
         itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
    -    itmProjectOpen.Command:=GetCommand(ecOpenProject);
    +    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
    +    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
         itmProjectClose.Command:=GetCommand(ecCloseProject);
         itmProjectSave.Command:=GetCommand(ecSaveProject);
         itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
    @@ -3091,8 +3124,9 @@
         // package menu
         itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
         itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
    -    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
    +    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
         itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
    +    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
         itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
         itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
         itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
    Index: ide/mainbase.pas
    ===================================================================
    --- ide/mainbase.pas	(revision 61623)
    +++ ide/mainbase.pas	(working copy)
    @@ -93,7 +93,7 @@
       protected
         FNeedUpdateHighlighters: boolean;
     
    -    function CreateMenuSeparator : TMenuItem;
    +    function CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
         procedure CreateMenuItem(Section: TIDEMenuSection;
                                  var MenuCommand: TIDEMenuCommand;
                                  const MenuItemName, MenuItemCaption: String;
    @@ -204,13 +204,6 @@
         property DisplayState: TDisplayState read FDisplayState write SetDisplayState;
       end;
     
    -  { TJumpToSectionToolButton }
    -
    -  TJumpToSectionToolButton = class(TIDEToolButton_DropDown)
    -  protected
    -    procedure RefreshMenu; override;
    -  end;
    -
       { TSetBuildModeToolButton }
     
       TSetBuildModeToolButton = class(TIDEToolButton)
    @@ -608,19 +601,6 @@
       Style := tbsDropDown;
     end;
     
    -{ TJumpToSectionToolButton }
    -
    -procedure TJumpToSectionToolButton.RefreshMenu;
    -begin
    -  AddMenuItem(MainIDEBar.itmJumpToInterface);
    -  AddMenuItem(MainIDEBar.itmJumpToInterfaceUses);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(MainIDEBar.itmJumpToImplementation);
    -  AddMenuItem(MainIDEBar.itmJumpToImplementationUses);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(MainIDEBar.itmJumpToInitialization);
    -end;
    -
     {$IFDEF LCLCocoa}
     var
       mnuApple: TIDEMenuSection = nil;
    @@ -953,10 +933,13 @@
       {$ENDIF}
     end;
     
    -function TMainIDEBase.CreateMenuSeparator : TMenuItem;
    +var
    +  SeparatorNum: Integer=0;
    +
    +function TMainIDEBase.CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
     begin
    -  Result := TMenuItem.Create(MainIDEBar);
    -  Result.Caption := '-';
    +  Inc(SeparatorNum);
    +  CreateMenuItem(Section, Result, 'Separator'+IntToStr(SeparatorNum), '-');
     end;
     
     procedure TMainIDEBase.CreateMenuItem(Section: TIDEMenuSection;
    @@ -1144,8 +1127,10 @@
     
         CreateMenuItem(ParentMI,itmJumpToInterface,'itmJumpToInterface',lisMenuJumpToInterface, 'menu_jumpto_interface');
         CreateMenuItem(ParentMI,itmJumpToInterfaceUses,'itmJumpToInterfaceUses',lisMenuJumpToInterfaceUses, 'menu_jumpto_interfaceuses');
    +    CreateMenuSeparator(ParentMI);
         CreateMenuItem(ParentMI,itmJumpToImplementation,'itmJumpToImplementation',lisMenuJumpToImplementation, 'menu_jumpto_implementation');
         CreateMenuItem(ParentMI,itmJumpToImplementationUses,'itmJumpToImplementationUses',lisMenuJumpToImplementationUses, 'menu_jumpto_implementationuses');
    +    CreateMenuSeparator(ParentMI);
         CreateMenuItem(ParentMI,itmJumpToInitialization,'itmJumpToInitialization',lisMenuJumpToInitialization, 'menu_jumpto_initialization');
     
         CreateMenuSeparatorSection(mnuSearch,itmBookmarks,'itmBookmarks');
    @@ -1409,7 +1394,7 @@
         CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
         CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
         CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
    -    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
    +    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
     
         CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
         ParentMI:=itmPkgUnits;
    Index: images/copyright.txt
    ===================================================================
    --- images/copyright.txt	(revision 61623)
    +++ images/copyright.txt	(working copy)
    @@ -169,6 +169,9 @@
     	state_warning_150.png
     	state_warning_200.png
     
    +packages directory
    +	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
    +
     --------------------------------------------------------------------------------
     
     The following component palette and menu/toolbar icons (including equally named
    Index: images/laz_images_list.txt
    ===================================================================
    --- images/laz_images_list.txt	(revision 61623)
    +++ images/laz_images_list.txt	(working copy)
    @@ -945,6 +945,9 @@
     packages/pkg_open.png
     packages/pkg_open_150.png
     packages/pkg_open_200.png
    +packages/pkg_open_recent.png
    +packages/pkg_open_recent_150.png
    +packages/pkg_open_recent_200.png
     packages/pkg_package_autoinstall.png
     packages/pkg_package_autoinstall_150.png
     packages/pkg_package_autoinstall_200.png
    
    patch3.diff (21,340 bytes)
  • patch4.diff (29,367 bytes)
    Index: components/ideintf/idecommands.pas
    ===================================================================
    --- components/ideintf/idecommands.pas	(revision 61640)
    +++ components/ideintf/idecommands.pas	(working copy)
    @@ -81,13 +81,14 @@
       ecFindBlockStart          = ecFirstLazarus + 22;
       ecOpenFileAtCursor        = ecFirstLazarus + 23;
       ecGotoIncludeDirective    = ecFirstLazarus + 24;
    -  ecJumpToInterface         = ecFirstLazarus + 25;
    -  ecJumpToInterfaceUses     = ecFirstLazarus + 26;
    -  ecJumpToImplementation    = ecFirstLazarus + 27;
    -  ecJumpToImplementationUses= ecFirstLazarus + 28;
    -  ecJumpToInitialization    = ecFirstLazarus + 29;
    -  ecJumpToProcedureHeader   = ecFirstLazarus + 30;
    -  ecJumpToProcedureBegin    = ecFirstLazarus + 31;
    +  ecJumpToSection           = ecFirstLazarus + 25;
    +  ecJumpToInterface         = ecFirstLazarus + 26;
    +  ecJumpToInterfaceUses     = ecFirstLazarus + 27;
    +  ecJumpToImplementation    = ecFirstLazarus + 28;
    +  ecJumpToImplementationUses= ecFirstLazarus + 29;
    +  ecJumpToInitialization    = ecFirstLazarus + 30;
    +  ecJumpToProcedureHeader   = ecFirstLazarus + 31;
    +  ecJumpToProcedureBegin    = ecFirstLazarus + 32;
     
       // edit selection
       ecSelectionUpperCase      = ecFirstLazarus + 50;
    @@ -302,31 +303,33 @@
       ecNewProject              = ecFirstLazarus + 500;
       ecNewProjectFromFile      = ecFirstLazarus + 501;
       ecOpenProject             = ecFirstLazarus + 502;
    -  ecCloseProject            = ecFirstLazarus + 503;
    -  ecSaveProject             = ecFirstLazarus + 504;
    -  ecSaveProjectAs           = ecFirstLazarus + 505;
    -  ecPublishProject          = ecFirstLazarus + 506;
    -  ecProjectInspector        = ecFirstLazarus + 507;
    -  ecAddCurUnitToProj        = ecFirstLazarus + 508;
    -  ecRemoveFromProj          = ecFirstLazarus + 509;
    -  ecViewProjectUnits        = ecFirstLazarus + 510;
    -  ecViewProjectForms        = ecFirstLazarus + 511;
    -  ecViewProjectSource       = ecFirstLazarus + 512;
    -  ecProjectOptions          = ecFirstLazarus + 513;
    -  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
    -  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
    +  ecOpenRecentProject       = ecFirstLazarus + 503;
    +  ecCloseProject            = ecFirstLazarus + 504;
    +  ecSaveProject             = ecFirstLazarus + 505;
    +  ecSaveProjectAs           = ecFirstLazarus + 506;
    +  ecPublishProject          = ecFirstLazarus + 507;
    +  ecProjectInspector        = ecFirstLazarus + 508;
    +  ecAddCurUnitToProj        = ecFirstLazarus + 509;
    +  ecRemoveFromProj          = ecFirstLazarus + 510;
    +  ecViewProjectUnits        = ecFirstLazarus + 511;
    +  ecViewProjectForms        = ecFirstLazarus + 512;
    +  ecViewProjectSource       = ecFirstLazarus + 513;
    +  ecProjectOptions          = ecFirstLazarus + 514;
    +  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
    +  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
     
       // package menu
       ecOpenPackage             = ecFirstLazarus + 600;
       ecOpenPackageFile         = ecFirstLazarus + 601;
       ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
    -  ecAddCurFileToPkg         = ecFirstLazarus + 603;
    -  ecNewPkgComponent         = ecFirstLazarus + 604;
    -  ecPackageGraph            = ecFirstLazarus + 605;
    -  ecPackageLinks            = ecFirstLazarus + 606;
    -  ecEditInstallPkgs         = ecFirstLazarus + 607;
    -  ecConfigCustomComps       = ecFirstLazarus + 608;
    -  ecNewPackage              = ecFirstLazarus + 609;
    +  ecOpenRecentPackage       = ecFirstLazarus + 603;
    +  ecAddCurFileToPkg         = ecFirstLazarus + 604;
    +  ecNewPkgComponent         = ecFirstLazarus + 605;
    +  ecPackageGraph            = ecFirstLazarus + 606;
    +  ecPackageLinks            = ecFirstLazarus + 607;
    +  ecEditInstallPkgs         = ecFirstLazarus + 608;
    +  ecConfigCustomComps       = ecFirstLazarus + 609;
    +  ecNewPackage              = ecFirstLazarus + 610;
     
       // custom tools menu
       ecExtToolFirst            = ecFirstLazarus + 700;
    Index: components/ideintf/toolbarintf.pas
    ===================================================================
    --- components/ideintf/toolbarintf.pas	(revision 61640)
    +++ components/ideintf/toolbarintf.pas	(working copy)
    @@ -18,7 +18,7 @@
     uses
       Classes, SysUtils,
       // LCL
    -  Controls, ComCtrls, Menus, Forms,
    +  Controls, ComCtrls, Menus, Forms, LCLType,
       // IdeIntf
       IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
     
    @@ -29,6 +29,7 @@
     
       TIDEButtonCommand = class(TIDESpecialCommand)
       private
    +    FTag: PtrInt;
         FToolButtonClass: TIDEToolButtonClass;
         FToolButtons: TIDEToolButtons;
       protected
    @@ -46,6 +47,7 @@
         constructor Create(const TheName: string); override;
         destructor Destroy; override;
       public
    +    property Tag: PtrInt read FTag write FTag;
         property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
         property ToolButtons: TIDEToolButtons read FToolButtons;
       end;
    @@ -64,36 +66,42 @@
         property Item: TIDEButtonCommand read FItem write FItem;
       end;
     
    -  { TIDEToolButtonWithArrow }
    +  {%region *** Classes for toolbuttons with arrow *** }
     
    -  TIDEToolButtonWithArrow = class(TIDEToolButton)
    +  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
    +  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButton_ButtonDrop;
    +  TIDEToolButton_DropDown_Class = class of TIDEToolButton_DropDown;
    +
    +  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
    +
    +  TIDEToolButton_WithArrow = class(TIDEToolButton)
    +  private
    +    function GetSection: TIDEMenuSection;
       protected
    -    procedure AddMenuItem(ACommand: TIDEMenuCommand); virtual;
    -    procedure AddMenuItems(ACommands: array of TIDEMenuCommand);
    -    procedure DoOnMenuItemClick(Sender: TObject);
         procedure DoOnMenuPopup(Sender: TObject);
         procedure RefreshMenu; virtual;
    +    property Section: TIDEMenuSection read GetSection;
       public
         constructor Create(AOwner: TComponent); override;
       end;
     
    -  { TIDEToolButton_ButtonDrop }
    +  { TIDEToolButton_DropDown }    // [  ][▼]
     
    -  TIDEToolButton_ButtonDrop = class(TIDEToolButtonWithArrow)
    -  protected
    -    procedure PopUpAloneMenu;
    +  TIDEToolButton_DropDown = class(TIDEToolButton_WithArrow)
       public
         procedure DoOnAdded; override;
       end;
     
    -  { TIDEToolButton_DropDown }
    +  { TIDEToolButton_ButtonDrop }    // [ ▼]
     
    -  TIDEToolButton_DropDown = class(TIDEToolButtonWithArrow)
    +  TIDEToolButton_ButtonDrop = class(TIDEToolButton_WithArrow)
    +  protected
    +    procedure PopUpAloneMenu(Sender: TObject);
       public
         procedure DoOnAdded; override;
       end;
    +  {%endregion}
     
    -
       TIDEToolButtonCategory = class
       private
         FButtons: TFPList;
    @@ -171,6 +179,12 @@
       const aCommand: TIDECommand): TIDEButtonCommand;
     function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
     
    +function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
    +function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
    +
    +
     implementation
     
     function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
    @@ -189,64 +203,78 @@
       Result := IDEToolButtonCategories.AddButton(aCommand);
     end;
     
    -{ TIDEToolButtonWithArrow }
    +{%region *** Functions and classes for toolbuttons with arrow *** }
     
    -constructor TIDEToolButtonWithArrow.Create(AOwner: TComponent);
    +function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;  // not in Interface
    +           AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
    +var
    +  ButtonCommand: TIDEButtonCommand;
     begin
    +  Result:=IDECommandList.FindIDECommand(ACommand);
    +  if Result=nil then
    +    Exit(nil);
    +  ButtonCommand:=RegisterIDEButtonCommand(Result);
    +  ButtonCommand.ToolButtonClass:=AButtonClass;
    +  if AButtonClass.InheritsFrom(TIDEToolButton_ButtonDrop) then
    +    ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
    +  ButtonCommand.Tag:=PtrInt(AMenuSection);
    +end;
    +
    +function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
    +begin
    +  if AButtonClass=nil then
    +    AButtonClass:=TIDEToolButton_DropDown;
    +  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +end;
    +
    +function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
    +begin
    +  if AButtonClass=nil then
    +    AButtonClass:=TIDEToolButton_ButtonDrop;
    +  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +end;
    +
    +{ TIDEToolButton_WithArrow }
    +
    +constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
    +begin
       inherited Create(AOwner);
       DropdownMenu := TPopupMenu.Create(Self);
       DropdownMenu.Images := IDEImages.Images_16;
       DropdownMenu.OnPopup := @DoOnMenuPopup;
     end;
     
    -procedure TIDEToolButtonWithArrow.AddMenuItem(ACommand: TIDEMenuCommand);
    -var
    -  Itm: TMenuItem;
    +function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
     begin
    -  Itm := TMenuItem.Create(DropdownMenu);
    -  Itm.Caption := ACommand.Caption;
    -  Itm.ShortCut := ACommand.Command.AsShortCut;
    -  Itm.ImageIndex := ACommand.ImageIndex;
    -  Itm.Enabled := ACommand.Enabled;
    -  Itm.OnClick := @DoOnMenuItemClick;
    -  Itm.Tag := PtrInt(ACommand);
    -  DropdownMenu.Items.Add(Itm);
    +  Result:=nil;
    +  if (Item<>nil) then
    +    Result:=TIDEMenuSection(Item.Tag);
     end;
     
    -procedure TIDEToolButtonWithArrow.AddMenuItems(ACommands: array of TIDEMenuCommand);
    -var
    -  Cmd: TIDEMenuCommand;
    +procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
     begin
    -  for Cmd in ACommands do
    -    AddMenuItem(Cmd);
    -end;
    -
    -procedure TIDEToolButtonWithArrow.DoOnMenuPopup(Sender: TObject);
    -begin
       DropdownMenu.Items.Clear;
       RefreshMenu;
     end;
     
    -procedure TIDEToolButtonWithArrow.RefreshMenu;
    +procedure TIDEToolButton_WithArrow.RefreshMenu;
     begin
    -  { Override this method in descendants.
    -    DropdownMenu fully regenerates for every showing on OnPopup event.
    -    So, RefreshMenu calling happens:
    -    - On click to arrow (Style=tbsDropDown)
    -    - On click to button (Style=tbsButtonDrop)
    -    - On popup alone menu in static methods (on shortcuts)
    -        of TIDEToolButton_ButtonDrop descendants (Style is not matter)
    -    At calling time:
    -    - Instance of DropdownMenu exists
    -    - DropdownMenu is empty }
    +  if Section=nil then
    +    Exit;
    +  if Section.MenuItem=nil then
    +    Section.GetRoot.CreateMenuItem;  // this forces creating menu (it is necessary
    +                                     // for TPopupMenu before first popup)
    +  if Section.MenuItem<>nil then
    +    DropdownMenu.Items.Assign(Section.MenuItem);
     end;
     
    -procedure TIDEToolButtonWithArrow.DoOnMenuItemClick(Sender: TObject);
    -var
    -  Cmd: TIDEMenuCommand;
    +{ TIDEToolButton_DropDown }
    +
    +procedure TIDEToolButton_DropDown.DoOnAdded;
     begin
    -  Cmd:=TIDEMenuCommand((Sender as TMenuItem).Tag);
    -  Cmd.DoOnClick;  // Sender in handler should be a command but not a menu item
    +  Style := tbsDropDown;  // not in constructor
     end;
     
     { TIDEToolButton_ButtonDrop }
    @@ -254,9 +282,12 @@
     procedure TIDEToolButton_ButtonDrop.DoOnAdded;
     begin
       Style := tbsButtonDrop;  // not in constructor
    +  if (Item<>nil) then
    +    if (Item.Command<>nil) then
    +      Item.Command.OnExecute:=@PopUpAloneMenu;
     end;
     
    -procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu;
    +procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu(Sender: TObject);
     var
       ActiveEditor: TSourceEditorInterface;
       ScreenXY: TPoint;
    @@ -265,17 +296,10 @@
       if ActiveEditor=nil then
         Exit;
       ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
    -
       DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
     end;
    +{%endregion}
     
    -{ TIDEToolButton_DropDown }
    -
    -procedure TIDEToolButton_DropDown.DoOnAdded;
    -begin
    -  Style := tbsDropDown;  // not in constructor
    -end;
    -
     { TIDEToolButtonsEnumerator }
     
     constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
    @@ -285,6 +309,7 @@
       FPosition := -1;
     end;
     
    +
     function TIDEToolButtonsEnumerator.GetCurrent: TIDEToolButton;
     begin
       Result := FList[FPosition];
    Index: ide/keymapping.pp
    ===================================================================
    --- ide/keymapping.pp	(revision 61640)
    +++ ide/keymapping.pp	(working copy)
    @@ -579,6 +579,7 @@
         ecJumpToNextError         : Result:= lisMenuJumpToNextError;
         ecJumpToPrevError         : Result:= lisMenuJumpToPrevError;
         ecGotoIncludeDirective    : Result:= srkmecGotoIncludeDirective;
    +    ecJumpToSection           : Result:= lisMenuJumpTo;
         ecJumpToInterface         : Result:= lisMenuJumpToInterface;
         ecJumpToInterfaceUses     : Result:= lisMenuJumpToInterfaceUses;
         ecJumpToImplementation    : Result:= lisMenuJumpToImplementation;
    @@ -652,6 +653,7 @@
         ecNewProject              : Result:= lisMenuNewProject;
         ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
         ecOpenProject             : Result:= lisMenuOpenProject;
    +    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
         ecCloseProject            : Result:= lisMenuCloseProject;
         ecSaveProject             : Result:= lisMenuSaveProject;
         ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
    @@ -705,6 +707,7 @@
         ecOpenPackage             : Result:= lisMenuOpenPackage;
         ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
         ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
    +    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
         ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
         ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
         ecPackageGraph            : Result:= lisMenuPackageGraph;
    @@ -2886,6 +2889,7 @@
       AddDefault(C, 'Find block other end', srkmecFindBlockOtherEnd, ecFindBlockOtherEnd);
       AddDefault(C, 'Find block start', srkmecFindBlockStart, ecFindBlockStart);
       AddDefault(C, 'Goto include directive', lisMenuGotoIncludeDirective, ecGotoIncludeDirective);
    +  AddDefault(C, 'Jump to Section', lisMenuJumpTo, ecJumpToSection);
       AddDefault(C, 'Jump to Interface', lisMenuJumpToInterface, ecJumpToInterface);
       AddDefault(C, 'Jump to Interface uses', lisMenuJumpToInterfaceUses, ecJumpToInterfaceUses);
       AddDefault(C, 'Jump to Implementation', lisMenuJumpToImplementation, ecJumpToImplementation);
    @@ -3074,6 +3078,7 @@
       AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
       AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
       AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
    +  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
       AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
       AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
       AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
    @@ -3129,6 +3134,7 @@
       AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
       AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
       AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
    +  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
       AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
       AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
       AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
    Index: ide/lazarusidestrconsts.pas
    ===================================================================
    --- ide/lazarusidestrconsts.pas	(revision 61640)
    +++ ide/lazarusidestrconsts.pas	(working copy)
    @@ -252,6 +252,7 @@
       lisPathOfTheMakeUtility = 'Path of the make utility';
       lisProjectMacroProperties = 'Project macro properties';
       lisOpenProject2 = 'Open project';
    +  lisKMOpenRecentProject = 'Open recent project';
       lisFileHasNoProject = 'File has no project';
       lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
          'The file "%s" is not a Lazarus project.'
    @@ -4129,6 +4130,7 @@
       lisKMNewPackage = 'New package';
       lisCompPalOpenPackage = 'Open package';
       lisKMOpenPackageFile = 'Open package file';
    +  lisKMOpenRecentPackage = 'Open recent package';
       lisCPOpenPackage = 'Open Package %s';
       lisFilterAllMessagesOfType = 'Filter all messages of type %s';
       lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
    Index: ide/main.pp
    ===================================================================
    --- ide/main.pp	(revision 61640)
    +++ ide/main.pp	(working copy)
    @@ -2893,6 +2893,10 @@
           ToolButton.ToolButtonClass := ToolButtonClass;
       end;
     
    +  // See also in ToolBarIntf:
    +  //  function GetCommand_DropDown
    +  //  function GetCommand_ButtonDrop
    +
     var
       xBtnItem: TIDEButtonCommand;
     begin
    @@ -2955,11 +2959,12 @@
         itmSetFreeBookmark.Command:=GetCommand(ecSetFreeBookmark);
         itmJumpToNextBookmark.Command:=GetCommand(ecNextBookmark);
         itmJumpToPrevBookmark.Command:=GetCommand(ecPrevBookmark);
    -    itmJumpToInterface.Command:=GetCommand(ecJumpToInterface, nil, TJumpToSectionToolButton);
    -    itmJumpToInterfaceUses.Command:=GetCommand(ecJumpToInterfaceUses, nil, TJumpToSectionToolButton);
    -    itmJumpToImplementation.Command:=GetCommand(ecJumpToImplementation, nil, TJumpToSectionToolButton);
    -    itmJumpToImplementationUses.Command:=GetCommand(ecJumpToImplementationUses, nil, TJumpToSectionToolButton);
    -    itmJumpToInitialization.Command:=GetCommand(ecJumpToInitialization, nil, TJumpToSectionToolButton);
    +    GetCommand_ButtonDrop(ecJumpToSection, itmJumpToSection);
    +    itmJumpToInterface.Command:=GetCommand_DropDown(ecJumpToInterface, itmJumpToSection);
    +    itmJumpToInterfaceUses.Command:=GetCommand_DropDown(ecJumpToInterfaceUses, itmJumpToSection);
    +    itmJumpToImplementation.Command:=GetCommand_DropDown(ecJumpToImplementation, itmJumpToSection);
    +    itmJumpToImplementationUses.Command:=GetCommand_DropDown(ecJumpToImplementationUses, itmJumpToSection);
    +    itmJumpToInitialization.Command:=GetCommand_DropDown(ecJumpToInitialization, itmJumpToSection);
         GetCmdAndBtn(ecJumpToProcedureHeader, xBtnItem);
         xBtnItem.Caption := lisMenuJumpToProcedureHeader;
         xBtnItem.OnClick := @SourceEditorManager.JumpToProcedureHeaderClicked;
    @@ -3047,7 +3052,8 @@
         // project menu
         itmProjectNew.Command:=GetCommand(ecNewProject);
         itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
    -    itmProjectOpen.Command:=GetCommand(ecOpenProject);
    +    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
    +    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
         itmProjectClose.Command:=GetCommand(ecCloseProject);
         itmProjectSave.Command:=GetCommand(ecSaveProject);
         itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
    @@ -3093,8 +3099,9 @@
         // package menu
         itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
         itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
    -    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
    +    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
         itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
    +    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
         itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
         itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
         itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
    Index: ide/mainbase.pas
    ===================================================================
    --- ide/mainbase.pas	(revision 61640)
    +++ ide/mainbase.pas	(working copy)
    @@ -93,7 +93,7 @@
       protected
         FNeedUpdateHighlighters: boolean;
     
    -    function CreateMenuSeparator : TMenuItem;
    +    function CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
         procedure CreateMenuItem(Section: TIDEMenuSection;
                                  var MenuCommand: TIDEMenuCommand;
                                  const MenuItemName, MenuItemCaption: String;
    @@ -204,13 +204,6 @@
         property DisplayState: TDisplayState read FDisplayState write SetDisplayState;
       end;
     
    -  { TJumpToSectionToolButton }
    -
    -  TJumpToSectionToolButton = class(TIDEToolButton_DropDown)
    -  protected
    -    procedure RefreshMenu; override;
    -  end;
    -
       { TSetBuildModeToolButton }
     
       TSetBuildModeToolButton = class(TIDEToolButton)
    @@ -608,19 +601,6 @@
       Style := tbsDropDown;
     end;
     
    -{ TJumpToSectionToolButton }
    -
    -procedure TJumpToSectionToolButton.RefreshMenu;
    -begin
    -  AddMenuItem(MainIDEBar.itmJumpToInterface);
    -  AddMenuItem(MainIDEBar.itmJumpToInterfaceUses);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(MainIDEBar.itmJumpToImplementation);
    -  AddMenuItem(MainIDEBar.itmJumpToImplementationUses);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(MainIDEBar.itmJumpToInitialization);
    -end;
    -
     {$IFDEF LCLCocoa}
     var
       mnuApple: TIDEMenuSection = nil;
    @@ -953,10 +933,13 @@
       {$ENDIF}
     end;
     
    -function TMainIDEBase.CreateMenuSeparator : TMenuItem;
    +var
    +  SeparatorNum: Integer=0;
    +
    +function TMainIDEBase.CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
     begin
    -  Result := TMenuItem.Create(MainIDEBar);
    -  Result.Caption := '-';
    +  Inc(SeparatorNum);
    +  CreateMenuItem(Section, Result, 'Separator'+IntToStr(SeparatorNum), '-');  // Result - var parameter
     end;
     
     procedure TMainIDEBase.CreateMenuItem(Section: TIDEMenuSection;
    @@ -1144,8 +1127,10 @@
     
         CreateMenuItem(ParentMI,itmJumpToInterface,'itmJumpToInterface',lisMenuJumpToInterface, 'menu_jumpto_interface');
         CreateMenuItem(ParentMI,itmJumpToInterfaceUses,'itmJumpToInterfaceUses',lisMenuJumpToInterfaceUses, 'menu_jumpto_interfaceuses');
    +    CreateMenuSeparator(ParentMI);
         CreateMenuItem(ParentMI,itmJumpToImplementation,'itmJumpToImplementation',lisMenuJumpToImplementation, 'menu_jumpto_implementation');
         CreateMenuItem(ParentMI,itmJumpToImplementationUses,'itmJumpToImplementationUses',lisMenuJumpToImplementationUses, 'menu_jumpto_implementationuses');
    +    CreateMenuSeparator(ParentMI);
         CreateMenuItem(ParentMI,itmJumpToInitialization,'itmJumpToInitialization',lisMenuJumpToInitialization, 'menu_jumpto_initialization');
     
         CreateMenuSeparatorSection(mnuSearch,itmBookmarks,'itmBookmarks');
    @@ -1409,7 +1394,7 @@
         CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
         CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
         CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
    -    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
    +    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
     
         CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
         ParentMI:=itmPkgUnits;
    Index: ide/sourceeditor.pp
    ===================================================================
    --- ide/sourceeditor.pp	(revision 61640)
    +++ ide/sourceeditor.pp	(working copy)
    @@ -1369,9 +1369,7 @@
         SrcEditMenuClearFileBookmark: TIDEMenuCommand;
         SrcEditMenuClearAllBookmark: TIDEMenuCommand;
         SrcEditMenuGotoBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
    -    SrcEditMenuGotoBookmarks: TIDEMenuCommand;
         SrcEditMenuToggleBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
    -    SrcEditMenuToggleBookmarks: TIDEMenuCommand;
         // debugging
         SrcEditMenuToggleBreakpoint: TIDEMenuCommand;
         SrcEditMenuRunToCursor: TIDEMenuCommand;
    @@ -1436,27 +1434,7 @@
       EnglishModifiedLGPLNotice: string;
       EnglishMITNotice: string;
     
    -type
     
    -  { TToolButton_GotoBookmarks }
    -
    -  TToolButton_GotoBookmarks = class(TIDEToolButton_ButtonDrop)
    -  protected
    -    procedure RefreshMenu; override;
    -  public
    -    class procedure ShowAloneMenu(Sender: TObject); static;
    -  end;
    -
    -  { TToolButton_ToggleBookmarks }
    -
    -  TToolButton_ToggleBookmarks = class(TIDEToolButton_ButtonDrop)
    -  protected
    -    procedure RefreshMenu; override;
    -  public
    -    class procedure ShowAloneMenu(Sender: TObject); static;
    -  end;
    -
    -
     implementation
     
     {$R *.lfm}
    @@ -1711,13 +1689,6 @@
           SrcEditMenuPrevBookmark:=RegisterIDEMenuCommand(AParent,
               'Goto previous Bookmark',uemPrevBookmark, nil,
               @ExecuteIdeMenuClick, nil, 'menu_search_previous_bookmark');
    -
    -      {For toolbar only. Hidden in menu.}
    -      SrcEditMenuGotoBookmarks:=RegisterIDEMenuCommand(AParent,
    -          'Goto bookmarks', uemGotoBookmarks,
    -          nil, TNotifyProcedure(@TToolButton_GotoBookmarks.ShowAloneMenu), nil,
    -          'menu_goto_bookmarks');
    -      SrcEditMenuGotoBookmarks.Visible:=False;
       {%endregion}
     
       {%region *** Toggle Bookmarks Submenu ***}
    @@ -1739,13 +1710,6 @@
               'Clear Bookmark for current file',srkmecClearBookmarkForFile, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_file_bookmarks');
           SrcEditMenuClearAllBookmark:=RegisterIDEMenuCommand(AParent,
               'Clear all Bookmark',srkmecClearAllBookmark, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_all_bookmarks');
    -
    -      {For toolbar only. Hidden in menu.}
    -      SrcEditMenuToggleBookmarks:=RegisterIDEMenuCommand(AParent,
    -          'Toggle bookmarks', uemToggleBookmarks,
    -          nil, TNotifyProcedure(@TToolButton_ToggleBookmarks.ShowAloneMenu), nil,
    -          'menu_toggle_bookmarks');
    -      SrcEditMenuToggleBookmarks.Visible:=False;
       {%endregion}
     
       {%region *** Debug Section ***}
    @@ -1854,51 +1818,6 @@
       Result:=CompareFilenames(AnsiString(FileNameStr),SE1.FileName);
     end;
     
    -{ TToolButton_GotoBookmarks }
    -
    -procedure TToolButton_GotoBookmarks.RefreshMenu;
    -begin
    -  AddMenuItems(SrcEditMenuGotoBookmark);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItems([
    -    SrcEditMenuPrevBookmark,
    -    SrcEditMenuNextBookmark]);
    -end;
    -
    -class procedure TToolButton_GotoBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
    -const
    -  Btn: TToolButton_GotoBookmarks=nil;  // static var
    -begin
    -  if Btn = nil then
    -    Btn := TToolButton_GotoBookmarks.Create(Application);
    -  Btn.PopUpAloneMenu;
    -  // Btn should not be destroyed immediately after PopUp
    -end;
    -
    -
    -{ TToolButton_ToggleBookmarks }
    -
    -procedure TToolButton_ToggleBookmarks.RefreshMenu;
    -begin
    -  AddMenuItems(SrcEditMenuToggleBookmark);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(SrcEditMenuSetFreeBookmark);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItems([
    -    SrcEditMenuClearFileBookmark,
    -    SrcEditMenuClearAllBookmark]);
    -end;
    -
    -class procedure TToolButton_ToggleBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
    -const
    -  Btn: TToolButton_ToggleBookmarks=nil;  // static var
    -begin
    -  if Btn = nil then
    -    Btn := TToolButton_ToggleBookmarks.Create(Application);
    -  Btn.PopUpAloneMenu;
    -  // Btn should not be destroyed immediately after PopUp
    -end;
    -
     { TSourceEditorWordCompletion }
     
     constructor TSourceEditorWordCompletion.Create;
    @@ -10704,6 +10623,10 @@
           ToolButton.ToolButtonClass := ToolButtonClass;
       end;
     
    +  // See also in ToolBarIntf:
    +  //  function GetCommand_DropDown
    +  //  function GetCommand_ButtonDrop
    +
     var
       i: Integer;
     begin
    @@ -10769,14 +10692,13 @@
       SrcEditMenuClearFileBookmark.Command:=GetCommand(ecClearBookmarkForFile);
       SrcEditMenuClearAllBookmark.Command:=GetCommand(ecClearAllBookmark);
     
    -  SrcEditMenuGotoBookmarks.Command:=GetCommand(ecGotoBookmarks, TToolButton_GotoBookmarks);
    -  SrcEditMenuToggleBookmarks.Command:=GetCommand(ecToggleBookmarks, TToolButton_ToggleBookmarks);
    -
       for i in TBookmarkNumRange do
         SrcEditMenuGotoBookmark[i].Command := GetCommand(ecGotoMarker0 + i);
    +  GetCommand_ButtonDrop(ecGotoBookmarks ,SrcEditSubMenuGotoBookmarks);        // [ ▼]
     
       for i in TBookmarkNumRange do
         SrcEditMenuToggleBookmark[i].Command := GetCommand(ecToggleMarker0 + i);
    +  GetCommand_ButtonDrop(ecToggleBookmarks ,SrcEditSubMenuToggleBookmarks);    // [ ▼]
     
       {%region *** Source Section ***}
         SrcEditMenuEncloseSelection.Command:=GetCommand(ecSelectionEnclose);
    Index: images/copyright.txt
    ===================================================================
    --- images/copyright.txt	(revision 61640)
    +++ images/copyright.txt	(working copy)
    @@ -169,6 +169,9 @@
     	state_warning_150.png
     	state_warning_200.png
     
    +packages directory
    +	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
    +
     --------------------------------------------------------------------------------
     
     The following component palette and menu/toolbar icons (including equally named
    Index: images/laz_images_list.txt
    ===================================================================
    --- images/laz_images_list.txt	(revision 61640)
    +++ images/laz_images_list.txt	(working copy)
    @@ -945,6 +945,9 @@
     packages/pkg_open.png
     packages/pkg_open_150.png
     packages/pkg_open_200.png
    +packages/pkg_open_recent.png
    +packages/pkg_open_recent_150.png
    +packages/pkg_open_recent_200.png
     packages/pkg_package_autoinstall.png
     packages/pkg_package_autoinstall_150.png
     packages/pkg_package_autoinstall_200.png
    
    patch4.diff (29,367 bytes)
  • patch5.diff (31,545 bytes)
    Index: components/ideintf/idecommands.pas
    ===================================================================
    --- components/ideintf/idecommands.pas	(revision 61652)
    +++ components/ideintf/idecommands.pas	(working copy)
    @@ -81,13 +81,14 @@
       ecFindBlockStart          = ecFirstLazarus + 22;
       ecOpenFileAtCursor        = ecFirstLazarus + 23;
       ecGotoIncludeDirective    = ecFirstLazarus + 24;
    -  ecJumpToInterface         = ecFirstLazarus + 25;
    -  ecJumpToInterfaceUses     = ecFirstLazarus + 26;
    -  ecJumpToImplementation    = ecFirstLazarus + 27;
    -  ecJumpToImplementationUses= ecFirstLazarus + 28;
    -  ecJumpToInitialization    = ecFirstLazarus + 29;
    -  ecJumpToProcedureHeader   = ecFirstLazarus + 30;
    -  ecJumpToProcedureBegin    = ecFirstLazarus + 31;
    +  ecJumpToSection           = ecFirstLazarus + 25;
    +  ecJumpToInterface         = ecFirstLazarus + 26;
    +  ecJumpToInterfaceUses     = ecFirstLazarus + 27;
    +  ecJumpToImplementation    = ecFirstLazarus + 28;
    +  ecJumpToImplementationUses= ecFirstLazarus + 29;
    +  ecJumpToInitialization    = ecFirstLazarus + 30;
    +  ecJumpToProcedureHeader   = ecFirstLazarus + 31;
    +  ecJumpToProcedureBegin    = ecFirstLazarus + 32;
     
       // edit selection
       ecSelectionUpperCase      = ecFirstLazarus + 50;
    @@ -174,8 +175,9 @@
       ecRestart                 = ecFirstLazarus + 213;
       ecQuit                    = ecFirstLazarus + 214;
       ecOpenUnit                = ecFirstLazarus + 215;
    -  ecCloseOtherTabs          = ecFirstLazarus + 216;
    -  ecCloseRightTabs          = ecFirstLazarus + 217;
    +  ecOpenRecent              = ecFirstLazarus + 216;
    +  ecCloseOtherTabs          = ecFirstLazarus + 217;
    +  ecCloseRightTabs          = ecFirstLazarus + 218;
     
       // edit menu
       ecMultiPaste              = ecFirstLazarus + 230;
    @@ -302,31 +304,33 @@
       ecNewProject              = ecFirstLazarus + 500;
       ecNewProjectFromFile      = ecFirstLazarus + 501;
       ecOpenProject             = ecFirstLazarus + 502;
    -  ecCloseProject            = ecFirstLazarus + 503;
    -  ecSaveProject             = ecFirstLazarus + 504;
    -  ecSaveProjectAs           = ecFirstLazarus + 505;
    -  ecPublishProject          = ecFirstLazarus + 506;
    -  ecProjectInspector        = ecFirstLazarus + 507;
    -  ecAddCurUnitToProj        = ecFirstLazarus + 508;
    -  ecRemoveFromProj          = ecFirstLazarus + 509;
    -  ecViewProjectUnits        = ecFirstLazarus + 510;
    -  ecViewProjectForms        = ecFirstLazarus + 511;
    -  ecViewProjectSource       = ecFirstLazarus + 512;
    -  ecProjectOptions          = ecFirstLazarus + 513;
    -  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
    -  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
    +  ecOpenRecentProject       = ecFirstLazarus + 503;
    +  ecCloseProject            = ecFirstLazarus + 504;
    +  ecSaveProject             = ecFirstLazarus + 505;
    +  ecSaveProjectAs           = ecFirstLazarus + 506;
    +  ecPublishProject          = ecFirstLazarus + 507;
    +  ecProjectInspector        = ecFirstLazarus + 508;
    +  ecAddCurUnitToProj        = ecFirstLazarus + 509;
    +  ecRemoveFromProj          = ecFirstLazarus + 510;
    +  ecViewProjectUnits        = ecFirstLazarus + 511;
    +  ecViewProjectForms        = ecFirstLazarus + 512;
    +  ecViewProjectSource       = ecFirstLazarus + 513;
    +  ecProjectOptions          = ecFirstLazarus + 514;
    +  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
    +  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
     
       // package menu
       ecOpenPackage             = ecFirstLazarus + 600;
       ecOpenPackageFile         = ecFirstLazarus + 601;
       ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
    -  ecAddCurFileToPkg         = ecFirstLazarus + 603;
    -  ecNewPkgComponent         = ecFirstLazarus + 604;
    -  ecPackageGraph            = ecFirstLazarus + 605;
    -  ecPackageLinks            = ecFirstLazarus + 606;
    -  ecEditInstallPkgs         = ecFirstLazarus + 607;
    -  ecConfigCustomComps       = ecFirstLazarus + 608;
    -  ecNewPackage              = ecFirstLazarus + 609;
    +  ecOpenRecentPackage       = ecFirstLazarus + 603;
    +  ecAddCurFileToPkg         = ecFirstLazarus + 604;
    +  ecNewPkgComponent         = ecFirstLazarus + 605;
    +  ecPackageGraph            = ecFirstLazarus + 606;
    +  ecPackageLinks            = ecFirstLazarus + 607;
    +  ecEditInstallPkgs         = ecFirstLazarus + 608;
    +  ecConfigCustomComps       = ecFirstLazarus + 609;
    +  ecNewPackage              = ecFirstLazarus + 610;
     
       // custom tools menu
       ecExtToolFirst            = ecFirstLazarus + 700;
    Index: components/ideintf/toolbarintf.pas
    ===================================================================
    --- components/ideintf/toolbarintf.pas	(revision 61652)
    +++ components/ideintf/toolbarintf.pas	(working copy)
    @@ -18,7 +18,7 @@
     uses
       Classes, SysUtils,
       // LCL
    -  Controls, ComCtrls, Menus, Forms,
    +  Controls, ComCtrls, Menus, Forms, LCLType,
       // IdeIntf
       IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
     
    @@ -29,6 +29,7 @@
     
       TIDEButtonCommand = class(TIDESpecialCommand)
       private
    +    FTag: PtrInt;
         FToolButtonClass: TIDEToolButtonClass;
         FToolButtons: TIDEToolButtons;
       protected
    @@ -46,6 +47,7 @@
         constructor Create(const TheName: string); override;
         destructor Destroy; override;
       public
    +    property Tag: PtrInt read FTag write FTag;
         property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
         property ToolButtons: TIDEToolButtons read FToolButtons;
       end;
    @@ -64,36 +66,42 @@
         property Item: TIDEButtonCommand read FItem write FItem;
       end;
     
    -  { TIDEToolButtonWithArrow }
    +  {%region *** Classes for toolbuttons with arrow *** }
     
    -  TIDEToolButtonWithArrow = class(TIDEToolButton)
    +  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
    +  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButton_ButtonDrop;
    +  TIDEToolButton_DropDown_Class = class of TIDEToolButton_DropDown;
    +
    +  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
    +
    +  TIDEToolButton_WithArrow = class(TIDEToolButton)
    +  private
    +    function GetSection: TIDEMenuSection;
       protected
    -    procedure AddMenuItem(ACommand: TIDEMenuCommand); virtual;
    -    procedure AddMenuItems(ACommands: array of TIDEMenuCommand);
    -    procedure DoOnMenuItemClick(Sender: TObject);
         procedure DoOnMenuPopup(Sender: TObject);
         procedure RefreshMenu; virtual;
    +    property Section: TIDEMenuSection read GetSection;
       public
         constructor Create(AOwner: TComponent); override;
       end;
     
    -  { TIDEToolButton_ButtonDrop }
    +  { TIDEToolButton_DropDown }    // [  ][▼]
     
    -  TIDEToolButton_ButtonDrop = class(TIDEToolButtonWithArrow)
    -  protected
    -    procedure PopUpAloneMenu;
    +  TIDEToolButton_DropDown = class(TIDEToolButton_WithArrow)
       public
         procedure DoOnAdded; override;
       end;
     
    -  { TIDEToolButton_DropDown }
    +  { TIDEToolButton_ButtonDrop }    // [ ▼]
     
    -  TIDEToolButton_DropDown = class(TIDEToolButtonWithArrow)
    +  TIDEToolButton_ButtonDrop = class(TIDEToolButton_WithArrow)
    +  protected
    +    procedure PopUpAloneMenu(Sender: TObject);
       public
         procedure DoOnAdded; override;
       end;
    +  {%endregion}
     
    -
       TIDEToolButtonCategory = class
       private
         FButtons: TFPList;
    @@ -171,6 +179,12 @@
       const aCommand: TIDECommand): TIDEButtonCommand;
     function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
     
    +function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
    +function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
    +
    +
     implementation
     
     function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
    @@ -189,64 +203,78 @@
       Result := IDEToolButtonCategories.AddButton(aCommand);
     end;
     
    -{ TIDEToolButtonWithArrow }
    +{%region *** Functions and classes for toolbuttons with arrow *** }
     
    -constructor TIDEToolButtonWithArrow.Create(AOwner: TComponent);
    +function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;  // not in Interface
    +           AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
    +var
    +  ButtonCommand: TIDEButtonCommand;
     begin
    +  Result:=IDECommandList.FindIDECommand(ACommand);
    +  if Result=nil then
    +    Exit(nil);
    +  ButtonCommand:=RegisterIDEButtonCommand(Result);
    +  ButtonCommand.ToolButtonClass:=AButtonClass;
    +  if AButtonClass.InheritsFrom(TIDEToolButton_ButtonDrop) then
    +    ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
    +  ButtonCommand.Tag:=PtrInt(AMenuSection);
    +end;
    +
    +function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
    +begin
    +  if AButtonClass=nil then
    +    AButtonClass:=TIDEToolButton_DropDown;
    +  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +end;
    +
    +function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
    +    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
    +begin
    +  if AButtonClass=nil then
    +    AButtonClass:=TIDEToolButton_ButtonDrop;
    +  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
    +end;
    +
    +{ TIDEToolButton_WithArrow }
    +
    +constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
    +begin
       inherited Create(AOwner);
       DropdownMenu := TPopupMenu.Create(Self);
       DropdownMenu.Images := IDEImages.Images_16;
       DropdownMenu.OnPopup := @DoOnMenuPopup;
     end;
     
    -procedure TIDEToolButtonWithArrow.AddMenuItem(ACommand: TIDEMenuCommand);
    -var
    -  Itm: TMenuItem;
    +function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
     begin
    -  Itm := TMenuItem.Create(DropdownMenu);
    -  Itm.Caption := ACommand.Caption;
    -  Itm.ShortCut := ACommand.Command.AsShortCut;
    -  Itm.ImageIndex := ACommand.ImageIndex;
    -  Itm.Enabled := ACommand.Enabled;
    -  Itm.OnClick := @DoOnMenuItemClick;
    -  Itm.Tag := PtrInt(ACommand);
    -  DropdownMenu.Items.Add(Itm);
    +  Result:=nil;
    +  if (Item<>nil) then
    +    Result:=TIDEMenuSection(Item.Tag);
     end;
     
    -procedure TIDEToolButtonWithArrow.AddMenuItems(ACommands: array of TIDEMenuCommand);
    -var
    -  Cmd: TIDEMenuCommand;
    +procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
     begin
    -  for Cmd in ACommands do
    -    AddMenuItem(Cmd);
    -end;
    -
    -procedure TIDEToolButtonWithArrow.DoOnMenuPopup(Sender: TObject);
    -begin
       DropdownMenu.Items.Clear;
       RefreshMenu;
     end;
     
    -procedure TIDEToolButtonWithArrow.RefreshMenu;
    +procedure TIDEToolButton_WithArrow.RefreshMenu;
     begin
    -  { Override this method in descendants.
    -    DropdownMenu fully regenerates for every showing on OnPopup event.
    -    So, RefreshMenu calling happens:
    -    - On click to arrow (Style=tbsDropDown)
    -    - On click to button (Style=tbsButtonDrop)
    -    - On popup alone menu in static methods (on shortcuts)
    -        of TIDEToolButton_ButtonDrop descendants (Style is not matter)
    -    At calling time:
    -    - Instance of DropdownMenu exists
    -    - DropdownMenu is empty }
    +  if Section=nil then
    +    Exit;
    +  if Section.MenuItem=nil then
    +    Section.GetRoot.CreateMenuItem;  // this forces creating menu (it is necessary
    +                                     // for TPopupMenu before first popup)
    +  if Section.MenuItem<>nil then
    +    DropdownMenu.Items.Assign(Section.MenuItem);
     end;
     
    -procedure TIDEToolButtonWithArrow.DoOnMenuItemClick(Sender: TObject);
    -var
    -  Cmd: TIDEMenuCommand;
    +{ TIDEToolButton_DropDown }
    +
    +procedure TIDEToolButton_DropDown.DoOnAdded;
     begin
    -  Cmd:=TIDEMenuCommand((Sender as TMenuItem).Tag);
    -  Cmd.DoOnClick;  // Sender in handler should be a command but not a menu item
    +  Style := tbsDropDown;  // not in constructor
     end;
     
     { TIDEToolButton_ButtonDrop }
    @@ -254,9 +282,12 @@
     procedure TIDEToolButton_ButtonDrop.DoOnAdded;
     begin
       Style := tbsButtonDrop;  // not in constructor
    +  if (Item<>nil) then
    +    if (Item.Command<>nil) then
    +      Item.Command.OnExecute:=@PopUpAloneMenu;
     end;
     
    -procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu;
    +procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu(Sender: TObject);
     var
       ActiveEditor: TSourceEditorInterface;
       ScreenXY: TPoint;
    @@ -265,17 +296,10 @@
       if ActiveEditor=nil then
         Exit;
       ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
    -
       DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
     end;
    +{%endregion}
     
    -{ TIDEToolButton_DropDown }
    -
    -procedure TIDEToolButton_DropDown.DoOnAdded;
    -begin
    -  Style := tbsDropDown;  // not in constructor
    -end;
    -
     { TIDEToolButtonsEnumerator }
     
     constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
    @@ -285,6 +309,7 @@
       FPosition := -1;
     end;
     
    +
     function TIDEToolButtonsEnumerator.GetCurrent: TIDEToolButton;
     begin
       Result := FList[FPosition];
    Index: ide/keymapping.pp
    ===================================================================
    --- ide/keymapping.pp	(revision 61652)
    +++ ide/keymapping.pp	(working copy)
    @@ -509,6 +509,7 @@
         ecNewForm                 : Result:= lisMenuNewForm;
         ecOpen                    : Result:= lisMenuOpen;
         ecOpenUnit                : Result:= lisMenuOpenUnit;
    +    ecOpenRecent              : Result:= lisTBOpenRecent;
         ecRevert                  : Result:= lisMenuRevert;
         ecSave                    : Result:= lisSave;
         ecSaveAs                  : Result:= lisMenuSaveAs;
    @@ -579,6 +580,7 @@
         ecJumpToNextError         : Result:= lisMenuJumpToNextError;
         ecJumpToPrevError         : Result:= lisMenuJumpToPrevError;
         ecGotoIncludeDirective    : Result:= srkmecGotoIncludeDirective;
    +    ecJumpToSection           : Result:= lisMenuJumpTo;
         ecJumpToInterface         : Result:= lisMenuJumpToInterface;
         ecJumpToInterfaceUses     : Result:= lisMenuJumpToInterfaceUses;
         ecJumpToImplementation    : Result:= lisMenuJumpToImplementation;
    @@ -652,6 +654,7 @@
         ecNewProject              : Result:= lisMenuNewProject;
         ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
         ecOpenProject             : Result:= lisMenuOpenProject;
    +    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
         ecCloseProject            : Result:= lisMenuCloseProject;
         ecSaveProject             : Result:= lisMenuSaveProject;
         ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
    @@ -705,6 +708,7 @@
         ecOpenPackage             : Result:= lisMenuOpenPackage;
         ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
         ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
    +    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
         ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
         ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
         ecPackageGraph            : Result:= lisMenuPackageGraph;
    @@ -2886,6 +2890,7 @@
       AddDefault(C, 'Find block other end', srkmecFindBlockOtherEnd, ecFindBlockOtherEnd);
       AddDefault(C, 'Find block start', srkmecFindBlockStart, ecFindBlockStart);
       AddDefault(C, 'Goto include directive', lisMenuGotoIncludeDirective, ecGotoIncludeDirective);
    +  AddDefault(C, 'Jump to Section', lisMenuJumpTo, ecJumpToSection);
       AddDefault(C, 'Jump to Interface', lisMenuJumpToInterface, ecJumpToInterface);
       AddDefault(C, 'Jump to Interface uses', lisMenuJumpToInterfaceUses, ecJumpToInterfaceUses);
       AddDefault(C, 'Jump to Implementation', lisMenuJumpToImplementation, ecJumpToImplementation);
    @@ -3027,6 +3032,7 @@
       AddDefault(C, 'NewForm', lisMenuNewForm, ecNewForm);
       AddDefault(C, 'Open', lisOpen, ecOpen);
       AddDefault(C, 'OpenUnit', lisOpenUnit, ecOpenUnit);
    +  AddDefault(C, 'OpenRecent', lisKMOpenRecent, ecOpenRecent);
       AddDefault(C, 'Revert', lisMenuRevert, ecRevert);
       AddDefault(C, 'Save', lisSave, ecSave);
       AddDefault(C, 'SaveAs', lisKMSaveAs, ecSaveAs);
    @@ -3074,6 +3080,7 @@
       AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
       AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
       AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
    +  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
       AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
       AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
       AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
    @@ -3129,6 +3136,7 @@
       AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
       AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
       AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
    +  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
       AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
       AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
       AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
    Index: ide/lazarusidestrconsts.pas
    ===================================================================
    --- ide/lazarusidestrconsts.pas	(revision 61652)
    +++ ide/lazarusidestrconsts.pas	(working copy)
    @@ -252,6 +252,7 @@
       lisPathOfTheMakeUtility = 'Path of the make utility';
       lisProjectMacroProperties = 'Project macro properties';
       lisOpenProject2 = 'Open project';
    +  lisKMOpenRecentProject = 'Open recent project';
       lisFileHasNoProject = 'File has no project';
       lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
          'The file "%s" is not a Lazarus project.'
    @@ -307,6 +308,7 @@
       lisPkgEditPublishPackage = 'Publish Package';
       lisPERevertPackage = 'Revert Package';
       lisMenuOpenRecent = 'Open &Recent';
    +  lisTBOpenRecent = 'Open Recent';
       lisMenuSave = '&Save';
       lisMenuSaveAs = 'Save &As ...';
       lisKMSaveAs = 'SaveAs';
    @@ -4129,6 +4131,7 @@
       lisKMNewPackage = 'New package';
       lisCompPalOpenPackage = 'Open package';
       lisKMOpenPackageFile = 'Open package file';
    +  lisKMOpenRecentPackage = 'Open recent package';
       lisCPOpenPackage = 'Open Package %s';
       lisFilterAllMessagesOfType = 'Filter all messages of type %s';
       lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
    @@ -5095,6 +5098,7 @@
     
       // Standard File menu
       lisKMNewUnit = 'New Unit';
    +  lisKMOpenRecent = 'Open Recent';
     
       // Standard Help menu
       lisMenuTemplateAbout = 'About';
    Index: ide/main.pp
    ===================================================================
    --- ide/main.pp	(revision 61652)
    +++ ide/main.pp	(working copy)
    @@ -2893,6 +2893,10 @@
           ToolButton.ToolButtonClass := ToolButtonClass;
       end;
     
    +  // See also in ToolBarIntf:
    +  //  function GetCommand_DropDown
    +  //  function GetCommand_ButtonDrop
    +
     var
       xBtnItem: TIDEButtonCommand;
     begin
    @@ -2903,6 +2907,7 @@
         itmFileNewOther.Command:=GetCommand(ecNew);
         itmFileOpen.Command:=GetCommand(ecOpen, nil, TOpenFileToolButton);
         itmFileOpenUnit.Command:=GetCommand(ecOpenUnit);
    +    GetCommand_ButtonDrop(ecOpenRecent, itmFileRecentOpen);
         itmFileRevert.Command:=GetCommand(ecRevert);
         itmFileSave.Command:=GetCommand(ecSave);
         itmFileSaveAs.Command:=GetCommand(ecSaveAs);
    @@ -2955,11 +2960,12 @@
         itmSetFreeBookmark.Command:=GetCommand(ecSetFreeBookmark);
         itmJumpToNextBookmark.Command:=GetCommand(ecNextBookmark);
         itmJumpToPrevBookmark.Command:=GetCommand(ecPrevBookmark);
    -    itmJumpToInterface.Command:=GetCommand(ecJumpToInterface, nil, TJumpToSectionToolButton);
    -    itmJumpToInterfaceUses.Command:=GetCommand(ecJumpToInterfaceUses, nil, TJumpToSectionToolButton);
    -    itmJumpToImplementation.Command:=GetCommand(ecJumpToImplementation, nil, TJumpToSectionToolButton);
    -    itmJumpToImplementationUses.Command:=GetCommand(ecJumpToImplementationUses, nil, TJumpToSectionToolButton);
    -    itmJumpToInitialization.Command:=GetCommand(ecJumpToInitialization, nil, TJumpToSectionToolButton);
    +    GetCommand_ButtonDrop(ecJumpToSection, itmJumpToSection);
    +    itmJumpToInterface.Command:=GetCommand_DropDown(ecJumpToInterface, itmJumpToSection);
    +    itmJumpToInterfaceUses.Command:=GetCommand_DropDown(ecJumpToInterfaceUses, itmJumpToSection);
    +    itmJumpToImplementation.Command:=GetCommand_DropDown(ecJumpToImplementation, itmJumpToSection);
    +    itmJumpToImplementationUses.Command:=GetCommand_DropDown(ecJumpToImplementationUses, itmJumpToSection);
    +    itmJumpToInitialization.Command:=GetCommand_DropDown(ecJumpToInitialization, itmJumpToSection);
         GetCmdAndBtn(ecJumpToProcedureHeader, xBtnItem);
         xBtnItem.Caption := lisMenuJumpToProcedureHeader;
         xBtnItem.OnClick := @SourceEditorManager.JumpToProcedureHeaderClicked;
    @@ -3047,7 +3053,8 @@
         // project menu
         itmProjectNew.Command:=GetCommand(ecNewProject);
         itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
    -    itmProjectOpen.Command:=GetCommand(ecOpenProject);
    +    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
    +    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
         itmProjectClose.Command:=GetCommand(ecCloseProject);
         itmProjectSave.Command:=GetCommand(ecSaveProject);
         itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
    @@ -3093,8 +3100,9 @@
         // package menu
         itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
         itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
    -    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
    +    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
         itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
    +    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
         itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
         itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
         itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
    Index: ide/mainbase.pas
    ===================================================================
    --- ide/mainbase.pas	(revision 61652)
    +++ ide/mainbase.pas	(working copy)
    @@ -93,7 +93,7 @@
       protected
         FNeedUpdateHighlighters: boolean;
     
    -    function CreateMenuSeparator : TMenuItem;
    +    function CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
         procedure CreateMenuItem(Section: TIDEMenuSection;
                                  var MenuCommand: TIDEMenuCommand;
                                  const MenuItemName, MenuItemCaption: String;
    @@ -204,13 +204,6 @@
         property DisplayState: TDisplayState read FDisplayState write SetDisplayState;
       end;
     
    -  { TJumpToSectionToolButton }
    -
    -  TJumpToSectionToolButton = class(TIDEToolButton_DropDown)
    -  protected
    -    procedure RefreshMenu; override;
    -  end;
    -
       { TSetBuildModeToolButton }
     
       TSetBuildModeToolButton = class(TIDEToolButton)
    @@ -608,19 +601,6 @@
       Style := tbsDropDown;
     end;
     
    -{ TJumpToSectionToolButton }
    -
    -procedure TJumpToSectionToolButton.RefreshMenu;
    -begin
    -  AddMenuItem(MainIDEBar.itmJumpToInterface);
    -  AddMenuItem(MainIDEBar.itmJumpToInterfaceUses);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(MainIDEBar.itmJumpToImplementation);
    -  AddMenuItem(MainIDEBar.itmJumpToImplementationUses);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(MainIDEBar.itmJumpToInitialization);
    -end;
    -
     {$IFDEF LCLCocoa}
     var
       mnuApple: TIDEMenuSection = nil;
    @@ -953,10 +933,13 @@
       {$ENDIF}
     end;
     
    -function TMainIDEBase.CreateMenuSeparator : TMenuItem;
    +var
    +  SeparatorNum: Integer=0;
    +
    +function TMainIDEBase.CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
     begin
    -  Result := TMenuItem.Create(MainIDEBar);
    -  Result.Caption := '-';
    +  Inc(SeparatorNum);
    +  CreateMenuItem(Section, Result, 'Separator'+IntToStr(SeparatorNum), '-');  // Result - var parameter
     end;
     
     procedure TMainIDEBase.CreateMenuItem(Section: TIDEMenuSection;
    @@ -1144,8 +1127,10 @@
     
         CreateMenuItem(ParentMI,itmJumpToInterface,'itmJumpToInterface',lisMenuJumpToInterface, 'menu_jumpto_interface');
         CreateMenuItem(ParentMI,itmJumpToInterfaceUses,'itmJumpToInterfaceUses',lisMenuJumpToInterfaceUses, 'menu_jumpto_interfaceuses');
    +    CreateMenuSeparator(ParentMI);
         CreateMenuItem(ParentMI,itmJumpToImplementation,'itmJumpToImplementation',lisMenuJumpToImplementation, 'menu_jumpto_implementation');
         CreateMenuItem(ParentMI,itmJumpToImplementationUses,'itmJumpToImplementationUses',lisMenuJumpToImplementationUses, 'menu_jumpto_implementationuses');
    +    CreateMenuSeparator(ParentMI);
         CreateMenuItem(ParentMI,itmJumpToInitialization,'itmJumpToInitialization',lisMenuJumpToInitialization, 'menu_jumpto_initialization');
     
         CreateMenuSeparatorSection(mnuSearch,itmBookmarks,'itmBookmarks');
    @@ -1409,7 +1394,7 @@
         CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
         CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
         CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
    -    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
    +    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
     
         CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
         ParentMI:=itmPkgUnits;
    Index: ide/sourceeditor.pp
    ===================================================================
    --- ide/sourceeditor.pp	(revision 61652)
    +++ ide/sourceeditor.pp	(working copy)
    @@ -1369,9 +1369,7 @@
         SrcEditMenuClearFileBookmark: TIDEMenuCommand;
         SrcEditMenuClearAllBookmark: TIDEMenuCommand;
         SrcEditMenuGotoBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
    -    SrcEditMenuGotoBookmarks: TIDEMenuCommand;
         SrcEditMenuToggleBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
    -    SrcEditMenuToggleBookmarks: TIDEMenuCommand;
         // debugging
         SrcEditMenuToggleBreakpoint: TIDEMenuCommand;
         SrcEditMenuRunToCursor: TIDEMenuCommand;
    @@ -1436,27 +1434,7 @@
       EnglishModifiedLGPLNotice: string;
       EnglishMITNotice: string;
     
    -type
     
    -  { TToolButton_GotoBookmarks }
    -
    -  TToolButton_GotoBookmarks = class(TIDEToolButton_ButtonDrop)
    -  protected
    -    procedure RefreshMenu; override;
    -  public
    -    class procedure ShowAloneMenu(Sender: TObject); static;
    -  end;
    -
    -  { TToolButton_ToggleBookmarks }
    -
    -  TToolButton_ToggleBookmarks = class(TIDEToolButton_ButtonDrop)
    -  protected
    -    procedure RefreshMenu; override;
    -  public
    -    class procedure ShowAloneMenu(Sender: TObject); static;
    -  end;
    -
    -
     implementation
     
     {$R *.lfm}
    @@ -1711,13 +1689,6 @@
           SrcEditMenuPrevBookmark:=RegisterIDEMenuCommand(AParent,
               'Goto previous Bookmark',uemPrevBookmark, nil,
               @ExecuteIdeMenuClick, nil, 'menu_search_previous_bookmark');
    -
    -      {For toolbar only. Hidden in menu.}
    -      SrcEditMenuGotoBookmarks:=RegisterIDEMenuCommand(AParent,
    -          'Goto bookmarks', uemGotoBookmarks,
    -          nil, TNotifyProcedure(@TToolButton_GotoBookmarks.ShowAloneMenu), nil,
    -          'menu_goto_bookmarks');
    -      SrcEditMenuGotoBookmarks.Visible:=False;
       {%endregion}
     
       {%region *** Toggle Bookmarks Submenu ***}
    @@ -1739,13 +1710,6 @@
               'Clear Bookmark for current file',srkmecClearBookmarkForFile, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_file_bookmarks');
           SrcEditMenuClearAllBookmark:=RegisterIDEMenuCommand(AParent,
               'Clear all Bookmark',srkmecClearAllBookmark, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_all_bookmarks');
    -
    -      {For toolbar only. Hidden in menu.}
    -      SrcEditMenuToggleBookmarks:=RegisterIDEMenuCommand(AParent,
    -          'Toggle bookmarks', uemToggleBookmarks,
    -          nil, TNotifyProcedure(@TToolButton_ToggleBookmarks.ShowAloneMenu), nil,
    -          'menu_toggle_bookmarks');
    -      SrcEditMenuToggleBookmarks.Visible:=False;
       {%endregion}
     
       {%region *** Debug Section ***}
    @@ -1854,51 +1818,6 @@
       Result:=CompareFilenames(AnsiString(FileNameStr),SE1.FileName);
     end;
     
    -{ TToolButton_GotoBookmarks }
    -
    -procedure TToolButton_GotoBookmarks.RefreshMenu;
    -begin
    -  AddMenuItems(SrcEditMenuGotoBookmark);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItems([
    -    SrcEditMenuPrevBookmark,
    -    SrcEditMenuNextBookmark]);
    -end;
    -
    -class procedure TToolButton_GotoBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
    -const
    -  Btn: TToolButton_GotoBookmarks=nil;  // static var
    -begin
    -  if Btn = nil then
    -    Btn := TToolButton_GotoBookmarks.Create(Application);
    -  Btn.PopUpAloneMenu;
    -  // Btn should not be destroyed immediately after PopUp
    -end;
    -
    -
    -{ TToolButton_ToggleBookmarks }
    -
    -procedure TToolButton_ToggleBookmarks.RefreshMenu;
    -begin
    -  AddMenuItems(SrcEditMenuToggleBookmark);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItem(SrcEditMenuSetFreeBookmark);
    -  DropdownMenu.Items.AddSeparator;
    -  AddMenuItems([
    -    SrcEditMenuClearFileBookmark,
    -    SrcEditMenuClearAllBookmark]);
    -end;
    -
    -class procedure TToolButton_ToggleBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
    -const
    -  Btn: TToolButton_ToggleBookmarks=nil;  // static var
    -begin
    -  if Btn = nil then
    -    Btn := TToolButton_ToggleBookmarks.Create(Application);
    -  Btn.PopUpAloneMenu;
    -  // Btn should not be destroyed immediately after PopUp
    -end;
    -
     { TSourceEditorWordCompletion }
     
     constructor TSourceEditorWordCompletion.Create;
    @@ -10704,6 +10623,10 @@
           ToolButton.ToolButtonClass := ToolButtonClass;
       end;
     
    +  // See also in ToolBarIntf:
    +  //  function GetCommand_DropDown
    +  //  function GetCommand_ButtonDrop
    +
     var
       i: Integer;
     begin
    @@ -10769,14 +10692,13 @@
       SrcEditMenuClearFileBookmark.Command:=GetCommand(ecClearBookmarkForFile);
       SrcEditMenuClearAllBookmark.Command:=GetCommand(ecClearAllBookmark);
     
    -  SrcEditMenuGotoBookmarks.Command:=GetCommand(ecGotoBookmarks, TToolButton_GotoBookmarks);
    -  SrcEditMenuToggleBookmarks.Command:=GetCommand(ecToggleBookmarks, TToolButton_ToggleBookmarks);
    -
       for i in TBookmarkNumRange do
         SrcEditMenuGotoBookmark[i].Command := GetCommand(ecGotoMarker0 + i);
    +  GetCommand_ButtonDrop(ecGotoBookmarks ,SrcEditSubMenuGotoBookmarks);        // [ ▼]
     
       for i in TBookmarkNumRange do
         SrcEditMenuToggleBookmark[i].Command := GetCommand(ecToggleMarker0 + i);
    +  GetCommand_ButtonDrop(ecToggleBookmarks ,SrcEditSubMenuToggleBookmarks);    // [ ▼]
     
       {%region *** Source Section ***}
         SrcEditMenuEncloseSelection.Command:=GetCommand(ecSelectionEnclose);
    Index: images/copyright.txt
    ===================================================================
    --- images/copyright.txt	(revision 61652)
    +++ images/copyright.txt	(working copy)
    @@ -169,6 +169,9 @@
     	state_warning_150.png
     	state_warning_200.png
     
    +packages directory
    +	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
    +
     --------------------------------------------------------------------------------
     
     The following component palette and menu/toolbar icons (including equally named
    Index: images/laz_images_list.txt
    ===================================================================
    --- images/laz_images_list.txt	(revision 61652)
    +++ images/laz_images_list.txt	(working copy)
    @@ -945,6 +945,9 @@
     packages/pkg_open.png
     packages/pkg_open_150.png
     packages/pkg_open_200.png
    +packages/pkg_open_recent.png
    +packages/pkg_open_recent_150.png
    +packages/pkg_open_recent_200.png
     packages/pkg_package_autoinstall.png
     packages/pkg_package_autoinstall_150.png
     packages/pkg_package_autoinstall_200.png
    
    patch5.diff (31,545 bytes)

Activities

FTurtle

2019-07-24 20:30

reporter  

patch.diff (10,114 bytes)
Index: components/ideintf/idecommands.pas
===================================================================
--- components/ideintf/idecommands.pas	(revision 61618)
+++ components/ideintf/idecommands.pas	(working copy)
@@ -302,19 +302,20 @@
   ecNewProject              = ecFirstLazarus + 500;
   ecNewProjectFromFile      = ecFirstLazarus + 501;
   ecOpenProject             = ecFirstLazarus + 502;
-  ecCloseProject            = ecFirstLazarus + 503;
-  ecSaveProject             = ecFirstLazarus + 504;
-  ecSaveProjectAs           = ecFirstLazarus + 505;
-  ecPublishProject          = ecFirstLazarus + 506;
-  ecProjectInspector        = ecFirstLazarus + 507;
-  ecAddCurUnitToProj        = ecFirstLazarus + 508;
-  ecRemoveFromProj          = ecFirstLazarus + 509;
-  ecViewProjectUnits        = ecFirstLazarus + 510;
-  ecViewProjectForms        = ecFirstLazarus + 511;
-  ecViewProjectSource       = ecFirstLazarus + 512;
-  ecProjectOptions          = ecFirstLazarus + 513;
-  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
-  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
+  ecOpenRecentProject       = ecFirstLazarus + 503;
+  ecCloseProject            = ecFirstLazarus + 504;
+  ecSaveProject             = ecFirstLazarus + 505;
+  ecSaveProjectAs           = ecFirstLazarus + 506;
+  ecPublishProject          = ecFirstLazarus + 507;
+  ecProjectInspector        = ecFirstLazarus + 508;
+  ecAddCurUnitToProj        = ecFirstLazarus + 509;
+  ecRemoveFromProj          = ecFirstLazarus + 510;
+  ecViewProjectUnits        = ecFirstLazarus + 511;
+  ecViewProjectForms        = ecFirstLazarus + 512;
+  ecViewProjectSource       = ecFirstLazarus + 513;
+  ecProjectOptions          = ecFirstLazarus + 514;
+  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
+  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
 
   // package menu
   ecOpenPackage             = ecFirstLazarus + 600;
Index: components/ideintf/toolbarintf.pas
===================================================================
--- components/ideintf/toolbarintf.pas	(revision 61618)
+++ components/ideintf/toolbarintf.pas	(working copy)
@@ -18,7 +18,7 @@
 uses
   Classes, SysUtils,
   // LCL
-  Controls, ComCtrls, Menus, Forms,
+  Controls, ComCtrls, Menus, Forms, LCLType,
   // IdeIntf
   IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
 
@@ -29,6 +29,7 @@
 
   TIDEButtonCommand = class(TIDESpecialCommand)
   private
+    FTag: PtrInt;
     FToolButtonClass: TIDEToolButtonClass;
     FToolButtons: TIDEToolButtons;
   protected
@@ -46,6 +47,7 @@
     constructor Create(const TheName: string); override;
     destructor Destroy; override;
   public
+    property Tag: PtrInt read FTag write FTag;
     property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
     property ToolButtons: TIDEToolButtons read FToolButtons;
   end;
@@ -64,7 +66,7 @@
     property Item: TIDEButtonCommand read FItem write FItem;
   end;
 
-  { TIDEToolButtonWithArrow }
+{ TIDEToolButtonWithArrow }  // will be removed with descendants after complete switching on use TIDEToolButton_WithArrow
 
   TIDEToolButtonWithArrow = class(TIDEToolButton)
   protected
@@ -93,7 +95,39 @@
     procedure DoOnAdded; override;
   end;
 
+  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
+  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButtonButtonDrop;
+  TIDEToolButton_DropDown_Class = class of TIDEToolButtonDropDown;
 
+  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
+
+  TIDEToolButton_WithArrow = class(TIDEToolButton)
+  private
+    function GetSection: TIDEMenuSection;
+  protected
+    procedure DoOnMenuPopup(Sender: TObject);
+    procedure RefreshMenu; virtual;
+    property Section: TIDEMenuSection read GetSection;
+  public
+    constructor Create(AOwner: TComponent); override;
+  end;
+
+  { TIDEToolButtonDropDown }    // [  ][▼]
+
+  TIDEToolButtonDropDown = class(TIDEToolButton_WithArrow)
+  public
+    procedure DoOnAdded; override;
+  end;
+
+  { TIDEToolButtonButtonDrop }    // [ ▼]
+
+  TIDEToolButtonButtonDrop = class(TIDEToolButton_WithArrow)
+  protected
+    procedure PopUpAloneMenu(Sender: TObject);
+  public
+    procedure DoOnAdded; override;
+  end;
+
   TIDEToolButtonCategory = class
   private
     FButtons: TFPList;
@@ -171,6 +205,7 @@
   const aCommand: TIDECommand): TIDEButtonCommand;
 function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
 
+
 implementation
 
 function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
@@ -276,6 +311,65 @@
   Style := tbsDropDown;  // not in constructor
 end;
 
+{ TIDEToolButton_WithArrow }
+
+constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  DropdownMenu := TPopupMenu.Create(Self);
+  DropdownMenu.Images := IDEImages.Images_16;
+  DropdownMenu.OnPopup := @DoOnMenuPopup;
+end;
+
+function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
+begin
+  Result:=nil;
+  if (Item<>nil) then
+    if (Item.Command<>nil) then
+      Result:=TIDEMenuSection(Item.Tag);
+end;
+
+procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
+begin
+  DropdownMenu.Items.Clear;
+  RefreshMenu;
+end;
+
+procedure TIDEToolButton_WithArrow.RefreshMenu;
+begin
+  if Section<>nil then
+    DropdownMenu.Items.Assign(Section.MenuItem);
+end;
+
+{ TIDEToolButtonDropDown }
+
+procedure TIDEToolButtonDropDown.DoOnAdded;
+begin
+  Style := tbsDropDown;  // not in constructor
+end;
+
+{ TIDEToolButtonButtonDrop }
+
+procedure TIDEToolButtonButtonDrop.DoOnAdded;
+begin
+  Style := tbsButtonDrop;  // not in constructor
+  if (Item<>nil) then
+    if (Item.Command<>nil) then
+      Item.Command.OnExecute:=@PopUpAloneMenu;
+end;
+
+procedure TIDEToolButtonButtonDrop.PopUpAloneMenu(Sender: TObject);
+var
+  ActiveEditor: TSourceEditorInterface;
+  ScreenXY: TPoint;
+begin
+  ActiveEditor := SourceEditorManagerIntf.ActiveEditor;
+  if ActiveEditor=nil then
+    Exit;
+  ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
+  DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
+end;
+
 { TIDEToolButtonsEnumerator }
 
 constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
Index: ide/keymapping.pp
===================================================================
--- ide/keymapping.pp	(revision 61618)
+++ ide/keymapping.pp	(working copy)
@@ -652,6 +652,7 @@
     ecNewProject              : Result:= lisMenuNewProject;
     ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
     ecOpenProject             : Result:= lisMenuOpenProject;
+    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
     ecCloseProject            : Result:= lisMenuCloseProject;
     ecSaveProject             : Result:= lisMenuSaveProject;
     ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
@@ -3074,6 +3075,7 @@
   AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
   AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
   AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
+  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
   AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
   AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
   AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
Index: ide/lazarusidestrconsts.pas
===================================================================
--- ide/lazarusidestrconsts.pas	(revision 61618)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -252,6 +252,7 @@
   lisPathOfTheMakeUtility = 'Path of the make utility';
   lisProjectMacroProperties = 'Project macro properties';
   lisOpenProject2 = 'Open project';
+  lisKMOpenRecentProject = 'Open recent project';
   lisFileHasNoProject = 'File has no project';
   lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
      'The file "%s" is not a Lazarus project.'
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 61618)
+++ ide/main.pp	(working copy)
@@ -2891,6 +2891,37 @@
       ToolButton.ToolButtonClass := ToolButtonClass;
   end;
 
+  function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;
+             AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
+  var
+    ButtonCommand: TIDEButtonCommand;
+  begin
+    Result:=IDECommandList.FindIDECommand(ACommand);
+    if Result=nil then
+      Exit(nil);
+    ButtonCommand:=RegisterIDEButtonCommand(Result);
+    ButtonCommand.ToolButtonClass:=AButtonClass;
+    if AButtonClass.InheritsFrom(TIDEToolButtonButtonDrop) then
+      ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
+    ButtonCommand.Tag:=PtrInt(AMenuSection);
+  end;
+
+  function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
+      AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
+  begin
+    if AButtonClass=nil then
+      AButtonClass:=TIDEToolButtonDropDown;
+    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+  end;
+
+  function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
+      AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
+  begin
+    if AButtonClass=nil then
+      AButtonClass:=TIDEToolButtonButtonDrop;
+    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+  end;
+
 var
   xBtnItem: TIDEButtonCommand;
 begin
@@ -3045,7 +3076,8 @@
     // project menu
     itmProjectNew.Command:=GetCommand(ecNewProject);
     itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
-    itmProjectOpen.Command:=GetCommand(ecOpenProject);
+    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
+    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
     itmProjectClose.Command:=GetCommand(ecCloseProject);
     itmProjectSave.Command:=GetCommand(ecSaveProject);
     itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
patch.diff (10,114 bytes)

FTurtle

2019-07-24 20:30

reporter  

pic1.png (17,593 bytes)
pic1.png (17,593 bytes)

FTurtle

2019-07-24 20:31

reporter  

pic2.png (19,058 bytes)
pic2.png (19,058 bytes)

FTurtle

2019-07-24 20:31

reporter  

pic3.png (16,646 bytes)
pic3.png (16,646 bytes)

FTurtle

2019-07-25 18:50

reporter   ~0117398

New patch: patch2.diff
Added:

1. Image for command "Open Recent Package"
2. New toolbutton "Open Recent Package"
3. Separate popup menu by shortcut (shortcut not assigned by default)
4. Section with arrow for toolbutton "Open Package File"

patch2.diff (15,122 bytes)
Index: components/ideintf/idecommands.pas
===================================================================
--- components/ideintf/idecommands.pas	(revision 61618)
+++ components/ideintf/idecommands.pas	(working copy)
@@ -302,31 +302,33 @@
   ecNewProject              = ecFirstLazarus + 500;
   ecNewProjectFromFile      = ecFirstLazarus + 501;
   ecOpenProject             = ecFirstLazarus + 502;
-  ecCloseProject            = ecFirstLazarus + 503;
-  ecSaveProject             = ecFirstLazarus + 504;
-  ecSaveProjectAs           = ecFirstLazarus + 505;
-  ecPublishProject          = ecFirstLazarus + 506;
-  ecProjectInspector        = ecFirstLazarus + 507;
-  ecAddCurUnitToProj        = ecFirstLazarus + 508;
-  ecRemoveFromProj          = ecFirstLazarus + 509;
-  ecViewProjectUnits        = ecFirstLazarus + 510;
-  ecViewProjectForms        = ecFirstLazarus + 511;
-  ecViewProjectSource       = ecFirstLazarus + 512;
-  ecProjectOptions          = ecFirstLazarus + 513;
-  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
-  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
+  ecOpenRecentProject       = ecFirstLazarus + 503;
+  ecCloseProject            = ecFirstLazarus + 504;
+  ecSaveProject             = ecFirstLazarus + 505;
+  ecSaveProjectAs           = ecFirstLazarus + 506;
+  ecPublishProject          = ecFirstLazarus + 507;
+  ecProjectInspector        = ecFirstLazarus + 508;
+  ecAddCurUnitToProj        = ecFirstLazarus + 509;
+  ecRemoveFromProj          = ecFirstLazarus + 510;
+  ecViewProjectUnits        = ecFirstLazarus + 511;
+  ecViewProjectForms        = ecFirstLazarus + 512;
+  ecViewProjectSource       = ecFirstLazarus + 513;
+  ecProjectOptions          = ecFirstLazarus + 514;
+  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
+  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
 
   // package menu
   ecOpenPackage             = ecFirstLazarus + 600;
   ecOpenPackageFile         = ecFirstLazarus + 601;
   ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
-  ecAddCurFileToPkg         = ecFirstLazarus + 603;
-  ecNewPkgComponent         = ecFirstLazarus + 604;
-  ecPackageGraph            = ecFirstLazarus + 605;
-  ecPackageLinks            = ecFirstLazarus + 606;
-  ecEditInstallPkgs         = ecFirstLazarus + 607;
-  ecConfigCustomComps       = ecFirstLazarus + 608;
-  ecNewPackage              = ecFirstLazarus + 609;
+  ecOpenRecentPackage       = ecFirstLazarus + 603;
+  ecAddCurFileToPkg         = ecFirstLazarus + 604;
+  ecNewPkgComponent         = ecFirstLazarus + 605;
+  ecPackageGraph            = ecFirstLazarus + 606;
+  ecPackageLinks            = ecFirstLazarus + 607;
+  ecEditInstallPkgs         = ecFirstLazarus + 608;
+  ecConfigCustomComps       = ecFirstLazarus + 609;
+  ecNewPackage              = ecFirstLazarus + 610;
 
   // custom tools menu
   ecExtToolFirst            = ecFirstLazarus + 700;
Index: components/ideintf/toolbarintf.pas
===================================================================
--- components/ideintf/toolbarintf.pas	(revision 61618)
+++ components/ideintf/toolbarintf.pas	(working copy)
@@ -18,7 +18,7 @@
 uses
   Classes, SysUtils,
   // LCL
-  Controls, ComCtrls, Menus, Forms,
+  Controls, ComCtrls, Menus, Forms, LCLType,
   // IdeIntf
   IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
 
@@ -29,6 +29,7 @@
 
   TIDEButtonCommand = class(TIDESpecialCommand)
   private
+    FTag: PtrInt;
     FToolButtonClass: TIDEToolButtonClass;
     FToolButtons: TIDEToolButtons;
   protected
@@ -46,6 +47,7 @@
     constructor Create(const TheName: string); override;
     destructor Destroy; override;
   public
+    property Tag: PtrInt read FTag write FTag;
     property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
     property ToolButtons: TIDEToolButtons read FToolButtons;
   end;
@@ -64,7 +66,7 @@
     property Item: TIDEButtonCommand read FItem write FItem;
   end;
 
-  { TIDEToolButtonWithArrow }
+{ TIDEToolButtonWithArrow }  // will be removed with descendants after complete switching on use TIDEToolButton_WithArrow
 
   TIDEToolButtonWithArrow = class(TIDEToolButton)
   protected
@@ -93,7 +95,39 @@
     procedure DoOnAdded; override;
   end;
 
+  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
+  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButtonButtonDrop;
+  TIDEToolButton_DropDown_Class = class of TIDEToolButtonDropDown;
 
+  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
+
+  TIDEToolButton_WithArrow = class(TIDEToolButton)
+  private
+    function GetSection: TIDEMenuSection;
+  protected
+    procedure DoOnMenuPopup(Sender: TObject);
+    procedure RefreshMenu; virtual;
+    property Section: TIDEMenuSection read GetSection;
+  public
+    constructor Create(AOwner: TComponent); override;
+  end;
+
+  { TIDEToolButtonDropDown }    // [  ][▼]
+
+  TIDEToolButtonDropDown = class(TIDEToolButton_WithArrow)
+  public
+    procedure DoOnAdded; override;
+  end;
+
+  { TIDEToolButtonButtonDrop }    // [ ▼]
+
+  TIDEToolButtonButtonDrop = class(TIDEToolButton_WithArrow)
+  protected
+    procedure PopUpAloneMenu(Sender: TObject);
+  public
+    procedure DoOnAdded; override;
+  end;
+
   TIDEToolButtonCategory = class
   private
     FButtons: TFPList;
@@ -171,6 +205,7 @@
   const aCommand: TIDECommand): TIDEButtonCommand;
 function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
 
+
 implementation
 
 function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
@@ -276,6 +311,65 @@
   Style := tbsDropDown;  // not in constructor
 end;
 
+{ TIDEToolButton_WithArrow }
+
+constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  DropdownMenu := TPopupMenu.Create(Self);
+  DropdownMenu.Images := IDEImages.Images_16;
+  DropdownMenu.OnPopup := @DoOnMenuPopup;
+end;
+
+function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
+begin
+  Result:=nil;
+  if (Item<>nil) then
+    if (Item.Command<>nil) then
+      Result:=TIDEMenuSection(Item.Tag);
+end;
+
+procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
+begin
+  DropdownMenu.Items.Clear;
+  RefreshMenu;
+end;
+
+procedure TIDEToolButton_WithArrow.RefreshMenu;
+begin
+  if Section<>nil then
+    DropdownMenu.Items.Assign(Section.MenuItem);
+end;
+
+{ TIDEToolButtonDropDown }
+
+procedure TIDEToolButtonDropDown.DoOnAdded;
+begin
+  Style := tbsDropDown;  // not in constructor
+end;
+
+{ TIDEToolButtonButtonDrop }
+
+procedure TIDEToolButtonButtonDrop.DoOnAdded;
+begin
+  Style := tbsButtonDrop;  // not in constructor
+  if (Item<>nil) then
+    if (Item.Command<>nil) then
+      Item.Command.OnExecute:=@PopUpAloneMenu;
+end;
+
+procedure TIDEToolButtonButtonDrop.PopUpAloneMenu(Sender: TObject);
+var
+  ActiveEditor: TSourceEditorInterface;
+  ScreenXY: TPoint;
+begin
+  ActiveEditor := SourceEditorManagerIntf.ActiveEditor;
+  if ActiveEditor=nil then
+    Exit;
+  ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
+  DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
+end;
+
 { TIDEToolButtonsEnumerator }
 
 constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
Index: ide/keymapping.pp
===================================================================
--- ide/keymapping.pp	(revision 61618)
+++ ide/keymapping.pp	(working copy)
@@ -652,6 +652,7 @@
     ecNewProject              : Result:= lisMenuNewProject;
     ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
     ecOpenProject             : Result:= lisMenuOpenProject;
+    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
     ecCloseProject            : Result:= lisMenuCloseProject;
     ecSaveProject             : Result:= lisMenuSaveProject;
     ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
@@ -705,6 +706,7 @@
     ecOpenPackage             : Result:= lisMenuOpenPackage;
     ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
     ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
+    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
     ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
     ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
     ecPackageGraph            : Result:= lisMenuPackageGraph;
@@ -3074,6 +3076,7 @@
   AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
   AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
   AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
+  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
   AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
   AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
   AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
@@ -3129,6 +3132,7 @@
   AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
   AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
   AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
+  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
   AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
   AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
   AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
Index: ide/lazarusidestrconsts.pas
===================================================================
--- ide/lazarusidestrconsts.pas	(revision 61618)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -252,6 +252,7 @@
   lisPathOfTheMakeUtility = 'Path of the make utility';
   lisProjectMacroProperties = 'Project macro properties';
   lisOpenProject2 = 'Open project';
+  lisKMOpenRecentProject = 'Open recent project';
   lisFileHasNoProject = 'File has no project';
   lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
      'The file "%s" is not a Lazarus project.'
@@ -4129,6 +4130,7 @@
   lisKMNewPackage = 'New package';
   lisCompPalOpenPackage = 'Open package';
   lisKMOpenPackageFile = 'Open package file';
+  lisKMOpenRecentPackage = 'Open recent package';
   lisCPOpenPackage = 'Open Package %s';
   lisFilterAllMessagesOfType = 'Filter all messages of type %s';
   lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 61618)
+++ ide/main.pp	(working copy)
@@ -2891,6 +2891,37 @@
       ToolButton.ToolButtonClass := ToolButtonClass;
   end;
 
+  function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;
+             AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
+  var
+    ButtonCommand: TIDEButtonCommand;
+  begin
+    Result:=IDECommandList.FindIDECommand(ACommand);
+    if Result=nil then
+      Exit(nil);
+    ButtonCommand:=RegisterIDEButtonCommand(Result);
+    ButtonCommand.ToolButtonClass:=AButtonClass;
+    if AButtonClass.InheritsFrom(TIDEToolButtonButtonDrop) then
+      ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
+    ButtonCommand.Tag:=PtrInt(AMenuSection);
+  end;
+
+  function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
+      AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
+  begin
+    if AButtonClass=nil then
+      AButtonClass:=TIDEToolButtonDropDown;
+    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+  end;
+
+  function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
+      AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
+  begin
+    if AButtonClass=nil then
+      AButtonClass:=TIDEToolButtonButtonDrop;
+    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+  end;
+
 var
   xBtnItem: TIDEButtonCommand;
 begin
@@ -3045,7 +3076,8 @@
     // project menu
     itmProjectNew.Command:=GetCommand(ecNewProject);
     itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
-    itmProjectOpen.Command:=GetCommand(ecOpenProject);
+    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
+    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
     itmProjectClose.Command:=GetCommand(ecCloseProject);
     itmProjectSave.Command:=GetCommand(ecSaveProject);
     itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
@@ -3091,8 +3123,9 @@
     // package menu
     itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
     itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
-    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
+    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
     itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
+    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
     itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
     itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
     itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
Index: ide/mainbase.pas
===================================================================
--- ide/mainbase.pas	(revision 61618)
+++ ide/mainbase.pas	(working copy)
@@ -1409,7 +1409,7 @@
     CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
     CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
     CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
-    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
+    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
 
     CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
     ParentMI:=itmPkgUnits;
Index: images/copyright.txt
===================================================================
--- images/copyright.txt	(revision 61618)
+++ images/copyright.txt	(working copy)
@@ -169,6 +169,9 @@
 	state_warning_150.png
 	state_warning_200.png
 
+packages directory
+	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
+
 --------------------------------------------------------------------------------
 
 The following component palette and menu/toolbar icons (including equally named
Index: images/laz_images_list.txt
===================================================================
--- images/laz_images_list.txt	(revision 61618)
+++ images/laz_images_list.txt	(working copy)
@@ -945,6 +945,9 @@
 packages/pkg_open.png
 packages/pkg_open_150.png
 packages/pkg_open_200.png
+packages/pkg_open_recent.png
+packages/pkg_open_recent_150.png
+packages/pkg_open_recent_200.png
 packages/pkg_package_autoinstall.png
 packages/pkg_package_autoinstall_150.png
 packages/pkg_package_autoinstall_200.png
patch2.diff (15,122 bytes)
images.zip (4,037 bytes)

FTurtle

2019-07-26 19:21

reporter   ~0117422

Attached new patch: patch3.diff

New in this patch:

1. New toolbutton "Jump to"
2. Separate popup menu by shortcut (shortcut not assigned by default)
3. Fixed method TMainIDEBase.CreateMenuSeparator
4. Added separators to menu Search/Jump to
5. Deleted class TJumpToSectionToolButton

patch3.diff (21,340 bytes)
Index: components/ideintf/idecommands.pas
===================================================================
--- components/ideintf/idecommands.pas	(revision 61623)
+++ components/ideintf/idecommands.pas	(working copy)
@@ -81,13 +81,14 @@
   ecFindBlockStart          = ecFirstLazarus + 22;
   ecOpenFileAtCursor        = ecFirstLazarus + 23;
   ecGotoIncludeDirective    = ecFirstLazarus + 24;
-  ecJumpToInterface         = ecFirstLazarus + 25;
-  ecJumpToInterfaceUses     = ecFirstLazarus + 26;
-  ecJumpToImplementation    = ecFirstLazarus + 27;
-  ecJumpToImplementationUses= ecFirstLazarus + 28;
-  ecJumpToInitialization    = ecFirstLazarus + 29;
-  ecJumpToProcedureHeader   = ecFirstLazarus + 30;
-  ecJumpToProcedureBegin    = ecFirstLazarus + 31;
+  ecJumpToSection           = ecFirstLazarus + 25;
+  ecJumpToInterface         = ecFirstLazarus + 26;
+  ecJumpToInterfaceUses     = ecFirstLazarus + 27;
+  ecJumpToImplementation    = ecFirstLazarus + 28;
+  ecJumpToImplementationUses= ecFirstLazarus + 29;
+  ecJumpToInitialization    = ecFirstLazarus + 30;
+  ecJumpToProcedureHeader   = ecFirstLazarus + 31;
+  ecJumpToProcedureBegin    = ecFirstLazarus + 32;
 
   // edit selection
   ecSelectionUpperCase      = ecFirstLazarus + 50;
@@ -302,31 +303,33 @@
   ecNewProject              = ecFirstLazarus + 500;
   ecNewProjectFromFile      = ecFirstLazarus + 501;
   ecOpenProject             = ecFirstLazarus + 502;
-  ecCloseProject            = ecFirstLazarus + 503;
-  ecSaveProject             = ecFirstLazarus + 504;
-  ecSaveProjectAs           = ecFirstLazarus + 505;
-  ecPublishProject          = ecFirstLazarus + 506;
-  ecProjectInspector        = ecFirstLazarus + 507;
-  ecAddCurUnitToProj        = ecFirstLazarus + 508;
-  ecRemoveFromProj          = ecFirstLazarus + 509;
-  ecViewProjectUnits        = ecFirstLazarus + 510;
-  ecViewProjectForms        = ecFirstLazarus + 511;
-  ecViewProjectSource       = ecFirstLazarus + 512;
-  ecProjectOptions          = ecFirstLazarus + 513;
-  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
-  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
+  ecOpenRecentProject       = ecFirstLazarus + 503;
+  ecCloseProject            = ecFirstLazarus + 504;
+  ecSaveProject             = ecFirstLazarus + 505;
+  ecSaveProjectAs           = ecFirstLazarus + 506;
+  ecPublishProject          = ecFirstLazarus + 507;
+  ecProjectInspector        = ecFirstLazarus + 508;
+  ecAddCurUnitToProj        = ecFirstLazarus + 509;
+  ecRemoveFromProj          = ecFirstLazarus + 510;
+  ecViewProjectUnits        = ecFirstLazarus + 511;
+  ecViewProjectForms        = ecFirstLazarus + 512;
+  ecViewProjectSource       = ecFirstLazarus + 513;
+  ecProjectOptions          = ecFirstLazarus + 514;
+  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
+  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
 
   // package menu
   ecOpenPackage             = ecFirstLazarus + 600;
   ecOpenPackageFile         = ecFirstLazarus + 601;
   ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
-  ecAddCurFileToPkg         = ecFirstLazarus + 603;
-  ecNewPkgComponent         = ecFirstLazarus + 604;
-  ecPackageGraph            = ecFirstLazarus + 605;
-  ecPackageLinks            = ecFirstLazarus + 606;
-  ecEditInstallPkgs         = ecFirstLazarus + 607;
-  ecConfigCustomComps       = ecFirstLazarus + 608;
-  ecNewPackage              = ecFirstLazarus + 609;
+  ecOpenRecentPackage       = ecFirstLazarus + 603;
+  ecAddCurFileToPkg         = ecFirstLazarus + 604;
+  ecNewPkgComponent         = ecFirstLazarus + 605;
+  ecPackageGraph            = ecFirstLazarus + 606;
+  ecPackageLinks            = ecFirstLazarus + 607;
+  ecEditInstallPkgs         = ecFirstLazarus + 608;
+  ecConfigCustomComps       = ecFirstLazarus + 609;
+  ecNewPackage              = ecFirstLazarus + 610;
 
   // custom tools menu
   ecExtToolFirst            = ecFirstLazarus + 700;
Index: components/ideintf/toolbarintf.pas
===================================================================
--- components/ideintf/toolbarintf.pas	(revision 61623)
+++ components/ideintf/toolbarintf.pas	(working copy)
@@ -18,7 +18,7 @@
 uses
   Classes, SysUtils,
   // LCL
-  Controls, ComCtrls, Menus, Forms,
+  Controls, ComCtrls, Menus, Forms, LCLType,
   // IdeIntf
   IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
 
@@ -29,6 +29,7 @@
 
   TIDEButtonCommand = class(TIDESpecialCommand)
   private
+    FTag: PtrInt;
     FToolButtonClass: TIDEToolButtonClass;
     FToolButtons: TIDEToolButtons;
   protected
@@ -46,6 +47,7 @@
     constructor Create(const TheName: string); override;
     destructor Destroy; override;
   public
+    property Tag: PtrInt read FTag write FTag;
     property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
     property ToolButtons: TIDEToolButtons read FToolButtons;
   end;
@@ -64,7 +66,7 @@
     property Item: TIDEButtonCommand read FItem write FItem;
   end;
 
-  { TIDEToolButtonWithArrow }
+{ TIDEToolButtonWithArrow }  // will be removed with descendants after complete switching on use TIDEToolButton_WithArrow
 
   TIDEToolButtonWithArrow = class(TIDEToolButton)
   protected
@@ -93,7 +95,39 @@
     procedure DoOnAdded; override;
   end;
 
+  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
+  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButtonButtonDrop;
+  TIDEToolButton_DropDown_Class = class of TIDEToolButtonDropDown;
 
+  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
+
+  TIDEToolButton_WithArrow = class(TIDEToolButton)
+  private
+    function GetSection: TIDEMenuSection;
+  protected
+    procedure DoOnMenuPopup(Sender: TObject);
+    procedure RefreshMenu; virtual;
+    property Section: TIDEMenuSection read GetSection;
+  public
+    constructor Create(AOwner: TComponent); override;
+  end;
+
+  { TIDEToolButtonDropDown }    // [  ][▼]
+
+  TIDEToolButtonDropDown = class(TIDEToolButton_WithArrow)
+  public
+    procedure DoOnAdded; override;
+  end;
+
+  { TIDEToolButtonButtonDrop }    // [ ▼]
+
+  TIDEToolButtonButtonDrop = class(TIDEToolButton_WithArrow)
+  protected
+    procedure PopUpAloneMenu(Sender: TObject);
+  public
+    procedure DoOnAdded; override;
+  end;
+
   TIDEToolButtonCategory = class
   private
     FButtons: TFPList;
@@ -171,6 +205,7 @@
   const aCommand: TIDECommand): TIDEButtonCommand;
 function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
 
+
 implementation
 
 function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
@@ -276,6 +311,64 @@
   Style := tbsDropDown;  // not in constructor
 end;
 
+{ TIDEToolButton_WithArrow }
+
+constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
+begin
+  inherited Create(AOwner);
+  DropdownMenu := TPopupMenu.Create(Self);
+  DropdownMenu.Images := IDEImages.Images_16;
+  DropdownMenu.OnPopup := @DoOnMenuPopup;
+end;
+
+function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
+begin
+  Result:=nil;
+  if (Item<>nil) then
+    Result:=TIDEMenuSection(Item.Tag);
+end;
+
+procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
+begin
+  DropdownMenu.Items.Clear;
+  RefreshMenu;
+end;
+
+procedure TIDEToolButton_WithArrow.RefreshMenu;
+begin
+  if Section<>nil then
+    DropdownMenu.Items.Assign(Section.MenuItem);
+end;
+
+{ TIDEToolButtonDropDown }
+
+procedure TIDEToolButtonDropDown.DoOnAdded;
+begin
+  Style := tbsDropDown;  // not in constructor
+end;
+
+{ TIDEToolButtonButtonDrop }
+
+procedure TIDEToolButtonButtonDrop.DoOnAdded;
+begin
+  Style := tbsButtonDrop;  // not in constructor
+  if (Item<>nil) then
+    if (Item.Command<>nil) then
+      Item.Command.OnExecute:=@PopUpAloneMenu;
+end;
+
+procedure TIDEToolButtonButtonDrop.PopUpAloneMenu(Sender: TObject);
+var
+  ActiveEditor: TSourceEditorInterface;
+  ScreenXY: TPoint;
+begin
+  ActiveEditor := SourceEditorManagerIntf.ActiveEditor;
+  if ActiveEditor=nil then
+    Exit;
+  ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
+  DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
+end;
+
 { TIDEToolButtonsEnumerator }
 
 constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
Index: ide/keymapping.pp
===================================================================
--- ide/keymapping.pp	(revision 61623)
+++ ide/keymapping.pp	(working copy)
@@ -579,6 +579,7 @@
     ecJumpToNextError         : Result:= lisMenuJumpToNextError;
     ecJumpToPrevError         : Result:= lisMenuJumpToPrevError;
     ecGotoIncludeDirective    : Result:= srkmecGotoIncludeDirective;
+    ecJumpToSection           : Result:= lisMenuJumpTo;
     ecJumpToInterface         : Result:= lisMenuJumpToInterface;
     ecJumpToInterfaceUses     : Result:= lisMenuJumpToInterfaceUses;
     ecJumpToImplementation    : Result:= lisMenuJumpToImplementation;
@@ -652,6 +653,7 @@
     ecNewProject              : Result:= lisMenuNewProject;
     ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
     ecOpenProject             : Result:= lisMenuOpenProject;
+    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
     ecCloseProject            : Result:= lisMenuCloseProject;
     ecSaveProject             : Result:= lisMenuSaveProject;
     ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
@@ -705,6 +707,7 @@
     ecOpenPackage             : Result:= lisMenuOpenPackage;
     ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
     ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
+    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
     ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
     ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
     ecPackageGraph            : Result:= lisMenuPackageGraph;
@@ -2886,6 +2889,7 @@
   AddDefault(C, 'Find block other end', srkmecFindBlockOtherEnd, ecFindBlockOtherEnd);
   AddDefault(C, 'Find block start', srkmecFindBlockStart, ecFindBlockStart);
   AddDefault(C, 'Goto include directive', lisMenuGotoIncludeDirective, ecGotoIncludeDirective);
+  AddDefault(C, 'Jump to Section', lisMenuJumpTo, ecJumpToSection);
   AddDefault(C, 'Jump to Interface', lisMenuJumpToInterface, ecJumpToInterface);
   AddDefault(C, 'Jump to Interface uses', lisMenuJumpToInterfaceUses, ecJumpToInterfaceUses);
   AddDefault(C, 'Jump to Implementation', lisMenuJumpToImplementation, ecJumpToImplementation);
@@ -3074,6 +3078,7 @@
   AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
   AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
   AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
+  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
   AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
   AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
   AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
@@ -3129,6 +3134,7 @@
   AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
   AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
   AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
+  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
   AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
   AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
   AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
Index: ide/lazarusidestrconsts.pas
===================================================================
--- ide/lazarusidestrconsts.pas	(revision 61623)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -252,6 +252,7 @@
   lisPathOfTheMakeUtility = 'Path of the make utility';
   lisProjectMacroProperties = 'Project macro properties';
   lisOpenProject2 = 'Open project';
+  lisKMOpenRecentProject = 'Open recent project';
   lisFileHasNoProject = 'File has no project';
   lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
      'The file "%s" is not a Lazarus project.'
@@ -4129,6 +4130,7 @@
   lisKMNewPackage = 'New package';
   lisCompPalOpenPackage = 'Open package';
   lisKMOpenPackageFile = 'Open package file';
+  lisKMOpenRecentPackage = 'Open recent package';
   lisCPOpenPackage = 'Open Package %s';
   lisFilterAllMessagesOfType = 'Filter all messages of type %s';
   lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 61623)
+++ ide/main.pp	(working copy)
@@ -2891,6 +2891,37 @@
       ToolButton.ToolButtonClass := ToolButtonClass;
   end;
 
+  function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;
+             AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
+  var
+    ButtonCommand: TIDEButtonCommand;
+  begin
+    Result:=IDECommandList.FindIDECommand(ACommand);
+    if Result=nil then
+      Exit(nil);
+    ButtonCommand:=RegisterIDEButtonCommand(Result);
+    ButtonCommand.ToolButtonClass:=AButtonClass;
+    if AButtonClass.InheritsFrom(TIDEToolButtonButtonDrop) then
+      ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
+    ButtonCommand.Tag:=PtrInt(AMenuSection);
+  end;
+
+  function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
+      AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
+  begin
+    if AButtonClass=nil then
+      AButtonClass:=TIDEToolButtonDropDown;
+    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+  end;
+
+  function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
+      AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
+  begin
+    if AButtonClass=nil then
+      AButtonClass:=TIDEToolButtonButtonDrop;
+    Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+  end;
+
 var
   xBtnItem: TIDEButtonCommand;
 begin
@@ -2953,11 +2984,12 @@
     itmSetFreeBookmark.Command:=GetCommand(ecSetFreeBookmark);
     itmJumpToNextBookmark.Command:=GetCommand(ecNextBookmark);
     itmJumpToPrevBookmark.Command:=GetCommand(ecPrevBookmark);
-    itmJumpToInterface.Command:=GetCommand(ecJumpToInterface, nil, TJumpToSectionToolButton);
-    itmJumpToInterfaceUses.Command:=GetCommand(ecJumpToInterfaceUses, nil, TJumpToSectionToolButton);
-    itmJumpToImplementation.Command:=GetCommand(ecJumpToImplementation, nil, TJumpToSectionToolButton);
-    itmJumpToImplementationUses.Command:=GetCommand(ecJumpToImplementationUses, nil, TJumpToSectionToolButton);
-    itmJumpToInitialization.Command:=GetCommand(ecJumpToInitialization, nil, TJumpToSectionToolButton);
+    GetCommand_ButtonDrop(ecJumpToSection, itmJumpToSection);
+    itmJumpToInterface.Command:=GetCommand_DropDown(ecJumpToInterface, itmJumpToSection);
+    itmJumpToInterfaceUses.Command:=GetCommand_DropDown(ecJumpToInterfaceUses, itmJumpToSection);
+    itmJumpToImplementation.Command:=GetCommand_DropDown(ecJumpToImplementation, itmJumpToSection);
+    itmJumpToImplementationUses.Command:=GetCommand_DropDown(ecJumpToImplementationUses, itmJumpToSection);
+    itmJumpToInitialization.Command:=GetCommand_DropDown(ecJumpToInitialization, itmJumpToSection);
     GetCmdAndBtn(ecJumpToProcedureHeader, xBtnItem);
     xBtnItem.Caption := lisMenuJumpToProcedureHeader;
     xBtnItem.OnClick := @SourceEditorManager.JumpToProcedureHeaderClicked;
@@ -3045,7 +3077,8 @@
     // project menu
     itmProjectNew.Command:=GetCommand(ecNewProject);
     itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
-    itmProjectOpen.Command:=GetCommand(ecOpenProject);
+    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
+    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
     itmProjectClose.Command:=GetCommand(ecCloseProject);
     itmProjectSave.Command:=GetCommand(ecSaveProject);
     itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
@@ -3091,8 +3124,9 @@
     // package menu
     itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
     itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
-    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
+    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
     itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
+    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
     itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
     itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
     itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
Index: ide/mainbase.pas
===================================================================
--- ide/mainbase.pas	(revision 61623)
+++ ide/mainbase.pas	(working copy)
@@ -93,7 +93,7 @@
   protected
     FNeedUpdateHighlighters: boolean;
 
-    function CreateMenuSeparator : TMenuItem;
+    function CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
     procedure CreateMenuItem(Section: TIDEMenuSection;
                              var MenuCommand: TIDEMenuCommand;
                              const MenuItemName, MenuItemCaption: String;
@@ -204,13 +204,6 @@
     property DisplayState: TDisplayState read FDisplayState write SetDisplayState;
   end;
 
-  { TJumpToSectionToolButton }
-
-  TJumpToSectionToolButton = class(TIDEToolButton_DropDown)
-  protected
-    procedure RefreshMenu; override;
-  end;
-
   { TSetBuildModeToolButton }
 
   TSetBuildModeToolButton = class(TIDEToolButton)
@@ -608,19 +601,6 @@
   Style := tbsDropDown;
 end;
 
-{ TJumpToSectionToolButton }
-
-procedure TJumpToSectionToolButton.RefreshMenu;
-begin
-  AddMenuItem(MainIDEBar.itmJumpToInterface);
-  AddMenuItem(MainIDEBar.itmJumpToInterfaceUses);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(MainIDEBar.itmJumpToImplementation);
-  AddMenuItem(MainIDEBar.itmJumpToImplementationUses);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(MainIDEBar.itmJumpToInitialization);
-end;
-
 {$IFDEF LCLCocoa}
 var
   mnuApple: TIDEMenuSection = nil;
@@ -953,10 +933,13 @@
   {$ENDIF}
 end;
 
-function TMainIDEBase.CreateMenuSeparator : TMenuItem;
+var
+  SeparatorNum: Integer=0;
+
+function TMainIDEBase.CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
 begin
-  Result := TMenuItem.Create(MainIDEBar);
-  Result.Caption := '-';
+  Inc(SeparatorNum);
+  CreateMenuItem(Section, Result, 'Separator'+IntToStr(SeparatorNum), '-');
 end;
 
 procedure TMainIDEBase.CreateMenuItem(Section: TIDEMenuSection;
@@ -1144,8 +1127,10 @@
 
     CreateMenuItem(ParentMI,itmJumpToInterface,'itmJumpToInterface',lisMenuJumpToInterface, 'menu_jumpto_interface');
     CreateMenuItem(ParentMI,itmJumpToInterfaceUses,'itmJumpToInterfaceUses',lisMenuJumpToInterfaceUses, 'menu_jumpto_interfaceuses');
+    CreateMenuSeparator(ParentMI);
     CreateMenuItem(ParentMI,itmJumpToImplementation,'itmJumpToImplementation',lisMenuJumpToImplementation, 'menu_jumpto_implementation');
     CreateMenuItem(ParentMI,itmJumpToImplementationUses,'itmJumpToImplementationUses',lisMenuJumpToImplementationUses, 'menu_jumpto_implementationuses');
+    CreateMenuSeparator(ParentMI);
     CreateMenuItem(ParentMI,itmJumpToInitialization,'itmJumpToInitialization',lisMenuJumpToInitialization, 'menu_jumpto_initialization');
 
     CreateMenuSeparatorSection(mnuSearch,itmBookmarks,'itmBookmarks');
@@ -1409,7 +1394,7 @@
     CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
     CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
     CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
-    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
+    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
 
     CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
     ParentMI:=itmPkgUnits;
Index: images/copyright.txt
===================================================================
--- images/copyright.txt	(revision 61623)
+++ images/copyright.txt	(working copy)
@@ -169,6 +169,9 @@
 	state_warning_150.png
 	state_warning_200.png
 
+packages directory
+	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
+
 --------------------------------------------------------------------------------
 
 The following component palette and menu/toolbar icons (including equally named
Index: images/laz_images_list.txt
===================================================================
--- images/laz_images_list.txt	(revision 61623)
+++ images/laz_images_list.txt	(working copy)
@@ -945,6 +945,9 @@
 packages/pkg_open.png
 packages/pkg_open_150.png
 packages/pkg_open_200.png
+packages/pkg_open_recent.png
+packages/pkg_open_recent_150.png
+packages/pkg_open_recent_200.png
 packages/pkg_package_autoinstall.png
 packages/pkg_package_autoinstall_150.png
 packages/pkg_package_autoinstall_200.png
patch3.diff (21,340 bytes)

FTurtle

2019-07-29 16:22

reporter   ~0117490

Last edited: 2019-07-29 16:27

View 2 revisions

Attached new patch: patch4.diff

New in this patch:

1. Toolbuttons "Goto Bookmark..." and "Toggle Bookmark..." switched to use new class TIDEToolButtonButtonDrop introduced in patch1.diff (renamed later to TIDEToolButton_ButtonDrop, see 3)
2. Removed classes:

TIDEToolButtonWithArrow
TIDEToolButton_ButtonDrop
TIDEToolButton_DropDown
TToolButton_GotoBookmarks
TToolButton_ToggleBookmarks

3. Renamed classes:

TIDEToolButtonButtonDrop -> TIDEToolButton_ButtonDrop
TIDEToolButtonDropDown -> TIDEToolButton_DropDown



patch4.diff (29,367 bytes)
Index: components/ideintf/idecommands.pas
===================================================================
--- components/ideintf/idecommands.pas	(revision 61640)
+++ components/ideintf/idecommands.pas	(working copy)
@@ -81,13 +81,14 @@
   ecFindBlockStart          = ecFirstLazarus + 22;
   ecOpenFileAtCursor        = ecFirstLazarus + 23;
   ecGotoIncludeDirective    = ecFirstLazarus + 24;
-  ecJumpToInterface         = ecFirstLazarus + 25;
-  ecJumpToInterfaceUses     = ecFirstLazarus + 26;
-  ecJumpToImplementation    = ecFirstLazarus + 27;
-  ecJumpToImplementationUses= ecFirstLazarus + 28;
-  ecJumpToInitialization    = ecFirstLazarus + 29;
-  ecJumpToProcedureHeader   = ecFirstLazarus + 30;
-  ecJumpToProcedureBegin    = ecFirstLazarus + 31;
+  ecJumpToSection           = ecFirstLazarus + 25;
+  ecJumpToInterface         = ecFirstLazarus + 26;
+  ecJumpToInterfaceUses     = ecFirstLazarus + 27;
+  ecJumpToImplementation    = ecFirstLazarus + 28;
+  ecJumpToImplementationUses= ecFirstLazarus + 29;
+  ecJumpToInitialization    = ecFirstLazarus + 30;
+  ecJumpToProcedureHeader   = ecFirstLazarus + 31;
+  ecJumpToProcedureBegin    = ecFirstLazarus + 32;
 
   // edit selection
   ecSelectionUpperCase      = ecFirstLazarus + 50;
@@ -302,31 +303,33 @@
   ecNewProject              = ecFirstLazarus + 500;
   ecNewProjectFromFile      = ecFirstLazarus + 501;
   ecOpenProject             = ecFirstLazarus + 502;
-  ecCloseProject            = ecFirstLazarus + 503;
-  ecSaveProject             = ecFirstLazarus + 504;
-  ecSaveProjectAs           = ecFirstLazarus + 505;
-  ecPublishProject          = ecFirstLazarus + 506;
-  ecProjectInspector        = ecFirstLazarus + 507;
-  ecAddCurUnitToProj        = ecFirstLazarus + 508;
-  ecRemoveFromProj          = ecFirstLazarus + 509;
-  ecViewProjectUnits        = ecFirstLazarus + 510;
-  ecViewProjectForms        = ecFirstLazarus + 511;
-  ecViewProjectSource       = ecFirstLazarus + 512;
-  ecProjectOptions          = ecFirstLazarus + 513;
-  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
-  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
+  ecOpenRecentProject       = ecFirstLazarus + 503;
+  ecCloseProject            = ecFirstLazarus + 504;
+  ecSaveProject             = ecFirstLazarus + 505;
+  ecSaveProjectAs           = ecFirstLazarus + 506;
+  ecPublishProject          = ecFirstLazarus + 507;
+  ecProjectInspector        = ecFirstLazarus + 508;
+  ecAddCurUnitToProj        = ecFirstLazarus + 509;
+  ecRemoveFromProj          = ecFirstLazarus + 510;
+  ecViewProjectUnits        = ecFirstLazarus + 511;
+  ecViewProjectForms        = ecFirstLazarus + 512;
+  ecViewProjectSource       = ecFirstLazarus + 513;
+  ecProjectOptions          = ecFirstLazarus + 514;
+  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
+  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
 
   // package menu
   ecOpenPackage             = ecFirstLazarus + 600;
   ecOpenPackageFile         = ecFirstLazarus + 601;
   ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
-  ecAddCurFileToPkg         = ecFirstLazarus + 603;
-  ecNewPkgComponent         = ecFirstLazarus + 604;
-  ecPackageGraph            = ecFirstLazarus + 605;
-  ecPackageLinks            = ecFirstLazarus + 606;
-  ecEditInstallPkgs         = ecFirstLazarus + 607;
-  ecConfigCustomComps       = ecFirstLazarus + 608;
-  ecNewPackage              = ecFirstLazarus + 609;
+  ecOpenRecentPackage       = ecFirstLazarus + 603;
+  ecAddCurFileToPkg         = ecFirstLazarus + 604;
+  ecNewPkgComponent         = ecFirstLazarus + 605;
+  ecPackageGraph            = ecFirstLazarus + 606;
+  ecPackageLinks            = ecFirstLazarus + 607;
+  ecEditInstallPkgs         = ecFirstLazarus + 608;
+  ecConfigCustomComps       = ecFirstLazarus + 609;
+  ecNewPackage              = ecFirstLazarus + 610;
 
   // custom tools menu
   ecExtToolFirst            = ecFirstLazarus + 700;
Index: components/ideintf/toolbarintf.pas
===================================================================
--- components/ideintf/toolbarintf.pas	(revision 61640)
+++ components/ideintf/toolbarintf.pas	(working copy)
@@ -18,7 +18,7 @@
 uses
   Classes, SysUtils,
   // LCL
-  Controls, ComCtrls, Menus, Forms,
+  Controls, ComCtrls, Menus, Forms, LCLType,
   // IdeIntf
   IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
 
@@ -29,6 +29,7 @@
 
   TIDEButtonCommand = class(TIDESpecialCommand)
   private
+    FTag: PtrInt;
     FToolButtonClass: TIDEToolButtonClass;
     FToolButtons: TIDEToolButtons;
   protected
@@ -46,6 +47,7 @@
     constructor Create(const TheName: string); override;
     destructor Destroy; override;
   public
+    property Tag: PtrInt read FTag write FTag;
     property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
     property ToolButtons: TIDEToolButtons read FToolButtons;
   end;
@@ -64,36 +66,42 @@
     property Item: TIDEButtonCommand read FItem write FItem;
   end;
 
-  { TIDEToolButtonWithArrow }
+  {%region *** Classes for toolbuttons with arrow *** }
 
-  TIDEToolButtonWithArrow = class(TIDEToolButton)
+  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
+  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButton_ButtonDrop;
+  TIDEToolButton_DropDown_Class = class of TIDEToolButton_DropDown;
+
+  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
+
+  TIDEToolButton_WithArrow = class(TIDEToolButton)
+  private
+    function GetSection: TIDEMenuSection;
   protected
-    procedure AddMenuItem(ACommand: TIDEMenuCommand); virtual;
-    procedure AddMenuItems(ACommands: array of TIDEMenuCommand);
-    procedure DoOnMenuItemClick(Sender: TObject);
     procedure DoOnMenuPopup(Sender: TObject);
     procedure RefreshMenu; virtual;
+    property Section: TIDEMenuSection read GetSection;
   public
     constructor Create(AOwner: TComponent); override;
   end;
 
-  { TIDEToolButton_ButtonDrop }
+  { TIDEToolButton_DropDown }    // [  ][▼]
 
-  TIDEToolButton_ButtonDrop = class(TIDEToolButtonWithArrow)
-  protected
-    procedure PopUpAloneMenu;
+  TIDEToolButton_DropDown = class(TIDEToolButton_WithArrow)
   public
     procedure DoOnAdded; override;
   end;
 
-  { TIDEToolButton_DropDown }
+  { TIDEToolButton_ButtonDrop }    // [ ▼]
 
-  TIDEToolButton_DropDown = class(TIDEToolButtonWithArrow)
+  TIDEToolButton_ButtonDrop = class(TIDEToolButton_WithArrow)
+  protected
+    procedure PopUpAloneMenu(Sender: TObject);
   public
     procedure DoOnAdded; override;
   end;
+  {%endregion}
 
-
   TIDEToolButtonCategory = class
   private
     FButtons: TFPList;
@@ -171,6 +179,12 @@
   const aCommand: TIDECommand): TIDEButtonCommand;
 function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
 
+function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
+function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
+
+
 implementation
 
 function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
@@ -189,64 +203,78 @@
   Result := IDEToolButtonCategories.AddButton(aCommand);
 end;
 
-{ TIDEToolButtonWithArrow }
+{%region *** Functions and classes for toolbuttons with arrow *** }
 
-constructor TIDEToolButtonWithArrow.Create(AOwner: TComponent);
+function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;  // not in Interface
+           AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
+var
+  ButtonCommand: TIDEButtonCommand;
 begin
+  Result:=IDECommandList.FindIDECommand(ACommand);
+  if Result=nil then
+    Exit(nil);
+  ButtonCommand:=RegisterIDEButtonCommand(Result);
+  ButtonCommand.ToolButtonClass:=AButtonClass;
+  if AButtonClass.InheritsFrom(TIDEToolButton_ButtonDrop) then
+    ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
+  ButtonCommand.Tag:=PtrInt(AMenuSection);
+end;
+
+function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
+begin
+  if AButtonClass=nil then
+    AButtonClass:=TIDEToolButton_DropDown;
+  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+end;
+
+function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
+begin
+  if AButtonClass=nil then
+    AButtonClass:=TIDEToolButton_ButtonDrop;
+  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+end;
+
+{ TIDEToolButton_WithArrow }
+
+constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
+begin
   inherited Create(AOwner);
   DropdownMenu := TPopupMenu.Create(Self);
   DropdownMenu.Images := IDEImages.Images_16;
   DropdownMenu.OnPopup := @DoOnMenuPopup;
 end;
 
-procedure TIDEToolButtonWithArrow.AddMenuItem(ACommand: TIDEMenuCommand);
-var
-  Itm: TMenuItem;
+function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
 begin
-  Itm := TMenuItem.Create(DropdownMenu);
-  Itm.Caption := ACommand.Caption;
-  Itm.ShortCut := ACommand.Command.AsShortCut;
-  Itm.ImageIndex := ACommand.ImageIndex;
-  Itm.Enabled := ACommand.Enabled;
-  Itm.OnClick := @DoOnMenuItemClick;
-  Itm.Tag := PtrInt(ACommand);
-  DropdownMenu.Items.Add(Itm);
+  Result:=nil;
+  if (Item<>nil) then
+    Result:=TIDEMenuSection(Item.Tag);
 end;
 
-procedure TIDEToolButtonWithArrow.AddMenuItems(ACommands: array of TIDEMenuCommand);
-var
-  Cmd: TIDEMenuCommand;
+procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
 begin
-  for Cmd in ACommands do
-    AddMenuItem(Cmd);
-end;
-
-procedure TIDEToolButtonWithArrow.DoOnMenuPopup(Sender: TObject);
-begin
   DropdownMenu.Items.Clear;
   RefreshMenu;
 end;
 
-procedure TIDEToolButtonWithArrow.RefreshMenu;
+procedure TIDEToolButton_WithArrow.RefreshMenu;
 begin
-  { Override this method in descendants.
-    DropdownMenu fully regenerates for every showing on OnPopup event.
-    So, RefreshMenu calling happens:
-    - On click to arrow (Style=tbsDropDown)
-    - On click to button (Style=tbsButtonDrop)
-    - On popup alone menu in static methods (on shortcuts)
-        of TIDEToolButton_ButtonDrop descendants (Style is not matter)
-    At calling time:
-    - Instance of DropdownMenu exists
-    - DropdownMenu is empty }
+  if Section=nil then
+    Exit;
+  if Section.MenuItem=nil then
+    Section.GetRoot.CreateMenuItem;  // this forces creating menu (it is necessary
+                                     // for TPopupMenu before first popup)
+  if Section.MenuItem<>nil then
+    DropdownMenu.Items.Assign(Section.MenuItem);
 end;
 
-procedure TIDEToolButtonWithArrow.DoOnMenuItemClick(Sender: TObject);
-var
-  Cmd: TIDEMenuCommand;
+{ TIDEToolButton_DropDown }
+
+procedure TIDEToolButton_DropDown.DoOnAdded;
 begin
-  Cmd:=TIDEMenuCommand((Sender as TMenuItem).Tag);
-  Cmd.DoOnClick;  // Sender in handler should be a command but not a menu item
+  Style := tbsDropDown;  // not in constructor
 end;
 
 { TIDEToolButton_ButtonDrop }
@@ -254,9 +282,12 @@
 procedure TIDEToolButton_ButtonDrop.DoOnAdded;
 begin
   Style := tbsButtonDrop;  // not in constructor
+  if (Item<>nil) then
+    if (Item.Command<>nil) then
+      Item.Command.OnExecute:=@PopUpAloneMenu;
 end;
 
-procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu;
+procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu(Sender: TObject);
 var
   ActiveEditor: TSourceEditorInterface;
   ScreenXY: TPoint;
@@ -265,17 +296,10 @@
   if ActiveEditor=nil then
     Exit;
   ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
-
   DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
 end;
+{%endregion}
 
-{ TIDEToolButton_DropDown }
-
-procedure TIDEToolButton_DropDown.DoOnAdded;
-begin
-  Style := tbsDropDown;  // not in constructor
-end;
-
 { TIDEToolButtonsEnumerator }
 
 constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
@@ -285,6 +309,7 @@
   FPosition := -1;
 end;
 
+
 function TIDEToolButtonsEnumerator.GetCurrent: TIDEToolButton;
 begin
   Result := FList[FPosition];
Index: ide/keymapping.pp
===================================================================
--- ide/keymapping.pp	(revision 61640)
+++ ide/keymapping.pp	(working copy)
@@ -579,6 +579,7 @@
     ecJumpToNextError         : Result:= lisMenuJumpToNextError;
     ecJumpToPrevError         : Result:= lisMenuJumpToPrevError;
     ecGotoIncludeDirective    : Result:= srkmecGotoIncludeDirective;
+    ecJumpToSection           : Result:= lisMenuJumpTo;
     ecJumpToInterface         : Result:= lisMenuJumpToInterface;
     ecJumpToInterfaceUses     : Result:= lisMenuJumpToInterfaceUses;
     ecJumpToImplementation    : Result:= lisMenuJumpToImplementation;
@@ -652,6 +653,7 @@
     ecNewProject              : Result:= lisMenuNewProject;
     ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
     ecOpenProject             : Result:= lisMenuOpenProject;
+    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
     ecCloseProject            : Result:= lisMenuCloseProject;
     ecSaveProject             : Result:= lisMenuSaveProject;
     ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
@@ -705,6 +707,7 @@
     ecOpenPackage             : Result:= lisMenuOpenPackage;
     ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
     ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
+    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
     ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
     ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
     ecPackageGraph            : Result:= lisMenuPackageGraph;
@@ -2886,6 +2889,7 @@
   AddDefault(C, 'Find block other end', srkmecFindBlockOtherEnd, ecFindBlockOtherEnd);
   AddDefault(C, 'Find block start', srkmecFindBlockStart, ecFindBlockStart);
   AddDefault(C, 'Goto include directive', lisMenuGotoIncludeDirective, ecGotoIncludeDirective);
+  AddDefault(C, 'Jump to Section', lisMenuJumpTo, ecJumpToSection);
   AddDefault(C, 'Jump to Interface', lisMenuJumpToInterface, ecJumpToInterface);
   AddDefault(C, 'Jump to Interface uses', lisMenuJumpToInterfaceUses, ecJumpToInterfaceUses);
   AddDefault(C, 'Jump to Implementation', lisMenuJumpToImplementation, ecJumpToImplementation);
@@ -3074,6 +3078,7 @@
   AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
   AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
   AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
+  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
   AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
   AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
   AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
@@ -3129,6 +3134,7 @@
   AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
   AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
   AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
+  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
   AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
   AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
   AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
Index: ide/lazarusidestrconsts.pas
===================================================================
--- ide/lazarusidestrconsts.pas	(revision 61640)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -252,6 +252,7 @@
   lisPathOfTheMakeUtility = 'Path of the make utility';
   lisProjectMacroProperties = 'Project macro properties';
   lisOpenProject2 = 'Open project';
+  lisKMOpenRecentProject = 'Open recent project';
   lisFileHasNoProject = 'File has no project';
   lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
      'The file "%s" is not a Lazarus project.'
@@ -4129,6 +4130,7 @@
   lisKMNewPackage = 'New package';
   lisCompPalOpenPackage = 'Open package';
   lisKMOpenPackageFile = 'Open package file';
+  lisKMOpenRecentPackage = 'Open recent package';
   lisCPOpenPackage = 'Open Package %s';
   lisFilterAllMessagesOfType = 'Filter all messages of type %s';
   lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 61640)
+++ ide/main.pp	(working copy)
@@ -2893,6 +2893,10 @@
       ToolButton.ToolButtonClass := ToolButtonClass;
   end;
 
+  // See also in ToolBarIntf:
+  //  function GetCommand_DropDown
+  //  function GetCommand_ButtonDrop
+
 var
   xBtnItem: TIDEButtonCommand;
 begin
@@ -2955,11 +2959,12 @@
     itmSetFreeBookmark.Command:=GetCommand(ecSetFreeBookmark);
     itmJumpToNextBookmark.Command:=GetCommand(ecNextBookmark);
     itmJumpToPrevBookmark.Command:=GetCommand(ecPrevBookmark);
-    itmJumpToInterface.Command:=GetCommand(ecJumpToInterface, nil, TJumpToSectionToolButton);
-    itmJumpToInterfaceUses.Command:=GetCommand(ecJumpToInterfaceUses, nil, TJumpToSectionToolButton);
-    itmJumpToImplementation.Command:=GetCommand(ecJumpToImplementation, nil, TJumpToSectionToolButton);
-    itmJumpToImplementationUses.Command:=GetCommand(ecJumpToImplementationUses, nil, TJumpToSectionToolButton);
-    itmJumpToInitialization.Command:=GetCommand(ecJumpToInitialization, nil, TJumpToSectionToolButton);
+    GetCommand_ButtonDrop(ecJumpToSection, itmJumpToSection);
+    itmJumpToInterface.Command:=GetCommand_DropDown(ecJumpToInterface, itmJumpToSection);
+    itmJumpToInterfaceUses.Command:=GetCommand_DropDown(ecJumpToInterfaceUses, itmJumpToSection);
+    itmJumpToImplementation.Command:=GetCommand_DropDown(ecJumpToImplementation, itmJumpToSection);
+    itmJumpToImplementationUses.Command:=GetCommand_DropDown(ecJumpToImplementationUses, itmJumpToSection);
+    itmJumpToInitialization.Command:=GetCommand_DropDown(ecJumpToInitialization, itmJumpToSection);
     GetCmdAndBtn(ecJumpToProcedureHeader, xBtnItem);
     xBtnItem.Caption := lisMenuJumpToProcedureHeader;
     xBtnItem.OnClick := @SourceEditorManager.JumpToProcedureHeaderClicked;
@@ -3047,7 +3052,8 @@
     // project menu
     itmProjectNew.Command:=GetCommand(ecNewProject);
     itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
-    itmProjectOpen.Command:=GetCommand(ecOpenProject);
+    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
+    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
     itmProjectClose.Command:=GetCommand(ecCloseProject);
     itmProjectSave.Command:=GetCommand(ecSaveProject);
     itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
@@ -3093,8 +3099,9 @@
     // package menu
     itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
     itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
-    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
+    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
     itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
+    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
     itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
     itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
     itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
Index: ide/mainbase.pas
===================================================================
--- ide/mainbase.pas	(revision 61640)
+++ ide/mainbase.pas	(working copy)
@@ -93,7 +93,7 @@
   protected
     FNeedUpdateHighlighters: boolean;
 
-    function CreateMenuSeparator : TMenuItem;
+    function CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
     procedure CreateMenuItem(Section: TIDEMenuSection;
                              var MenuCommand: TIDEMenuCommand;
                              const MenuItemName, MenuItemCaption: String;
@@ -204,13 +204,6 @@
     property DisplayState: TDisplayState read FDisplayState write SetDisplayState;
   end;
 
-  { TJumpToSectionToolButton }
-
-  TJumpToSectionToolButton = class(TIDEToolButton_DropDown)
-  protected
-    procedure RefreshMenu; override;
-  end;
-
   { TSetBuildModeToolButton }
 
   TSetBuildModeToolButton = class(TIDEToolButton)
@@ -608,19 +601,6 @@
   Style := tbsDropDown;
 end;
 
-{ TJumpToSectionToolButton }
-
-procedure TJumpToSectionToolButton.RefreshMenu;
-begin
-  AddMenuItem(MainIDEBar.itmJumpToInterface);
-  AddMenuItem(MainIDEBar.itmJumpToInterfaceUses);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(MainIDEBar.itmJumpToImplementation);
-  AddMenuItem(MainIDEBar.itmJumpToImplementationUses);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(MainIDEBar.itmJumpToInitialization);
-end;
-
 {$IFDEF LCLCocoa}
 var
   mnuApple: TIDEMenuSection = nil;
@@ -953,10 +933,13 @@
   {$ENDIF}
 end;
 
-function TMainIDEBase.CreateMenuSeparator : TMenuItem;
+var
+  SeparatorNum: Integer=0;
+
+function TMainIDEBase.CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
 begin
-  Result := TMenuItem.Create(MainIDEBar);
-  Result.Caption := '-';
+  Inc(SeparatorNum);
+  CreateMenuItem(Section, Result, 'Separator'+IntToStr(SeparatorNum), '-');  // Result - var parameter
 end;
 
 procedure TMainIDEBase.CreateMenuItem(Section: TIDEMenuSection;
@@ -1144,8 +1127,10 @@
 
     CreateMenuItem(ParentMI,itmJumpToInterface,'itmJumpToInterface',lisMenuJumpToInterface, 'menu_jumpto_interface');
     CreateMenuItem(ParentMI,itmJumpToInterfaceUses,'itmJumpToInterfaceUses',lisMenuJumpToInterfaceUses, 'menu_jumpto_interfaceuses');
+    CreateMenuSeparator(ParentMI);
     CreateMenuItem(ParentMI,itmJumpToImplementation,'itmJumpToImplementation',lisMenuJumpToImplementation, 'menu_jumpto_implementation');
     CreateMenuItem(ParentMI,itmJumpToImplementationUses,'itmJumpToImplementationUses',lisMenuJumpToImplementationUses, 'menu_jumpto_implementationuses');
+    CreateMenuSeparator(ParentMI);
     CreateMenuItem(ParentMI,itmJumpToInitialization,'itmJumpToInitialization',lisMenuJumpToInitialization, 'menu_jumpto_initialization');
 
     CreateMenuSeparatorSection(mnuSearch,itmBookmarks,'itmBookmarks');
@@ -1409,7 +1394,7 @@
     CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
     CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
     CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
-    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
+    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
 
     CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
     ParentMI:=itmPkgUnits;
Index: ide/sourceeditor.pp
===================================================================
--- ide/sourceeditor.pp	(revision 61640)
+++ ide/sourceeditor.pp	(working copy)
@@ -1369,9 +1369,7 @@
     SrcEditMenuClearFileBookmark: TIDEMenuCommand;
     SrcEditMenuClearAllBookmark: TIDEMenuCommand;
     SrcEditMenuGotoBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
-    SrcEditMenuGotoBookmarks: TIDEMenuCommand;
     SrcEditMenuToggleBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
-    SrcEditMenuToggleBookmarks: TIDEMenuCommand;
     // debugging
     SrcEditMenuToggleBreakpoint: TIDEMenuCommand;
     SrcEditMenuRunToCursor: TIDEMenuCommand;
@@ -1436,27 +1434,7 @@
   EnglishModifiedLGPLNotice: string;
   EnglishMITNotice: string;
 
-type
 
-  { TToolButton_GotoBookmarks }
-
-  TToolButton_GotoBookmarks = class(TIDEToolButton_ButtonDrop)
-  protected
-    procedure RefreshMenu; override;
-  public
-    class procedure ShowAloneMenu(Sender: TObject); static;
-  end;
-
-  { TToolButton_ToggleBookmarks }
-
-  TToolButton_ToggleBookmarks = class(TIDEToolButton_ButtonDrop)
-  protected
-    procedure RefreshMenu; override;
-  public
-    class procedure ShowAloneMenu(Sender: TObject); static;
-  end;
-
-
 implementation
 
 {$R *.lfm}
@@ -1711,13 +1689,6 @@
       SrcEditMenuPrevBookmark:=RegisterIDEMenuCommand(AParent,
           'Goto previous Bookmark',uemPrevBookmark, nil,
           @ExecuteIdeMenuClick, nil, 'menu_search_previous_bookmark');
-
-      {For toolbar only. Hidden in menu.}
-      SrcEditMenuGotoBookmarks:=RegisterIDEMenuCommand(AParent,
-          'Goto bookmarks', uemGotoBookmarks,
-          nil, TNotifyProcedure(@TToolButton_GotoBookmarks.ShowAloneMenu), nil,
-          'menu_goto_bookmarks');
-      SrcEditMenuGotoBookmarks.Visible:=False;
   {%endregion}
 
   {%region *** Toggle Bookmarks Submenu ***}
@@ -1739,13 +1710,6 @@
           'Clear Bookmark for current file',srkmecClearBookmarkForFile, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_file_bookmarks');
       SrcEditMenuClearAllBookmark:=RegisterIDEMenuCommand(AParent,
           'Clear all Bookmark',srkmecClearAllBookmark, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_all_bookmarks');
-
-      {For toolbar only. Hidden in menu.}
-      SrcEditMenuToggleBookmarks:=RegisterIDEMenuCommand(AParent,
-          'Toggle bookmarks', uemToggleBookmarks,
-          nil, TNotifyProcedure(@TToolButton_ToggleBookmarks.ShowAloneMenu), nil,
-          'menu_toggle_bookmarks');
-      SrcEditMenuToggleBookmarks.Visible:=False;
   {%endregion}
 
   {%region *** Debug Section ***}
@@ -1854,51 +1818,6 @@
   Result:=CompareFilenames(AnsiString(FileNameStr),SE1.FileName);
 end;
 
-{ TToolButton_GotoBookmarks }
-
-procedure TToolButton_GotoBookmarks.RefreshMenu;
-begin
-  AddMenuItems(SrcEditMenuGotoBookmark);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItems([
-    SrcEditMenuPrevBookmark,
-    SrcEditMenuNextBookmark]);
-end;
-
-class procedure TToolButton_GotoBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
-const
-  Btn: TToolButton_GotoBookmarks=nil;  // static var
-begin
-  if Btn = nil then
-    Btn := TToolButton_GotoBookmarks.Create(Application);
-  Btn.PopUpAloneMenu;
-  // Btn should not be destroyed immediately after PopUp
-end;
-
-
-{ TToolButton_ToggleBookmarks }
-
-procedure TToolButton_ToggleBookmarks.RefreshMenu;
-begin
-  AddMenuItems(SrcEditMenuToggleBookmark);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(SrcEditMenuSetFreeBookmark);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItems([
-    SrcEditMenuClearFileBookmark,
-    SrcEditMenuClearAllBookmark]);
-end;
-
-class procedure TToolButton_ToggleBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
-const
-  Btn: TToolButton_ToggleBookmarks=nil;  // static var
-begin
-  if Btn = nil then
-    Btn := TToolButton_ToggleBookmarks.Create(Application);
-  Btn.PopUpAloneMenu;
-  // Btn should not be destroyed immediately after PopUp
-end;
-
 { TSourceEditorWordCompletion }
 
 constructor TSourceEditorWordCompletion.Create;
@@ -10704,6 +10623,10 @@
       ToolButton.ToolButtonClass := ToolButtonClass;
   end;
 
+  // See also in ToolBarIntf:
+  //  function GetCommand_DropDown
+  //  function GetCommand_ButtonDrop
+
 var
   i: Integer;
 begin
@@ -10769,14 +10692,13 @@
   SrcEditMenuClearFileBookmark.Command:=GetCommand(ecClearBookmarkForFile);
   SrcEditMenuClearAllBookmark.Command:=GetCommand(ecClearAllBookmark);
 
-  SrcEditMenuGotoBookmarks.Command:=GetCommand(ecGotoBookmarks, TToolButton_GotoBookmarks);
-  SrcEditMenuToggleBookmarks.Command:=GetCommand(ecToggleBookmarks, TToolButton_ToggleBookmarks);
-
   for i in TBookmarkNumRange do
     SrcEditMenuGotoBookmark[i].Command := GetCommand(ecGotoMarker0 + i);
+  GetCommand_ButtonDrop(ecGotoBookmarks ,SrcEditSubMenuGotoBookmarks);        // [ ▼]
 
   for i in TBookmarkNumRange do
     SrcEditMenuToggleBookmark[i].Command := GetCommand(ecToggleMarker0 + i);
+  GetCommand_ButtonDrop(ecToggleBookmarks ,SrcEditSubMenuToggleBookmarks);    // [ ▼]
 
   {%region *** Source Section ***}
     SrcEditMenuEncloseSelection.Command:=GetCommand(ecSelectionEnclose);
Index: images/copyright.txt
===================================================================
--- images/copyright.txt	(revision 61640)
+++ images/copyright.txt	(working copy)
@@ -169,6 +169,9 @@
 	state_warning_150.png
 	state_warning_200.png
 
+packages directory
+	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
+
 --------------------------------------------------------------------------------
 
 The following component palette and menu/toolbar icons (including equally named
Index: images/laz_images_list.txt
===================================================================
--- images/laz_images_list.txt	(revision 61640)
+++ images/laz_images_list.txt	(working copy)
@@ -945,6 +945,9 @@
 packages/pkg_open.png
 packages/pkg_open_150.png
 packages/pkg_open_200.png
+packages/pkg_open_recent.png
+packages/pkg_open_recent_150.png
+packages/pkg_open_recent_200.png
 packages/pkg_package_autoinstall.png
 packages/pkg_package_autoinstall_150.png
 packages/pkg_package_autoinstall_200.png
patch4.diff (29,367 bytes)

FTurtle

2019-08-02 18:48

reporter   ~0117549

Attached new patch: patch5.diff

Added toolbutton "Open Recent" with separate popup menu on shortcut (shortcut not assigned by default).

patch5.diff (31,545 bytes)
Index: components/ideintf/idecommands.pas
===================================================================
--- components/ideintf/idecommands.pas	(revision 61652)
+++ components/ideintf/idecommands.pas	(working copy)
@@ -81,13 +81,14 @@
   ecFindBlockStart          = ecFirstLazarus + 22;
   ecOpenFileAtCursor        = ecFirstLazarus + 23;
   ecGotoIncludeDirective    = ecFirstLazarus + 24;
-  ecJumpToInterface         = ecFirstLazarus + 25;
-  ecJumpToInterfaceUses     = ecFirstLazarus + 26;
-  ecJumpToImplementation    = ecFirstLazarus + 27;
-  ecJumpToImplementationUses= ecFirstLazarus + 28;
-  ecJumpToInitialization    = ecFirstLazarus + 29;
-  ecJumpToProcedureHeader   = ecFirstLazarus + 30;
-  ecJumpToProcedureBegin    = ecFirstLazarus + 31;
+  ecJumpToSection           = ecFirstLazarus + 25;
+  ecJumpToInterface         = ecFirstLazarus + 26;
+  ecJumpToInterfaceUses     = ecFirstLazarus + 27;
+  ecJumpToImplementation    = ecFirstLazarus + 28;
+  ecJumpToImplementationUses= ecFirstLazarus + 29;
+  ecJumpToInitialization    = ecFirstLazarus + 30;
+  ecJumpToProcedureHeader   = ecFirstLazarus + 31;
+  ecJumpToProcedureBegin    = ecFirstLazarus + 32;
 
   // edit selection
   ecSelectionUpperCase      = ecFirstLazarus + 50;
@@ -174,8 +175,9 @@
   ecRestart                 = ecFirstLazarus + 213;
   ecQuit                    = ecFirstLazarus + 214;
   ecOpenUnit                = ecFirstLazarus + 215;
-  ecCloseOtherTabs          = ecFirstLazarus + 216;
-  ecCloseRightTabs          = ecFirstLazarus + 217;
+  ecOpenRecent              = ecFirstLazarus + 216;
+  ecCloseOtherTabs          = ecFirstLazarus + 217;
+  ecCloseRightTabs          = ecFirstLazarus + 218;
 
   // edit menu
   ecMultiPaste              = ecFirstLazarus + 230;
@@ -302,31 +304,33 @@
   ecNewProject              = ecFirstLazarus + 500;
   ecNewProjectFromFile      = ecFirstLazarus + 501;
   ecOpenProject             = ecFirstLazarus + 502;
-  ecCloseProject            = ecFirstLazarus + 503;
-  ecSaveProject             = ecFirstLazarus + 504;
-  ecSaveProjectAs           = ecFirstLazarus + 505;
-  ecPublishProject          = ecFirstLazarus + 506;
-  ecProjectInspector        = ecFirstLazarus + 507;
-  ecAddCurUnitToProj        = ecFirstLazarus + 508;
-  ecRemoveFromProj          = ecFirstLazarus + 509;
-  ecViewProjectUnits        = ecFirstLazarus + 510;
-  ecViewProjectForms        = ecFirstLazarus + 511;
-  ecViewProjectSource       = ecFirstLazarus + 512;
-  ecProjectOptions          = ecFirstLazarus + 513;
-  ecProjectChangeBuildMode  = ecFirstLazarus + 514;
-  ecProjectResaveFormsWithI18n = ecFirstLazarus + 515;
+  ecOpenRecentProject       = ecFirstLazarus + 503;
+  ecCloseProject            = ecFirstLazarus + 504;
+  ecSaveProject             = ecFirstLazarus + 505;
+  ecSaveProjectAs           = ecFirstLazarus + 506;
+  ecPublishProject          = ecFirstLazarus + 507;
+  ecProjectInspector        = ecFirstLazarus + 508;
+  ecAddCurUnitToProj        = ecFirstLazarus + 509;
+  ecRemoveFromProj          = ecFirstLazarus + 510;
+  ecViewProjectUnits        = ecFirstLazarus + 511;
+  ecViewProjectForms        = ecFirstLazarus + 512;
+  ecViewProjectSource       = ecFirstLazarus + 513;
+  ecProjectOptions          = ecFirstLazarus + 514;
+  ecProjectChangeBuildMode  = ecFirstLazarus + 515;
+  ecProjectResaveFormsWithI18n = ecFirstLazarus + 516;
 
   // package menu
   ecOpenPackage             = ecFirstLazarus + 600;
   ecOpenPackageFile         = ecFirstLazarus + 601;
   ecOpenPackageOfCurUnit    = ecFirstLazarus + 602;
-  ecAddCurFileToPkg         = ecFirstLazarus + 603;
-  ecNewPkgComponent         = ecFirstLazarus + 604;
-  ecPackageGraph            = ecFirstLazarus + 605;
-  ecPackageLinks            = ecFirstLazarus + 606;
-  ecEditInstallPkgs         = ecFirstLazarus + 607;
-  ecConfigCustomComps       = ecFirstLazarus + 608;
-  ecNewPackage              = ecFirstLazarus + 609;
+  ecOpenRecentPackage       = ecFirstLazarus + 603;
+  ecAddCurFileToPkg         = ecFirstLazarus + 604;
+  ecNewPkgComponent         = ecFirstLazarus + 605;
+  ecPackageGraph            = ecFirstLazarus + 606;
+  ecPackageLinks            = ecFirstLazarus + 607;
+  ecEditInstallPkgs         = ecFirstLazarus + 608;
+  ecConfigCustomComps       = ecFirstLazarus + 609;
+  ecNewPackage              = ecFirstLazarus + 610;
 
   // custom tools menu
   ecExtToolFirst            = ecFirstLazarus + 700;
Index: components/ideintf/toolbarintf.pas
===================================================================
--- components/ideintf/toolbarintf.pas	(revision 61652)
+++ components/ideintf/toolbarintf.pas	(working copy)
@@ -18,7 +18,7 @@
 uses
   Classes, SysUtils,
   // LCL
-  Controls, ComCtrls, Menus, Forms,
+  Controls, ComCtrls, Menus, Forms, LCLType,
   // IdeIntf
   IDECommands, MenuIntf, IDEImagesIntf, SrcEditorIntf;
 
@@ -29,6 +29,7 @@
 
   TIDEButtonCommand = class(TIDESpecialCommand)
   private
+    FTag: PtrInt;
     FToolButtonClass: TIDEToolButtonClass;
     FToolButtons: TIDEToolButtons;
   protected
@@ -46,6 +47,7 @@
     constructor Create(const TheName: string); override;
     destructor Destroy; override;
   public
+    property Tag: PtrInt read FTag write FTag;
     property ToolButtonClass: TIDEToolButtonClass read FToolButtonClass write FToolButtonClass;
     property ToolButtons: TIDEToolButtons read FToolButtons;
   end;
@@ -64,36 +66,42 @@
     property Item: TIDEButtonCommand read FItem write FItem;
   end;
 
-  { TIDEToolButtonWithArrow }
+  {%region *** Classes for toolbuttons with arrow *** }
 
-  TIDEToolButtonWithArrow = class(TIDEToolButton)
+  TIDEToolButton_WithArrow_Class = class of TIDEToolButton_WithArrow;
+  TIDEToolButton_ButtonDrop_Class = class of TIDEToolButton_ButtonDrop;
+  TIDEToolButton_DropDown_Class = class of TIDEToolButton_DropDown;
+
+  { TIDEToolButton_WithArrow }    // [  ][▼], [ ▼]
+
+  TIDEToolButton_WithArrow = class(TIDEToolButton)
+  private
+    function GetSection: TIDEMenuSection;
   protected
-    procedure AddMenuItem(ACommand: TIDEMenuCommand); virtual;
-    procedure AddMenuItems(ACommands: array of TIDEMenuCommand);
-    procedure DoOnMenuItemClick(Sender: TObject);
     procedure DoOnMenuPopup(Sender: TObject);
     procedure RefreshMenu; virtual;
+    property Section: TIDEMenuSection read GetSection;
   public
     constructor Create(AOwner: TComponent); override;
   end;
 
-  { TIDEToolButton_ButtonDrop }
+  { TIDEToolButton_DropDown }    // [  ][▼]
 
-  TIDEToolButton_ButtonDrop = class(TIDEToolButtonWithArrow)
-  protected
-    procedure PopUpAloneMenu;
+  TIDEToolButton_DropDown = class(TIDEToolButton_WithArrow)
   public
     procedure DoOnAdded; override;
   end;
 
-  { TIDEToolButton_DropDown }
+  { TIDEToolButton_ButtonDrop }    // [ ▼]
 
-  TIDEToolButton_DropDown = class(TIDEToolButtonWithArrow)
+  TIDEToolButton_ButtonDrop = class(TIDEToolButton_WithArrow)
+  protected
+    procedure PopUpAloneMenu(Sender: TObject);
   public
     procedure DoOnAdded; override;
   end;
+  {%endregion}
 
-
   TIDEToolButtonCategory = class
   private
     FButtons: TFPList;
@@ -171,6 +179,12 @@
   const aCommand: TIDECommand): TIDEButtonCommand;
 function RegisterIDEButtonCommand(const aCommand: TIDECommand): TIDEButtonCommand;
 
+function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
+function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
+
+
 implementation
 
 function RegisterIDEButtonCategory(const aName, aDescription: string): TIDEToolButtonCategory;
@@ -189,64 +203,78 @@
   Result := IDEToolButtonCategories.AddButton(aCommand);
 end;
 
-{ TIDEToolButtonWithArrow }
+{%region *** Functions and classes for toolbuttons with arrow *** }
 
-constructor TIDEToolButtonWithArrow.Create(AOwner: TComponent);
+function GetCommand_BtnWithArrow(ACommand: Word; AMenuSection: TIDEMenuSection;  // not in Interface
+           AButtonClass: TIDEToolButton_WithArrow_Class): TIDECommand;
+var
+  ButtonCommand: TIDEButtonCommand;
 begin
+  Result:=IDECommandList.FindIDECommand(ACommand);
+  if Result=nil then
+    Exit(nil);
+  ButtonCommand:=RegisterIDEButtonCommand(Result);
+  ButtonCommand.ToolButtonClass:=AButtonClass;
+  if AButtonClass.InheritsFrom(TIDEToolButton_ButtonDrop) then
+    ButtonCommand.ImageIndex:=AMenuSection.ImageIndex;
+  ButtonCommand.Tag:=PtrInt(AMenuSection);
+end;
+
+function GetCommand_DropDown(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_DropDown_Class=nil): TIDECommand;
+begin
+  if AButtonClass=nil then
+    AButtonClass:=TIDEToolButton_DropDown;
+  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+end;
+
+function GetCommand_ButtonDrop(ACommand: Word; AMenuSection: TIDEMenuSection;
+    AButtonClass: TIDEToolButton_ButtonDrop_Class=nil): TIDECommand;
+begin
+  if AButtonClass=nil then
+    AButtonClass:=TIDEToolButton_ButtonDrop;
+  Result:=GetCommand_BtnWithArrow(ACommand, AMenuSection, AButtonClass);
+end;
+
+{ TIDEToolButton_WithArrow }
+
+constructor TIDEToolButton_WithArrow.Create(AOwner: TComponent);
+begin
   inherited Create(AOwner);
   DropdownMenu := TPopupMenu.Create(Self);
   DropdownMenu.Images := IDEImages.Images_16;
   DropdownMenu.OnPopup := @DoOnMenuPopup;
 end;
 
-procedure TIDEToolButtonWithArrow.AddMenuItem(ACommand: TIDEMenuCommand);
-var
-  Itm: TMenuItem;
+function TIDEToolButton_WithArrow.GetSection: TIDEMenuSection;
 begin
-  Itm := TMenuItem.Create(DropdownMenu);
-  Itm.Caption := ACommand.Caption;
-  Itm.ShortCut := ACommand.Command.AsShortCut;
-  Itm.ImageIndex := ACommand.ImageIndex;
-  Itm.Enabled := ACommand.Enabled;
-  Itm.OnClick := @DoOnMenuItemClick;
-  Itm.Tag := PtrInt(ACommand);
-  DropdownMenu.Items.Add(Itm);
+  Result:=nil;
+  if (Item<>nil) then
+    Result:=TIDEMenuSection(Item.Tag);
 end;
 
-procedure TIDEToolButtonWithArrow.AddMenuItems(ACommands: array of TIDEMenuCommand);
-var
-  Cmd: TIDEMenuCommand;
+procedure TIDEToolButton_WithArrow.DoOnMenuPopup(Sender: TObject);
 begin
-  for Cmd in ACommands do
-    AddMenuItem(Cmd);
-end;
-
-procedure TIDEToolButtonWithArrow.DoOnMenuPopup(Sender: TObject);
-begin
   DropdownMenu.Items.Clear;
   RefreshMenu;
 end;
 
-procedure TIDEToolButtonWithArrow.RefreshMenu;
+procedure TIDEToolButton_WithArrow.RefreshMenu;
 begin
-  { Override this method in descendants.
-    DropdownMenu fully regenerates for every showing on OnPopup event.
-    So, RefreshMenu calling happens:
-    - On click to arrow (Style=tbsDropDown)
-    - On click to button (Style=tbsButtonDrop)
-    - On popup alone menu in static methods (on shortcuts)
-        of TIDEToolButton_ButtonDrop descendants (Style is not matter)
-    At calling time:
-    - Instance of DropdownMenu exists
-    - DropdownMenu is empty }
+  if Section=nil then
+    Exit;
+  if Section.MenuItem=nil then
+    Section.GetRoot.CreateMenuItem;  // this forces creating menu (it is necessary
+                                     // for TPopupMenu before first popup)
+  if Section.MenuItem<>nil then
+    DropdownMenu.Items.Assign(Section.MenuItem);
 end;
 
-procedure TIDEToolButtonWithArrow.DoOnMenuItemClick(Sender: TObject);
-var
-  Cmd: TIDEMenuCommand;
+{ TIDEToolButton_DropDown }
+
+procedure TIDEToolButton_DropDown.DoOnAdded;
 begin
-  Cmd:=TIDEMenuCommand((Sender as TMenuItem).Tag);
-  Cmd.DoOnClick;  // Sender in handler should be a command but not a menu item
+  Style := tbsDropDown;  // not in constructor
 end;
 
 { TIDEToolButton_ButtonDrop }
@@ -254,9 +282,12 @@
 procedure TIDEToolButton_ButtonDrop.DoOnAdded;
 begin
   Style := tbsButtonDrop;  // not in constructor
+  if (Item<>nil) then
+    if (Item.Command<>nil) then
+      Item.Command.OnExecute:=@PopUpAloneMenu;
 end;
 
-procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu;
+procedure TIDEToolButton_ButtonDrop.PopUpAloneMenu(Sender: TObject);
 var
   ActiveEditor: TSourceEditorInterface;
   ScreenXY: TPoint;
@@ -265,17 +296,10 @@
   if ActiveEditor=nil then
     Exit;
   ScreenXY := ActiveEditor.EditorControl.ClientToScreen(Point(0, 0));
-
   DropdownMenu.PopUp(ScreenXY.X, ScreenXY.Y);
 end;
+{%endregion}
 
-{ TIDEToolButton_DropDown }
-
-procedure TIDEToolButton_DropDown.DoOnAdded;
-begin
-  Style := tbsDropDown;  // not in constructor
-end;
-
 { TIDEToolButtonsEnumerator }
 
 constructor TIDEToolButtonsEnumerator.Create(AButtons: TIDEToolButtons);
@@ -285,6 +309,7 @@
   FPosition := -1;
 end;
 
+
 function TIDEToolButtonsEnumerator.GetCurrent: TIDEToolButton;
 begin
   Result := FList[FPosition];
Index: ide/keymapping.pp
===================================================================
--- ide/keymapping.pp	(revision 61652)
+++ ide/keymapping.pp	(working copy)
@@ -509,6 +509,7 @@
     ecNewForm                 : Result:= lisMenuNewForm;
     ecOpen                    : Result:= lisMenuOpen;
     ecOpenUnit                : Result:= lisMenuOpenUnit;
+    ecOpenRecent              : Result:= lisTBOpenRecent;
     ecRevert                  : Result:= lisMenuRevert;
     ecSave                    : Result:= lisSave;
     ecSaveAs                  : Result:= lisMenuSaveAs;
@@ -579,6 +580,7 @@
     ecJumpToNextError         : Result:= lisMenuJumpToNextError;
     ecJumpToPrevError         : Result:= lisMenuJumpToPrevError;
     ecGotoIncludeDirective    : Result:= srkmecGotoIncludeDirective;
+    ecJumpToSection           : Result:= lisMenuJumpTo;
     ecJumpToInterface         : Result:= lisMenuJumpToInterface;
     ecJumpToInterfaceUses     : Result:= lisMenuJumpToInterfaceUses;
     ecJumpToImplementation    : Result:= lisMenuJumpToImplementation;
@@ -652,6 +654,7 @@
     ecNewProject              : Result:= lisMenuNewProject;
     ecNewProjectFromFile      : Result:= lisMenuNewProjectFromFile;
     ecOpenProject             : Result:= lisMenuOpenProject;
+    ecOpenRecentProject       : Result:= lisMenuOpenRecentProject;
     ecCloseProject            : Result:= lisMenuCloseProject;
     ecSaveProject             : Result:= lisMenuSaveProject;
     ecSaveProjectAs           : Result:= lisMenuSaveProjectAs;
@@ -705,6 +708,7 @@
     ecOpenPackage             : Result:= lisMenuOpenPackage;
     ecOpenPackageFile         : Result:= lisMenuOpenPackageFile;
     ecOpenPackageOfCurUnit    : Result:= lisMenuOpenPackageOfCurUnit;
+    ecOpenRecentPackage       : Result:= lisMenuOpenRecentPkg;
     ecAddCurFileToPkg         : Result:= lisMenuAddCurFileToPkg;
     ecNewPkgComponent         : Result:= lisMenuPkgNewPackageComponent;
     ecPackageGraph            : Result:= lisMenuPackageGraph;
@@ -2886,6 +2890,7 @@
   AddDefault(C, 'Find block other end', srkmecFindBlockOtherEnd, ecFindBlockOtherEnd);
   AddDefault(C, 'Find block start', srkmecFindBlockStart, ecFindBlockStart);
   AddDefault(C, 'Goto include directive', lisMenuGotoIncludeDirective, ecGotoIncludeDirective);
+  AddDefault(C, 'Jump to Section', lisMenuJumpTo, ecJumpToSection);
   AddDefault(C, 'Jump to Interface', lisMenuJumpToInterface, ecJumpToInterface);
   AddDefault(C, 'Jump to Interface uses', lisMenuJumpToInterfaceUses, ecJumpToInterfaceUses);
   AddDefault(C, 'Jump to Implementation', lisMenuJumpToImplementation, ecJumpToImplementation);
@@ -3027,6 +3032,7 @@
   AddDefault(C, 'NewForm', lisMenuNewForm, ecNewForm);
   AddDefault(C, 'Open', lisOpen, ecOpen);
   AddDefault(C, 'OpenUnit', lisOpenUnit, ecOpenUnit);
+  AddDefault(C, 'OpenRecent', lisKMOpenRecent, ecOpenRecent);
   AddDefault(C, 'Revert', lisMenuRevert, ecRevert);
   AddDefault(C, 'Save', lisSave, ecSave);
   AddDefault(C, 'SaveAs', lisKMSaveAs, ecSaveAs);
@@ -3074,6 +3080,7 @@
   AddDefault(C, 'New project', lisKMNewProject, ecNewProject);
   AddDefault(C, 'New project from file', lisKMNewProjectFromFile, ecNewProjectFromFile);
   AddDefault(C, 'Open project', lisOpenProject2, ecOpenProject);
+  AddDefault(C, 'Open recent project', lisKMOpenRecentProject, ecOpenRecentProject);
   AddDefault(C, 'Close project', lisKMCloseProject, ecCloseProject);
   AddDefault(C, 'Save project', lisKMSaveProject, ecSaveProject);
   AddDefault(C, 'Save project as', lisKMSaveProjectAs, ecSaveProjectAs);
@@ -3129,6 +3136,7 @@
   AddDefault(C, 'New package', lisKMNewPackage, ecNewPackage);
   AddDefault(C, 'Open package', lisCompPalOpenPackage, ecOpenPackage);
   AddDefault(C, 'Open package file', lisKMOpenPackageFile, ecOpenPackageFile);
+  AddDefault(C, 'Open recent package', lisKMOpenRecentPackage, ecOpenRecentPackage);
   AddDefault(C, 'Open package of current unit', lisMenuOpenPackageOfCurUnit, ecOpenPackageOfCurUnit);
   AddDefault(C, 'Add active unit to a package', lisMenuAddCurFileToPkg, ecAddCurFileToPkg);
   AddDefault(C, 'Add new component to a package', lisMenuPkgNewPackageComponent, ecNewPkgComponent);
Index: ide/lazarusidestrconsts.pas
===================================================================
--- ide/lazarusidestrconsts.pas	(revision 61652)
+++ ide/lazarusidestrconsts.pas	(working copy)
@@ -252,6 +252,7 @@
   lisPathOfTheMakeUtility = 'Path of the make utility';
   lisProjectMacroProperties = 'Project macro properties';
   lisOpenProject2 = 'Open project';
+  lisKMOpenRecentProject = 'Open recent project';
   lisFileHasNoProject = 'File has no project';
   lisTheFileIsNotALazarusProjectCreateANewProjectForThi =
      'The file "%s" is not a Lazarus project.'
@@ -307,6 +308,7 @@
   lisPkgEditPublishPackage = 'Publish Package';
   lisPERevertPackage = 'Revert Package';
   lisMenuOpenRecent = 'Open &Recent';
+  lisTBOpenRecent = 'Open Recent';
   lisMenuSave = '&Save';
   lisMenuSaveAs = 'Save &As ...';
   lisKMSaveAs = 'SaveAs';
@@ -4129,6 +4131,7 @@
   lisKMNewPackage = 'New package';
   lisCompPalOpenPackage = 'Open package';
   lisKMOpenPackageFile = 'Open package file';
+  lisKMOpenRecentPackage = 'Open recent package';
   lisCPOpenPackage = 'Open Package %s';
   lisFilterAllMessagesOfType = 'Filter all messages of type %s';
   lisFilterAllMessagesOfCertainType = 'Filter all messages of certain type';
@@ -5095,6 +5098,7 @@
 
   // Standard File menu
   lisKMNewUnit = 'New Unit';
+  lisKMOpenRecent = 'Open Recent';
 
   // Standard Help menu
   lisMenuTemplateAbout = 'About';
Index: ide/main.pp
===================================================================
--- ide/main.pp	(revision 61652)
+++ ide/main.pp	(working copy)
@@ -2893,6 +2893,10 @@
       ToolButton.ToolButtonClass := ToolButtonClass;
   end;
 
+  // See also in ToolBarIntf:
+  //  function GetCommand_DropDown
+  //  function GetCommand_ButtonDrop
+
 var
   xBtnItem: TIDEButtonCommand;
 begin
@@ -2903,6 +2907,7 @@
     itmFileNewOther.Command:=GetCommand(ecNew);
     itmFileOpen.Command:=GetCommand(ecOpen, nil, TOpenFileToolButton);
     itmFileOpenUnit.Command:=GetCommand(ecOpenUnit);
+    GetCommand_ButtonDrop(ecOpenRecent, itmFileRecentOpen);
     itmFileRevert.Command:=GetCommand(ecRevert);
     itmFileSave.Command:=GetCommand(ecSave);
     itmFileSaveAs.Command:=GetCommand(ecSaveAs);
@@ -2955,11 +2960,12 @@
     itmSetFreeBookmark.Command:=GetCommand(ecSetFreeBookmark);
     itmJumpToNextBookmark.Command:=GetCommand(ecNextBookmark);
     itmJumpToPrevBookmark.Command:=GetCommand(ecPrevBookmark);
-    itmJumpToInterface.Command:=GetCommand(ecJumpToInterface, nil, TJumpToSectionToolButton);
-    itmJumpToInterfaceUses.Command:=GetCommand(ecJumpToInterfaceUses, nil, TJumpToSectionToolButton);
-    itmJumpToImplementation.Command:=GetCommand(ecJumpToImplementation, nil, TJumpToSectionToolButton);
-    itmJumpToImplementationUses.Command:=GetCommand(ecJumpToImplementationUses, nil, TJumpToSectionToolButton);
-    itmJumpToInitialization.Command:=GetCommand(ecJumpToInitialization, nil, TJumpToSectionToolButton);
+    GetCommand_ButtonDrop(ecJumpToSection, itmJumpToSection);
+    itmJumpToInterface.Command:=GetCommand_DropDown(ecJumpToInterface, itmJumpToSection);
+    itmJumpToInterfaceUses.Command:=GetCommand_DropDown(ecJumpToInterfaceUses, itmJumpToSection);
+    itmJumpToImplementation.Command:=GetCommand_DropDown(ecJumpToImplementation, itmJumpToSection);
+    itmJumpToImplementationUses.Command:=GetCommand_DropDown(ecJumpToImplementationUses, itmJumpToSection);
+    itmJumpToInitialization.Command:=GetCommand_DropDown(ecJumpToInitialization, itmJumpToSection);
     GetCmdAndBtn(ecJumpToProcedureHeader, xBtnItem);
     xBtnItem.Caption := lisMenuJumpToProcedureHeader;
     xBtnItem.OnClick := @SourceEditorManager.JumpToProcedureHeaderClicked;
@@ -3047,7 +3053,8 @@
     // project menu
     itmProjectNew.Command:=GetCommand(ecNewProject);
     itmProjectNewFromFile.Command:=GetCommand(ecNewProjectFromFile);
-    itmProjectOpen.Command:=GetCommand(ecOpenProject);
+    itmProjectOpen.Command:=GetCommand_DropDown(ecOpenProject, itmProjectRecentOpen);
+    GetCommand_ButtonDrop(ecOpenRecentProject, itmProjectRecentOpen);
     itmProjectClose.Command:=GetCommand(ecCloseProject);
     itmProjectSave.Command:=GetCommand(ecSaveProject);
     itmProjectSaveAs.Command:=GetCommand(ecSaveProjectAs);
@@ -3093,8 +3100,9 @@
     // package menu
     itmPkgNewPackage.Command:=GetCommand(ecNewPackage);
     itmPkgOpenLoadedPackage.Command:=GetCommand(ecOpenPackage);
-    itmPkgOpenPackageFile.Command:=GetCommand(ecOpenPackageFile);
+    itmPkgOpenPackageFile.Command:=GetCommand_DropDown(ecOpenPackageFile, itmPkgOpenRecent);
     itmPkgOpenPackageOfCurUnit.Command:=GetCommand(ecOpenPackageOfCurUnit);
+    GetCommand_ButtonDrop(ecOpenRecentPackage, itmPkgOpenRecent);
     itmPkgAddCurFileToPkg.Command:=GetCommand(ecAddCurFileToPkg);
     itmPkgAddNewComponentToPkg.Command:=GetCommand(ecNewPkgComponent);
     itmPkgPkgGraph.Command:=GetCommand(ecPackageGraph);
Index: ide/mainbase.pas
===================================================================
--- ide/mainbase.pas	(revision 61652)
+++ ide/mainbase.pas	(working copy)
@@ -93,7 +93,7 @@
   protected
     FNeedUpdateHighlighters: boolean;
 
-    function CreateMenuSeparator : TMenuItem;
+    function CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
     procedure CreateMenuItem(Section: TIDEMenuSection;
                              var MenuCommand: TIDEMenuCommand;
                              const MenuItemName, MenuItemCaption: String;
@@ -204,13 +204,6 @@
     property DisplayState: TDisplayState read FDisplayState write SetDisplayState;
   end;
 
-  { TJumpToSectionToolButton }
-
-  TJumpToSectionToolButton = class(TIDEToolButton_DropDown)
-  protected
-    procedure RefreshMenu; override;
-  end;
-
   { TSetBuildModeToolButton }
 
   TSetBuildModeToolButton = class(TIDEToolButton)
@@ -608,19 +601,6 @@
   Style := tbsDropDown;
 end;
 
-{ TJumpToSectionToolButton }
-
-procedure TJumpToSectionToolButton.RefreshMenu;
-begin
-  AddMenuItem(MainIDEBar.itmJumpToInterface);
-  AddMenuItem(MainIDEBar.itmJumpToInterfaceUses);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(MainIDEBar.itmJumpToImplementation);
-  AddMenuItem(MainIDEBar.itmJumpToImplementationUses);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(MainIDEBar.itmJumpToInitialization);
-end;
-
 {$IFDEF LCLCocoa}
 var
   mnuApple: TIDEMenuSection = nil;
@@ -953,10 +933,13 @@
   {$ENDIF}
 end;
 
-function TMainIDEBase.CreateMenuSeparator : TMenuItem;
+var
+  SeparatorNum: Integer=0;
+
+function TMainIDEBase.CreateMenuSeparator(Section: TIDEMenuSection): TIDEMenuCommand;
 begin
-  Result := TMenuItem.Create(MainIDEBar);
-  Result.Caption := '-';
+  Inc(SeparatorNum);
+  CreateMenuItem(Section, Result, 'Separator'+IntToStr(SeparatorNum), '-');  // Result - var parameter
 end;
 
 procedure TMainIDEBase.CreateMenuItem(Section: TIDEMenuSection;
@@ -1144,8 +1127,10 @@
 
     CreateMenuItem(ParentMI,itmJumpToInterface,'itmJumpToInterface',lisMenuJumpToInterface, 'menu_jumpto_interface');
     CreateMenuItem(ParentMI,itmJumpToInterfaceUses,'itmJumpToInterfaceUses',lisMenuJumpToInterfaceUses, 'menu_jumpto_interfaceuses');
+    CreateMenuSeparator(ParentMI);
     CreateMenuItem(ParentMI,itmJumpToImplementation,'itmJumpToImplementation',lisMenuJumpToImplementation, 'menu_jumpto_implementation');
     CreateMenuItem(ParentMI,itmJumpToImplementationUses,'itmJumpToImplementationUses',lisMenuJumpToImplementationUses, 'menu_jumpto_implementationuses');
+    CreateMenuSeparator(ParentMI);
     CreateMenuItem(ParentMI,itmJumpToInitialization,'itmJumpToInitialization',lisMenuJumpToInitialization, 'menu_jumpto_initialization');
 
     CreateMenuSeparatorSection(mnuSearch,itmBookmarks,'itmBookmarks');
@@ -1409,7 +1394,7 @@
     CreateMenuItem(ParentMI,itmPkgOpenLoadedPackage,'itmPkgOpenPackage',lisMenuOpenPackage,'pkg_installed');
     CreateMenuItem(ParentMI,itmPkgOpenPackageFile,'itmPkgOpenPackageFile',lisMenuOpenPackageFile,'pkg_open');
     CreateMenuItem(ParentMI,itmPkgOpenPackageOfCurUnit,'itmPkgOpenPackageOfCurUnit',lisMenuOpenPackageOfCurUnit);
-    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg);
+    CreateMenuSubSection(ParentMI,itmPkgOpenRecent,'itmPkgOpenRecent',lisMenuOpenRecentPkg, 'pkg_open_recent');
 
     CreateMenuSeparatorSection(mnuComponent,itmPkgUnits,'itmPkgUnits');
     ParentMI:=itmPkgUnits;
Index: ide/sourceeditor.pp
===================================================================
--- ide/sourceeditor.pp	(revision 61652)
+++ ide/sourceeditor.pp	(working copy)
@@ -1369,9 +1369,7 @@
     SrcEditMenuClearFileBookmark: TIDEMenuCommand;
     SrcEditMenuClearAllBookmark: TIDEMenuCommand;
     SrcEditMenuGotoBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
-    SrcEditMenuGotoBookmarks: TIDEMenuCommand;
     SrcEditMenuToggleBookmark: array [TBookmarkNumRange] of TIDEMenuCommand;
-    SrcEditMenuToggleBookmarks: TIDEMenuCommand;
     // debugging
     SrcEditMenuToggleBreakpoint: TIDEMenuCommand;
     SrcEditMenuRunToCursor: TIDEMenuCommand;
@@ -1436,27 +1434,7 @@
   EnglishModifiedLGPLNotice: string;
   EnglishMITNotice: string;
 
-type
 
-  { TToolButton_GotoBookmarks }
-
-  TToolButton_GotoBookmarks = class(TIDEToolButton_ButtonDrop)
-  protected
-    procedure RefreshMenu; override;
-  public
-    class procedure ShowAloneMenu(Sender: TObject); static;
-  end;
-
-  { TToolButton_ToggleBookmarks }
-
-  TToolButton_ToggleBookmarks = class(TIDEToolButton_ButtonDrop)
-  protected
-    procedure RefreshMenu; override;
-  public
-    class procedure ShowAloneMenu(Sender: TObject); static;
-  end;
-
-
 implementation
 
 {$R *.lfm}
@@ -1711,13 +1689,6 @@
       SrcEditMenuPrevBookmark:=RegisterIDEMenuCommand(AParent,
           'Goto previous Bookmark',uemPrevBookmark, nil,
           @ExecuteIdeMenuClick, nil, 'menu_search_previous_bookmark');
-
-      {For toolbar only. Hidden in menu.}
-      SrcEditMenuGotoBookmarks:=RegisterIDEMenuCommand(AParent,
-          'Goto bookmarks', uemGotoBookmarks,
-          nil, TNotifyProcedure(@TToolButton_GotoBookmarks.ShowAloneMenu), nil,
-          'menu_goto_bookmarks');
-      SrcEditMenuGotoBookmarks.Visible:=False;
   {%endregion}
 
   {%region *** Toggle Bookmarks Submenu ***}
@@ -1739,13 +1710,6 @@
           'Clear Bookmark for current file',srkmecClearBookmarkForFile, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_file_bookmarks');
       SrcEditMenuClearAllBookmark:=RegisterIDEMenuCommand(AParent,
           'Clear all Bookmark',srkmecClearAllBookmark, nil, @ExecuteIdeMenuClick, nil, 'menu_clear_all_bookmarks');
-
-      {For toolbar only. Hidden in menu.}
-      SrcEditMenuToggleBookmarks:=RegisterIDEMenuCommand(AParent,
-          'Toggle bookmarks', uemToggleBookmarks,
-          nil, TNotifyProcedure(@TToolButton_ToggleBookmarks.ShowAloneMenu), nil,
-          'menu_toggle_bookmarks');
-      SrcEditMenuToggleBookmarks.Visible:=False;
   {%endregion}
 
   {%region *** Debug Section ***}
@@ -1854,51 +1818,6 @@
   Result:=CompareFilenames(AnsiString(FileNameStr),SE1.FileName);
 end;
 
-{ TToolButton_GotoBookmarks }
-
-procedure TToolButton_GotoBookmarks.RefreshMenu;
-begin
-  AddMenuItems(SrcEditMenuGotoBookmark);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItems([
-    SrcEditMenuPrevBookmark,
-    SrcEditMenuNextBookmark]);
-end;
-
-class procedure TToolButton_GotoBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
-const
-  Btn: TToolButton_GotoBookmarks=nil;  // static var
-begin
-  if Btn = nil then
-    Btn := TToolButton_GotoBookmarks.Create(Application);
-  Btn.PopUpAloneMenu;
-  // Btn should not be destroyed immediately after PopUp
-end;
-
-
-{ TToolButton_ToggleBookmarks }
-
-procedure TToolButton_ToggleBookmarks.RefreshMenu;
-begin
-  AddMenuItems(SrcEditMenuToggleBookmark);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItem(SrcEditMenuSetFreeBookmark);
-  DropdownMenu.Items.AddSeparator;
-  AddMenuItems([
-    SrcEditMenuClearFileBookmark,
-    SrcEditMenuClearAllBookmark]);
-end;
-
-class procedure TToolButton_ToggleBookmarks.ShowAloneMenu(Sender: TObject);  // on shortcuts only
-const
-  Btn: TToolButton_ToggleBookmarks=nil;  // static var
-begin
-  if Btn = nil then
-    Btn := TToolButton_ToggleBookmarks.Create(Application);
-  Btn.PopUpAloneMenu;
-  // Btn should not be destroyed immediately after PopUp
-end;
-
 { TSourceEditorWordCompletion }
 
 constructor TSourceEditorWordCompletion.Create;
@@ -10704,6 +10623,10 @@
       ToolButton.ToolButtonClass := ToolButtonClass;
   end;
 
+  // See also in ToolBarIntf:
+  //  function GetCommand_DropDown
+  //  function GetCommand_ButtonDrop
+
 var
   i: Integer;
 begin
@@ -10769,14 +10692,13 @@
   SrcEditMenuClearFileBookmark.Command:=GetCommand(ecClearBookmarkForFile);
   SrcEditMenuClearAllBookmark.Command:=GetCommand(ecClearAllBookmark);
 
-  SrcEditMenuGotoBookmarks.Command:=GetCommand(ecGotoBookmarks, TToolButton_GotoBookmarks);
-  SrcEditMenuToggleBookmarks.Command:=GetCommand(ecToggleBookmarks, TToolButton_ToggleBookmarks);
-
   for i in TBookmarkNumRange do
     SrcEditMenuGotoBookmark[i].Command := GetCommand(ecGotoMarker0 + i);
+  GetCommand_ButtonDrop(ecGotoBookmarks ,SrcEditSubMenuGotoBookmarks);        // [ ▼]
 
   for i in TBookmarkNumRange do
     SrcEditMenuToggleBookmark[i].Command := GetCommand(ecToggleMarker0 + i);
+  GetCommand_ButtonDrop(ecToggleBookmarks ,SrcEditSubMenuToggleBookmarks);    // [ ▼]
 
   {%region *** Source Section ***}
     SrcEditMenuEncloseSelection.Command:=GetCommand(ecSelectionEnclose);
Index: images/copyright.txt
===================================================================
--- images/copyright.txt	(revision 61652)
+++ images/copyright.txt	(working copy)
@@ -169,6 +169,9 @@
 	state_warning_150.png
 	state_warning_200.png
 
+packages directory
+	pkg_open_recent.png    (used 'pkg_open.png' created by Roland Hahn)
+
 --------------------------------------------------------------------------------
 
 The following component palette and menu/toolbar icons (including equally named
Index: images/laz_images_list.txt
===================================================================
--- images/laz_images_list.txt	(revision 61652)
+++ images/laz_images_list.txt	(working copy)
@@ -945,6 +945,9 @@
 packages/pkg_open.png
 packages/pkg_open_150.png
 packages/pkg_open_200.png
+packages/pkg_open_recent.png
+packages/pkg_open_recent_150.png
+packages/pkg_open_recent_200.png
 packages/pkg_package_autoinstall.png
 packages/pkg_package_autoinstall_150.png
 packages/pkg_package_autoinstall_200.png
patch5.diff (31,545 bytes)

Issue History

Date Modified Username Field Change
2019-07-24 20:30 FTurtle New Issue
2019-07-24 20:30 FTurtle File Added: patch.diff
2019-07-24 20:30 FTurtle File Added: pic1.png
2019-07-24 20:31 FTurtle File Added: pic2.png
2019-07-24 20:31 FTurtle File Added: pic3.png
2019-07-25 18:50 FTurtle File Added: patch2.diff
2019-07-25 18:50 FTurtle File Added: images.zip
2019-07-25 18:50 FTurtle Note Added: 0117398
2019-07-26 19:21 FTurtle File Added: patch3.diff
2019-07-26 19:21 FTurtle Note Added: 0117422
2019-07-29 16:22 FTurtle File Added: patch4.diff
2019-07-29 16:22 FTurtle Note Added: 0117490
2019-07-29 16:27 FTurtle Note Edited: 0117490 View Revisions
2019-08-02 18:48 FTurtle File Added: patch5.diff
2019-08-02 18:48 FTurtle Note Added: 0117549