mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-12-05 21:18:06 +01:00
528 lines
15 KiB
ObjectPascal
528 lines
15 KiB
ObjectPascal
{
|
|
*****************************************************************************
|
|
This file is part of a Lazarus Package, IconFinder.
|
|
|
|
See the file COPYING.modifiedLGPL.txt, included in the Lazarus distribution,
|
|
for details about the license.
|
|
*****************************************************************************
|
|
|
|
A frame composed of the essential controls for viewing thumbnails and
|
|
filtering them.
|
|
|
|
Is used by the imagelist component editor, by the graphic property editor
|
|
and by the IDE settings page.
|
|
}
|
|
|
|
unit IconViewer;
|
|
|
|
{$mode ObjFPC}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
// RTL/FCL
|
|
Classes, SysUtils,
|
|
// LazUtils
|
|
LazFileUtils, LazLoggerBase,
|
|
// LCL/LazControls
|
|
Forms, Controls, Graphics, StdCtrls, ExtCtrls, FileCtrl, Buttons, Dialogs,
|
|
ImgList, DividerBevel,
|
|
// Icon Finder
|
|
IconFinderStrConsts, IconThumbnails, IconKeywordFilterEditor;
|
|
|
|
type
|
|
|
|
{ TIconViewerFrame }
|
|
|
|
TIconViewerFrame = class(TFrame)
|
|
Bevel2: TBevel;
|
|
btnKeywordEditor: TSpeedButton;
|
|
cmbFilterByKeywords: TComboBox;
|
|
cmbFilterBySize: TComboBox;
|
|
cmbFilterByStyle: TComboBox;
|
|
DividerBevel1: TDividerBevel;
|
|
FilterPanel: TPanel;
|
|
infoFileName: TLabel;
|
|
infoKeywords: TLabel;
|
|
infoSize: TLabel;
|
|
infoStyle: TLabel;
|
|
lblFileName: TLabel;
|
|
lblKeywords: TLabel;
|
|
lblSize: TLabel;
|
|
lblStyle: TLabel;
|
|
IconDetailsPanel: TPanel;
|
|
btnExecuteFilter: TSpeedButton;
|
|
btnClearFilter: TSpeedButton;
|
|
CaptionPanel: TPanel;
|
|
procedure btnClearFilterClick(Sender: TObject);
|
|
procedure btnExecuteFilterClick(Sender: TObject);
|
|
procedure btnKeywordEditorClick(Sender: TObject);
|
|
procedure cmbFilterByKeywordsEditingDone(Sender: TObject);
|
|
procedure cmbFilterBySizeChange(Sender: TObject);
|
|
procedure cmbFilterByStyleChange(Sender: TObject);
|
|
procedure IconDetailsPanelResize(Sender: TObject);
|
|
private
|
|
FIconViewer: TIconThumbnailViewer;
|
|
FOnChange: TNotifyEvent;
|
|
FOnFilter: TNotifyEvent;
|
|
FOnIconDblClick: TNotifyEvent;
|
|
function GetFilteredCount: Integer;
|
|
function GetImageIndex(AIndex: Integer): TImageIndex;
|
|
function GetImageList: TCustomImageList;
|
|
function GetSelectedIcon: TIconItem;
|
|
function GetSizeFilter: String;
|
|
function GetStyleFilter: String;
|
|
function GetTotalCount: Integer;
|
|
procedure SetImageIndex(AIndex: Integer; AValue: TImageIndex);
|
|
procedure SetImageList(AValue: TCustomImageList);
|
|
procedure SetSizeFilter(AValue: String);
|
|
procedure SetStyleFilter(AValue: String);
|
|
|
|
protected
|
|
procedure AddKeywordFilterToHistory(AFilter: String);
|
|
procedure DoIconViewerDblClick(Sender: TObject);
|
|
procedure DoIconViewerFilter(Sender: TObject);
|
|
procedure DoIconViewerSelect(Sender: TObject);
|
|
procedure UpdateCmds;
|
|
procedure UpdateIconDetails;
|
|
|
|
public
|
|
constructor Create(AOwner: TComponent); override;
|
|
procedure AddIconFolder(AFolder: String; Hidden: Boolean = false);
|
|
procedure CopyMetadataToNameBase(AIcon: TIconItem);
|
|
procedure DeleteSelectedIcon;
|
|
procedure FocusKeywordFilter;
|
|
procedure GetKeywordsHistory(AList: TStrings);
|
|
function IndexOfIconFolder(AFolder: String): Integer;
|
|
procedure ReadIconFolders(AList: TStrings);
|
|
procedure SetKeywordsHistory(AList: TStrings);
|
|
procedure UpdateIconCount;
|
|
procedure UpdateIconSizes(ASizeIndex: Integer);
|
|
procedure UpdateIconStyles(AStyleIndex: Integer);
|
|
procedure UpdateLanguage;
|
|
|
|
property FilteredCount: Integer read GetFilteredCount;
|
|
property IconViewer: TIconThumbnailViewer read FIconViewer;
|
|
property ImageIndex_ExecuteFilter: TImageIndex index 0 read GetImageIndex write SetImageIndex;
|
|
property ImageIndex_ClearFilter: TImageIndex index 1 read GetImageIndex write SetImageIndex;
|
|
property ImageList: TCustomImageList read GetImageList write SetImageList;
|
|
property SelectedIcon: TIconItem read GetSelectedIcon;
|
|
property SizeFilter: String read GetSizeFilter write SetSizeFilter;
|
|
property StyleFilter: String read GetStyleFilter write SetStyleFilter;
|
|
property TotalCount: Integer read GetTotalCount;
|
|
property OnChange: TNotifyEvent read FOnChange write FOnChange;
|
|
property OnFilter: TNotifyEvent read FOnFilter write FOnFilter;
|
|
property OnIconDblClick: TNotifyEvent read FOnIconDblClick write FOnIconDblClick;
|
|
|
|
end;
|
|
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
const
|
|
MAX_KEYWORDS_HISTORY = 20;
|
|
|
|
{ TIconViewerFrame }
|
|
|
|
constructor TIconViewerFrame.Create(AOwner: TComponent);
|
|
begin
|
|
inherited;
|
|
FIconViewer := TIconThumbnailViewer.Create(self);
|
|
FIconViewer.Align := alClient;
|
|
FIconViewer.FocusedColor := clWindowText;
|
|
FIconViewer.Parent := self;
|
|
FIconViewer.OnDblClick := @DoIconViewerDblClick;
|
|
FIconViewer.OnFilter := @DoIconViewerFilter;
|
|
FIconViewer.OnSelect := @DoIconViewerSelect;
|
|
|
|
UpdateIconDetails;
|
|
UpdateLanguage;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.AddIconFolder(AFolder: String; Hidden: Boolean = false);
|
|
var
|
|
filterByStyle: Integer;
|
|
filterBySize: Integer;
|
|
begin
|
|
filterByStyle := cmbFilterByStyle.ItemIndex;
|
|
if filterByStyle = -1 then filterByStyle := 0;
|
|
filterBySize := cmbFilterBySize.ItemIndex;
|
|
if filterBySize = -1 then filterBySize := 0;
|
|
|
|
AFolder := AppendPathDelim(SwitchPathDelims(AFolder, true));
|
|
IconViewer.AddIconFolder(AFolder, Hidden);
|
|
|
|
UpdateIconSizes(filterBySize);
|
|
UpdateIconStyles(filterByStyle);
|
|
UpdateIconDetails;
|
|
UpdateIconCount;
|
|
UpdateCmds;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.AddKeywordFilterToHistory(AFilter: String);
|
|
var
|
|
idx: Integer;
|
|
begin
|
|
if AFilter = '' then
|
|
exit;
|
|
|
|
idx := cmbFilterByKeywords.Items.IndexOf(AFilter);
|
|
if idx = -1 then
|
|
cmbFilterByKeywords.Items.Insert(0, AFilter)
|
|
else
|
|
cmbFilterByKeywords.Items.Move(idx, 0);
|
|
|
|
while cmbFilterByKeywords.Items.Count > MAX_KEYWORDS_HISTORY do
|
|
cmbFilterByKeywords.Items.Delete(cmbFilterByKeywords.Items.Count-1);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.btnKeywordEditorClick(Sender: TObject);
|
|
var
|
|
F: TKeywordFilterEditorForm;
|
|
L: TStringList;
|
|
P: TPoint;
|
|
begin
|
|
F := TKeywordFilterEditorForm.Create(Self);
|
|
L := TStringList.Create;
|
|
try
|
|
F.Position := poDesigned;
|
|
P := ClientToScreen(Point(cmbFilterByKeywords.Left, cmbFilterByKeywords.Top + cmbFilterByKeywords.Height));
|
|
F.SetBounds(P.X, P.Y, F.Width, F.Height);
|
|
F.Filter := cmbFilterByKeywords.Text;
|
|
FIconViewer.GetKeywordsAsStrings(L);
|
|
F.Keywords := L;
|
|
if F.ShowModal = mrOK then
|
|
begin
|
|
cmbFilterByKeywords.Text := F.Filter;
|
|
FIconViewer.FilterByIconKeywords := F.Filter;
|
|
AddKeywordFilterToHistory(F.Filter);
|
|
end;
|
|
finally
|
|
L.Free;
|
|
F.Free;
|
|
end;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.btnClearFilterClick(Sender: TObject);
|
|
begin
|
|
cmbFilterByKeywords.Text := '';
|
|
FIconViewer.FilterByIconKeywords := '';
|
|
end;
|
|
|
|
procedure TIconViewerFrame.btnExecuteFilterClick(Sender: TObject);
|
|
var
|
|
filter: String;
|
|
begin
|
|
filter := cmbFilterByKeywords.Text;
|
|
FIconViewer.FilterByIconKeywords := filter;
|
|
AddKeywordFilterToHistory(filter);
|
|
cmbFilterByKeywords.Text := filter; // Must be after AddKeywordFilterToHistory!
|
|
UpdateIconCount;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.cmbFilterByKeywordsEditingDone(Sender: TObject);
|
|
begin
|
|
btnExecuteFilterClick(nil);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.cmbFilterBySizeChange(Sender: TObject);
|
|
begin
|
|
if cmbFilterBySize.ItemIndex = 0 then // Filter by any size
|
|
FIconViewer.FilterByIconSize := ''
|
|
else
|
|
FIconViewer.FilterByIconSize := cmbFilterBySize.Items[cmbFilterBySize.ItemIndex];
|
|
FIconViewer.Invalidate;
|
|
UpdateIconCount;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.cmbFilterByStyleChange(Sender: TObject);
|
|
begin
|
|
FIconViewer.FilterByIconStyle := TIconStyle(cmbFilterByStyle.ItemIndex);
|
|
FIconViewer.Invalidate;
|
|
UpdateIconCount;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.CopyMetadataToNameBase(AIcon: TIconItem);
|
|
begin
|
|
IconViewer.CopyMetadataToNameBase(AIcon);
|
|
IconViewer.Invalidate;
|
|
UpdateIconDetails;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.DeleteSelectedIcon;
|
|
var
|
|
res: TModalResult;
|
|
begin
|
|
res := MessageDlg(RSIconViewer_ConfirmDeleteIconMsg, mtConfirmation, [mbYes, mbNo], 0);
|
|
if res = mrYes then
|
|
begin
|
|
IconViewer.DeleteIcon(IconViewer.SelectedIcon);
|
|
UpdateIconDetails;
|
|
end;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.DoIconViewerDblClick(Sender: TObject);
|
|
begin
|
|
if Assigned(FOnIconDblClick) then
|
|
FOnIconDblClick(Self);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.DoIconViewerFilter(Sender: TObject);
|
|
begin
|
|
UpdateIconCount;
|
|
if Assigned(FOnFilter) then
|
|
FOnFilter(Self);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.DoIconViewerSelect(Sender: TObject);
|
|
begin
|
|
UpdateIconDetails;
|
|
if Assigned(FOnChange) then
|
|
FOnChange(self);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.FocusKeywordFilter;
|
|
begin
|
|
if HandleAllocated and cmbFilterByKeywords.CanFocus then
|
|
cmbFilterByKeywords.SetFocus;
|
|
end;
|
|
|
|
function TIconViewerFrame.GetFilteredCount: Integer;
|
|
begin
|
|
Result := FIconViewer.ThumbnailCount;
|
|
end;
|
|
|
|
function TIconViewerFrame.GetImageIndex(AIndex: Integer): TImageIndex;
|
|
begin
|
|
case AIndex of
|
|
0: Result := btnExecuteFilter.ImageIndex;
|
|
1: Result := btnClearFilter.ImageIndex;
|
|
end;
|
|
end;
|
|
|
|
function TIconViewerFrame.GetImageList: TCustomImageList;
|
|
begin
|
|
Result := btnExecuteFilter.Images;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.GetKeywordsHistory(AList: TStrings);
|
|
begin
|
|
AList.Assign(cmbFilterByKeywords.Items);
|
|
end;
|
|
|
|
function TIconViewerFrame.GetSelectedIcon: TIconItem;
|
|
begin
|
|
Result := FIconViewer.SelectedIcon;
|
|
end;
|
|
|
|
function TIconViewerFrame.GetSizeFilter: String;
|
|
begin
|
|
if cmbFilterBySize.ItemIndex <= 0 then
|
|
Result := ''
|
|
else
|
|
Result := cmbFilterBySize.Items[cmbFilterBySize.ItemIndex];
|
|
end;
|
|
|
|
function TIconViewerFrame.GetStyleFilter: String;
|
|
begin
|
|
Result := IconStyleToStr(TIconStyle(cmbFilterByStyle.ItemIndex));
|
|
end;
|
|
|
|
function TIconViewerFrame.GetTotalCount: Integer;
|
|
begin
|
|
Result := FIconViewer.IconCount;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.IconDetailsPanelResize(Sender: TObject);
|
|
begin
|
|
if FIconViewer.SelectedIcon <> nil then
|
|
begin
|
|
infoFileName.Hint := FIconViewer.SelectedIcon.FileName;
|
|
infoFileName.Caption := MinimizeName(infoFileName.Hint, infoFileName.Canvas, IconDetailsPanel.Width - infoFileName.Left);
|
|
end;
|
|
end;
|
|
|
|
function TIconViewerFrame.IndexOfIconFolder(AFolder: String): Integer;
|
|
begin
|
|
Result := FIconViewer.IndexOfFolder(AFolder);
|
|
end;
|
|
|
|
{ Reads the icons from the directories contained in AList and adds them to the
|
|
library. }
|
|
procedure TIconViewerFrame.ReadIconFolders(AList: TStrings);
|
|
var
|
|
sizeFilt, styleFilt: Integer;
|
|
selectedIconFileName: String = '';
|
|
begin
|
|
styleFilt := cmbFilterByStyle.ItemIndex;
|
|
if styleFilt = -1 then styleFilt := 0;
|
|
sizeFilt := cmbFilterBySize.ItemIndex;
|
|
if sizeFilt = -1 then sizeFilt := 0;
|
|
if Assigned(IconViewer.SelectedIcon) then
|
|
selectedIconFileName := IconViewer.SelectedIcon.FileName;
|
|
|
|
IconViewer.LockFilter;
|
|
try
|
|
IconViewer.ReadIconFolders(AList);
|
|
UpdateIconSizes(sizefilt);
|
|
UpdateIconStyles(stylefilt);
|
|
finally
|
|
IconViewer.UnlockFilter;
|
|
IconViewer.SelectIconInFile(selectedIconFileName);;
|
|
end;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.SetImageIndex(AIndex: Integer; AValue: TImageIndex);
|
|
begin
|
|
case AIndex of
|
|
0: btnExecuteFilter.ImageIndex := AValue;
|
|
1: btnClearFilter.ImageIndex := AValue;
|
|
end;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.SetImageList(AValue: TCustomImageList);
|
|
begin
|
|
btnExecuteFilter.Images := AValue;
|
|
btnClearFilter.Images := AValue;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.SetKeywordsHistory(AList: TStrings);
|
|
begin
|
|
cmbFilterByKeywords.Items.BeginUpdate;
|
|
try
|
|
cmbFilterByKeywords.Items.Assign(AList);
|
|
while cmbFilterByKeywords.Items.Count > MAX_KEYWORDS_HISTORY do
|
|
cmbFilterByKeywords.Items.Delete(cmbFilterByKeywords.Items.Count-1);
|
|
finally
|
|
cmbFilterByKeywords.Items.EndUpdate;
|
|
end;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.SetSizeFilter(AValue: String);
|
|
var
|
|
idx: Integer;
|
|
begin
|
|
idx := cmbFilterBySize.Items.IndexOf(AValue);
|
|
if idx = -1 then
|
|
cmbFilterBySize.ItemIndex := 0
|
|
else
|
|
cmbFilterBySize.ItemIndex := idx;
|
|
cmbFilterBySizeChange(nil);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.SetStyleFilter(AValue: String);
|
|
var
|
|
idx: Integer;
|
|
begin
|
|
idx := cmbFilterByStyle.Items.IndexOf(AValue);
|
|
if idx = -1 then
|
|
cmbFilterByStyle.ItemIndex := 0
|
|
else
|
|
cmbFilterByStyle.ItemIndex := idx;
|
|
cmbFilterByStyleChange(nil);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.UpdateCmds;
|
|
begin
|
|
btnKeywordEditor.Enabled := TotalCount > 0;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.UpdateIconCount;
|
|
begin
|
|
DividerBevel1.Caption := Format(RSIconViewer_IconCountInfo,
|
|
[ FIconViewer.ThumbnailCount, FIconViewer.IconCount ]
|
|
);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.UpdateIconDetails;
|
|
var
|
|
keywordList: TStrings;
|
|
begin
|
|
if FIconViewer.SelectedIcon <> nil then
|
|
begin
|
|
infoFileName.Hint := FIconViewer.SelectedIcon.FileName;
|
|
infoFileName.Caption := MinimizeName(infoFileName.Hint, infoFileName.Canvas, IconDetailsPanel.Width - infoFileName.Left);
|
|
infoSize.Caption := FIconViewer.SelectedIcon.SizeAsString;
|
|
infoStyle.Caption := FIconViewer.SelectedIcon.StyleAsString;
|
|
keywordList := TStringList.Create;
|
|
try
|
|
FIconViewer.SelectedIcon.ExportKeywordsToStrings(keywordList);
|
|
keywordList.Delimiter := ';';
|
|
keywordList.StrictDelimiter := true;
|
|
infoKeywords.Caption := StringReplace(keywordList.DelimitedText, ';', '; ', [rfReplaceAll]);
|
|
finally
|
|
keywordList.Free;
|
|
end;
|
|
end else
|
|
begin
|
|
infoFileName.Caption := '';
|
|
infoFileName.Hint := '';
|
|
infoStyle.Caption := '';
|
|
infoSize.Caption := '';
|
|
infoKeywords.Caption := '';
|
|
end;
|
|
end;
|
|
|
|
procedure TIconViewerFrame.UpdateIconSizes(ASizeIndex: Integer);
|
|
begin
|
|
FIconViewer.GetIconSizesAsStrings(cmbFilterBySize.Items);
|
|
cmbFilterBySize.Items.Insert(0, RSMetadata_AnySize);
|
|
if ASizeIndex < 0 then ASizeIndex := 0;
|
|
cmbFilterBySize.ItemIndex := ASizeIndex;
|
|
if ASizeIndex = 0 then
|
|
FIconViewer.FilterByIconSize := ''
|
|
else
|
|
FIconViewer.FilterByIconSize := cmbFilterBySize.Items[ASizeIndex];
|
|
end;
|
|
|
|
procedure TIconViewerFrame.UpdateIconStyles(AStyleIndex: Integer);
|
|
begin
|
|
IconStylesToStrings(cmbFilterByStyle.Items);
|
|
if AStyleIndex < 0 then AStyleIndex := 0;
|
|
cmbFilterByStyle.ItemIndex := AStyleIndex;
|
|
if AStyleIndex = 0 then
|
|
FIconViewer.FilterByIconStyle := isAnyStyle
|
|
else
|
|
FIconViewer.FilterByIconStyle := TIconStyle(AStyleIndex);
|
|
end;
|
|
|
|
procedure TIconViewerFrame.UpdateLanguage;
|
|
begin
|
|
cmbFilterBySize.Hint := RSIconViewer_FilterByIconSizeHint;
|
|
cmbFilterByStyle.Hint := RSIconViewer_FilterByIconStyleHint;
|
|
cmbFilterByKeywords.Hint := RSIconViewer_ExpressionToFilterByKeywordsHint;
|
|
btnKeywordEditor.Hint := RSIconViewer_EditKeywordFilterHint;
|
|
btnClearFilter.Hint := RSIconViewer_ClearFilterHint;
|
|
btnExecuteFilter.Hint := RSIconViewer_FilterByKeywordsHint;
|
|
|
|
lblFileName.Caption := RSIconViewer_FileNameLbl;
|
|
lblSize.Caption := RSIconViewer_SizeLbl;
|
|
lblStyle.Caption := RSIconViewer_StyleLbl;
|
|
lblKeywords.Caption := RSIconViewer_KeywordsLbl;
|
|
|
|
cmbFilterByKeywords.TextHint := RSIconViewer_EnterKeywordsHere;
|
|
|
|
(* // activate only when translation of keywords and styles is ready!
|
|
idx := cmbFilterByStyle.ItemIndex;
|
|
cmbFilterByStyle.Items.BeginUpdate;
|
|
try
|
|
cmbFilterByStyle.Clear;
|
|
cmbFilterByStyle.Items.Add(RSMetadata_ClassicStyle);
|
|
cmbFilterByStyle.Items.Add(RSMetadata_Flatstyle);
|
|
cmbFilterByStyle.Items.Add(RSMetadata_OutlineStyle);
|
|
cmbFilterByStyle.Items.Add(RSMetadata_Outline2Style);
|
|
if idx < cmbFilterBystyle.Items.Count then
|
|
cmbFilterByStyle.ItemIndex := idx;
|
|
finally
|
|
cmbFilterByStyle.Items.EndUpdate;
|
|
end;
|
|
*)
|
|
|
|
// UpdateLayout;
|
|
end;
|
|
|
|
end.
|
|
|