mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-05-01 03:43:53 +02:00
462 lines
10 KiB
ObjectPascal
462 lines
10 KiB
ObjectPascal
unit OptionsEditorBase;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, LResources, Forms, Controls, Graphics, Dialogs, StdCtrls,
|
|
Buttons, ComCtrls, ExtCtrls;
|
|
|
|
type
|
|
|
|
{ TStringIndexItem }
|
|
|
|
TStringIndexItem = class
|
|
Name, Value: String;
|
|
Next: TStringIndexItem;
|
|
|
|
constructor Create;
|
|
constructor Create(AName, AValue: string);
|
|
end;
|
|
|
|
{ TStringIndex }
|
|
TStringIndex = class
|
|
Last, First: TStringIndexItem;
|
|
|
|
constructor Create;
|
|
destructor Destroy;override;
|
|
|
|
procedure AddItem(ItemName, ItemValue: String);
|
|
procedure RemoveItem(ItemName: String);
|
|
function ItemHasValue(ItemName: String; SubStringValue: String): Boolean;
|
|
function ItemHasValues(Item: String; SubStringValues: TStrings): Boolean;
|
|
|
|
procedure DebugOutFileWords(FileName: String);
|
|
end;
|
|
|
|
{ TOptionsEditorForm }
|
|
|
|
TOptionsEditorForm = class(TForm)
|
|
btnCancel: TBitBtn;
|
|
btnOK: TBitBtn;
|
|
ClearFilterButton: TBitBtn;
|
|
FilterEdit: TEdit;
|
|
HelpButton: TBitBtn;
|
|
Label1: TLabel;
|
|
OptionsAreaPanel: TPanel;
|
|
SectionList: TListBox;
|
|
SectionsTreePanel: TPanel;
|
|
SectionTitleLabel: TLabel;
|
|
BottomPanel: TPanel;
|
|
OKCancelPanel: TPanel;
|
|
CategoriesPanel: TPanel;
|
|
MainSplitter: TSplitter;
|
|
procedure ClearFilterButtonClick(Sender: TObject);
|
|
procedure FilterEditChange(Sender: TObject);
|
|
procedure FilterEditEnter(Sender: TObject);
|
|
procedure FilterEditExit(Sender: TObject);
|
|
procedure FormActivate(Sender: TObject);
|
|
procedure HelpButtonClick(Sender: TObject);
|
|
procedure SearchLabelClick(Sender: TObject);
|
|
procedure SectionListSelectionChange(Sender: TObject; User: boolean);
|
|
private
|
|
{ private declarations }
|
|
FilterText: String;
|
|
|
|
ItemList: TStringList;
|
|
IndexTexts: TStringIndex;
|
|
FilterWords: TStringList;
|
|
|
|
FilterResult: TStringList;
|
|
|
|
LastControl: TWinControl;
|
|
|
|
UpdatePageFromSectionList: Boolean;
|
|
|
|
procedure DoFilter;
|
|
|
|
protected
|
|
procedure ScanControlTextsForIndex(ItemName: String; Item: TWinControl);
|
|
public
|
|
{ public declarations }
|
|
function AddCategoryItem(ItemName: String; ParentItem: String;
|
|
Item: TPanel): Boolean;
|
|
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
procedure RecusiveControlsIndex(const Item: TWinControl;
|
|
const ItemName: String);
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
IDEContextHelpEdit;
|
|
|
|
type
|
|
TCustomNotebookAccess = class(TCustomNotebook)
|
|
end;
|
|
|
|
{ TOptionsEditorForm }
|
|
|
|
procedure TOptionsEditorForm.RecusiveControlsIndex(const Item: TWinControl; const ItemName: String
|
|
);
|
|
var
|
|
NewItem: TControl;
|
|
i: Integer;
|
|
begin
|
|
for i:= 0 to item.ControlCount-1 do
|
|
begin
|
|
NewItem:= item.Controls[i];
|
|
if NewItem <> Nil then
|
|
begin
|
|
if NewItem is TButton then
|
|
begin
|
|
IndexTexts.AddItem(ItemName, (NewItem as TButton).Caption);
|
|
end
|
|
else
|
|
if NewItem is TCheckBox then
|
|
begin
|
|
IndexTexts.AddItem(ItemName, (NewItem as TCheckBox).Caption);
|
|
end
|
|
else
|
|
if NewItem is TRadioButton then
|
|
begin
|
|
IndexTexts.AddItem(ItemName, (NewItem as TRadioButton).Caption);
|
|
end
|
|
else
|
|
if NewItem is TLabel then
|
|
begin
|
|
IndexTexts.AddItem(ItemName, (NewItem as TLabel).Caption);
|
|
end
|
|
else
|
|
if NewItem is TEdit then
|
|
begin
|
|
IndexTexts.AddItem(ItemName, (NewItem as TEdit).Text);
|
|
end
|
|
else
|
|
if (NewItem is TPanel)
|
|
or (NewItem is TGroupBox)
|
|
or (NewItem is TRadioGroup)
|
|
then
|
|
RecusiveControlsIndex(NewItem as TWinControl, ItemName);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.FilterEditChange(Sender: TObject);
|
|
begin
|
|
if FilterEdit.Text = 'text to filter...' then
|
|
begin
|
|
FilterText:= '';
|
|
ClearFilterButton.Visible:= False;
|
|
end
|
|
else
|
|
begin
|
|
FilterText:= FilterEdit.Text;
|
|
FilterEdit.Font.Color:= clText;
|
|
ClearFilterButton.Visible:= (FilterText <> '');
|
|
end;
|
|
DoFilter;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.ClearFilterButtonClick(Sender: TObject);
|
|
begin
|
|
FilterEdit.Text:= '';
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.FilterEditEnter(Sender: TObject);
|
|
begin
|
|
FilterEdit.Text:= FilterText;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.FilterEditExit(Sender: TObject);
|
|
begin
|
|
if FilterText = '' then
|
|
begin
|
|
FilterEdit.Font.Color:= clGrayText;
|
|
FilterEdit.Text:= 'text to filter...';
|
|
end;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.FormActivate(Sender: TObject);
|
|
begin
|
|
DoFilter;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.HelpButtonClick(Sender: TObject);
|
|
begin
|
|
ShowContextHelpForIDE(Self);
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.SearchLabelClick(Sender: TObject);
|
|
begin
|
|
FilterEdit.SetFocus;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.SectionListSelectionChange(Sender: TObject;
|
|
User: boolean);
|
|
var
|
|
selIndex: Integer;
|
|
begin
|
|
if not UpdatePageFromSectionList then
|
|
begin
|
|
Exit;
|
|
end;
|
|
|
|
selIndex:= SectionList.ItemIndex;
|
|
if selIndex = -1 then
|
|
Exit;
|
|
if LastControl <> Nil then
|
|
begin
|
|
LastControl.Visible:= false;
|
|
end;
|
|
LastControl:= SectionList.Items.Objects[selIndex] as TWinControl;
|
|
SectionTitleLabel.Caption:= SectionList.Items[selIndex];
|
|
if (LastControl.Parent is TCustomNotebook) and (LastControl is TCustomPage) then
|
|
TCustomNotebookAccess(LastControl.Parent).ActivePageComponent := TCustomPage(LastControl)
|
|
else
|
|
LastControl.Visible:=True;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.DoFilter;
|
|
var
|
|
FilterTextCopy: String;
|
|
FirstWord: String;
|
|
I: Integer;
|
|
LastIndex, NewIndex: Integer;
|
|
LastText: String;
|
|
begin
|
|
//Create the list of filter words
|
|
FilterWords.Clear;
|
|
FilterTextCopy:= FilterText;
|
|
while FilterTextCopy <> '' do
|
|
begin
|
|
if Pos(' ', FilterTextCopy) = 0 then
|
|
begin
|
|
FilterWords.Add(FilterTextCopy);
|
|
FilterTextCopy:='';
|
|
end
|
|
else
|
|
begin
|
|
FirstWord:= Copy(FilterTextCopy, 1, Pos(' ', FilterTextCopy) - 1);
|
|
if FirstWord <> '' then
|
|
FilterWords.Add(FirstWord);
|
|
Delete(FilterTextCopy, 1, Length(FirstWord) + 1);
|
|
end;
|
|
end;
|
|
LastIndex:= SectionList.ItemIndex;
|
|
if LastIndex <> -1 then
|
|
begin
|
|
LastText:= SectionList.Items[LastIndex];
|
|
end
|
|
else
|
|
begin
|
|
LastText:= '';
|
|
end;
|
|
SectionList.Items.Clear;
|
|
|
|
for I:= 0 to ItemList.Count-1 do
|
|
begin
|
|
if IndexTexts.ItemHasValues(ItemList[i], FilterWords) then
|
|
SectionList.Items.AddObject(ItemList[i], ItemList.Objects[i]);
|
|
end;
|
|
UpdatePageFromSectionList:= False;
|
|
NewIndex :=SectionList.Items.IndexOf(LastText);
|
|
if NewIndex = -1 then
|
|
begin
|
|
if SectionList.Items.Count>0 then
|
|
begin
|
|
SectionList.ItemIndex:= 0;
|
|
end;
|
|
end;
|
|
UpdatePageFromSectionList:= True;
|
|
end;
|
|
|
|
procedure TOptionsEditorForm.ScanControlTextsForIndex(ItemName: String;
|
|
Item: TWinControl);
|
|
begin
|
|
ItemList.AddObject(ItemName, Item);
|
|
|
|
if ItemList.Count = 1 then
|
|
begin
|
|
Item.Visible:= True;
|
|
SectionTitleLabel.Caption:= ItemName;
|
|
end
|
|
else
|
|
begin
|
|
Item.Visible:= False;
|
|
end;
|
|
|
|
//clear all texts for the current item name
|
|
IndexTexts.RemoveItem(ItemName);
|
|
|
|
RecusiveControlsIndex(Item, ItemName);
|
|
IndexTexts.DebugOutFileWords('indexdata.txt');
|
|
DoFilter;
|
|
end;
|
|
|
|
function TOptionsEditorForm.AddCategoryItem(ItemName: String;
|
|
ParentItem: String; Item: TPanel): Boolean;
|
|
begin
|
|
Item.Parent:= OptionsAreaPanel;
|
|
Item.Align:= alClient;
|
|
Result:= True;
|
|
end;
|
|
|
|
constructor TOptionsEditorForm.Create(TheOwner: TComponent);
|
|
begin
|
|
inherited Create(TheOwner);
|
|
LastControl:= nil;
|
|
IndexTexts:= TStringIndex.Create;
|
|
|
|
ItemList:= TStringList.Create;
|
|
FilterResult:= TStringList.Create;
|
|
FilterWords:= TStringList.Create;
|
|
end;
|
|
|
|
destructor TOptionsEditorForm.Destroy;
|
|
begin
|
|
IndexTexts.Free;
|
|
ItemList.Free;
|
|
FilterResult.Free;
|
|
FilterWords.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
{ TStringIndex }
|
|
|
|
constructor TStringIndex.Create;
|
|
begin
|
|
First:= nil;
|
|
Last:= nil;
|
|
end;
|
|
|
|
destructor TStringIndex.Destroy;
|
|
var
|
|
Item, Next: TStringIndexItem;
|
|
begin
|
|
inherited;
|
|
Item:= First;
|
|
while Item <> Nil do
|
|
begin
|
|
Next:= Item.Next;
|
|
Item.Free;
|
|
Item:= Next;
|
|
end;
|
|
end;
|
|
|
|
procedure TStringIndex.AddItem(ItemName, ItemValue: String);
|
|
begin
|
|
ItemValue:= UpperCase(ItemValue);
|
|
if First = Nil then
|
|
begin
|
|
Last:= TStringIndexItem.Create(ItemName, ItemValue);
|
|
First:= Last;
|
|
Exit;
|
|
end;
|
|
Last.Next:= TStringIndexItem.Create(ItemName, ItemValue);
|
|
Last:= Last.Next;
|
|
end;
|
|
|
|
procedure TStringIndex.RemoveItem(ItemName: String);
|
|
var
|
|
ItemToRemove, AuxNode: TStringIndexItem;
|
|
begin
|
|
ItemToRemove:= First;
|
|
while ItemToRemove <> Nil do
|
|
begin
|
|
if ItemToRemove.Name = ItemName then
|
|
begin
|
|
AuxNode:= ItemToRemove.Next;
|
|
ItemToRemove.Free;
|
|
if ItemToRemove = First then
|
|
begin
|
|
First:= AuxNode;
|
|
end;
|
|
ItemToRemove:= AuxNode;
|
|
end
|
|
else
|
|
begin
|
|
ItemToRemove:= ItemToRemove.Next;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
function TStringIndex.ItemHasValue(ItemName: String; SubStringValue: String
|
|
): Boolean;
|
|
var
|
|
ItemToScan: TStringIndexItem;
|
|
begin
|
|
ItemToScan:= First;
|
|
SubStringValue:= UpperCase(SubStringValue);
|
|
while ItemToScan <> nil do
|
|
begin
|
|
if (ItemName = ItemToScan.Name) and (Pos(SubStringValue, ItemToScan.Value)<> 0) then
|
|
begin
|
|
Result:= True;
|
|
Exit;
|
|
end;
|
|
ItemToScan:= ItemToScan.Next;
|
|
end;
|
|
Result:= False;
|
|
end;
|
|
|
|
function TStringIndex.ItemHasValues(Item: String; SubStringValues: TStrings
|
|
): Boolean;
|
|
var
|
|
I: Integer;
|
|
begin
|
|
if SubStringValues.Count = 0 then
|
|
begin
|
|
Result:= True;
|
|
Exit;
|
|
end;
|
|
for I:= 0 to SubStringValues.Count-1 do
|
|
begin
|
|
if not ItemHasValue(Item, SubStringValues[i]) then
|
|
begin
|
|
result:= false;
|
|
Exit;
|
|
end;
|
|
end;
|
|
Result:= True;
|
|
end;
|
|
|
|
procedure TStringIndex.DebugOutFileWords(FileName: String);
|
|
var
|
|
F: TextFile;
|
|
ItemToScan: TStringIndexItem;
|
|
begin
|
|
AssignFile(F, FileName); Rewrite(F);
|
|
ItemToScan:= First;
|
|
while ItemToScan <> Nil do
|
|
begin
|
|
Writeln(F, 'Item: ', ItemToScan.Name, ' Value: ', ItemToScan.Value);
|
|
ItemToScan:= ItemToScan.Next;
|
|
end;
|
|
CloseFile(F);
|
|
end;
|
|
|
|
{ TStringIndexItem }
|
|
|
|
constructor TStringIndexItem.Create;
|
|
begin
|
|
inherited;
|
|
Next:= nil;
|
|
end;
|
|
|
|
constructor TStringIndexItem.Create(Aname, AValue: string);
|
|
begin
|
|
Create;
|
|
Name:= Aname;
|
|
Value:= AValue;
|
|
end;
|
|
|
|
initialization
|
|
{$I optionseditorbase.lrs}
|
|
end.
|
|
|
|
|