Added: Sort by Name / Sort by Type option
Added: optionally include descendants in non-wildcard filters Changed: filter checkboxes now work in reverse; checking them shows that particular group, unchecking hides it (makes more sense)
This commit is contained in:
parent
cfff9522ab
commit
450baa3705
Binary file not shown.
@ -73,12 +73,6 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function SortByName(Item1, Item2: Pointer): Integer;
|
||||
begin
|
||||
Result := CompareText(TCmpSwComponent(Item1).Name, TCmpSwComponent(Item2).Name)
|
||||
end;
|
||||
|
||||
|
||||
procedure TComponentSwitcherHook.NewExecute(Sender: TObject);
|
||||
var
|
||||
editor: IOTAEditor;
|
||||
@ -108,19 +102,6 @@ begin
|
||||
|
||||
if itemList.Count > 0 then
|
||||
begin
|
||||
itemList.Sort(SortByName);
|
||||
|
||||
(*
|
||||
ps := (borlandideservices as IOTAPackageServices);
|
||||
for pi := 0 to Pred(ps.PackageCount) do
|
||||
begin
|
||||
for ci := 0 to Pred(ps.ComponentCount[pi]) do
|
||||
begin
|
||||
itemList.Add(TTestItem.Create(ps.PackageNames[pi] + ' - ' + ps.ComponentNames[pi, ci]));
|
||||
end;
|
||||
end;
|
||||
*)
|
||||
|
||||
selectedItems := TfrmCmpSwDialog.Execute(itemList);
|
||||
|
||||
if Assigned(selectedItems) then
|
||||
|
@ -53,7 +53,6 @@ inherited frmCmpSwDialog: TfrmCmpSwDialog
|
||||
Width = 342
|
||||
Height = 65
|
||||
Align = alClient
|
||||
Caption = ' Filter '
|
||||
TabOrder = 0
|
||||
DesignSize = (
|
||||
342
|
||||
@ -75,6 +74,18 @@ inherited frmCmpSwDialog: TfrmCmpSwDialog
|
||||
Caption = '&Filter selected class(es)'
|
||||
Enabled = False
|
||||
end
|
||||
object actSortByName: TAction
|
||||
Caption = 'Sort by &Name'
|
||||
GroupIndex = 1
|
||||
ShortCut = 49230
|
||||
OnExecute = SortExecute
|
||||
end
|
||||
object actSortByType: TAction
|
||||
Caption = 'Sort by &Type'
|
||||
GroupIndex = 1
|
||||
ShortCut = 49236
|
||||
OnExecute = SortExecute
|
||||
end
|
||||
end
|
||||
inherited pmnItems: TPopupMenu
|
||||
object pmnItemsFilters: TMenuItem [0]
|
||||
@ -86,6 +97,15 @@ inherited frmCmpSwDialog: TfrmCmpSwDialog
|
||||
object pmnItemsSep1: TMenuItem [2]
|
||||
Caption = '-'
|
||||
end
|
||||
object pmnItemsSortByName: TMenuItem [3]
|
||||
Action = actSortByName
|
||||
end
|
||||
object pmnItemsSortByType: TMenuItem [4]
|
||||
Action = actSortByType
|
||||
end
|
||||
object pmnItemsSep2: TMenuItem [5]
|
||||
Caption = '-'
|
||||
end
|
||||
end
|
||||
object pmnMoreFilters: TPopupMenu
|
||||
Left = 192
|
||||
|
@ -17,7 +17,7 @@ uses
|
||||
|
||||
BaseSwDialog,
|
||||
BaseSwObjects,
|
||||
CmpSwFilters;
|
||||
CmpSwFilters, UnSwDialog;
|
||||
|
||||
|
||||
type
|
||||
@ -46,25 +46,36 @@ type
|
||||
gbFilters: TGroupBox;
|
||||
btnMoreFilters: TButton;
|
||||
pmnMoreFilters: TPopupMenu;
|
||||
actSortByName: TAction;
|
||||
actSortByType: TAction;
|
||||
pmnItemsSortByName: TMenuItem;
|
||||
pmnItemsSortByType: TMenuItem;
|
||||
pmnItemsSep2: TMenuItem;
|
||||
|
||||
procedure btnMoreFiltersClick(Sender: TObject);
|
||||
procedure FormShow(Sender: TObject);
|
||||
procedure SortExecute(Sender: TObject);
|
||||
private
|
||||
FClassFilteredList: TBaseSwItemList;
|
||||
FClassFilter: TCmpSwComponentClassFilter;
|
||||
|
||||
FFilterCheckBoxes: TObjectList;
|
||||
FOtherGroup: TCmpSwFilterGroup;
|
||||
protected
|
||||
function InternalExecute(): TBaseSwItemList; override;
|
||||
|
||||
function CreateStyleVisitor(): TBaseSwStyleVisitor; override;
|
||||
function GetBaseItemList(): TBaseSwItemList; override;
|
||||
|
||||
function AllowEmptyResult(): Boolean; override;
|
||||
function ColorsEnabled(): Boolean; override;
|
||||
|
||||
procedure LoadSettings(); override;
|
||||
procedure SaveSettings(); override;
|
||||
|
||||
procedure DrawItemText(ACanvas: TCanvas; AItem: TBaseSwItem; ARect: TRect); override;
|
||||
procedure UpdateClassFilter();
|
||||
procedure SortList();
|
||||
|
||||
procedure BuildFilterCheckboxes();
|
||||
function CreateFilterMenuItem(AParent: TMenuItem; AGroup: TCmpSwFilterGroup; AItemIndex: Integer): TMenuItem;
|
||||
@ -72,7 +83,8 @@ type
|
||||
procedure FilterCheckBoxClick(Sender: TObject);
|
||||
procedure FilterMenuItemClick(Sender: TObject);
|
||||
|
||||
property ClassFilter: TCmpSwComponentClassFilter read FClassFilter;
|
||||
property ClassFilter: TCmpSwComponentClassFilter read FClassFilter;
|
||||
property ClassFilteredList: TBaseSwItemList read FClassFilteredList;
|
||||
end;
|
||||
|
||||
|
||||
@ -233,9 +245,15 @@ begin
|
||||
FClassFilteredList := TBaseSwItemList.Create();
|
||||
FClassFilter := TCmpSwComponentClassFilter.Create();
|
||||
FFilterCheckBoxes := TObjectList.Create();
|
||||
FOtherGroup := TCmpSwFilterGroup.Create(nil);
|
||||
try
|
||||
Result := inherited InternalExecute();
|
||||
FOtherGroup.Name := 'Other';
|
||||
FOtherGroup.Enabled := False;
|
||||
FOtherGroup.Visible := False;
|
||||
|
||||
Result := inherited InternalExecute();
|
||||
finally
|
||||
FreeAndNil(FOtherGroup);
|
||||
FreeAndNil(FFilterCheckBoxes);
|
||||
FreeAndNil(FClassFilter);
|
||||
FreeAndNil(FClassFilteredList);
|
||||
@ -271,7 +289,7 @@ begin
|
||||
DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS or DT_CALCRECT);
|
||||
|
||||
textRect.Left := textRect.Right;
|
||||
textRect.Right := ARect.Right;
|
||||
textRect.Right := ARect.Right - 2;
|
||||
|
||||
{ Draw component class text }
|
||||
ACanvas.Font.Color := clGrayText;
|
||||
@ -288,62 +306,6 @@ var
|
||||
itemIndex: Integer;
|
||||
|
||||
begin
|
||||
if ClassFilter.Groups.Count = 0 then
|
||||
begin
|
||||
with ClassFilter.Groups.Add() do
|
||||
begin
|
||||
Name := 'Actions';
|
||||
Filter.Add('TAction');
|
||||
Visible := True;
|
||||
end;
|
||||
|
||||
with ClassFilter.Groups.Add() do
|
||||
begin
|
||||
Name := 'Menu items';
|
||||
Filter.Add('TMenuItem');
|
||||
Visible := True;
|
||||
end;
|
||||
|
||||
with ClassFilter.Groups.Add() do
|
||||
begin
|
||||
Name := 'Dataset fields';
|
||||
|
||||
Filter.Add('TField');
|
||||
Filter.Add('T*Field');
|
||||
Visible := True;
|
||||
end;
|
||||
|
||||
with ClassFilter.Groups.Add() do
|
||||
begin
|
||||
Name := 'DevEx Grid columns';
|
||||
|
||||
Filter.Add('TcxGridDBColumn');
|
||||
Filter.Add('TcxGridColumn');
|
||||
end;
|
||||
|
||||
// with ClassFilter.Groups.Add() do
|
||||
// begin
|
||||
// Name := 'Toolbar2000 items';
|
||||
// Enabled := True;
|
||||
//
|
||||
// Filter.Add('TTBXItem');
|
||||
// Filter.Add('TTBItem');
|
||||
// Filter.Add('TTBXSeparatorItem');
|
||||
// Filter.Add('TTBXNoPrefixItem');
|
||||
// Filter.Add('TTBXNoPrefixSubmenuItem');
|
||||
// Filter.Add('TTBXSubmenuItem');
|
||||
// end;
|
||||
|
||||
// with ClassFilter.Groups.Add() do
|
||||
// begin
|
||||
// Name := 'X2Software items';
|
||||
// Enabled := True;
|
||||
//
|
||||
// Filter.Add('TX2GraphicContainerItem');
|
||||
// end;
|
||||
end;
|
||||
|
||||
|
||||
pnlFilters.Visible := (ClassFilter.Groups.Count > 0);
|
||||
|
||||
|
||||
@ -358,6 +320,9 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
CreateFilterMenuItem(pmnItemsFilters, FOtherGroup, itemIndex);
|
||||
Inc(itemIndex);
|
||||
|
||||
{ Remove excess menu items }
|
||||
for groupIndex := Pred(pmnItemsFilters.Count) downto itemIndex do
|
||||
pmnItemsFilters.Delete(groupIndex);
|
||||
@ -374,6 +339,9 @@ begin
|
||||
end;
|
||||
end;
|
||||
|
||||
CreateFilterMenuItem(pmnMoreFilters.Items, FOtherGroup, itemIndex);
|
||||
Inc(itemIndex);
|
||||
|
||||
for groupIndex := Pred(pmnMoreFilters.Items.Count) downto itemIndex do
|
||||
pmnMoreFilters.Items.Delete(groupIndex);
|
||||
|
||||
@ -381,14 +349,17 @@ begin
|
||||
BuildFilterCheckboxes();
|
||||
btnMoreFilters.Visible := (pmnMoreFilters.Items.Count > 0);
|
||||
|
||||
FClassFilteredList.Clone(ItemList);
|
||||
ClassFilter.FilterList(FClassFilteredList);
|
||||
ClassFilteredList.Clone(ItemList);
|
||||
|
||||
ClassFilter.FilterUnmatched := FOtherGroup.Enabled;
|
||||
ClassFilter.FilterList(ClassFilteredList);
|
||||
SortList();
|
||||
end;
|
||||
|
||||
|
||||
function TfrmCmpSwDialog.GetBaseItemList(): TBaseSwItemList;
|
||||
begin
|
||||
Result := FClassFilteredList;
|
||||
Result := ClassFilteredList;
|
||||
end;
|
||||
|
||||
|
||||
@ -418,7 +389,7 @@ begin
|
||||
checkBox.Top := checkBoxTop;
|
||||
checkBox.Left := 12;
|
||||
checkBox.Caption := StringReplace(group.Name, '&', '&&', [rfReplaceAll]);
|
||||
checkBox.Checked := group.Enabled;
|
||||
checkBox.Checked := not group.Enabled;
|
||||
checkBox.Tag := Integer(group);
|
||||
checkBox.OnClick := FilterCheckBoxClick;
|
||||
checkBox.Parent := gbFilters;
|
||||
@ -443,7 +414,7 @@ begin
|
||||
Result := AParent[AItemIndex];
|
||||
|
||||
Result.Caption := StringReplace(AGroup.Name, '&', '&&', [rfReplaceAll]);
|
||||
Result.Checked := AGroup.Enabled;
|
||||
Result.Checked := not AGroup.Enabled;
|
||||
Result.Tag := Integer(AGroup);
|
||||
end;
|
||||
|
||||
@ -457,9 +428,9 @@ begin
|
||||
checkBox := (Sender as TCheckBox);
|
||||
group := TCmpSwFilterGroup(checkBox.Tag);
|
||||
|
||||
if checkBox.Checked <> group.Enabled then
|
||||
if checkBox.Checked = group.Enabled then
|
||||
begin
|
||||
group.Enabled := checkBox.Checked;
|
||||
group.Enabled := not checkBox.Checked;
|
||||
|
||||
UpdateClassFilter();
|
||||
UpdateSubFilters();
|
||||
@ -476,8 +447,8 @@ begin
|
||||
menuItem := (Sender as TMenuItem);
|
||||
group := TCmpSwFilterGroup(menuItem.Tag);
|
||||
|
||||
menuItem.Checked := not menuItem.Checked;
|
||||
group.Enabled := menuItem.Checked;
|
||||
menuItem.Checked := not menuItem.Checked;
|
||||
|
||||
UpdateClassFilter();
|
||||
UpdateSubFilters();
|
||||
@ -508,6 +479,8 @@ end;
|
||||
|
||||
procedure TfrmCmpSwDialog.SaveSettings();
|
||||
begin
|
||||
// #ToDo2 (MvR) 12-12-2007: save 'sort by ...'
|
||||
|
||||
Settings.Dialog.Width := Self.ClientWidth;
|
||||
Settings.Dialog.Height := Self.ClientHeight;
|
||||
Settings.Dialog.MRUList.Assign(MRUList);
|
||||
@ -518,4 +491,46 @@ begin
|
||||
inherited SaveSettings();
|
||||
end;
|
||||
|
||||
|
||||
|
||||
function TfrmCmpSwDialog.AllowEmptyResult(): Boolean;
|
||||
begin
|
||||
Result := True;
|
||||
end;
|
||||
|
||||
|
||||
function TfrmCmpSwDialog.ColorsEnabled(): Boolean;
|
||||
begin
|
||||
Result := inherited ColorsEnabled();
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmCmpSwDialog.SortExecute(Sender: TObject);
|
||||
begin
|
||||
(Sender as TAction).Checked := True;
|
||||
SortList();
|
||||
UpdateSubFilters();
|
||||
end;
|
||||
|
||||
|
||||
function SortByName(Item1, Item2: Pointer): Integer;
|
||||
begin
|
||||
Result := CompareText(TCmpSwComponent(Item1).Name, TCmpSwComponent(Item2).Name);
|
||||
end;
|
||||
|
||||
|
||||
function SortByType(Item1, Item2: Pointer): Integer;
|
||||
begin
|
||||
Result := CompareText(TCmpSwComponent(Item1).ComponentClass, TCmpSwComponent(Item2).ComponentClass);
|
||||
end;
|
||||
|
||||
|
||||
procedure TfrmCmpSwDialog.SortList();
|
||||
begin
|
||||
if actSortByType.Checked then
|
||||
ClassFilteredList.Sort(SortByType)
|
||||
else
|
||||
ClassFilteredList.Sort(SortByName);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -10,16 +10,15 @@ uses
|
||||
|
||||
|
||||
type
|
||||
// #ToDo3 (MvR) 11-12-2007: "Include descendants" option
|
||||
|
||||
TCmpSwFilterGroup = class(TCollectionItem)
|
||||
private
|
||||
FEnabled: Boolean;
|
||||
FFilter: TStrings;
|
||||
FFilterChanged: Boolean;
|
||||
FFilterMasks: TObjectList;
|
||||
FName: String;
|
||||
FVisible: Boolean;
|
||||
FEnabled: Boolean;
|
||||
FFilter: TStrings;
|
||||
FFilterChanged: Boolean;
|
||||
FFilterMasks: TObjectList;
|
||||
FIncludeDescendants: Boolean;
|
||||
FName: String;
|
||||
FVisible: Boolean;
|
||||
protected
|
||||
procedure FilterChange(Sender: TObject);
|
||||
|
||||
@ -33,13 +32,16 @@ type
|
||||
|
||||
function Matches(const AValue: String): Boolean;
|
||||
|
||||
property Enabled: Boolean read FEnabled write FEnabled;
|
||||
property Filter: TStrings read FFilter;
|
||||
property Name: String read FName write FName;
|
||||
property Visible: Boolean read FVisible write FVisible;
|
||||
property Enabled: Boolean read FEnabled write FEnabled;
|
||||
property Filter: TStrings read FFilter;
|
||||
property IncludeDescendants: Boolean read FIncludeDescendants write FIncludeDescendants;
|
||||
property Name: String read FName write FName;
|
||||
property Visible: Boolean read FVisible write FVisible;
|
||||
end;
|
||||
|
||||
|
||||
TCmpSwMatchResult = (mrNoMatch, mrDisabledMatch, mrMatch);
|
||||
|
||||
TCmpSwFilterGroups = class(TCollection)
|
||||
private
|
||||
function GetItem(Index: Integer): TCmpSwFilterGroup;
|
||||
@ -48,7 +50,7 @@ type
|
||||
constructor Create();
|
||||
|
||||
function Add(): TCmpSwFilterGroup;
|
||||
function Matches(const AValue: String): Boolean;
|
||||
function Matches(const AValue: String; AMatchDisabled: Boolean): TCmpSwMatchResult;
|
||||
|
||||
property Items[Index: Integer]: TCmpSwFilterGroup read GetItem write SetItem; default;
|
||||
end;
|
||||
@ -56,14 +58,16 @@ type
|
||||
|
||||
TCmpSwComponentClassFilter = class(TBaseSwItemFilter)
|
||||
private
|
||||
FGroups: TCmpSwFilterGroups;
|
||||
FFilterUnmatched: Boolean;
|
||||
FGroups: TCmpSwFilterGroups;
|
||||
protected
|
||||
procedure VisitItem(const AItem: TBaseSwItem); override;
|
||||
public
|
||||
constructor Create();
|
||||
destructor Destroy(); override;
|
||||
|
||||
property Groups: TCmpSwFilterGroups read FGroups;
|
||||
property FilterUnmatched: Boolean read FFilterUnmatched write FFilterUnmatched;
|
||||
property Groups: TCmpSwFilterGroups read FGroups;
|
||||
end;
|
||||
|
||||
|
||||
@ -72,7 +76,7 @@ uses
|
||||
Masks,
|
||||
SysUtils,
|
||||
|
||||
CmpSwObjects;
|
||||
CmpSwObjects, Dialogs;
|
||||
|
||||
|
||||
const
|
||||
@ -105,6 +109,8 @@ end;
|
||||
function TCmpSwFilterGroup.Matches(const AValue: String): Boolean;
|
||||
var
|
||||
filterIndex: Integer;
|
||||
valueClass: TClass;
|
||||
filterClass: TClass;
|
||||
|
||||
begin
|
||||
Result := False;
|
||||
@ -113,10 +119,24 @@ begin
|
||||
for filterIndex := Pred(Filter.Count) downto 0 do
|
||||
begin
|
||||
if Assigned(Filter.Objects[filterIndex]) then
|
||||
Result := TMask(Filter.Objects[filterIndex]).Matches(AValue)
|
||||
else
|
||||
begin
|
||||
Result := TMask(Filter.Objects[filterIndex]).Matches(AValue);
|
||||
end else
|
||||
begin
|
||||
Result := SameText(Filter[filterIndex], AValue);
|
||||
|
||||
if (not Result) and IncludeDescendants then
|
||||
begin
|
||||
filterClass := GetClass(Filter[filterIndex]);
|
||||
if Assigned(filterClass) then
|
||||
begin
|
||||
valueClass := GetClass(AValue);
|
||||
if Assigned(valueClass) then
|
||||
Result := valueClass.InheritsFrom(filterClass);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
if Result then
|
||||
Break;
|
||||
end;
|
||||
@ -197,20 +217,26 @@ begin
|
||||
end;
|
||||
|
||||
|
||||
function TCmpSwFilterGroups.Matches(const AValue: String): Boolean;
|
||||
function TCmpSwFilterGroups.Matches(const AValue: String; AMatchDisabled: Boolean): TCmpSwMatchResult;
|
||||
var
|
||||
itemIndex: Integer;
|
||||
|
||||
begin
|
||||
Result := False;
|
||||
Result := mrNoMatch;
|
||||
|
||||
for itemIndex := Pred(Count) downto 0 do
|
||||
begin
|
||||
if Items[itemIndex].Enabled then
|
||||
if AMatchDisabled or Items[itemIndex].Enabled then
|
||||
begin
|
||||
Result := Items[itemIndex].Matches(AValue);
|
||||
if Result then
|
||||
if Items[itemIndex].Matches(AValue) then
|
||||
begin
|
||||
if Items[itemIndex].Enabled then
|
||||
Result := mrMatch
|
||||
else
|
||||
Result := mrDisabledMatch;
|
||||
|
||||
Break;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
@ -235,8 +261,13 @@ end;
|
||||
|
||||
procedure TCmpSwComponentClassFilter.VisitItem(const AItem: TBaseSwItem);
|
||||
begin
|
||||
if Groups.Matches(TCmpSwComponent(AItem).ComponentClass) then
|
||||
FilterItem(AItem);
|
||||
case Groups.Matches(TCmpSwComponent(AItem).ComponentClass, FilterUnmatched) of
|
||||
mrMatch:
|
||||
FilterItem(AItem);
|
||||
mrNoMatch:
|
||||
if FilterUnmatched then
|
||||
FilterItem(AItem);
|
||||
end;
|
||||
end;
|
||||
|
||||
end.
|
||||
|
@ -240,6 +240,42 @@ begin
|
||||
CloseKey();
|
||||
end;
|
||||
end;
|
||||
end else
|
||||
begin
|
||||
{ Fill default groups }
|
||||
with AGroups.Add() do
|
||||
begin
|
||||
Name := 'Actions';
|
||||
|
||||
Filter.Add('TAction');
|
||||
IncludeDescendants := True;
|
||||
Visible := True;
|
||||
end;
|
||||
|
||||
with AGroups.Add() do
|
||||
begin
|
||||
Name := 'Menu items';
|
||||
|
||||
Filter.Add('TMenuItem');
|
||||
Visible := True;
|
||||
end;
|
||||
|
||||
with AGroups.Add() do
|
||||
begin
|
||||
Name := 'Dataset fields';
|
||||
|
||||
Filter.Add('TField');
|
||||
IncludeDescendants := True;
|
||||
Visible := True;
|
||||
end;
|
||||
|
||||
with AGroups.Add() do
|
||||
begin
|
||||
Name := 'DevEx Grid columns';
|
||||
|
||||
Filter.Add('TcxGridDBColumn');
|
||||
Filter.Add('TcxGridColumn');
|
||||
end;
|
||||
end;
|
||||
finally
|
||||
Free();
|
||||
@ -300,9 +336,10 @@ var
|
||||
filterText: String;
|
||||
|
||||
begin
|
||||
AGroup.Name := ARegistry.ReadString('Name');
|
||||
AGroup.Enabled := ARegistry.ReadBool('Enabled');
|
||||
AGroup.Visible := ARegistry.ReadBool('Visible');
|
||||
AGroup.Name := ARegistry.ReadString('Name');
|
||||
AGroup.Enabled := ARegistry.ReadBool('Enabled');
|
||||
AGroup.IncludeDescendants := ARegistry.ReadBool('IncludeDescendants');
|
||||
AGroup.Visible := ARegistry.ReadBool('Visible');
|
||||
|
||||
if ARegistry.ValueExists('Filter') then
|
||||
begin
|
||||
@ -323,6 +360,7 @@ var
|
||||
begin
|
||||
ARegistry.WriteString('Name', AGroup.Name);
|
||||
ARegistry.WriteBool('Enabled', AGroup.Enabled);
|
||||
ARegistry.WriteBool('IncludeDescendants', AGroup.IncludeDescendants);
|
||||
ARegistry.WriteBool('Visible', AGroup.Visible);
|
||||
|
||||
if AGroup.Filter.Count > 0 then
|
||||
|
Loading…
Reference in New Issue
Block a user