diff --git a/Lib/D7/UnitSwitcherD7.bpl b/Lib/D7/UnitSwitcherD7.bpl index 2ce98e9..992fc8e 100644 Binary files a/Lib/D7/UnitSwitcherD7.bpl and b/Lib/D7/UnitSwitcherD7.bpl differ diff --git a/Source/CmpSwClient.pas b/Source/CmpSwClient.pas index 6edcfff..daf06dd 100644 --- a/Source/CmpSwClient.pas +++ b/Source/CmpSwClient.pas @@ -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 diff --git a/Source/CmpSwDialog.dfm b/Source/CmpSwDialog.dfm index 78a3920..641a28b 100644 --- a/Source/CmpSwDialog.dfm +++ b/Source/CmpSwDialog.dfm @@ -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 diff --git a/Source/CmpSwDialog.pas b/Source/CmpSwDialog.pas index 0fed6ff..2ed592d 100644 --- a/Source/CmpSwDialog.pas +++ b/Source/CmpSwDialog.pas @@ -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. diff --git a/Source/CmpSwFilters.pas b/Source/CmpSwFilters.pas index dc12ae1..be247fc 100644 --- a/Source/CmpSwFilters.pas +++ b/Source/CmpSwFilters.pas @@ -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. diff --git a/Source/CmpSwSettings.pas b/Source/CmpSwSettings.pas index 5f58b70..061549c 100644 --- a/Source/CmpSwSettings.pas +++ b/Source/CmpSwSettings.pas @@ -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