1
0
mirror of synced 2024-11-15 00:43:50 +00:00

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:
Mark van Renswoude 2007-12-12 10:18:59 +00:00
parent cfff9522ab
commit 450baa3705
6 changed files with 201 additions and 116 deletions

Binary file not shown.

View File

@ -73,12 +73,6 @@ begin
end; end;
function SortByName(Item1, Item2: Pointer): Integer;
begin
Result := CompareText(TCmpSwComponent(Item1).Name, TCmpSwComponent(Item2).Name)
end;
procedure TComponentSwitcherHook.NewExecute(Sender: TObject); procedure TComponentSwitcherHook.NewExecute(Sender: TObject);
var var
editor: IOTAEditor; editor: IOTAEditor;
@ -108,19 +102,6 @@ begin
if itemList.Count > 0 then if itemList.Count > 0 then
begin 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); selectedItems := TfrmCmpSwDialog.Execute(itemList);
if Assigned(selectedItems) then if Assigned(selectedItems) then

View File

@ -53,7 +53,6 @@ inherited frmCmpSwDialog: TfrmCmpSwDialog
Width = 342 Width = 342
Height = 65 Height = 65
Align = alClient Align = alClient
Caption = ' Filter '
TabOrder = 0 TabOrder = 0
DesignSize = ( DesignSize = (
342 342
@ -75,6 +74,18 @@ inherited frmCmpSwDialog: TfrmCmpSwDialog
Caption = '&Filter selected class(es)' Caption = '&Filter selected class(es)'
Enabled = False Enabled = False
end 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 end
inherited pmnItems: TPopupMenu inherited pmnItems: TPopupMenu
object pmnItemsFilters: TMenuItem [0] object pmnItemsFilters: TMenuItem [0]
@ -86,6 +97,15 @@ inherited frmCmpSwDialog: TfrmCmpSwDialog
object pmnItemsSep1: TMenuItem [2] object pmnItemsSep1: TMenuItem [2]
Caption = '-' Caption = '-'
end end
object pmnItemsSortByName: TMenuItem [3]
Action = actSortByName
end
object pmnItemsSortByType: TMenuItem [4]
Action = actSortByType
end
object pmnItemsSep2: TMenuItem [5]
Caption = '-'
end
end end
object pmnMoreFilters: TPopupMenu object pmnMoreFilters: TPopupMenu
Left = 192 Left = 192

View File

@ -17,7 +17,7 @@ uses
BaseSwDialog, BaseSwDialog,
BaseSwObjects, BaseSwObjects,
CmpSwFilters; CmpSwFilters, UnSwDialog;
type type
@ -46,25 +46,36 @@ type
gbFilters: TGroupBox; gbFilters: TGroupBox;
btnMoreFilters: TButton; btnMoreFilters: TButton;
pmnMoreFilters: TPopupMenu; pmnMoreFilters: TPopupMenu;
actSortByName: TAction;
actSortByType: TAction;
pmnItemsSortByName: TMenuItem;
pmnItemsSortByType: TMenuItem;
pmnItemsSep2: TMenuItem;
procedure btnMoreFiltersClick(Sender: TObject); procedure btnMoreFiltersClick(Sender: TObject);
procedure FormShow(Sender: TObject); procedure FormShow(Sender: TObject);
procedure SortExecute(Sender: TObject);
private private
FClassFilteredList: TBaseSwItemList; FClassFilteredList: TBaseSwItemList;
FClassFilter: TCmpSwComponentClassFilter; FClassFilter: TCmpSwComponentClassFilter;
FFilterCheckBoxes: TObjectList; FFilterCheckBoxes: TObjectList;
FOtherGroup: TCmpSwFilterGroup;
protected protected
function InternalExecute(): TBaseSwItemList; override; function InternalExecute(): TBaseSwItemList; override;
function CreateStyleVisitor(): TBaseSwStyleVisitor; override; function CreateStyleVisitor(): TBaseSwStyleVisitor; override;
function GetBaseItemList(): TBaseSwItemList; override; function GetBaseItemList(): TBaseSwItemList; override;
function AllowEmptyResult(): Boolean; override;
function ColorsEnabled(): Boolean; override;
procedure LoadSettings(); override; procedure LoadSettings(); override;
procedure SaveSettings(); override; procedure SaveSettings(); override;
procedure DrawItemText(ACanvas: TCanvas; AItem: TBaseSwItem; ARect: TRect); override; procedure DrawItemText(ACanvas: TCanvas; AItem: TBaseSwItem; ARect: TRect); override;
procedure UpdateClassFilter(); procedure UpdateClassFilter();
procedure SortList();
procedure BuildFilterCheckboxes(); procedure BuildFilterCheckboxes();
function CreateFilterMenuItem(AParent: TMenuItem; AGroup: TCmpSwFilterGroup; AItemIndex: Integer): TMenuItem; function CreateFilterMenuItem(AParent: TMenuItem; AGroup: TCmpSwFilterGroup; AItemIndex: Integer): TMenuItem;
@ -73,6 +84,7 @@ type
procedure FilterMenuItemClick(Sender: TObject); procedure FilterMenuItemClick(Sender: TObject);
property ClassFilter: TCmpSwComponentClassFilter read FClassFilter; property ClassFilter: TCmpSwComponentClassFilter read FClassFilter;
property ClassFilteredList: TBaseSwItemList read FClassFilteredList;
end; end;
@ -233,9 +245,15 @@ begin
FClassFilteredList := TBaseSwItemList.Create(); FClassFilteredList := TBaseSwItemList.Create();
FClassFilter := TCmpSwComponentClassFilter.Create(); FClassFilter := TCmpSwComponentClassFilter.Create();
FFilterCheckBoxes := TObjectList.Create(); FFilterCheckBoxes := TObjectList.Create();
FOtherGroup := TCmpSwFilterGroup.Create(nil);
try try
FOtherGroup.Name := 'Other';
FOtherGroup.Enabled := False;
FOtherGroup.Visible := False;
Result := inherited InternalExecute(); Result := inherited InternalExecute();
finally finally
FreeAndNil(FOtherGroup);
FreeAndNil(FFilterCheckBoxes); FreeAndNil(FFilterCheckBoxes);
FreeAndNil(FClassFilter); FreeAndNil(FClassFilter);
FreeAndNil(FClassFilteredList); FreeAndNil(FClassFilteredList);
@ -271,7 +289,7 @@ begin
DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS or DT_CALCRECT); DT_LEFT or DT_VCENTER or DT_END_ELLIPSIS or DT_CALCRECT);
textRect.Left := textRect.Right; textRect.Left := textRect.Right;
textRect.Right := ARect.Right; textRect.Right := ARect.Right - 2;
{ Draw component class text } { Draw component class text }
ACanvas.Font.Color := clGrayText; ACanvas.Font.Color := clGrayText;
@ -288,62 +306,6 @@ var
itemIndex: Integer; itemIndex: Integer;
begin 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); pnlFilters.Visible := (ClassFilter.Groups.Count > 0);
@ -358,6 +320,9 @@ begin
end; end;
end; end;
CreateFilterMenuItem(pmnItemsFilters, FOtherGroup, itemIndex);
Inc(itemIndex);
{ Remove excess menu items } { Remove excess menu items }
for groupIndex := Pred(pmnItemsFilters.Count) downto itemIndex do for groupIndex := Pred(pmnItemsFilters.Count) downto itemIndex do
pmnItemsFilters.Delete(groupIndex); pmnItemsFilters.Delete(groupIndex);
@ -374,6 +339,9 @@ begin
end; end;
end; end;
CreateFilterMenuItem(pmnMoreFilters.Items, FOtherGroup, itemIndex);
Inc(itemIndex);
for groupIndex := Pred(pmnMoreFilters.Items.Count) downto itemIndex do for groupIndex := Pred(pmnMoreFilters.Items.Count) downto itemIndex do
pmnMoreFilters.Items.Delete(groupIndex); pmnMoreFilters.Items.Delete(groupIndex);
@ -381,14 +349,17 @@ begin
BuildFilterCheckboxes(); BuildFilterCheckboxes();
btnMoreFilters.Visible := (pmnMoreFilters.Items.Count > 0); btnMoreFilters.Visible := (pmnMoreFilters.Items.Count > 0);
FClassFilteredList.Clone(ItemList); ClassFilteredList.Clone(ItemList);
ClassFilter.FilterList(FClassFilteredList);
ClassFilter.FilterUnmatched := FOtherGroup.Enabled;
ClassFilter.FilterList(ClassFilteredList);
SortList();
end; end;
function TfrmCmpSwDialog.GetBaseItemList(): TBaseSwItemList; function TfrmCmpSwDialog.GetBaseItemList(): TBaseSwItemList;
begin begin
Result := FClassFilteredList; Result := ClassFilteredList;
end; end;
@ -418,7 +389,7 @@ begin
checkBox.Top := checkBoxTop; checkBox.Top := checkBoxTop;
checkBox.Left := 12; checkBox.Left := 12;
checkBox.Caption := StringReplace(group.Name, '&', '&&', [rfReplaceAll]); checkBox.Caption := StringReplace(group.Name, '&', '&&', [rfReplaceAll]);
checkBox.Checked := group.Enabled; checkBox.Checked := not group.Enabled;
checkBox.Tag := Integer(group); checkBox.Tag := Integer(group);
checkBox.OnClick := FilterCheckBoxClick; checkBox.OnClick := FilterCheckBoxClick;
checkBox.Parent := gbFilters; checkBox.Parent := gbFilters;
@ -443,7 +414,7 @@ begin
Result := AParent[AItemIndex]; Result := AParent[AItemIndex];
Result.Caption := StringReplace(AGroup.Name, '&', '&&', [rfReplaceAll]); Result.Caption := StringReplace(AGroup.Name, '&', '&&', [rfReplaceAll]);
Result.Checked := AGroup.Enabled; Result.Checked := not AGroup.Enabled;
Result.Tag := Integer(AGroup); Result.Tag := Integer(AGroup);
end; end;
@ -457,9 +428,9 @@ begin
checkBox := (Sender as TCheckBox); checkBox := (Sender as TCheckBox);
group := TCmpSwFilterGroup(checkBox.Tag); group := TCmpSwFilterGroup(checkBox.Tag);
if checkBox.Checked <> group.Enabled then if checkBox.Checked = group.Enabled then
begin begin
group.Enabled := checkBox.Checked; group.Enabled := not checkBox.Checked;
UpdateClassFilter(); UpdateClassFilter();
UpdateSubFilters(); UpdateSubFilters();
@ -476,8 +447,8 @@ begin
menuItem := (Sender as TMenuItem); menuItem := (Sender as TMenuItem);
group := TCmpSwFilterGroup(menuItem.Tag); group := TCmpSwFilterGroup(menuItem.Tag);
menuItem.Checked := not menuItem.Checked;
group.Enabled := menuItem.Checked; group.Enabled := menuItem.Checked;
menuItem.Checked := not menuItem.Checked;
UpdateClassFilter(); UpdateClassFilter();
UpdateSubFilters(); UpdateSubFilters();
@ -508,6 +479,8 @@ end;
procedure TfrmCmpSwDialog.SaveSettings(); procedure TfrmCmpSwDialog.SaveSettings();
begin begin
// #ToDo2 (MvR) 12-12-2007: save 'sort by ...'
Settings.Dialog.Width := Self.ClientWidth; Settings.Dialog.Width := Self.ClientWidth;
Settings.Dialog.Height := Self.ClientHeight; Settings.Dialog.Height := Self.ClientHeight;
Settings.Dialog.MRUList.Assign(MRUList); Settings.Dialog.MRUList.Assign(MRUList);
@ -518,4 +491,46 @@ begin
inherited SaveSettings(); inherited SaveSettings();
end; 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. end.

