diff --git a/Lib/D7/UnitSwitcherD7.bpl b/Lib/D7/UnitSwitcherD7.bpl index 848ea50..6e6a8ee 100644 Binary files a/Lib/D7/UnitSwitcherD7.bpl and b/Lib/D7/UnitSwitcherD7.bpl differ diff --git a/Source/UnSwDialog.dfm b/Source/UnSwDialog.dfm index 310c6d1..bdbec98 100644 --- a/Source/UnSwDialog.dfm +++ b/Source/UnSwDialog.dfm @@ -1,10 +1,10 @@ object frmUnSwDialog: TfrmUnSwDialog Left = 187 Top = 83 + Width = 320 + Height = 425 BorderIcons = [biSystemMenu] Caption = 'UnitSwitcher' - ClientHeight = 398 - ClientWidth = 312 Color = clBtnFace Constraints.MinHeight = 240 Constraints.MinWidth = 290 @@ -204,10 +204,10 @@ object frmUnSwDialog: TfrmUnSwDialog end end object ilsTypes: TImageList - Left = 16 - Top = 264 + Left = 28 + Top = 228 Bitmap = { - 494C010106000900040010001000FFFFFFFFFF00FFFFFFFFFFFFFFFF424D3600 + 494C010106000900040010001000FFFFFFFFFF10FFFFFFFFFFFFFFFF424D3600 0000000000003600000028000000400000003000000001002000000000000030 0000000000000000000000000000000000000000000000000000000000000000 0000000000000000000000000000000000000000000000000000000000000000 @@ -607,11 +607,12 @@ object frmUnSwDialog: TfrmUnSwDialog E000E0000000AC0FE000E0000000BF3FE000E0000000FFFFE000600000001000 E000200000001000E00000000000B000E00020000000F000E00060000000F000 E000E0000000F000E000E0000000F000E000E0000000F000E001E0010000F000 - E003E003FFFFF000E007E007FFFFF000} + E003E003FFFFF000E007E007FFFFF00000000000000000000000000000000000 + 000000000000} end object alMain: TActionList - Left = 44 - Top = 264 + Left = 84 + Top = 228 object actSelectAll: TAction Caption = 'Select &All' ShortCut = 16449 @@ -666,8 +667,8 @@ object frmUnSwDialog: TfrmUnSwDialog end end object pmnUnits: TPopupMenu - Left = 72 - Top = 264 + Left = 140 + Top = 228 object pmnUnitsSelectAll: TMenuItem Action = actSelectAll end diff --git a/Source/UnSwDialog.pas b/Source/UnSwDialog.pas index fa91844..77ecead 100644 --- a/Source/UnSwDialog.pas +++ b/Source/UnSwDialog.pas @@ -120,6 +120,7 @@ type FTypeFilter: TUnSwUnitTypeFilter; FSubFilter: TUnSwUnitSimpleFilter; FInputFilter: TUnSwUnitSimpleFilter; + FLastFilter: String; FStyleVisitor: TUnSwStyleVisitor; @@ -168,22 +169,26 @@ type destructor Destroy(); override; end; + TUnSwOpenFolderVisitor = class(TUnSwOpenVisitor) protected procedure OpenFile(const AFileName: String); override; end; + TUnSwOpenPropertiesVisitor = class(TUnSwOpenVisitor) protected procedure OpenFile(const AFileName: String); override; end; + TUnSwOpenDFMPropertiesVisitor = class(TUnSwOpenPropertiesVisitor) protected procedure VisitModule(const AUnit: TUnSwModuleUnit); override; procedure VisitProject(const AUnit: TUnSwProjectUnit); override; end; + TUnSwReadOnlyVisitor = class(TUnSwOpenVisitor) private FReadOnlyCount: Integer; @@ -193,6 +198,7 @@ type property ReadOnlyCount: Integer read FReadOnlyCount; end; + TUnSwSetReadOnlyVisitor = class(TUnSwOpenVisitor) private FReadOnlyFlag: Boolean; @@ -225,6 +231,7 @@ begin FProcessed.CaseSensitive := False; end; + destructor TUnSwOpenVisitor.Destroy(); begin FreeAndNil(FProcessed); @@ -232,6 +239,7 @@ begin inherited; end; + function TUnSwOpenVisitor.IsProcessed(const AFileName: String; const ARegister: Boolean): Boolean; begin @@ -244,11 +252,13 @@ begin end; end; + procedure TUnSwOpenVisitor.VisitModule(const AUnit: TUnSwModuleUnit); begin OpenFile(AUnit.FileName); end; + procedure TUnSwOpenVisitor.VisitProject(const AUnit: TUnSwProjectUnit); begin OpenFile(AUnit.FileName); @@ -305,6 +315,7 @@ begin OpenFile(ChangeFileExt(AUnit.FileName, '.dfm')); end; + procedure TUnSwOpenDFMPropertiesVisitor.VisitProject(const AUnit: TUnSwProjectUnit); begin end; @@ -360,6 +371,7 @@ begin FOverlayIndex := -1; end; + procedure TUnSwStyleVisitor.VisitModule(const AUnit: TUnSwModuleUnit); begin VisitUnit(AUnit); @@ -385,6 +397,7 @@ begin end; end; + procedure TUnSwStyleVisitor.VisitProject(const AUnit: TUnSwProjectUnit); begin VisitUnit(AUnit); @@ -409,21 +422,24 @@ begin end; end; + procedure TfrmUnSwDialog.FormResize(Sender: TObject); begin lstUnits.Invalidate(); end; + procedure TfrmUnSwDialog.FormShow(Sender: TObject); begin // Setting ListBox.Selected[x] won't work before OnShow... UpdateTypeFilter(); end; + function TfrmUnSwDialog.InternalExecute(): TUnSwUnitList; type TUnSwUnitSimpleFilterClass = class of TUnSwUnitSimpleFilter; - + var iIndex: Integer; pClass: TUnSwUnitSimpleFilterClass; @@ -434,15 +450,15 @@ begin FTypeFilteredList := TUnSwUnitList.Create(); FSubFilteredList := TUnSwUnitList.Create(); FInputFilteredList := TUnSwUnitList.Create(); - FTypeFilter := TUnSwUnitTypeFilter.Create(FTypeFilteredList); + FTypeFilter := TUnSwUnitTypeFilter.Create; if FFormsOnly then pClass := TUnSwUnitSimpleFormNameFilter else pClass := TUnSwUnitSimpleNameFilter; - FSubFilter := pClass.Create(FSubFilteredList); - FInputFilter := pClass.Create(FInputFilteredList); + FSubFilter := pClass.Create; + FInputFilter := pClass.Create; try LoadSettings(); @@ -489,6 +505,7 @@ begin end; end; + procedure TfrmUnSwDialog.UpdateUnitActions(); var bDFM: Boolean; @@ -549,18 +566,43 @@ begin actOpenDFMProperties.Enabled := bDFM; end; + procedure TfrmUnSwDialog.UpdateList(); var activeUnit: TUnSwUnit; activeUnits: TUnSwUnitList; itemIndex: Integer; listIndex: Integer; + filteredList: TUnSwUnitList; + selStart: Integer; begin - activeUnits := GetActiveUnits(); + activeUnits := GetActiveUnits(); + + filteredList := TUnSwUnitList.Create(); + try + filteredList.Clone(FSubFilteredList); + FInputFilter.FilterList(filteredList); + + if (filteredList.Count = 0) and (not Settings.Filter.AllowEmptyResult) then + begin + { Only enforce AllowEmptyResult when adding to the filter } + if Length(FInputFilter.Filter) > Length(FLastFilter) then + begin + FInputFilter.Filter := FLastFilter; + selStart := cmbSearch.SelStart; + cmbSearch.Text := FLastFilter; + cmbSearch.SelStart := selStart; + Exit; + end; + end; + + FLastFilter := FInputFilter.Filter; + FInputFilteredList.Clone(filteredList); + finally + FreeAndNil(filteredList); + end; - FInputFilteredList.Clone(FSubFilteredList); - FInputFilteredList.AcceptVisitor(FInputFilter); lstUnits.Count := FInputFilteredList.Count; if FInputFilteredList.Count > 0 then @@ -588,11 +630,13 @@ begin lstUnits.OnClick(nil); end; + function SortByName(Item1, Item2: Pointer): Integer; begin Result := CompareText(TUnSwUnit(Item1).Name, TUnSwUnit(Item2).Name) end; + function SortByType(Item1, Item2: Pointer): Integer; const Above = -1; @@ -641,6 +685,7 @@ begin Result := SortByName(Item1, Item2); end; + procedure TfrmUnSwDialog.UpdateTypeFilter(); begin FTypeFilter.IncludeUnits := ((not FFormsOnly) and chkUnits.Checked); @@ -649,7 +694,7 @@ begin FTypeFilter.IncludeDataModules := chkDataModules.Checked; FTypeFilteredList.Clone(FUnitList); - FTypeFilteredList.AcceptVisitor(FTypeFilter); + FTypeFilter.FilterList(FTypeFilteredList); if actSortByName.Checked then FTypeFilteredList.Sort(SortByName) @@ -659,6 +704,7 @@ begin UpdateSubFilters(); end; + procedure TfrmUnSwDialog.PopFilter(); begin if FSubFilters.Count > 0 then @@ -668,6 +714,7 @@ begin end; end; + procedure TfrmUnSwDialog.UpdateSubFilters(); var iFilter: Integer; @@ -682,7 +729,7 @@ begin begin sFilters := sFilters + FSubFilters[iFilter] + ' '#187' '; FSubFilter.Filter := FSubFilters[iFilter]; - FSubFilteredList.AcceptVisitor(FSubFilter); + FSubFilter.FilterList(FSubFilteredList); end; lblSubFilters.Caption := Trim(sFilters); @@ -708,6 +755,7 @@ begin end; end; + function TfrmUnSwDialog.GetActiveUnits(): TUnSwUnitList; var itemIndex: Integer; @@ -764,6 +812,7 @@ begin end; end; + procedure TfrmUnSwDialog.SaveSettings(); var dialogSettings: TUnSwDialogSettings; @@ -796,6 +845,7 @@ begin lstUnits.SelectAll(); end; + procedure TfrmUnSwDialog.actSelectInvertExecute(Sender: TObject); var iItem: Integer; @@ -805,6 +855,7 @@ begin lstUnits.Selected[iItem] := not lstUnits.Selected[iItem]; end; + procedure TfrmUnSwDialog.SortExecute(Sender: TObject); begin (Sender as TAction).Checked := True; @@ -822,6 +873,7 @@ begin cmbSearch.OnChange(nil); end; + procedure TfrmUnSwDialog.actMRUNextExecute(Sender: TObject); begin if FMRUIndex < Pred(FMRUList.Count) then @@ -830,6 +882,7 @@ begin SelectMRUItem(); end; + procedure TfrmUnSwDialog.actMRUPriorExecute(Sender: TObject); begin if FMRUIndex >= -1 then @@ -838,6 +891,7 @@ begin SelectMRUItem(); end; + procedure TfrmUnSwDialog.actOpenFolderExecute(Sender: TObject); var pUnits: TUnSwUnitList; @@ -852,6 +906,7 @@ begin end; end; + procedure TfrmUnSwDialog.actOpenPropertiesExecute(Sender: TObject); var pUnits: TUnSwUnitList; @@ -866,6 +921,7 @@ begin end; end; + procedure TfrmUnSwDialog.actOpenDFMPropertiesExecute(Sender: TObject); var pUnits: TUnSwUnitList; @@ -887,12 +943,17 @@ begin lstUnits.Invalidate(); end; + procedure TfrmUnSwDialog.cmbSearchChange(Sender: TObject); begin - FInputFilter.Filter := cmbSearch.Text; - UpdateList(); + if cmbSearch.Text <> FInputFilter.Filter then + begin + FInputFilter.Filter := cmbSearch.Text; + UpdateList(); + end; end; + procedure TfrmUnSwDialog.cmbSearchKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin @@ -922,6 +983,7 @@ begin end; end; + procedure TfrmUnSwDialog.cmbSearchKeyPress(Sender: TObject; var Key: Char); begin // Ctrl-Backspace @@ -929,28 +991,33 @@ begin Key := #0; end; + procedure TfrmUnSwDialog.TypeFilterChange(Sender: TObject); begin if not FLoading then UpdateTypeFilter(); end; + procedure TfrmUnSwDialog.lstUnitsDblClick(Sender: TObject); begin btnOK.Click(); end; + procedure TfrmUnSwDialog.lstUnitsClick(Sender: TObject); begin UpdateUnitActions(); end; + procedure TfrmUnSwDialog.lstUnitsData(Control: TWinControl; Index: Integer; var Data: string); begin Data := FInputFilteredList[Index].Name; end; + procedure TfrmUnSwDialog.lstUnitsDrawItem(Control: TWinControl; Index: Integer; Rect: TRect; State: TOwnerDrawState); var @@ -996,6 +1063,7 @@ begin end; end; + procedure TfrmUnSwDialog.lstUnitsMouseDown(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var itemIndex: Integer; @@ -1015,6 +1083,7 @@ begin end; end; + procedure TfrmUnSwDialog.actReadOnlyExecute(Sender: TObject); var pUnits: TUnSwUnitList; diff --git a/Source/UnSwFilters.pas b/Source/UnSwFilters.pas index 5e7c3b6..807ca84 100644 --- a/Source/UnSwFilters.pas +++ b/Source/UnSwFilters.pas @@ -23,7 +23,7 @@ type procedure FilterUnit(const AUnit: TUnSwUnit); virtual; public - constructor Create(const AList: TUnSwUnitList); virtual; + procedure FilterList(AList: TUnSwUnitList); end; TUnSwUnitSimpleFilter = class(TUnSwUnitFilter) @@ -55,7 +55,7 @@ type procedure VisitModule(const AUnit: TUnSwModuleUnit); override; procedure VisitProject(const AUnit: TUnSwProjectUnit); override; public - constructor Create(const AList: TUnSwUnitList); override; + constructor Create; property IncludeDataModules: Boolean read FIncludeDataModules write FIncludeDataModules; property IncludeForms: Boolean read FIncludeForms write FIncludeForms; @@ -69,28 +69,34 @@ uses { TUnSwUnitFilter } -constructor TUnSwUnitFilter.Create(const AList: TUnSwUnitList); +procedure TUnSwUnitFilter.FilterList(AList: TUnSwUnitList); begin - inherited Create(); - - Assert(Assigned(AList), 'List must be assigned.'); FList := AList; + try + FList.AcceptVisitor(Self); + finally + FList := nil; + end; end; + procedure TUnSwUnitFilter.VisitUnit(const AUnit: TUnSwUnit); begin end; + procedure TUnSwUnitFilter.VisitModule(const AUnit: TUnSwModuleUnit); begin VisitUnit(AUnit); end; + procedure TUnSwUnitFilter.VisitProject(const AUnit: TUnSwProjectUnit); begin VisitUnit(AUnit); end; + procedure TUnSwUnitFilter.FilterUnit(const AUnit: TUnSwUnit); begin FList.Remove(AUnit); @@ -123,7 +129,7 @@ end; { TUnSwUnitTypeFilter } -constructor TUnSwUnitTypeFilter.Create(const AList: TUnSwUnitList); +constructor TUnSwUnitTypeFilter.Create; begin inherited; @@ -133,6 +139,7 @@ begin FIncludeUnits := True; end; + procedure TUnSwUnitTypeFilter.VisitModule(const AUnit: TUnSwModuleUnit); var validTypes: TUnSwUnitTypes; @@ -153,6 +160,7 @@ begin FilterUnit(AUnit); end; + procedure TUnSwUnitTypeFilter.VisitProject(const AUnit: TUnSwProjectUnit); begin if not FIncludeProjectSource then diff --git a/Source/UnSwSettings.pas b/Source/UnSwSettings.pas index cdc8ef7..02360d5 100644 --- a/Source/UnSwSettings.pas +++ b/Source/UnSwSettings.pas @@ -29,6 +29,7 @@ type procedure WriteColor(const ARegistry: TRegistry; const AValue: TColor; const AName: String); end; + TUnSwDialogSort = (dsName, dsType); TUnSwDialogSettings = class(TUnSwBaseSettings) @@ -60,6 +61,7 @@ type property Width: Integer read FWidth write FWidth; end; + TUnSwColorSettings = class(TUnSwBaseSettings) private FDataModules: TColor; @@ -78,9 +80,22 @@ type property Units: TColor read FUnits write FUnits; end; + + TUnSwFilterSettings = class(TUnSwBaseSettings) + private + FAllowEmptyResults: Boolean; + protected + procedure Load(const ARegistry: TRegistry); override; + procedure Save(const ARegistry: TRegistry); override; + public + property AllowEmptyResult: Boolean read FAllowEmptyResults write FAllowEmptyResults; + end; + + TUnSwSettings = class(TObject) private FColors: TUnSwColorSettings; + FFilter: TUnSwFilterSettings; FFormsDialog: TUnSwDialogSettings; FUnitsDialog: TUnSwDialogSettings; @@ -95,12 +110,15 @@ type procedure Save(); property Colors: TUnSwColorSettings read FColors write FColors; + property Filter: TUnSwFilterSettings read FFilter write FFilter; property FormsDialog: TUnSwDialogSettings read FFormsDialog write FFormsDialog; property UnitsDialog: TUnSwDialogSettings read FUnitsDialog write FUnitsDialog; end; + function Settings(): TUnSwSettings; + implementation uses SysUtils, @@ -126,6 +144,7 @@ begin Result := AName; end; + procedure TUnSwBaseSettings.ReadBoolDef(const ARegistry: TRegistry; var AValue: Boolean; const AName: String); @@ -134,6 +153,7 @@ begin AValue := ARegistry.ReadBool(GetKeyName(AName)); end; + procedure TUnSwBaseSettings.ReadColorDef(const ARegistry: TRegistry; var AValue: TColor; const AName: String); @@ -142,6 +162,7 @@ begin AValue := TColor(ARegistry.ReadInteger(GetKeyName(AName))); end; + procedure TUnSwBaseSettings.ReadIntegerDef(const ARegistry: TRegistry; var AValue: Integer; const AName: String); @@ -158,6 +179,7 @@ begin ARegistry.WriteBool(GetKeyName(AName), AValue); end; + procedure TUnSwBaseSettings.WriteColor(const ARegistry: TRegistry; const AValue: TColor; const AName: String); @@ -165,6 +187,7 @@ begin WriteInteger(ARegistry, Integer(AValue), AName); end; + procedure TUnSwBaseSettings.WriteInteger(const ARegistry: TRegistry; const AValue: Integer; const AName: String); @@ -184,6 +207,7 @@ begin TStringList(FMRUList).CaseSensitive := False end; + destructor TUnSwDialogSettings.Destroy(); begin FreeAndNil(FMRUList); @@ -240,6 +264,7 @@ begin end; end; + procedure TUnSwDialogSettings.Save(const ARegistry: TRegistry); var sMRU: String; @@ -274,6 +299,7 @@ begin ReadColorDef(ARegistry, FUnits, 'ColorUnits'); end; + procedure TUnSwColorSettings.Save(const ARegistry: TRegistry); begin WriteBool(ARegistry, FEnabled, 'ColorEnabled'); @@ -284,6 +310,19 @@ begin end; +{ TUnSwFilterSettings } +procedure TUnSwFilterSettings.Load(const ARegistry: TRegistry); +begin + ReadBoolDef(ARegistry, FAllowEmptyResults, 'AllowEmptyResults'); +end; + + +procedure TUnSwFilterSettings.Save(const ARegistry: TRegistry); +begin + WriteBool(ARegistry, FAllowEmptyResults, 'AllowEmptyResults'); +end; + + { TUnSwSettings } constructor TUnSwSettings.Create(); begin @@ -293,16 +332,20 @@ begin '\UnitSwitcher'; FColors := TUnSwColorSettings.Create(); + FFilter := TUnSwFilterSettings.Create(); FFormsDialog := TUnSwDialogSettings.Create('Forms'); FUnitsDialog := TUnSwDialogSettings.Create('Units'); + ResetDefaults(); Load(); end; + destructor TUnSwSettings.Destroy(); begin FreeAndNil(FUnitsDialog); FreeAndNil(FFormsDialog); + FreeAndNil(FFilter); FreeAndNil(FColors); inherited; @@ -310,6 +353,7 @@ end; procedure TUnSwSettings.ResetDefaults(const AColorsOnly: Boolean); + procedure ResetDialog(const ADialog: TUnSwDialogSettings); begin ADialog.IncludeDataModules := True; @@ -321,6 +365,7 @@ procedure TUnSwSettings.ResetDefaults(const AColorsOnly: Boolean); ADialog.Height := 425; end; + begin if not AColorsOnly then begin @@ -328,11 +373,13 @@ begin ResetDialog(FUnitsDialog); end; - FColors.Enabled := True; - FColors.DataModules := RGB( 35, 120, 35); // Green - FColors.Forms := RGB( 50, 70, 120); // Blue - FColors.ProjectSource := RGB(120, 120, 35); // Yellow - FColors.Units := RGB(150, 35, 35); // Red + FColors.Enabled := True; + FColors.DataModules := RGB( 35, 120, 35); // Green + FColors.Forms := RGB( 50, 70, 120); // Blue + FColors.ProjectSource := RGB(120, 120, 35); // Yellow + FColors.Units := RGB(150, 35, 35); // Red + + FFilter.AllowEmptyResult := False; end; procedure TUnSwSettings.Load(); @@ -344,11 +391,14 @@ begin with ideRegistry do try RootKey := HKEY_CURRENT_USER; + if OpenKey(FRegistryKey, False) then begin FColors.Load(ideRegistry); + FFilter.Load(ideRegistry); FFormsDialog.Load(ideRegistry); FUnitsDialog.Load(ideRegistry); + CloseKey(); end; finally @@ -356,6 +406,7 @@ begin end; end; + procedure TUnSwSettings.Save(); var ideRegistry: TRegistry; @@ -365,11 +416,14 @@ begin with ideRegistry do try RootKey := HKEY_CURRENT_USER; + if OpenKey(FRegistryKey, True) then begin FColors.Save(ideRegistry); + FFilter.Save(ideRegistry); FFormsDialog.Save(ideRegistry); FUnitsDialog.Save(ideRegistry); + CloseKey(); end; finally