summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--examples/apps/uidesigner/newformdesigner.pas39
-rw-r--r--examples/apps/uidesigner/vfddesigner.pas15
-rw-r--r--examples/apps/uidesigner/vfdforms.pas102
-rw-r--r--examples/apps/uidesigner/vfdmain.pas32
-rw-r--r--examples/apps/uidesigner/vfdresizer.pas5
-rw-r--r--src/gui/fpgui_package.lpk14
-rw-r--r--src/gui/fpgui_package.pas2
-rw-r--r--src/gui/gui_memo.pas61
-rw-r--r--src/gui/gui_mru.pas273
9 files changed, 472 insertions, 71 deletions
diff --git a/examples/apps/uidesigner/newformdesigner.pas b/examples/apps/uidesigner/newformdesigner.pas
index 42a437a6..90c1ca3a 100644
--- a/examples/apps/uidesigner/newformdesigner.pas
+++ b/examples/apps/uidesigner/newformdesigner.pas
@@ -34,6 +34,7 @@ uses
gui_memo,
gui_combobox,
gui_menu,
+ gui_mru,
vfdwidgetclass,
vfdwidgets;
@@ -54,9 +55,9 @@ type
TfrmMain = class(TfpgForm)
private
FFileOpenRecent: TfpgMenuItem;
- procedure OpenRecentFileClick(Sender: TObject);
procedure miHelpAboutClick(Sender: TObject);
procedure miHelpAboutGUI(Sender: TObject);
+ procedure miMRUClick(Sender: TObject; const FileName: string);
public
{@VFD_HEAD_BEGIN: frmMain}
MainMenu: TfpgMenuBar;
@@ -72,12 +73,12 @@ type
helpmenu: TfpgPopupMenu;
previewmenu: TfpgPopupMenu;
{@VFD_HEAD_END: frmMain}
+ mru: TfpgMRU;
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
function GetSelectedWidget: TVFDWidgetClass;
procedure SetSelectedWidget(wgc: TVFDWidgetClass);
- procedure AddRecentFile(AFilename: string);
procedure AfterCreate; override;
procedure OnPaletteClick(Sender: TObject);
property SelectedWidget: TVFDWidgetClass read GetSelectedWidget write SetSelectedWidget;
@@ -337,8 +338,8 @@ begin
SetPosition(464, 64, 120, 20);
AddMenuItem('New', '', @(maindsgn.OnNewFile));
AddMenuItem('Open', '', @(maindsgn.OnLoadFile));
- // FFileOpenRecent := AddMenuItem('Open Recent...', '', nil);
- // FFileOpenRecent.Enabled := False;
+ FFileOpenRecent := AddMenuItem('Open Recent...', '', nil);
+// FFileOpenRecent.Enabled := False;
AddMenuItem('Save', '', @(maindsgn.OnSaveFile));
AddMenuItem('-', '', nil);
AddMenuItem('New Form...', '', @(maindsgn.OnNewForm));
@@ -415,7 +416,14 @@ begin
MainMenu.AddMenuItem('&Preview', nil).SubMenu := previewmenu;
MainMenu.AddMenuItem('&Help', nil).SubMenu := helpmenu;
-// FFileOpenRecent.SubMenu := miOpenRecentMenu;
+ FFileOpenRecent.SubMenu := miOpenRecentMenu;
+
+ mru := TfpgMRU.Create(self);
+ mru.ParentMenuItem := miOpenRecentMenu;
+ mru.OnClick := @miMRUClick;
+ mru.MaxItems := gINI.ReadInteger('Options', 'MRUFileCount', 4);
+ mru.ShowFullPath := gINI.ReadBool('Options', 'ShowFullPath', True);
+ mru.LoadMRU;
end;
procedure TfrmMain.OnPaletteClick(Sender: TObject);
@@ -808,12 +816,6 @@ begin
editor.SetPosition(x, editor.Top, Width - ScrollBarWidth - x, editor.Height);
end;
-procedure TfrmMain.OpenRecentFileClick(Sender: TObject);
-begin
- if Sender is TfpgMenuItem then
- writeln(TfpgMenuItem(Sender).Text + ' clicked...');
-end;
-
procedure TfrmMain.miHelpAboutClick(Sender: TObject);
begin
TfrmAbout.Execute;
@@ -824,6 +826,12 @@ begin
ShowMessage('This product was created using fpGUI v0.5', 'About fpGUI');
end;
+procedure TfrmMain.miMRUClick(Sender: TObject; const FileName: string);
+begin
+ maindsgn.EditedFileName := FileName;
+ maindsgn.OnLoadFile(maindsgn);
+end;
+
constructor TfrmMain.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
@@ -858,15 +866,6 @@ begin
end;
end;
-procedure TfrmMain.AddRecentFile(AFilename: string);
-var
- mi: TfpgMenuItem;
-begin
- gINI.WriteString('RecentFiles', ExtractFileName(AFileName), AFileName);
- FFileOpenRecent.Enabled := True;
- mi := miOpenRecentMenu.AddMenuItem(AFileName, '', @OpenRecentFileClick);
-end;
-
procedure TwgPropertyList.ReleaseEditor;
begin
self.ActiveWidget := nil;
diff --git a/examples/apps/uidesigner/vfddesigner.pas b/examples/apps/uidesigner/vfddesigner.pas
index b6ee116d..30fce227 100644
--- a/examples/apps/uidesigner/vfddesigner.pas
+++ b/examples/apps/uidesigner/vfddesigner.pas
@@ -331,10 +331,10 @@ begin
x := msg.Params.mouse.x;
y := msg.Params.mouse.y;
- if GridResolution > 1 then
+ if maindsgn.GridResolution > 1 then
begin
- x := x - x mod GridResolution;
- y := y - y mod GridResolution;
+ x := x - x mod maindsgn.GridResolution;
+ y := y - y mod maindsgn.GridResolution;
end;
InsertWidget(pwg, x, y, wgc);
@@ -386,10 +386,10 @@ begin
if (wgd = nil) or (not wgd.Selected) then
Exit;
- if GridResolution > 1 then
+ if maindsgn.GridResolution > 1 then
begin
- dx := dx - (dx mod GridResolution);
- dy := dy - (dy mod GridResolution);
+ dx := dx - (dx mod maindsgn.GridResolution);
+ dy := dy - (dy mod maindsgn.GridResolution);
end;
MoveResizeWidgets(dx, dy, 0, 0);
@@ -580,8 +580,7 @@ begin
cd := TWidgetDesigner(FWidgets.Items[n]);
if cd.Selected then
begin
- if GridResolution > 1 then
- ;
+// if maindsgn.GridResolution > 1 then;
cd.Widget.MoveAndResizeBy(dx, dy, dw, dh);
cd.UpdateResizerPositions;
end;
diff --git a/examples/apps/uidesigner/vfdforms.pas b/examples/apps/uidesigner/vfdforms.pas
index 6454dff2..61b33b29 100644
--- a/examples/apps/uidesigner/vfdforms.pas
+++ b/examples/apps/uidesigner/vfdforms.pas
@@ -31,7 +31,9 @@ uses
gui_edit,
gui_button,
gui_listbox,
- gui_combobox;
+ gui_combobox,
+ gui_trackbar,
+ gui_checkbox;
type
@@ -102,12 +104,21 @@ type
TfrmVFDSetup = class(TfpgForm)
+ private
+ procedure LoadSettings;
+ procedure SaveSettings;
+ procedure btnOKClick(Sender: TObject);
public
{@VFD_HEAD_BEGIN: frmVFDSetup}
lb1: TfpgLabel;
chlGrid: TfpgComboBox;
btnOK: TfpgButton;
btnCancel: TfpgButton;
+ lblRecentFiles: TfpgLabel;
+ tbMRUFileCount: TfpgTrackBar;
+ cbFullPath: TfpgCheckBox;
+ lblName1: TfpgLabel;
+ lblName2: TfpgLabel;
{@VFD_HEAD_END: frmVFDSetup}
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
@@ -118,8 +129,6 @@ type
var
PaletteForm: TPaletteForm;
-function GridResolution: integer;
-
implementation
uses
@@ -127,10 +136,6 @@ uses
fpgfx,
gui_iniutils;
-function GridResolution: integer;
-begin
- Result := maindsgn.GridResolution;
-end;
{ TPaletteForm }
@@ -425,11 +430,32 @@ begin
inherited HandleKeyPress(keycode, shiftstate, consumed);
end;
+procedure TfrmVFDSetup.LoadSettings;
+begin
+ chlGrid.FocusItem := gINI.ReadInteger('Options', 'GridResolution', 2);
+ tbMRUFileCount.Position := gINI.ReadInteger('Options', 'MRUFileCount', 4);
+ cbFullPath.Checked := gINI.ReadBool('Options', 'ShowFullPath', True);
+end;
+
+procedure TfrmVFDSetup.SaveSettings;
+begin
+ gINI.WriteInteger('Options', 'GridResolution', chlGrid.FocusItem);
+ gINI.WriteInteger('Options', 'MRUFileCount', tbMRUFileCount.Position);
+ gINI.WriteBool('Options', 'ShowFullPath', cbFullPath.Checked);
+end;
+
+procedure TfrmVFDSetup.btnOKClick(Sender: TObject);
+begin
+ SaveSettings;
+ ModalResult := 1;
+end;
+
constructor TfrmVFDSetup.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
Name := 'frmVFDSetup';
gINI.ReadFormState(self);
+ LoadSettings;
end;
destructor TfrmVFDSetup.Destroy;
@@ -441,14 +467,14 @@ end;
procedure TfrmVFDSetup.AfterCreate;
begin
{@VFD_BODY_BEGIN: frmVFDSetup}
- SetPosition(394, 399, 237, 70);
+ SetPosition(394, 399, 252, 184);
WindowTitle := 'General settings';
WindowPosition := wpScreenCenter;
lb1 := TfpgLabel.Create(self);
with lb1 do
begin
- SetPosition(8, 8, 116, 16);
+ SetPosition(28, 28, 116, 16);
Text := 'Grid resolution:';
FontDesc := '#Label1';
end;
@@ -456,36 +482,80 @@ begin
chlGrid := TfpgComboBox.Create(self);
with chlGrid do
begin
- SetPosition(128, 4, 56, 22);
+ SetPosition(140, 24, 88, 22);
Items.Add('1');
Items.Add('4');
Items.Add('8');
FontDesc := '#List';
- FocusItem := 2;
+ FocusItem := 0;
end;
btnOK := TfpgButton.Create(self);
with btnOK do
begin
- SetPosition(77, 40, 75, 24);
+ SetPosition(92, 154, 75, 24);
Anchors := [anRight,anBottom];
Text := 'OK';
FontDesc := '#Label1';
ImageName := 'stdimg.ok';
- ModalResult := 1;
- ShowImage := True;
+ ModalResult := 0;
+ ShowImage := True;
+ OnClick := @btnOKClick;
end;
btnCancel := TfpgButton.Create(self);
with btnCancel do
begin
- SetPosition(156, 40, 75, 24);
+ SetPosition(171, 154, 75, 24);
Anchors := [anRight,anBottom];
Text := 'Cancel';
FontDesc := '#Label1';
ImageName := 'stdimg.cancel';
ModalResult := -1;
- ShowImage := True;
+ ShowImage := True;
+ end;
+
+ lblRecentFiles := TfpgLabel.Create(self);
+ with lblRecentFiles do
+ begin
+ SetPosition(28, 88, 136, 16);
+ Text := 'Recent files count:';
+ FontDesc := '#Label1';
+ end;
+
+ tbMRUFileCount := TfpgTrackBar.Create(self);
+ with tbMRUFileCount do
+ begin
+ SetPosition(156, 80, 76, 30);
+ Min := 2;
+ Max := 10;
+ Position := 4;
+ Orientation := orHorizontal;
+ ShowPosition := True;
+ end;
+
+ cbFullPath := TfpgCheckBox.Create(self);
+ with cbFullPath do
+ begin
+ SetPosition(24, 108, 204, 20);
+ Text := 'Show the full file path';
+ FontDesc := '#Label1';
+ end;
+
+ lblName1 := TfpgLabel.Create(self);
+ with lblName1 do
+ begin
+ SetPosition(8, 8, 176, 16);
+ Text := 'Form designer';
+ FontDesc := '#Label2';
+ end;
+
+ lblName2 := TfpgLabel.Create(self);
+ with lblName2 do
+ begin
+ SetPosition(8, 64, 232, 16);
+ Text := 'Open Recent menu settings';
+ FontDesc := '#Label2';
end;
{@VFD_BODY_END: frmVFDSetup}
diff --git a/examples/apps/uidesigner/vfdmain.pas b/examples/apps/uidesigner/vfdmain.pas
index cead1ede..cd3413e4 100644
--- a/examples/apps/uidesigner/vfdmain.pas
+++ b/examples/apps/uidesigner/vfdmain.pas
@@ -80,7 +80,8 @@ var
implementation
uses
- vfdformparser;
+ vfdformparser,
+ gui_iniutils;
{ TMainDesigner }
@@ -156,6 +157,8 @@ begin
CreateParseForm(bl.FormName, bl.Data, bl2.Data); // pair was found
end;
end;
+
+ frmMain.mru.AddItem(fname);
end;
procedure TMainDesigner.OnSaveFile(Sender: TObject);
@@ -303,8 +306,8 @@ begin
FFile := TVFDFile.Create;
// options
- SaveComponentNames := False;
- GridResolution := 4;
+ SaveComponentNames := True;
+ GridResolution := gINI.ReadInteger('Options', 'GridResolution', 4);
FEditedFileName := '';
end;
@@ -402,21 +405,16 @@ var
frm: TfrmVFDSetup;
begin
frm := TfrmVFDSetup.Create(nil);
-
- case GridResolution of
- 1: frm.chlGrid.FocusItem := 1;
- 4: frm.chlGrid.FocusItem := 2;
- 8: frm.chlGrid.FocusItem := 3;
- end;
-
- if frm.ShowModal > 0 then
- case frm.chlGrid.FocusItem of
- 1: GridResolution := 1;
- 2: GridResolution := 4;
- 3: GridResolution := 8;
+ try
+ if frm.ShowModal = 1 then
+ begin
+ GridResolution := gINI.ReadInteger('Options', 'GridResolution', 4);
+ frmMain.mru.MaxItems := gINI.ReadInteger('Options', 'MRUFileCount', 4);
+ frmMain.mru.ShowFullPath := gINI.ReadBool('Options', 'ShowFullPath', True);
end;
-
- frm.Free;
+ finally
+ frm.Free;
+ end;
end;
procedure TMainDesigner.SetEditedFileName(const Value: string);
diff --git a/examples/apps/uidesigner/vfdresizer.pas b/examples/apps/uidesigner/vfdresizer.pas
index 5c4185b3..2faccfe8 100644
--- a/examples/apps/uidesigner/vfdresizer.pas
+++ b/examples/apps/uidesigner/vfdresizer.pas
@@ -49,7 +49,8 @@ implementation
uses
vfddesigner,
- vfdforms;
+ vfdforms,
+ vfdmain;
{ TwgResizer }
@@ -91,7 +92,7 @@ begin
dy := y - FDragPosY;
wgd := TWidgetDesigner(wgdesigner);
- gridc := GridResolution;
+ gridc := maindsgn.GridResolution;
dx := dx - dx mod gridc;
dy := dy - dy mod gridc;
diff --git a/src/gui/fpgui_package.lpk b/src/gui/fpgui_package.lpk
index 45d475ca..901eacc9 100644
--- a/src/gui/fpgui_package.lpk
+++ b/src/gui/fpgui_package.lpk
@@ -26,7 +26,7 @@
<License Value="Modified LGPL
"/>
<Version Minor="5" Release="1"/>
- <Files Count="23">
+ <Files Count="24">
<Item1>
<Filename Value="gui_button.pas"/>
<UnitName Value="gui_button"/>
@@ -119,15 +119,19 @@
<Filename Value="gui_iniutils.pas"/>
<UnitName Value="gui_iniutils"/>
</Item23>
+ <Item24>
+ <Filename Value="gui_mru.pas"/>
+ <UnitName Value="gui_mru"/>
+ </Item24>
</Files>
<RequiredPkgs Count="2">
<Item1>
- <PackageName Value="FCL"/>
- <MinVersion Major="1" Valid="True"/>
- </Item1>
- <Item2>
<PackageName Value="fpgfx_package"/>
<MinVersion Minor="5" Valid="True"/>
+ </Item1>
+ <Item2>
+ <PackageName Value="FCL"/>
+ <MinVersion Major="1" Valid="True"/>
</Item2>
</RequiredPkgs>
<UsageOptions>
diff --git a/src/gui/fpgui_package.pas b/src/gui/fpgui_package.pas
index f9599fe7..662408ba 100644
--- a/src/gui/fpgui_package.pas
+++ b/src/gui/fpgui_package.pas
@@ -11,7 +11,7 @@ uses
gui_listbox, gui_memo, gui_scrollbar, gui_bevel, gui_checkbox,
gui_radiobutton, gui_trackbar, gui_tab, gui_basegrid, gui_listview,
gui_customgrid, gui_progressbar, gui_menu, gui_style, gui_grid, gui_tree,
- gui_iniutils;
+ gui_iniutils, gui_mru;
implementation
diff --git a/src/gui/gui_memo.pas b/src/gui/gui_memo.pas
index b424a523..7339ab23 100644
--- a/src/gui/gui_memo.pas
+++ b/src/gui/gui_memo.pas
@@ -2,6 +2,12 @@ unit gui_memo;
{$mode objfpc}{$H+}
+{
+ TODO:
+ * Started a implementation for Tab support. It is still very experimental
+ and should not be used yet.
+}
+
interface
uses
@@ -36,6 +42,8 @@ type
FDrawOffset: integer;
FLineHeight: integer;
FFirstLine: integer;
+ FTabWidth: integer;
+ FUseTabs: boolean;
FVScrollBar: TfpgScrollBar;
FHScrollBar: TfpgScrollBar;
FWrapping: boolean;
@@ -82,6 +90,8 @@ type
property Text: string read GetText write SetText;
property Font: TfpgFont read FFont;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
+ property UseTabs: boolean read FUseTabs write FUseTabs;
+ property TabWidth: integer read FTabWidth write FTabWidth;
published
property Lines: TStringList read FLines;
property FontDesc: string read GetFontDesc write SetFontDesc;
@@ -178,6 +188,8 @@ begin
FWrapping := False;
FOnChange := nil;
FBackgroundColor := clBoxColor;
+ FUseTabs := False;
+ FTabWidth := 4;
FLines := TStringList.Create;
FFirstLine := 1;
@@ -633,10 +645,12 @@ procedure TfpgMemo.HandlePaint;
var
n: integer;
tw, tw2, st, len: integer;
- yp: integer;
+ yp, xp: integer;
ls: string;
r: TfpgRect;
selsl, selsp, selel, selep: integer;
+ c: integer;
+ s: string;
begin
Canvas.BeginDraw;
Canvas.ClearClipRect;
@@ -673,7 +687,27 @@ begin
for n := FFirstline to LineCount do
begin
ls := GetLineText(n);
- Canvas.DrawString(-FDrawOffset + FSideMargin, yp, ls);
+ if FUseTabs then
+ begin
+ xp := 0;
+ s := '';
+ for c := 1 to Length(ls) do
+ begin
+ if ls[c] = #9 then
+ begin
+ if s <> '' then
+ Canvas.DrawString(-FDrawOffset + FSideMargin + xp, yp, s);
+ xp := xp + Canvas.Font.TextWidth(' ') * FTabWidth;
+ s := '';
+ end
+ else
+ s := s + ls[c];
+ end;
+ if s <> '' then
+ Canvas.DrawString(-FDrawOffset + FSideMargin + xp, yp, s);
+ end
+ else
+ Canvas.DrawString(-FDrawOffset + FSideMargin, yp, ls);
if Focused then
begin
@@ -972,6 +1006,29 @@ begin
end;
hasChanged := True;
end;
+ keyTab:
+ begin
+ if FUseTabs then
+ begin
+ ls := GetLineText(FCursorLine);
+{ if FSelEndLine > 0 then
+ DeleteSelection
+ else} if FCursorPos < UTF8Length(ls) then
+ begin
+ Insert(#9, ls, FCursorPos);
+ SetLineText(FCursorLine, ls);
+ end;
+{
+ else if FCursorLine < LineCount then
+ begin
+ ls2 := FLines.Strings[FCursorLine];
+ FLines.Delete(FCursorLine);
+ FLines.Strings[FCursorLine - 1] := ls + ls2;
+ end;
+}
+ hasChanged := True;
+ end;
+ end;
else
consumed := False;
end;
diff --git a/src/gui/gui_mru.pas b/src/gui/gui_mru.pas
new file mode 100644
index 00000000..353a2d03
--- /dev/null
+++ b/src/gui/gui_mru.pas
@@ -0,0 +1,273 @@
+{
+ fpGUI - Free Pascal GUI Library
+
+ Copyright (C) 2006 - 2007 See the file AUTHORS.txt, included in this
+ distribution, for details of the copyright.
+
+ See the file COPYING.modifiedLGPL, included in this distribution,
+ for details about redistributing fpGUI.
+
+ 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.
+
+ Description:
+ A component implementing a 'Most Recently Used' feature normally
+ inserted in the File menu.
+}
+
+unit gui_mru;
+
+{$mode objfpc}{$H+}
+
+interface
+
+uses
+ Classes, SysUtils, gui_menu;
+
+type
+
+ TMRUClickEvent = procedure(Sender: TObject; const FileName: String) of object;
+
+ TfpgMRU = class(TComponent)
+ private
+ FItems: TStringList;
+ FMaxItems: cardinal;
+ FShowFullPath: boolean;
+ FParentMenuItem: TfpgPopupMenu;
+ FIniFilePath: string;
+ FOnClick: TMRUClickEvent;
+ procedure SetMaxItems(const AValue: cardinal);
+// procedure SetIniFilePath(const AValue: string);
+ procedure SetParentMenuItem(const AValue: TfpgPopupMenu);
+ procedure SetShowFullPath(const AValue: boolean);
+ procedure SaveMRU;
+ procedure ItemsChange(Sender: TObject);
+ procedure ClearParentMenu;
+ protected
+ // this never gets called without a Form Streaming class, which fpGUI doesn't use
+ procedure Loaded; override;
+ procedure Notification(AComponent: TComponent; Operation: TOperation); override;
+ procedure DoClick(Sender: TObject);
+ public
+ constructor Create(AOwner: TComponent); override;
+ destructor Destroy; override;
+ procedure AddItem(const FileName: string);
+ function RemoveItem(const FileName : string) : boolean;
+ procedure LoadMRU;
+ published
+ property MaxItems: cardinal read FMaxItems write SetMaxItems default 4;
+// property IniFilePath: string read FIniFilePath write SetIniFilePath;
+ property ShowFullPath: boolean read FShowFullPath write SetShowFullPath default True;
+ property ParentMenuItem: TfpgPopupMenu read FParentMenuItem write SetParentMenuItem;
+ property OnClick: TMRUClickEvent read FOnClick write FOnClick;
+ end;
+
+
+implementation
+
+uses
+ gui_iniutils;
+
+type
+ //to be able to recognize MRU menu item when deleting
+ TMRUMenuItem = class(TfpgMenuItem);
+
+
+{ TfpgMRU }
+
+procedure TfpgMRU.SetMaxItems(const AValue: cardinal);
+begin
+ if AValue <> FMaxItems then
+ begin
+ if AValue < 1 then FMaxItems := 1
+ else
+ if AValue > MaxInt then
+ FMaxItems := MaxInt - 1
+ else
+ begin
+ FMaxItems := AValue;
+ FItems.BeginUpdate;
+ try
+ while FItems.Count > MaxItems do
+ FItems.Delete(FItems.Count - 1);
+ finally
+ FItems.EndUpdate;
+ end;
+ end;
+ end;
+end;
+
+{
+procedure TfpgMRU.SetIniFilePath(const AValue: string);
+begin
+ if FIniFilePath=AValue then exit;
+ FIniFilePath:=AValue;
+end;
+}
+
+procedure TfpgMRU.SetParentMenuItem(const AValue: TfpgPopupMenu);
+begin
+ if AValue = FParentMenuItem then
+ Exit;
+ FParentMenuItem := AValue;
+end;
+
+procedure TfpgMRU.SetShowFullPath(const AValue: boolean);
+begin
+ if FShowFullPath <> AValue then
+ begin
+ FShowFullPath := AValue;
+ ItemsChange(Self);
+ end;
+end;
+
+procedure TfpgMRU.LoadMRU;
+var
+ i: cardinal;
+begin
+ FItems.BeginUpdate;
+ FItems.Clear;
+ try
+ for i := 1 to FMaxItems do
+ if gINI.ValueExists('MRU', 'MRU'+IntToStr(i)) then
+ FItems.Add(gINI.ReadString('MRU', 'MRU'+IntToStr(i), ''));
+ finally
+ FItems.EndUpdate;
+ end;
+end;
+
+procedure TfpgMRU.SaveMRU;
+var
+ i: integer;
+begin
+ if FItems.Count = 0 then
+ Exit;
+
+ //delete old mru
+ i := 1;
+ while gINI.ValueExists('MRU', 'MRU'+IntToStr(i)) do
+ begin
+ gINI.DeleteKey('MRU', 'MRU'+IntToStr(i));
+ Inc(i);
+ end;
+
+ //write new mru
+ for i := 0 to FItems.Count-1 do
+ gINI.WriteString('MRU', 'MRU'+IntToStr(i+1), FItems[i]);
+end;
+
+procedure TfpgMRU.ItemsChange(Sender: TObject);
+var
+ i: Integer;
+ NewMenuItem: TfpgMenuItem;
+ FileName: String;
+begin
+// writeln('TfpgMRU.ItemsChange');
+ if ParentMenuItem <> nil then
+ begin
+ ClearParentMenu;
+ if FItems.Count = 0 then
+ ParentMenuItem.AddMenuItem('-', '', nil); // add something if we have no previous MRU's
+ for i := 0 to -1 + FItems.Count do
+ begin
+ if ShowFullPath then
+ FileName := StringReplace(FItems[I], '&', '&&', [rfReplaceAll, rfIgnoreCase])
+ else
+ FileName := StringReplace(ExtractFileName(FItems[i]), '&', '&&', [rfReplaceAll, rfIgnoreCase]);
+
+// NewMenuItem := ParentMenuItem.AddMenuItem(Format('%s', [FileName]), '', @DoClick);
+// NewMenuItem.Tag := i;
+ NewMenuItem := TMRUMenuItem.Create(ParentMenuItem);
+ NewMenuItem.Text := Format('%s', [FileName]);
+ NewMenuItem.Tag := i;
+ NewMenuItem.OnClick := @DoClick;
+ end;
+ end;
+end;
+
+procedure TfpgMRU.ClearParentMenu;
+//var
+// i:integer;
+begin
+ if Assigned(ParentMenuItem) then
+ ParentMenuItem.DestroyComponents;
+{
+ for i := ParentMenuItem.ComponentCount-1 downto 0 do
+ if ParentMenuItem.Components[i] is TMRUMenuItem then
+ ParentMenuItem.Delete(i);
+}
+end;
+
+procedure TfpgMRU.Loaded;
+begin
+ inherited Loaded;
+ if not (csDesigning in ComponentState) then
+// if FIniFilePath <> '' then
+ LoadMRU;
+end;
+
+procedure TfpgMRU.Notification(AComponent: TComponent; Operation: TOperation);
+begin
+ inherited Notification(AComponent, Operation);
+ if (Operation = opRemove) and (AComponent = FParentMenuItem) then
+ FParentMenuItem := nil;
+end;
+
+procedure TfpgMRU.DoClick(Sender: TObject);
+begin
+ if Assigned(FOnClick) and (Sender is TMRUMenuItem) then
+ FOnClick(Self, FItems[TMRUMenuItem(Sender).Tag]);
+end;
+
+constructor TfpgMRU.Create(AOwner: TComponent);
+begin
+ inherited Create(AOwner);
+ FParentMenuItem := nil;
+ FItems := TStringList.Create;
+ FItems.OnChange := @ItemsChange;
+ FMaxItems := 4;
+ FShowFullPath := True;
+// Loaded;
+end;
+
+destructor TfpgMRU.Destroy;
+begin
+ if not (csDesigning in ComponentState) then
+ SaveMRU;
+ FItems.OnChange := nil;
+ FItems.Free;
+ inherited Destroy;
+end;
+
+procedure TfpgMRU.AddItem(const FileName: string);
+begin
+ if FileName <> '' then
+ begin
+ FItems.BeginUpdate;
+ try
+ if FItems.IndexOf(FileName) > -1 then
+ FItems.Delete(FItems.IndexOf(FileName));
+ FItems.Insert(0, FileName);
+
+ while FItems.Count > MaxItems do
+ FItems.Delete(MaxItems);
+ finally
+ FItems.EndUpdate;
+ end;
+ end;
+end;
+
+function TfpgMRU.RemoveItem(const FileName: string): boolean;
+begin
+ if FItems.IndexOf(FileName) > -1 then
+ begin
+ FItems.Delete(FItems.IndexOf(FileName));
+ Result := True;
+ end
+ else
+ Result := False;
+end;
+
+end.
+