View File

@ -10,14 +10,13 @@ uses
type type
// #ToDo3 (MvR) 11-12-2007: "Include descendants" option
TCmpSwFilterGroup = class(TCollectionItem) TCmpSwFilterGroup = class(TCollectionItem)
private private
FEnabled: Boolean; FEnabled: Boolean;
FFilter: TStrings; FFilter: TStrings;
FFilterChanged: Boolean; FFilterChanged: Boolean;
FFilterMasks: TObjectList; FFilterMasks: TObjectList;
FIncludeDescendants: Boolean;
FName: String; FName: String;
FVisible: Boolean; FVisible: Boolean;
protected protected
@ -35,11 +34,14 @@ type
property Enabled: Boolean read FEnabled write FEnabled; property Enabled: Boolean read FEnabled write FEnabled;
property Filter: TStrings read FFilter; property Filter: TStrings read FFilter;
property IncludeDescendants: Boolean read FIncludeDescendants write FIncludeDescendants;
property Name: String read FName write FName; property Name: String read FName write FName;
property Visible: Boolean read FVisible write FVisible; property Visible: Boolean read FVisible write FVisible;
end; end;
TCmpSwMatchResult = (mrNoMatch, mrDisabledMatch, mrMatch);
TCmpSwFilterGroups = class(TCollection) TCmpSwFilterGroups = class(TCollection)
private private
function GetItem(Index: Integer): TCmpSwFilterGroup; function GetItem(Index: Integer): TCmpSwFilterGroup;
@ -48,7 +50,7 @@ type
constructor Create(); constructor Create();
function Add(): TCmpSwFilterGroup; 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; property Items[Index: Integer]: TCmpSwFilterGroup read GetItem write SetItem; default;
end; end;
@ -56,6 +58,7 @@ type
TCmpSwComponentClassFilter = class(TBaseSwItemFilter) TCmpSwComponentClassFilter = class(TBaseSwItemFilter)
private private
FFilterUnmatched: Boolean;
FGroups: TCmpSwFilterGroups; FGroups: TCmpSwFilterGroups;
protected protected
procedure VisitItem(const AItem: TBaseSwItem); override; procedure VisitItem(const AItem: TBaseSwItem); override;
@ -63,6 +66,7 @@ type
constructor Create(); constructor Create();
destructor Destroy(); override; destructor Destroy(); override;
property FilterUnmatched: Boolean read FFilterUnmatched write FFilterUnmatched;
property Groups: TCmpSwFilterGroups read FGroups; property Groups: TCmpSwFilterGroups read FGroups;
end; end;
@ -72,7 +76,7 @@ uses
Masks, Masks,
SysUtils, SysUtils,
CmpSwObjects; CmpSwObjects, Dialogs;
const const
@ -105,6 +109,8 @@ end;
function TCmpSwFilterGroup.Matches(const AValue: String): Boolean; function TCmpSwFilterGroup.Matches(const AValue: String): Boolean;
var var
filterIndex: Integer; filterIndex: Integer;
valueClass: TClass;
filterClass: TClass;
begin begin
Result := False; Result := False;
@ -113,10 +119,24 @@ begin
for filterIndex := Pred(Filter.Count) downto 0 do for filterIndex := Pred(Filter.Count) downto 0 do
begin begin
if Assigned(Filter.Objects[filterIndex]) then if Assigned(Filter.Objects[filterIndex]) then
Result := TMask(Filter.Objects[filterIndex]).Matches(AValue) begin
else Result := TMask(Filter.Objects[filterIndex]).Matches(AValue);
end else
begin
Result := SameText(Filter[filterIndex], AValue); 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 if Result then
Break; Break;
end; end;
@ -197,23 +217,29 @@ begin
end; end;
function TCmpSwFilterGroups.Matches(const AValue: String): Boolean; function TCmpSwFilterGroups.Matches(const AValue: String; AMatchDisabled: Boolean): TCmpSwMatchResult;
var var
itemIndex: Integer; itemIndex: Integer;
begin begin
Result := False; Result := mrNoMatch;
for itemIndex := Pred(Count) downto 0 do for itemIndex := Pred(Count) downto 0 do
begin begin
if Items[itemIndex].Enabled then if AMatchDisabled or Items[itemIndex].Enabled then
begin begin
Result := Items[itemIndex].Matches(AValue); if Items[itemIndex].Matches(AValue) then
if Result then begin
if Items[itemIndex].Enabled then
Result := mrMatch
else
Result := mrDisabledMatch;
Break; Break;
end; end;
end; end;
end; end;
end;
{ TCmpSwComponentClassFilter } { TCmpSwComponentClassFilter }
@ -235,8 +261,13 @@ end;
procedure TCmpSwComponentClassFilter.VisitItem(const AItem: TBaseSwItem); procedure TCmpSwComponentClassFilter.VisitItem(const AItem: TBaseSwItem);
begin begin
if Groups.Matches(TCmpSwComponent(AItem).ComponentClass) then case Groups.Matches(TCmpSwComponent(AItem).ComponentClass, FilterUnmatched) of
mrMatch:
FilterItem(AItem); FilterItem(AItem);
mrNoMatch:
if FilterUnmatched then
FilterItem(AItem);
end;
end; end;
end. end.

