lazarus/ide/optionseditorbase.pas
2007-11-14 02:28:30 +00:00

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.