/components/editortoolbar/editortoolbar_impl.pas
http://github.com/graemeg/lazarus · Pascal · 606 lines · 496 code · 74 blank · 36 comment · 32 complexity · da5b53e5057108d17f5f1ef98b6b41d5 MD5 · raw file
- {
- Copyright (C) 2007 Graeme Geldenhuys (graemeg@gmail.com)
- This library is free software; you can redistribute it and/or modify it
- under the terms of the GNU Library General Public License as published by
- the Free Software Foundation; either version 2 of the License, or (at your
- option) any later version.
- This program is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License
- for more details.
- You should have received a copy of the GNU Library General Public License
- along with this library; if not, write to the Free Software Foundation,
- Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- }
- unit editortoolbar_impl;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes
- ,jumpto_impl
- ,Forms
- ,ComCtrls
- ,Controls
- ,ExtCtrls
- ,Menus
- ,MenuIntf
- ,IDEImagesIntf
- ,SrcEditorIntf
- ,editortoolbar_str
- ,IDECommands;
- const
- cSettingsFile = 'editortoolbar.xml';
- cDivider = '---------------';
- iAll = 15;
- iDesign = 1;
- iDebug = 2;
- iHTML = 4;
- iCustom = 8;
- type
- { TEditorToolbar }
- TEditorToolbar = class(TComponent)
- private
- FJumpHandler: TJumpHandler;
- FWindow: TSourceEditorWindowInterface;
- TB: TToolbar;
- PM: TPopupMenu;
- PPUP: TPopupMenu;
- CfgButton: TToolButton;
- FButtonList: TList;
- UpdateTimer: TTimer;
- procedure CreateEditorToolbar(AW: TForm; var ATB: TToolbar);
- function CreateJumpItem(AJumpType: TJumpType; O: TComponent): TMenuItem;
- function CreateProfileItem(ProfIndx: Integer; O: TComponent): TMenuItem;
- procedure DoConfigureToolbar(Sender: TObject);
- procedure UpdateBar(Sender: TObject);
- protected
- procedure MenuItemClick (Sender: TObject);
- procedure AddButton(AMenuItem: TIDEMenuItem);
- procedure PositionAtEnd(AToolbar: TToolbar; AButton: TToolButton);
- procedure Reload;
- public
- constructor Create(AOwner: TComponent); override;
- destructor Destroy; override;
- procedure InitEditorToolBar;
- procedure AddCustomItems;
- procedure AddDivider;
- procedure AddStaticItems;
- procedure ClearToolbar;
- property OwnerWindow: TSourceEditorWindowInterface read FWindow;
- end;
-
- { TEditorToolbarList }
- TEditorToolbarList = class
- private
- FToolBarList: TFPList;
- protected
- procedure SourceWindowCreated(Sender: TObject);
- procedure SourceWindowDestroyed(Sender: TObject);
- procedure AddBar(ABar: TEditorToolbar);
- procedure DelBar(ABar: TEditorToolbar);
- procedure ReloadAll;
- public
- constructor Create;
- destructor Destroy; override;
- end;
- function GetShortcut(AMenuItem: TIDEMenuItem): string;
- function GetProfileIndex (aMask: Integer): Integer;
- procedure Register;
- var
- sToolbarPos: string;
- bToolBarShow: boolean;
- EditorMenuCommand:TIDEMenuCommand;
- ProfileMask: array [0..4] of Integer = (iAll,iDesign,iDebug,iHTML,iCustom);
- sLocalizedProfileNames: array[0..4] of string;
- implementation
- {$R toolbar.res} // all required images
- uses
- Dialogs
- ,SysUtils
- ,LResources
- ,EdtTbConfigFrm
- ,LazConfigStorage
- ,BaseIDEIntf
- ,LCLProc;
- type
- { TEditToolBarToolButton }
- TEditToolBarToolButton = class(TToolButton)
- private
- FMenuItem: TIDEMenuItem;
- public
- procedure Click; override;
- property IdeMenuItem: TIDEMenuItem read FMenuItem write FMenuItem;
- end;
- var
- uEditorToolbarList: TEditorToolbarList;
- procedure ConfigureToolbar (Sender:TObject);
- begin
- if TEdtTbConfigForm.Execute then
- uEditorToolbarList.ReloadAll;
- end;
- procedure ToggleToolbar (Sender:TObject);
- var
- ToolBarVisible: Boolean;
- begin
- ToolBarVisible:= not bToolBarShow;
- EditorMenuCommand.Checked:= ToolBarVisible;
- bToolBarShow:= ToolBarVisible;
- TEdtTbConfigForm.UpdateVisible(ToolBarVisible);
- uEditorToolbarList.ReloadAll;
- end;
- procedure TEditToolBarToolButton.Click;
- begin
- inherited Click;
- if assigned(FMenuItem) then
- FMenuItem.TriggerClick;
- end;
- { TEditorToolbarList }
- procedure TEditorToolbarList.SourceWindowCreated(Sender: TObject);
- begin
- TEditorToolbar.Create(Sender as TSourceEditorWindowInterface);
- end;
- procedure TEditorToolbarList.SourceWindowDestroyed(Sender: TObject);
- var
- i: integer;
- aBar: TEditorToolbar;
- begin
- // Let's remove from our list the destroyed window and then destroy the ToolBar
- for i:= 0 to FToolBarList.Count -1 do begin
- aBar := TEditorToolbar(FToolBarList[i]);
- if aBar.OwnerWindow = TSourceEditorWindowInterface(Sender) then begin
- DelBar(aBar);
- aBar.Free;
- exit;
- end;
- end;
- end;
- procedure TEditorToolbarList.AddBar(ABar: TEditorToolbar);
- begin
- FToolBarList.Add(ABar);
- end;
- procedure TEditorToolbarList.DelBar(ABar: TEditorToolbar);
- begin
- FToolBarList.Remove(ABar);
- end;
- procedure TEditorToolbarList.ReloadAll;
- var
- i: Integer;
- begin
- for i := 0 to FToolBarList.Count - 1 do
- TEditorToolbar(FToolBarList[i]).Reload
- end;
- constructor TEditorToolbarList.Create;
- begin
- inherited;
- uEditorToolbarList := self;
- FToolBarList := TFPList.Create;
- if SourceEditorManagerIntf <> nil then begin
- SourceEditorManagerIntf.RegisterChangeEvent(semWindowCreate, @SourceWindowCreated);
- SourceEditorManagerIntf.RegisterChangeEvent(semWindowDestroy,@SourceWindowDestroyed);
- end;
- end;
- destructor TEditorToolbarList.Destroy;
- begin
- while FToolBarList.Count > 0 do
- TEditorToolbar(FToolBarList[0]).Free;
- FreeAndNil(FToolBarList);
- inherited Destroy;
- end;
- { TEditorToolbar }
- procedure TEditorToolbar.CreateEditorToolbar(AW: TForm; var ATB: TToolbar);
- begin
- { It must be created with Align = alTop, so that the first positioning
- of buttons is correct. }
- ATB := TToolbar.Create(AW);
- ATB.Parent := AW;
- ATB.Height := 26;
- ATB.Align := alTop;
- ATB.Flat := True;
- ATB.Images := IDEImages.Images_16;
- ATB.ShowHint := True;
- ATB.Hint := rsHint;
- ATB.PopupMenu := PPUP;
- end;
- function TEditorToolbar.CreateJumpItem(AJumpType: TJumpType; O: TComponent): TMenuItem;
- begin
- Result := TMenuItem.Create(O);
- Result.Tag := Ord(AJumpType);
- Result.OnClick := @FJumpHandler.DoJump;
- Result.Caption := cJumpNames[AJumpType];
- end;
- function TEditorToolbar.CreateProfileItem(ProfIndx: Integer; O: TComponent
- ): TMenuItem;
- begin
- Result := TMenuItem.Create(O);
- Result.Tag := ProfIndx;
- Result.Caption := sLocalizedProfileNames[ProfIndx];
- Result.GroupIndex := 1;
- Result.RadioItem := True;
- //Result.AutoCheck := True;
- Result.OnClick := @MenuItemClick;
- end;
- procedure TEditorToolbar.DoConfigureToolbar(Sender: TObject);
- begin
- if TEdtTbConfigForm.Execute then
- uEditorToolbarList.ReloadAll;
- end;
- procedure TEditorToolbar.UpdateBar(Sender: TObject);
- var
- i,j: integer;
- mi: TIDEMenuItem;
- begin
- TB.BeginUpdate;
- try
- for i := TB.ButtonCount - 1 downto 0 do begin
- if TB.Buttons[I].tag <> 0 then begin
- j := TB.Buttons[I].tag-1;
- mi := TIDEMenuItem(FButtonList.Items[j]);
- if mi <> nil then begin
- TB.Buttons[I].Enabled := mi.Enabled;
- end;
- end;
- end;
- finally
- TB.EndUpdate;
- end;
- end;
- procedure TEditorToolbar.MenuItemClick(Sender: TObject);
- var
- cfg: TConfigStorage;
- Value: Integer;
- begin
- if (Sender <> nil ) and (Sender is TMenuItem) then begin
- TMenuItem(Sender).Checked:= True;
- Value:= TMenuItem(Sender).Tag;
- CurrProfile := ProfileMask[Value];
- cfg := GetIDEConfigStorage(cSettingsFile,True);
- try
- cfg.SetDeleteValue('Profile',CurrProfile,iAll);
- cfg.WriteToDisk;
- finally
- cfg.Free;
- end;
- Reload;
- end;
- end;
- constructor TEditorToolbar.Create(AOwner: TComponent);
- var
- T: TJumpType;
- c: integer;
- cfg: TConfigStorage;
- begin
- uEditorToolbarList.AddBar(Self);
- if assigned(TB) then exit;
- FButtonList := TList.Create;
- sLocalizedProfileNames[0] := rsAll;
- sLocalizedProfileNames[1] := rsDesign;
- sLocalizedProfileNames[2] := rsDebug;
- sLocalizedProfileNames[3] := rsHTML;
- sLocalizedProfileNames[4] := rsCustom;
- FJumpHandler := TJumpHandler.Create(nil);
- FWindow := TSourceEditorWindowInterface(AOwner);
- PPUP := TPopupMenu.Create(FWindow);
- for c := 0 to High(sLocalizedProfileNames) do begin
- PPUP.Items.Add(CreateProfileItem(c,FWindow));
- end;
- CreateEditorToolBar(FWindow, TB);
- PM := TPopupMenu.Create(FWindow);
- for T := Low(TJumpType) to High(TJumpType) do
- PM.Items.Add(CreateJumpItem(T, FWindow));
- AddStaticItems;
- // Let's verify if it's a first start
- c:= 0; // Just in case...
- cfg := GetIDEConfigStorage(cSettingsFile, True);
- try
- c := cfg.GetValue('Count', 0);
- finally
- cfg.Free;
- end;
- if c = 0 then
- TEdtTbConfigForm.Setup;
- AddCustomItems;
- UpdateTimer := TTimer.Create(Self);
- UpdateTimer.Interval := 500;
- UpdateTimer.OnTimer := @UpdateBar;
- UpdateTimer.Enabled := True;
- end;
- destructor TEditorToolbar.Destroy;
- begin
- uEditorToolbarList.DelBar(Self);
- FJumpHandler.Free;
- FButtonList.Free;
- inherited Destroy;
- end;
- procedure TEditorToolbar.InitEditorToolBar;
- begin
- TB := nil;
- CfgButton := nil;
- end;
- procedure TEditorToolbar.AddButton(AMenuItem: TIDEMenuItem);
- var
- B: TEditToolBarToolButton;
- ACaption: string;
- iPos: Integer;
- begin
- B := TEditToolBarToolButton.Create(TB);
- ACaption := AMenuItem.Caption;
- DeleteAmpersands(ACaption);
- B.Caption := ACaption;
- // Get Shortcut, if any, and append to Hint
- ACaption:= ACaption + GetShortcut(AMenuItem);
- B.Hint := ACaption;
- // If we have a image, us it. Otherwise supply a default.
- if AMenuItem.ImageIndex <> -1 then
- B.ImageIndex := AMenuItem.ImageIndex
- else
- B.ImageIndex := IDEImages.LoadImage(16, 'execute16');
- B.Style := tbsButton;
- B.IdeMenuItem := AMenuItem;
- iPos := FButtonList.Add(AMenuItem);
- B.Tag:= iPos+1;
- //B.OnClick := AMenuItem.OnClick;
- PositionAtEnd(TB, B);
- end;
- // position the button next to the last button
- procedure TEditorToolbar.PositionAtEnd(AToolbar: TToolbar; AButton: TToolButton);
- var
- SiblingButton: TToolButton;
- begin
- if AToolbar.ButtonCount > 0 then
- begin
- SiblingButton := AToolbar.Buttons[AToolbar.ButtonCount-1];
- AButton.SetBounds(SiblingButton.Left + SiblingButton.Width,
- SiblingButton.Top, AButton.Width, AButton.Height);
- end;
- AButton.Parent := AToolbar;
- end;
- procedure TEditorToolbar.Reload;
- begin
- ClearToolbar;
- AddStaticItems;
- AddCustomItems;
- end;
- procedure TEditorToolbar.AddCustomItems;
- var
- i: integer;
- c: integer;
- cfg: TConfigStorage;
- value: string;
- profile: Integer;
- mi: TIDEMenuItem;
- ShowItem: Boolean;
- procedure SetTbPos;
- begin
- case sToolbarPos of
- 'Top': begin
- TB.Align:= alTop;
- TB.Height:= 26;
- end;
- 'Bottom': begin
- TB.Align:= alBottom;
- TB.Height:= 26;
- end;
- 'Left': begin
- TB.Align:= alLeft;
- TB.Width:= 26;
- end;
- 'Right': begin
- TB.Align:= alRight;
- TB.Width:= 26;
- end;
- end;
- end;
- begin
- cfg := GetIDEConfigStorage(cSettingsFile, True);
- TB.BeginUpdate;
- try
- c:= cfg.GetValue('Profile',iAll);
- CurrProfile := c;
- c := GetProfileIndex(CurrProfile);
- PPUP.Items[c].Checked:= True;
- c := cfg.GetValue('Count', 0);
- for i := 1 to c do
- begin
- value := cfg.GetValue('Button' + Format('%2.2d', [i]) + '/Value', '');
- profile := cfg.GetValue('Button' + Format('%2.2d', [i]) + '/Profile', iall);
- ShowItem := (CurrProfile = iAll) or ((profile and CurrProfile) <> 0);
- if (value <> '') and ShowItem then
- begin
- if value = cDivider then
- AddDivider
- else
- begin
- mi := IDEMenuRoots.FindByPath(value,false);
- if Assigned(mi) then
- AddButton(mi);
- end;
- end;
- end;
- sToolbarPos := cfg.GetValue('Position','Top');
- bToolBarShow:= cfg.GetValue('Visible',true);
- EditorMenuCommand.Checked:= bToolBarShow;
- SetTbPos;
- finally
- cfg.Free;
- TB.EndUpdate;
- end;
- TB.Visible:= bToolBarShow;
- end;
- procedure TEditorToolbar.AddDivider;
- var
- B: TToolButton;
- begin
- B := TToolbutton.Create(TB);
- B.Style := tbsDivider;
- PositionAtEnd(TB, B);
- end;
- procedure TEditorToolbar.AddStaticItems;
- var
- B: TToolButton;
- begin
- TB.BeginUpdate;
- try
- // Config Button
- if CfgButton = nil then
- CfgButton := TToolbutton.Create(TB);
- CfgButton.Caption := rsConfigureToo;
- CfgButton.Hint := CfgButton.Caption;
- CfgButton.ImageIndex := IDEImages.LoadImage(16, 'preferences16');
- CfgButton.Style := tbsButton;
- CfgButton.OnClick := @DoConfigureToolbar;
- PositionAtEnd(TB, CfgButton);
- AddDivider;
- // JumpTo Button
- B := TToolbutton.Create(TB);
- B.Caption := rsJumpTo;
- B.Hint := B.Caption;
- B.ImageIndex := IDEImages.LoadImage(16, 'jumpto16');
- B.Style := tbsDropDown;
- B.OnClick := @FJumpHandler.DoJumpToImplementation;
- B.DropdownMenu := PM;
- PositionAtEnd(TB, B);
- if TB.ButtonCount <> 0 then
- AddDivider;
- finally
- TB.EndUpdate;
- end;
- end;
- procedure TEditorToolbar.ClearToolbar;
- var
- i: integer;
- begin
- TB.BeginUpdate;
- try
- for i := TB.ButtonCount - 1 downto 0 do
- if TB.Buttons[i] <> CfgButton then
- TB.Buttons[i].Free
- else
- TB.Buttons[i].Parent := nil;
- finally
- TB.EndUpdate;
- end;
- end;
- function GetShortcut(AMenuItem: TIDEMenuItem): string;
- var
- ACommand: TIDECommand;
- AShortcut: string;
- begin
- Result := '';
- AShortcut:= '';
- if AMenuItem is TIDEMenuCommand then begin
- ACommand := TIDEMenuCommand(AMenuItem).Command;
- if Assigned(ACommand) then AShortcut:= ShortCutToText(ACommand.AsShortCut);
- if AShortcut <> '' then Result:= ' (' + AShortcut +')';
- end;
- end;
- function GetProfileIndex(aMask: Integer): Integer;
- var
- I: Integer;
- begin
- for I:= 0 to High(ProfileMask) do begin
- if aMask = ProfileMask[I] then begin
- Result := I;
- Exit;
- end;
- end;
- Result := 0;
- end;
- procedure Register;
- var
- MenuIcon: string;
- begin
- if uEditorToolbarList = nil then begin
- TEditorToolbarList.Create;
- EditorMenuCommand:= RegisterIDEMenuCommand(itmViewSecondaryWindows,'EditorToolBar',
- rsEditorToolbar,nil,@ToggleToolbar);
- EditorMenuCommand.Checked:= True;
- EditorMenuCommand.Enabled:= True;
- MenuIcon:= 'menu_editor_options';
- //MenuIcon:= 'menu_editor_toolbar'; TODO!
- EditorMenuCommand.ImageIndex := IDEImages.LoadImage(16, MenuIcon);
- end;
- end;
- initialization
- uEditorToolbarList := nil;
- sToolbarPos:= 'Top';
- bToolBarShow:= True;
- CurrProfile:= iAll;
- finalization
- uEditorToolbarList.Free;
- end.