View File

@ -240,6 +240,42 @@ begin
CloseKey(); CloseKey();
end; end;
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; end;
finally finally
Free(); Free();
@ -302,6 +338,7 @@ var
begin begin
AGroup.Name := ARegistry.ReadString('Name'); AGroup.Name := ARegistry.ReadString('Name');
AGroup.Enabled := ARegistry.ReadBool('Enabled'); AGroup.Enabled := ARegistry.ReadBool('Enabled');
AGroup.IncludeDescendants := ARegistry.ReadBool('IncludeDescendants');
AGroup.Visible := ARegistry.ReadBool('Visible'); AGroup.Visible := ARegistry.ReadBool('Visible');
if ARegistry.ValueExists('Filter') then if ARegistry.ValueExists('Filter') then
@ -323,6 +360,7 @@ var
begin begin
ARegistry.WriteString('Name', AGroup.Name); ARegistry.WriteString('Name', AGroup.Name);
ARegistry.WriteBool('Enabled', AGroup.Enabled); ARegistry.WriteBool('Enabled', AGroup.Enabled);
ARegistry.WriteBool('IncludeDescendants', AGroup.IncludeDescendants);
ARegistry.WriteBool('Visible', AGroup.Visible); ARegistry.WriteBool('Visible', AGroup.Visible);
if AGroup.Filter.Count > 0 then if AGroup.Filter.Count > 0 then