diff --git a/components/lazcontrols/treefilteredit.pas b/components/lazcontrols/treefilteredit.pas index 5b97245bd6..63025a08ed 100644 --- a/components/lazcontrols/treefilteredit.pas +++ b/components/lazcontrols/treefilteredit.pas @@ -159,18 +159,18 @@ procedure TTreeFilterBranch.SortAndFilter; // Copy data from fOriginalData to fSortedData in sorted order var Origi, i: Integer; - FileN: string; + s: string; begin fSortedData.Clear; for Origi:=0 to fOriginalData.Count-1 do begin - FileN:=fOriginalData[Origi]; - if (fOwner.Filter='') or (Pos(fOwner.Filter,lowercase(FileN))>0) then begin + s:=fOriginalData[Origi]; + if (fOwner.Filter='') or (Pos(fOwner.Filter,lowercase(s))>0) then begin i:=fSortedData.Count-1; while i>=0 do begin - if CompareFNs(FileN,fSortedData[i])>=0 then break; + if CompareFNs(s,fSortedData[i])>=0 then break; dec(i); end; - fSortedData.InsertObject(i+1,FileN, fOriginalData.Objects[Origi]); + fSortedData.InsertObject(i+1,s, fOriginalData.Objects[Origi]); end; end; end; @@ -374,13 +374,23 @@ end; function TTreeFilterEdit.FilterTree(Node: TTreeNode): Boolean; // Filter all tree branches recursively, setting Node.Visible as needed. // Returns True if Node or its siblings or child nodes have visible items. +var + ChildVisible: Boolean; + Pass, Done: Boolean; begin Result:=False; + Done:=False; while Node<>nil do begin + // Call OnFilterItem handler. + Pass:=False; + if Assigned(OnFilterItem) then + Pass:=OnFilterItem(TObject(Node.Data), Done); + // Filter by item's title text if needed. + if not (Pass or Done) then + Pass:=(Filter='') or (Pos(Filter,lowercase(Node.Text))>0); // Recursive call for child nodes. - Node.Visible:=FilterTree(Node.GetFirstChild) - or (Filter='') or (Pos(Filter,lowercase(Node.Text))>0); + Node.Visible:=FilterTree(Node.GetFirstChild) or Pass; if Node.Visible then Result:=True; Node:=Node.GetNextSibling; @@ -409,7 +419,7 @@ begin for i:=0 to fBranches.Count-1 do fBranches[i].SortAndFilter; end - else begin // Filter the whole tree. + else begin // Filter the whole tree (done in ApplyFilterCore). // end; end; diff --git a/ide/ideoptionsdlg.lfm b/ide/ideoptionsdlg.lfm index 60cddd65cb..dee366d201 100644 --- a/ide/ideoptionsdlg.lfm +++ b/ide/ideoptionsdlg.lfm @@ -1,8 +1,9 @@ -object IDEOptionsDialog: TIDEOptionsDialog - Left = 317 +inherited IDEOptionsDialog: TIDEOptionsDialog + Left = 318 Height = 500 - Top = 304 + Top = 182 Width = 700 + ActiveControl = CatTVSplitter BorderIcons = [biSystemMenu] Caption = 'IDEOptionsDialog' ClientHeight = 500 @@ -11,53 +12,84 @@ object IDEOptionsDialog: TIDEOptionsDialog Constraints.MinWidth = 700 OnShow = FormShow Position = poScreenCenter - LCLVersion = '0.9.31' - object ButtonPanel: TButtonPanel + object ButtonPanel: TButtonPanel[0] AnchorSideLeft.Control = Owner AnchorSideRight.Control = Owner AnchorSideRight.Side = asrBottom AnchorSideBottom.Control = Owner Left = 6 - Height = 34 - Top = 460 + Height = 38 + Top = 456 Width = 688 BorderSpacing.Left = 6 BorderSpacing.Right = 6 BorderSpacing.Bottom = 6 BorderSpacing.Around = 0 OKButton.Name = 'OKButton' + OKButton.DefaultCaption = True HelpButton.Name = 'HelpButton' + HelpButton.DefaultCaption = True CloseButton.Name = 'CloseButton' + CloseButton.DefaultCaption = True CloseButton.Enabled = False CancelButton.Name = 'CancelButton' - TabOrder = 1 + CancelButton.DefaultCaption = True + TabOrder = 0 ShowButtons = [pbOK, pbCancel, pbHelp] end - object CategoryTree: TTreeView - AnchorSideLeft.Control = Owner - AnchorSideTop.Control = Owner - AnchorSideBottom.Control = ButtonPanel - Left = 6 - Height = 454 - Top = 6 - Width = 206 - Align = alLeft - BorderSpacing.Left = 6 - BorderSpacing.Top = 6 - Constraints.MinWidth = 206 - DefaultItemHeight = 17 - ReadOnly = True - TabOrder = 0 - OnChange = CategoryTreeChange - OnCollapsed = CategoryTreeCollapsed - OnExpanded = CategoryTreeExpanded - OnKeyDown = CategoryTreeKeyDown - Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] - end - object CatTVSplitter: TSplitter - Left = 212 - Height = 460 + object CatTVSplitter: TSplitter[1] + Left = 234 + Height = 456 Top = 0 Width = 5 end + object Panel1: TPanel[2] + Left = 0 + Height = 456 + Top = 0 + Width = 234 + Align = alLeft + ClientHeight = 456 + ClientWidth = 234 + TabOrder = 2 + object CategoryTree: TTreeView + AnchorSideLeft.Control = FilterEdit + AnchorSideTop.Control = FilterEdit + AnchorSideTop.Side = asrBottom + AnchorSideRight.Control = Panel1 + AnchorSideRight.Side = asrBottom + AnchorSideBottom.Control = Panel1 + AnchorSideBottom.Side = asrBottom + Left = 7 + Height = 410 + Top = 39 + Width = 220 + Anchors = [akTop, akLeft, akRight, akBottom] + BorderSpacing.Top = 6 + BorderSpacing.Right = 6 + BorderSpacing.Bottom = 6 + Constraints.MinWidth = 206 + ReadOnly = True + TabOrder = 0 + OnChange = CategoryTreeChange + OnCollapsed = CategoryTreeCollapsed + OnExpanded = CategoryTreeExpanded + OnKeyDown = CategoryTreeKeyDown + Options = [tvoAutoItemHeight, tvoHideSelection, tvoKeepCollapsedNodes, tvoReadOnly, tvoShowButtons, tvoShowLines, tvoShowRoot, tvoToolTips, tvoThemedDraw] + end + object FilterEdit: TTreeFilterEdit + AnchorSideLeft.Control = Panel1 + Left = 7 + Height = 25 + Top = 8 + Width = 136 + OnFilterItem = FilterEditFilterItem + ButtonWidth = 23 + NumGlyphs = 0 + BorderSpacing.Left = 6 + MaxLength = 0 + TabOrder = 1 + FilteredTreeview = CategoryTree + end + end end diff --git a/ide/ideoptionsdlg.pas b/ide/ideoptionsdlg.pas index be97f04427..ef937e93d5 100644 --- a/ide/ideoptionsdlg.pas +++ b/ide/ideoptionsdlg.pas @@ -34,7 +34,7 @@ uses Buttons, ButtonPanel, ExtCtrls, IDEWindowIntf, IDEOptionsIntf, IDECommands, IDEHelpIntf, EnvironmentOpts, LazarusIDEStrConsts, - EditorOptions; + EditorOptions, TreeFilterEdit, EditBtn; type TIDEOptsDlgAction = ( @@ -51,10 +51,13 @@ type ButtonPanel: TButtonPanel; CategoryTree: TTreeView; CatTVSplitter: TSplitter; + Panel1: TPanel; + FilterEdit: TTreeFilterEdit; procedure CategoryTreeChange(Sender: TObject; Node: TTreeNode); procedure CategoryTreeCollapsed(Sender: TObject; Node: TTreeNode); procedure CategoryTreeExpanded(Sender: TObject; Node: TTreeNode); procedure CategoryTreeKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); + function FilterEditFilterItem(Item: TObject; out Done: Boolean): Boolean; procedure FormShow(Sender: TObject); procedure HelpButtonClick(Sender: TObject); procedure IDEOptionsDialogKeyPress(Sender: TObject; var Key: char); @@ -71,6 +74,7 @@ type SelectNode: TTreeNode; NewLastSelected: PIDEOptionsEditorRec; + procedure TraverseSettings(AOptions: TAbstractIDEOptions; anAction: TIDEOptsDlgAction); function CheckValues: boolean; procedure DoOpenEditor(EditorToOpen: TAbstractIDEOptionsEditorClass); procedure LoadIDEOptions(Sender: TObject; AOptions: TAbstractIDEOptions); @@ -82,7 +86,6 @@ type public constructor Create(AOwner: TComponent); override; function ShowModal: Integer; override; - function AddButton: TBitBtn; override; function AddControl(AControlClass: TControlClass): TControl; override; procedure OpenEditor(AEditor: TAbstractIDEOptionsEditorClass); override; @@ -90,10 +93,9 @@ type function FindEditor(AEditor: TAbstractIDEOptionsEditorClass): TAbstractIDEOptionsEditor; override; function FindEditor(GroupIndex, AIndex: integer): TAbstractIDEOptionsEditor; override; function FindEditorClass(GroupIndex, AIndex: integer): TAbstractIDEOptionsEditorClass; override; - procedure TraverseSettings(AOptions: TAbstractIDEOptions; anAction: TIDEOptsDlgAction); procedure ReadAll; procedure WriteAll(Restore: boolean); - + public property OptionsFilter: TIDEOptionsEditorFilter read FOptionsFilter write FOptionsFilter; property Settings: TIDEOptionsEditorSettings read FSettings write SetSettings; property OnLoadIDEOptions: TOnLoadIDEOptions read FOnLoadOptions write FOnLoadOptions; @@ -142,17 +144,18 @@ begin debugln(['TIDEOptionsDialog.IDEOptionsDialogKeyPress ',ord(Key)]); end; -procedure TIDEOptionsDialog.CategoryTreeChange(Sender: TObject; - Node: TTreeNode); +procedure TIDEOptionsDialog.CategoryTreeChange(Sender: TObject; Node: TTreeNode); var AEditor: TAbstractIDEOptionsEditor; begin + if Node = nil then Exit; while Node <> nil do begin if Node.Data <> nil then break; Node := Node.GetFirstChild; end; + if Node.Data = nil then Exit; AEditor := TAbstractIDEOptionsEditor(Node.Data); NewLastSelected := AEditor.Rec; @@ -203,6 +206,17 @@ begin end; end; +function TIDEOptionsDialog.FilterEditFilterItem(Item: TObject; out Done: Boolean): Boolean; +var + OptEditor: TAbstractIDEOptionsEditor; +begin + Result:=False; + Done:=False; // Filter will use also the node caption. + if Item=nil then Exit; + OptEditor:=TAbstractIDEOptionsEditor(Item); + Result:=OptEditor.ContainsTextInCaption(FilterEdit.Filter); +end; + procedure TIDEOptionsDialog.FormShow(Sender: TObject); begin // make the category visible in the treeview diff --git a/ideintf/ideoptionsintf.pas b/ideintf/ideoptionsintf.pas index 5d2a0f7381..e4ec6b05a9 100644 --- a/ideintf/ideoptionsintf.pas +++ b/ideintf/ideoptionsintf.pas @@ -25,7 +25,7 @@ unit IDEOptionsIntf; interface uses - Classes, SysUtils, LCLProc, Controls, Buttons, Forms; + Classes, SysUtils, LCLProc, Controls, Buttons, Forms, StdCtrls, Graphics; const NoParent = -1; @@ -122,6 +122,7 @@ type class function SupportedOptionsClass: TAbstractIDEOptionsClass; virtual; abstract; class function DefaultCollapseChildNodes: Boolean; virtual; function FindOptionControl(AClass: TControlClass): TControl; + function ContainsTextInCaption(AText: string): Boolean; property OnLoadIDEOptions: TOnLoadIDEOptions read FOnLoadIDEOptions write FOnLoadIDEOptions; property OnSaveIDEOptions: TOnSaveIDEOptions read FOnSaveIDEOptions write FOnSaveIDEOptions; @@ -389,8 +390,7 @@ begin Result := True; end; -procedure TAbstractIDEOptionsEditor.RestoreSettings( - AOptions: TAbstractIDEOptions); +procedure TAbstractIDEOptionsEditor.RestoreSettings(AOptions: TAbstractIDEOptions); begin end; @@ -400,8 +400,7 @@ begin Result := False; end; -function TAbstractIDEOptionsEditor.FindOptionControl(AClass: TControlClass - ): TControl; +function TAbstractIDEOptionsEditor.FindOptionControl(AClass: TControlClass): TControl; function Search(AControl: TControl): TControl; var @@ -424,6 +423,43 @@ begin Result:=Search(GetParentForm(Self)); end; +function TAbstractIDEOptionsEditor.ContainsTextInCaption(AText: string): Boolean; +const + FoundColor = clFuchsia; +var + UpperText: String; + + function Search(AControl: TControl): Boolean; + var + i: Integer; + AWinControl: TWinControl; + begin + if Pos(UpperText, Uppercase(AControl.Caption))>0 then begin + //if Length(UpperText)>2 then + // DebugLn('TAbstractIDEOptionsEditor.ContainsTextInCaption: Searching "', UpperText, + // '", Found "', AControl.Caption, '", in ', AControl.Name); + AControl.Font.Color:=FoundColor; + exit(True); + end + else if AControl.Font.Color=FoundColor then + AControl.Font.Color:=clDefault; + if AControl is TWinControl then begin + AWinControl:=TWinControl(AControl); + for i:=0 to AWinControl.ControlCount-1 do + // Memo.Caption return all the lines, skip it. + if not (AWinControl.Controls[i] is TMemo) then begin + Result:=Search(AWinControl.Controls[i]); // Recursive call + if Result then exit; + end; + end; + Result:=False; + end; + +begin + UpperText:=Uppercase(AText); + Result:=Search(Self); +end; + { TIDEOptionsEditorList } function TIDEOptionsEditorList.GetItem(AIndex: Integer): PIDEOptionsEditorRec;