Componentes.Terceros.jvcl/official/3.32/run/JvMRUManager.pas

878 lines
25 KiB
ObjectPascal

{-----------------------------------------------------------------------------
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in compliance
with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/MPL-1.1.html
Software distributed under the License is distributed on an "AS IS" basis,
WITHOUT WARRANTY OF ANY KIND, either expressed or implied. See the License for
the specific language governing rights and limitations under the License.
The Original Code is: JvMRUList.PAS, released on 2002-07-04.
The Initial Developers of the Original Code are: Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 1997, 1998 Fedor Koshevnikov, Igor Pavluk and Serge Korolev
Copyright (c) 2001,2002 SGB Software
All Rights Reserved.
Contributors:
Michael Fritz (MenuLocation)
You may retrieve the latest version of this file at the Project JEDI's JVCL home page,
located at http://jvcl.sourceforge.net
Known Issues:
* Using a divider as RecentMenu when MenuLocation = mruChild doesn't work
-----------------------------------------------------------------------------}
// $Id: JvMRUManager.pas 11057 2006-11-29 14:32:05Z marquardt $
unit JvMRUManager;
{$I jvcl.inc}
interface
uses
{$IFDEF UNITVERSIONING}
JclUnitVersioning,
{$ENDIF UNITVERSIONING}
SysUtils, Classes,
{$IFDEF VisualCLX}
Qt,
{$ENDIF VisualCLX}
Windows, Menus, Graphics, Controls, Forms,
JvFormPlacement, JvAppStorage, JvComponentBase;
type
TJvRecentStrings = class;
TGetItemEvent = procedure(Sender: TObject; var Caption: string;
var ShortCut: TShortCut; UserData: Longint) of object;
TReadItemEvent = procedure(Sender: TObject; AppStorage: TJvCustomAppStorage;
const Path: string; Index: Integer; var RecentName: string;
var UserData: Longint) of object;
TWriteItemEvent = procedure(Sender: TObject; AppStorage: TJvCustomAppStorage;
const Path: string; Index: Integer; const RecentName: string;
UserData: Longint) of object;
TClickMenuEvent = procedure(Sender: TObject; const RecentName,
Caption: string; UserData: Longint) of object;
TGetItemInfoEvent = procedure(Sender: TObject; Item: TMenuItem) of object;
TGetItemInfoExEvent = procedure(Sender: TObject; Item: TMenuItem; Index: Integer) of object;
TAccelDelimiter = (adTab, adSpace);
TRecentMode = (rmInsert, rmAppend);
TMenuLocation = (mruChild, mruSibling);
TJvRecentStrings = class(TStringList)
private
FMaxSize: Integer;
FMode: TRecentMode;
procedure SetMaxSize(Value: Integer);
protected
procedure SetTextStr(const Value: String); override;
public
constructor Create;
function Add(const S: string): Integer; override;
procedure AddStrings(Strings: TStrings); override;
procedure DeleteExceed;
procedure Remove(const S: string);
property MaxSize: Integer read FMaxSize write SetMaxSize;
property Mode: TRecentMode read FMode write FMode;
end;
TJvMRUManager = class(TJvComponent)
private
FStrings: TJvRecentStrings;
FItems: TList;
FIniLink: TJvIniLink;
FSeparateSize: Word;
FAutoEnable: Boolean;
FAutoUpdate: Boolean;
FShowAccelChar: Boolean;
FRemoveOnSelect: Boolean;
FStartAccel: Cardinal;
FAccelDelimiter: TAccelDelimiter;
FRecentMenu: TMenuItem;
FOnChange: TNotifyEvent;
FOnGetItem: TGetItemEvent;
FOnClick: TClickMenuEvent;
FOnReadItem: TReadItemEvent;
FOnWriteItem: TWriteItemEvent;
FOnAfterUpdate: TNotifyEvent;
FOnBeforeUpdate: TNotifyEvent;
FOnItemInfo: TGetItemInfoEvent;
FOnItemInfoEx: TGetItemInfoExEvent;
FDuplicates: TDuplicates;
FMenuLocation: TMenuLocation;
FMaxLength: Integer;
FCanvas: TCanvas;
FStartEllipsis: Boolean;
procedure ListChanged(Sender: TObject);
procedure ClearRecentMenu;
procedure SetRecentMenu(Value: TMenuItem);
procedure SetSeparateSize(Value: Word);
function GetStorage: TJvFormPlacement;
procedure SetStorage(Value: TJvFormPlacement);
function GetCapacity: Integer;
procedure SetCapacity(Value: Integer);
function GetMode: TRecentMode;
procedure SetMode(Value: TRecentMode);
procedure SetStartAccel(Value: Cardinal);
procedure SetShowAccelChar(Value: Boolean);
procedure SetAccelDelimiter(Value: TAccelDelimiter);
procedure SetAutoEnable(Value: Boolean);
procedure AddMenuItem(Item: TMenuItem);
procedure MenuItemClick(Sender: TObject);
procedure IniSave(Sender: TObject);
procedure IniLoad(Sender: TObject);
procedure InternalLoad(const Section: string);
procedure InternalSave(const Section: string);
procedure SetDuplicates(const Value: TDuplicates);
procedure DoDuplicateFixUp;
function GetStrings: TStrings;
procedure SetMenuLocation(const Value: TMenuLocation);
procedure SetMaxLength(const Value: Integer);
procedure SetStartEllipsis(const Value: Boolean);
protected
function GetCanvas: TCanvas;
function DoMinimizeName(const S: string): string;
procedure Change; dynamic;
procedure Notification(AComponent: TComponent; Operation: TOperation); override;
procedure DoReadItem(AppStorage: TJvCustomAppStorage; const Path: string; Index: Integer;
var RecentName: string; var UserData: Longint); dynamic;
procedure DoWriteItem(AppStorage: TJvCustomAppStorage; const Path: string; Index: Integer;
const RecentName: string; UserData: Longint); dynamic;
procedure GetItemData(var Caption: string; var ShortCut: TShortCut;
UserData: Longint); dynamic;
procedure GetItemInfo(Item: TMenuItem); dynamic;
procedure GetItemInfoEx(Item: TMenuItem; Index: Integer); dynamic;
procedure DoClick(const RecentName, Caption: string; UserData: Longint); dynamic;
procedure DoBeforeUpdate; virtual;
procedure DoAfterUpdate; virtual;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Add(const RecentName: string; UserData: Longint);
procedure Clear;
procedure Remove(const RecentName: string);
procedure UpdateRecentMenu;
procedure RemoveInvalid;
procedure LoadFromAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
procedure SaveToAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
procedure Load;
procedure Save;
function IsMenuEnabled: Boolean;
property Strings: TStrings read GetStrings;
published
// Duplicates works just as for TStrings, but the list doesn't need to be sorted
property Duplicates: TDuplicates read FDuplicates write SetDuplicates;
property AccelDelimiter: TAccelDelimiter read FAccelDelimiter write SetAccelDelimiter default adTab;
property AutoEnable: Boolean read FAutoEnable write SetAutoEnable default True;
property AutoUpdate: Boolean read FAutoUpdate write FAutoUpdate default True;
property MaxLength: Integer read FMaxLength write SetMaxLength default 0;
property StartEllipsis: Boolean read FStartEllipsis write SetStartEllipsis default False;
property Capacity: Integer read GetCapacity write SetCapacity default 10;
property MenuLocation: TMenuLocation read FMenuLocation write SetMenuLocation default mruChild;
property Mode: TRecentMode read GetMode write SetMode default rmInsert;
property RemoveOnSelect: Boolean read FRemoveOnSelect write FRemoveOnSelect default False;
property IniStorage: TJvFormPlacement read GetStorage write SetStorage;
property SeparateSize: Word read FSeparateSize write SetSeparateSize default 0;
property RecentMenu: TMenuItem read FRecentMenu write SetRecentMenu;
property ShowAccelChar: Boolean read FShowAccelChar write SetShowAccelChar default True;
property StartAccel: Cardinal read FStartAccel write SetStartAccel default 1;
property OnChange: TNotifyEvent read FOnChange write FOnChange;
property OnClick: TClickMenuEvent read FOnClick write FOnClick;
// OnGetItemData is called just before the menu item is created
property OnGetItemData: TGetItemEvent read FOnGetItem write FOnGetItem;
property OnReadItem: TReadItemEvent read FOnReadItem write FOnReadItem;
property OnWriteItem: TWriteItemEvent read FOnWriteItem write FOnWriteItem;
// called just before the menu items are updated
property OnBeforeUpdate: TNotifyEvent read FOnBeforeUpdate write FOnBeforeUpdate;
// called just after the menu items have been updated
property OnAfterUpdate: TNotifyEvent read FOnAfterUpdate write FOnAfterUpdate;
// called just before the newly created menu item is added to the RecentMenu submenu
// this makes it easier to set any additional properties of the menu item not
// handled by OnGetItemData.
property OnGetItemInfo: TGetItemInfoEvent read FOnItemInfo write FOnItemInfo;
property OnGetItemInfoEx: TGetItemInfoExEvent read FOnItemInfoEx write FOnItemInfoEx;
end;
{$IFDEF UNITVERSIONING}
const
UnitVersioning: TUnitVersionInfo = (
RCSfile: '$URL: https://jvcl.svn.sourceforge.net/svnroot/jvcl/tags/JVCL3_32/run/JvMRUManager.pas $';
Revision: '$Revision: 11057 $';
Date: '$Date: 2006-11-29 15:32:05 +0100 (mer., 29 nov. 2006) $';
LogPath: 'JVCL\run'
);
{$ENDIF UNITVERSIONING}
implementation
uses
Math,
JclFileUtils,
JvJVCLUtils, JvConsts, JvResources, JvTypes;
const
siRecentItem = 'Item_%d';
siRecentData = 'User_%d';
//=== { TJvMRUManager } ======================================================
constructor TJvMRUManager.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FStrings := TJvRecentStrings.Create;
FItems := TList.Create;
FStrings.OnChange := ListChanged;
FIniLink := TJvIniLink.Create;
FIniLink.OnSave := IniSave;
FIniLink.OnLoad := IniLoad;
FAutoUpdate := True;
FAutoEnable := True;
FShowAccelChar := True;
FStartAccel := 1;
FMenuLocation := mruChild;
end;
destructor TJvMRUManager.Destroy;
begin
ClearRecentMenu;
FIniLink.Free;
FStrings.OnChange := nil;
FStrings.Free;
FreeAndNil(FItems);
FreeAndNil(FCanvas);
inherited Destroy;
end;
procedure TJvMRUManager.Notification(AComponent: TComponent; Operation: TOperation);
begin
inherited Notification(AComponent, Operation);
if (AComponent = RecentMenu) and (Operation = opRemove) then
RecentMenu := nil;
end;
function TJvMRUManager.GetStrings: TStrings;
begin
Result := FStrings;
end;
procedure TJvMRUManager.GetItemData(var Caption: string; var ShortCut: TShortCut;
UserData: Longint);
begin
if Assigned(FOnGetItem) then
FOnGetItem(Self, Caption, ShortCut, UserData);
end;
procedure TJvMRUManager.DoClick(const RecentName, Caption: string; UserData: Longint);
begin
if Assigned(FOnClick) then
FOnClick(Self, RecentName, Caption, UserData);
end;
procedure TJvMRUManager.MenuItemClick(Sender: TObject);
var
I: Integer;
begin
if Sender is TMenuItem then
begin
I := TMenuItem(Sender).Tag;
if (I >= 0) and (I < Strings.Count) then
try
DoClick(Strings[I], TMenuItem(Sender).Caption, Longint(Strings.Objects[I]));
finally
if RemoveOnSelect then
Remove(Strings[I]);
end;
end;
end;
function TJvMRUManager.GetCapacity: Integer;
begin
Result := FStrings.MaxSize;
end;
procedure TJvMRUManager.SetCapacity(Value: Integer);
begin
FStrings.MaxSize := Value;
end;
function TJvMRUManager.GetMode: TRecentMode;
begin
Result := FStrings.Mode;
end;
procedure TJvMRUManager.SetMode(Value: TRecentMode);
begin
FStrings.Mode := Value;
end;
function TJvMRUManager.GetStorage: TJvFormPlacement;
begin
Result := FIniLink.Storage;
end;
procedure TJvMRUManager.SetStorage(Value: TJvFormPlacement);
begin
FIniLink.Storage := Value;
end;
procedure TJvMRUManager.SetAutoEnable(Value: Boolean);
begin
if FAutoEnable <> Value then
begin
FAutoEnable := Value;
if Assigned(FRecentMenu) then
begin
if FAutoEnable then
FRecentMenu.Enabled := IsMenuEnabled
else
FRecentMenu.Enabled := True;
end;
end;
end;
procedure TJvMRUManager.SetStartAccel(Value: Cardinal);
begin
if FStartAccel <> Value then
begin
FStartAccel := Value;
if FAutoUpdate then
UpdateRecentMenu;
end;
end;
procedure TJvMRUManager.SetAccelDelimiter(Value: TAccelDelimiter);
begin
if FAccelDelimiter <> Value then
begin
FAccelDelimiter := Value;
if FAutoUpdate and ShowAccelChar then
UpdateRecentMenu;
end;
end;
procedure TJvMRUManager.SetShowAccelChar(Value: Boolean);
begin
if FShowAccelChar <> Value then
begin
FShowAccelChar := Value;
if FAutoUpdate then
UpdateRecentMenu;
end;
end;
procedure TJvMRUManager.Add(const RecentName: string; UserData: Longint);
var
I: Integer;
begin
if not (Duplicates = dupAccept) and (Strings.IndexOf(RecentName) > -1) then
begin
if Duplicates = dupError then
raise EJVCLException.CreateRes(@RsEDuplicatesNotAllowedInMRUList);
end
else
begin
I := FStrings.Add(RecentName);
Strings.Objects[I] := TObject(UserData);
end;
end;
procedure TJvMRUManager.Clear;
begin
Strings.Clear;
end;
procedure TJvMRUManager.Remove(const RecentName: string);
begin
FStrings.Remove(RecentName);
end;
procedure TJvMRUManager.AddMenuItem(Item: TMenuItem);
begin
if Assigned(Item) then
begin
if FMenuLocation = mruSibling then
begin
if FRecentMenu.HasParent and (FRecentMenu.Parent.MenuIndex >= 0) then
FRecentMenu.Parent.Insert(FRecentMenu.MenuIndex + FItems.Count + 1, Item)
else
FRecentMenu.Add(Item);
end
else
FRecentMenu.Add(Item);
FItems.Add(Item);
end;
end;
procedure TJvMRUManager.DoDuplicateFixUp;
var
I, J: Integer;
Tmp: Boolean;
begin
if Duplicates = dupAccept then
Exit;
Tmp := AutoUpdate;
try
AutoUpdate := False;
I := Strings.Count - 1;
while I >= 0 do
begin
// we don't raise an error here even if Duplicates is dupError
J := Strings.IndexOf(Strings[I]);
while (J > -1) and (J <> I) do
begin
Strings.Delete(J);
Dec(I);
J := Strings.IndexOf(Strings[I]);
end;
Dec(I);
end;
finally
AutoUpdate := Tmp;
end;
end;
procedure TJvMRUManager.UpdateRecentMenu;
const
AccelDelimChars: array[TAccelDelimiter] of Char = (Tab, ' ');
var
I: Integer;
L: Cardinal;
S: string;
C: string[2];
ShortCut: TShortCut;
Item: TMenuItem;
begin
ClearRecentMenu;
DoDuplicateFixUp;
DoBeforeUpdate;
if Assigned(FRecentMenu) then
begin
if ((Strings.Count > 0) and (FRecentMenu.Count > 0) and (MenuLocation = mruChild)) then
AddMenuItem(NewLine);
for I := 0 to Strings.Count - 1 do
begin
if (FSeparateSize > 0) and (I > 0) and (I mod FSeparateSize = 0) then
AddMenuItem(NewLine)
else
if (I = 0) and (MenuLocation = mruSibling) and (FRecentMenu.Count = 0) then
AddMenuItem(NewLine);
S := Strings[I];
ShortCut := scNone;
GetItemData(S, ShortCut, Longint(Strings.Objects[I]));
Item := NewItem(GetShortHint(S), ShortCut, False, True,
MenuItemClick, 0, '');
Item.Hint := GetLongHint(S);
if FShowAccelChar then
begin
L := Cardinal(I) + FStartAccel;
if L < 10 then
C := '&' + Char(Ord('0') + L)
else
if L <= (Ord('Z') + 10) then
C := '&' + Char(L + Ord('A') - 10)
else
C := ' ';
Item.Caption := C + AccelDelimChars[FAccelDelimiter] + DoMinimizeName(S);
end
else
begin
Item.Caption := DoMinimizeName(S);
end;
Item.Tag := I;
AddMenuItem(Item);
GetItemInfoEx(Item, I);
end;
DoAfterUpdate;
if AutoEnable then
FRecentMenu.Enabled := IsMenuEnabled;
end;
end;
procedure TJvMRUManager.ClearRecentMenu;
var
Item: TMenuItem;
begin
while FItems.Count > 0 do
begin
Item := TMenuItem(FItems[0]);
FItems.Remove(Item);
// (p3) it doesn't matter if the item is in FRecentMenu or not - it still needs to be freed
// this also avoids duplicates when MenuLocation = mruSibling
// if Assigned(FRecentMenu) and (FRecentMenu.IndexOf(Item) >= 0) then
Item.Free;
end;
if Assigned(FRecentMenu) and AutoEnable then
FRecentMenu.Enabled := IsMenuEnabled;
end;
procedure TJvMRUManager.SetRecentMenu(Value: TMenuItem);
begin
ClearRecentMenu;
FRecentMenu := Value;
if Value <> nil then
Value.FreeNotification(Self);
FreeAndNil(FCanvas);
UpdateRecentMenu;
end;
procedure TJvMRUManager.SetSeparateSize(Value: Word);
begin
if FSeparateSize <> Value then
begin
FSeparateSize := Value;
if FAutoUpdate then
UpdateRecentMenu;
end;
end;
procedure TJvMRUManager.ListChanged(Sender: TObject);
begin
Change;
if FAutoUpdate then
UpdateRecentMenu;
end;
procedure TJvMRUManager.IniSave(Sender: TObject);
begin
if (Name <> '') and Assigned(IniStorage) then
InternalSave(GetDefaultSection(Self));
end;
procedure TJvMRUManager.IniLoad(Sender: TObject);
begin
if (Name <> '') and Assigned(IniStorage) then
InternalLoad(GetDefaultSection(Self));
end;
procedure TJvMRUManager.Change;
begin
if Assigned(FOnChange) then
FOnChange(Self);
end;
procedure TJvMRUManager.DoReadItem(AppStorage: TJvCustomAppStorage; const Path: string;
Index: Integer; var RecentName: string; var UserData: Longint);
begin
if Assigned(FOnReadItem) then
FOnReadItem(Self, AppStorage, Path, Index, RecentName, UserData)
else
begin
RecentName := AppStorage.ReadString(AppStorage.ConcatPaths(
[Path, Format(siRecentItem, [Index])]), RecentName);
UserData := AppStorage.ReadInteger(AppStorage.ConcatPaths(
[Path, Format(siRecentData, [Index])]), UserData);
end;
end;
procedure TJvMRUManager.DoWriteItem(AppStorage: TJvCustomAppStorage; const Path: string;
Index: Integer; const RecentName: string; UserData: Longint);
begin
if Assigned(FOnWriteItem) then
FOnWriteItem(Self, AppStorage, Path, Index, RecentName, UserData)
else
begin
AppStorage.WriteString(AppStorage.ConcatPaths(
[Path, Format(siRecentItem, [Index])]), RecentName);
if UserData = 0 then
AppStorage.DeleteValue(AppStorage.ConcatPaths(
[Path, Format(siRecentData, [Index])]))
else
AppStorage.WriteInteger(AppStorage.ConcatPaths(
[Path, Format(siRecentData, [Index])]), UserData);
end;
end;
procedure TJvMRUManager.InternalLoad(const Section: string);
begin
if Assigned(IniStorage) then
with IniStorage do
LoadFromAppStorage(AppStorage, AppStorage.ConcatPaths([AppStoragePath, Section]));
end;
procedure TJvMRUManager.InternalSave(const Section: string);
begin
if Assigned(IniStorage) then
with IniStorage do
SaveToAppStorage(AppStorage, AppStorage.ConcatPaths([AppStoragePath, Section]));
end;
procedure TJvMRUManager.LoadFromAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
var
I: Integer;
S: string;
UserData: Longint;
AMode: TRecentMode;
begin
AMode := Mode;
Strings.BeginUpdate;
try
Strings.Clear;
Mode := rmInsert;
for I := FStrings.MaxSize - 1 downto 0 do
begin
S := '';
UserData := 0;
DoReadItem(AppStorage, Path, I, S, UserData);
if S <> '' then
Add(S, UserData);
end;
finally
Mode := AMode;
Strings.EndUpdate;
end;
end;
procedure TJvMRUManager.SaveToAppStorage(const AppStorage: TJvCustomAppStorage; const Path: string);
var
I: Integer;
begin
AppStorage.DeleteSubTree(Path);
for I := 0 to Strings.Count - 1 do
DoWriteItem(AppStorage, Path, I, Strings[I], Longint(Strings.Objects[I]));
end;
procedure TJvMRUManager.Load;
begin
IniLoad(nil);
end;
procedure TJvMRUManager.Save;
begin
IniSave(nil);
end;
procedure TJvMRUManager.DoAfterUpdate;
begin
if Assigned(FOnAfterUpdate) then
FOnAfterUpdate(Self);
end;
procedure TJvMRUManager.DoBeforeUpdate;
begin
if Assigned(FOnBeforeUpdate) then
FOnBeforeUpdate(Self);
end;
procedure TJvMRUManager.RemoveInvalid;
var
I: Integer;
begin
for I := Strings.Count - 1 downto 0 do
if not FileExists(Strings[I]) then
Strings.Delete(I);
end;
procedure TJvMRUManager.GetItemInfo(Item: TMenuItem);
begin
if Assigned(FOnItemInfo) then
FOnItemInfo(Self, Item);
end;
procedure TJvMRUManager.GetItemInfoEx(Item: TMenuItem; Index: Integer);
begin
GetItemInfo(Item);
if Assigned(FOnItemInfoEx) then
FOnItemInfoEx(Self, Item, Index);
end;
procedure TJvMRUManager.SetDuplicates(const Value: TDuplicates);
begin
if FDuplicates <> Value then
begin
FDuplicates := Value;
if FAutoUpdate then
UpdateRecentMenu;
end;
end;
//=== { TJvRecentStrings } ===================================================
constructor TJvRecentStrings.Create;
begin
inherited Create;
FMaxSize := 10;
FMode := rmInsert;
end;
procedure TJvRecentStrings.SetTextStr(const Value: String);
var
LastMode: TRecentMode;
begin
{ Temporary change the FMode to rmAppend so the lines in Value will be added
in the correct ordern. }
LastMode := FMode;
try
FMode := rmAppend;
inherited SetTextStr(Value);
finally
FMode := LastMode;
end;
end;
procedure TJvRecentStrings.SetMaxSize(Value: Integer);
begin
if FMaxSize <> Value then
begin
FMaxSize := Max(1, Value);
DeleteExceed;
end;
end;
procedure TJvRecentStrings.DeleteExceed;
var
I: Integer;
begin
BeginUpdate;
try
if FMode = rmInsert then
for I := Count - 1 downto FMaxSize do
Delete(I)
else
begin { rmAppend }
while Count > FMaxSize do
Delete(0);
end;
finally
EndUpdate;
end;
end;
procedure TJvRecentStrings.Remove(const S: string);
var
I: Integer;
begin
I := IndexOf(S);
if I >= 0 then
Delete(I);
end;
function TJvRecentStrings.Add(const S: string): Integer;
begin
Result := IndexOf(S);
if Result >= 0 then
begin
if FMode = rmInsert then
Move(Result, 0)
else { rmAppend }
Move(Result, Count - 1);
end
else
begin
BeginUpdate;
try
if FMode = rmInsert then
Insert(0, S)
else { rmAppend }
Insert(Count, S);
DeleteExceed;
finally
EndUpdate;
end;
end;
if FMode = rmInsert then
Result := 0
else { rmAppend }
Result := Count - 1;
end;
procedure TJvRecentStrings.AddStrings(Strings: TStrings);
var
I: Integer;
begin
BeginUpdate;
try
if FMode = rmInsert then
begin
for I := Min(Strings.Count, FMaxSize) - 1 downto 0 do
AddObject(Strings[I], Strings.Objects[I]);
end
else { rmAppend }
for I := 0 to Min(Strings.Count, FMaxSize) - 1 do
AddObject(Strings[I], Strings.Objects[I]);
DeleteExceed;
finally
EndUpdate;
end;
end;
procedure TJvMRUManager.SetMenuLocation(const Value: TMenuLocation);
begin
if FMenuLocation <> Value then
begin
FMenuLocation := Value;
UpdateRecentMenu;
end;
end;
function TJvMRUManager.IsMenuEnabled: Boolean;
begin
Result := ((MenuLocation = mruChild) and (FRecentMenu.Count > 0)) or
((MenuLocation = mruSibling) and (Strings.Count > 0));
end;
procedure TJvMRUManager.SetMaxLength(const Value: Integer);
begin
if FMaxLength <> Value then
begin
FMaxLength := Value;
UpdateRecentMenu;
end;
end;
function TJvMRUManager.GetCanvas: TCanvas;
begin
if FCanvas = nil then
begin
FCanvas := TCanvas.Create;
if RecentMenu <> nil then
FCanvas.Handle := GetDC(GetDesktopWindow);
end;
Result := FCanvas;
end;
function TJvMRUManager.DoMinimizeName(const S: string): string;
begin
Result := '';
if MaxLength > 0 then
begin
if not StartEllipsis then
Result := PathCompactPath(
{$IFDEF VCL}
GetCanvas.Handle,
{$ENDIF VCL}
{$IFDEF VisualCLX}
QPainter_handle(GetCanvas.Handle),
{$ENDIF VisualCLX}
S, GetCanvas.TextWidth('n') * MaxLength, cpCenter)
else
if Length(S) > MaxLength then
Result := '...' + Copy(S, Length(S) - MaxLength + 1, MaxInt);
end;
if (Result = '...') or (Result = '') then
Result := S;
end;
procedure TJvMRUManager.SetStartEllipsis(const Value: Boolean);
begin
if FStartEllipsis <> Value then
begin
FStartEllipsis := Value;
UpdateRecentMenu;
end;
end;
{$IFDEF UNITVERSIONING}
initialization
RegisterUnitVersion(HInstance, UnitVersioning);
finalization
UnregisterUnitVersion(HInstance);
{$ENDIF UNITVERSIONING}
end.