mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
404 lines
13 KiB
ObjectPascal
404 lines
13 KiB
ObjectPascal
{
|
|
Double Commander
|
|
-------------------------------------------------------------------------
|
|
Content plugin search control
|
|
|
|
Copyright (C) 2014-2023 Alexander Koblov (alexx2000@mail.ru)
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
}
|
|
|
|
unit uSearchContent;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils, Controls, StdCtrls, ExtCtrls, LCLType, uFindFiles;
|
|
|
|
type
|
|
|
|
{ TPluginPanel }
|
|
|
|
TPluginPanel = class(TPanel)
|
|
private
|
|
FComboPlugin,
|
|
FComboField, // <---The text of this combo is filled from localized string. The "objects" pointed from the its list are "TWdxField" type.
|
|
FComboOperator,
|
|
FComboValue,
|
|
FComboUnit: TComboBox;
|
|
private
|
|
function GetCompare: TPluginOperator;
|
|
function GetField: String;
|
|
function GetFieldType: Integer;
|
|
function GetPlugin: String;
|
|
function GetUnitName: String;
|
|
function GetValue: Variant;
|
|
procedure PluginChange(Sender: TObject);
|
|
procedure FieldChange(Sender: TObject);
|
|
procedure SetCompare(AValue: TPluginOperator);
|
|
procedure SetField(AValue: String);
|
|
procedure SetPlugin(AValue: String);
|
|
procedure SetUnitName(AValue: String);
|
|
procedure SetValue(AValue: Variant);
|
|
procedure SetComboBox(ComboBox: TComboBox; const Value, Error: String);
|
|
procedure ComboValueKeyPress(Sender: TObject; var Key: Char);
|
|
procedure ComboValueUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
|
public
|
|
constructor Create(TheOwner: TComponent); override;
|
|
destructor Destroy; override;
|
|
public
|
|
property Plugin: String read GetPlugin write SetPlugin;
|
|
property Field: String read GetField write SetField;
|
|
property UnitName: String read GetUnitName write SetUnitName;
|
|
property FieldType: Integer read GetFieldType;
|
|
property Compare: TPluginOperator read GetCompare write SetCompare;
|
|
property Value: Variant read GetValue write SetValue;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
uLng, Variants, WdxPlugin, uGlobs, uWDXModule, Graphics, uShowMsg;
|
|
|
|
{ TPluginPanel }
|
|
|
|
function TPluginPanel.GetCompare: TPluginOperator;
|
|
begin
|
|
Result:= TPluginOperator(PtrInt(FComboOperator.Items.Objects[FComboOperator.ItemIndex]));
|
|
end;
|
|
|
|
function TPluginPanel.GetField: String;
|
|
begin
|
|
Result := TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]).FName;
|
|
end;
|
|
|
|
function TPluginPanel.GetFieldType: Integer;
|
|
begin
|
|
Result := TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]).FType
|
|
end;
|
|
|
|
function TPluginPanel.GetPlugin: String;
|
|
begin
|
|
Result:= FComboPlugin.Text;
|
|
end;
|
|
|
|
function TPluginPanel.GetUnitName: String;
|
|
begin
|
|
if (FComboField.ItemIndex < 0) or (FComboUnit.ItemIndex < 0) then
|
|
Result:= FComboUnit.Text
|
|
else begin
|
|
Result:= TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]).FUnits[FComboUnit.ItemIndex];
|
|
end;
|
|
end;
|
|
|
|
function TPluginPanel.GetValue: Variant;
|
|
var
|
|
WdxField: TWdxField;
|
|
begin
|
|
WdxField:= TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]);
|
|
if (WdxField.FType <> ft_multiplechoice) then
|
|
Result:= StrToVar(FComboValue.Text, WdxField.FType)
|
|
else begin
|
|
Result:= StrToVar(WdxField.FUnits[FComboValue.ItemIndex], WdxField.FType)
|
|
end;
|
|
end;
|
|
|
|
// When a plugin is selected from the plugin combo, we populate the others in cascade.
|
|
// In the field combo, each element references a corresding "TWdxField" object.
|
|
// Since this combo is for the user we populate text of it from localized strings.
|
|
procedure TPluginPanel.PluginChange(Sender: TObject);
|
|
var
|
|
I: Integer;
|
|
Module: TWDXModule;
|
|
begin
|
|
if FComboPlugin.ItemIndex < 0 then Exit;
|
|
|
|
FComboField.Clear;
|
|
Module:= gWdxPlugins.GetWdxModule(FComboPlugin.Text);
|
|
if Assigned(Module) then
|
|
for I:= 0 to Module.FieldList.Count - 1 do
|
|
FComboField.Items.AddObject(TWdxField(Module.FieldList.Objects[I]).LName, TObject(Module.FieldList.Objects[I]));
|
|
|
|
if FComboField.Items.Count > 0 then
|
|
begin
|
|
FComboField.ItemIndex:= 0;
|
|
FieldChange(FComboField);
|
|
end;
|
|
end;
|
|
|
|
procedure TPluginPanel.FieldChange(Sender: TObject);
|
|
var
|
|
WdxField: TWdxField;
|
|
begin
|
|
FComboUnit.Items.Clear;
|
|
FComboValue.Items.Clear;
|
|
FComboOperator.Items.Clear;
|
|
FComboValue.Text:= EmptyStr;
|
|
if (FComboField.ItemIndex < 0) then Exit;
|
|
|
|
WdxField:= TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]);
|
|
|
|
if (WdxField.FType <> FT_MULTIPLECHOICE) then
|
|
begin
|
|
FComboUnit.Items.AddStrings(WdxField.LUnits);
|
|
end;
|
|
FComboUnit.Enabled := (WdxField.FType <> FT_MULTIPLECHOICE) and (FComboUnit.Items.Count > 0);
|
|
if FComboUnit.Enabled then FComboUnit.ItemIndex:= 0;
|
|
|
|
case WdxField.FType of
|
|
FT_NUMERIC_32,
|
|
FT_NUMERIC_64,
|
|
FT_NUMERIC_FLOATING,
|
|
FT_DATE,
|
|
FT_TIME,
|
|
FT_DATETIME:
|
|
begin
|
|
FComboValue.Style:= csDropDown;
|
|
FComboOperator.Items.AddObject('=', TObject(PtrInt(poEqualCaseSensitive)));
|
|
FComboOperator.Items.AddObject('!=', TObject(PtrInt(poNotEqualCaseSensitive)));
|
|
FComboOperator.Items.AddObject('>', TObject(PtrInt(poMore)));
|
|
FComboOperator.Items.AddObject('<', TObject(PtrInt(poLess)));
|
|
FComboOperator.Items.AddObject('>=', TObject(PtrInt(poMoreEqual)));
|
|
FComboOperator.Items.AddObject('<=', TObject(PtrInt(poLessEqual)));
|
|
end;
|
|
FT_BOOLEAN:
|
|
begin
|
|
FComboValue.Items.Add(rsSimpleWordTrue);
|
|
FComboValue.Items.Add(rsSimpleWordFalse);
|
|
FComboValue.ItemIndex:= 0;
|
|
FComboValue.Style:= csDropDownList;
|
|
FComboOperator.Items.AddObject('=', TObject(PtrInt(poEqualCaseSensitive)));
|
|
end;
|
|
FT_MULTIPLECHOICE:
|
|
begin
|
|
begin
|
|
FComboValue.Style:= csDropDownList;
|
|
FComboOperator.Items.AddObject('=', TObject(PtrInt(poEqualCaseSensitive)));
|
|
FComboOperator.Items.AddObject('!=', TObject(PtrInt(poNotEqualCaseSensitive)));
|
|
FComboValue.Items.AddStrings(WdxField.LUnits);
|
|
if FComboValue.Items.Count > 0 then FComboValue.ItemIndex:= 0;
|
|
end;
|
|
end;
|
|
FT_STRING,
|
|
FT_STRINGW:
|
|
begin
|
|
FComboValue.Style:= csDropDown;
|
|
FComboOperator.Items.AddObject(rsPluginSearchEqualNotCase, TObject(PtrInt(poEqualCaseInsensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchNotEqualNotCase, TObject(PtrInt(poNotEqualCaseInsensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchEqualCaseSensitive, TObject(PtrInt(poEqualCaseSensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchNotEquaCaseSensitive, TObject(PtrInt(poNotEqualCaseSensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchContainsNotCase, TObject(PtrInt(poContainsCaseInsensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchNotContainsNotCase, TObject(PtrInt(poNotContainsCaseInsensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchContainsCaseSenstive, TObject(PtrInt(poContainsCaseSensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchNotContainsCaseSenstive, TObject(PtrInt(poNotContainsCaseSensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchRegExpr, TObject(PtrInt(poRegExpr)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchNotRegExpr, TObject(PtrInt(poNotRegExpr)));
|
|
end;
|
|
FT_FULLTEXT,
|
|
FT_FULLTEXTW:
|
|
begin
|
|
FComboValue.Style:= csDropDown;
|
|
FComboOperator.Items.AddObject(rsPluginSearchContainsNotCase, TObject(PtrInt(poContainsCaseInsensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchNotContainsNotCase, TObject(PtrInt(poNotContainsCaseInsensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchContainsCaseSenstive, TObject(PtrInt(poContainsCaseSensitive)));
|
|
FComboOperator.Items.AddObject(rsPluginSearchNotContainsCaseSenstive, TObject(PtrInt(poNotContainsCaseSensitive)));
|
|
end;
|
|
end;
|
|
if FComboOperator.Items.Count > 0 then FComboOperator.ItemIndex:= 0;
|
|
end;
|
|
|
|
procedure TPluginPanel.SetCompare(AValue: TPluginOperator);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index:= FComboOperator.Items.IndexOfObject(TObject(PtrInt(AValue)));
|
|
if Index >= 0 then FComboOperator.ItemIndex:= Index;
|
|
end;
|
|
|
|
// The "AValue" parameter received here is not localized.
|
|
// We can't search it in combo box directly so we go by index.
|
|
procedure TPluginPanel.SetField(AValue: String);
|
|
var
|
|
Module: TWDXModule;
|
|
begin
|
|
Module := gWdxPlugins.GetWdxModule(FComboPlugin.Text);
|
|
if Module = nil then exit;
|
|
|
|
FComboField.ItemIndex := Module.GetFieldIndex(AValue);
|
|
if FComboField.ItemIndex <> -1 then
|
|
begin
|
|
if Assigned(FComboField.OnChange) then FComboField.OnChange(FComboField);
|
|
end
|
|
else begin
|
|
msgError(rsPluginSearchFieldNotFound);
|
|
end;
|
|
end;
|
|
|
|
procedure TPluginPanel.SetPlugin(AValue: String);
|
|
begin
|
|
SetComboBox(FComboPlugin, AValue, Format(rsPluginSearchPluginNotFound, [AValue]));
|
|
end;
|
|
|
|
procedure TPluginPanel.SetUnitName(AValue: String);
|
|
var
|
|
Index: Integer;
|
|
WdxField: TWdxField;
|
|
begin
|
|
if FComboUnit.Enabled then
|
|
begin
|
|
WdxField:= TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]);
|
|
Index := WdxField.GetUnitIndex(AValue);
|
|
if Index >= 0 then AValue:= WdxField.LUnits[Index];
|
|
SetComboBox(FComboUnit, AValue, Format(rsPluginSearchUnitNotFoundForField, [AValue, Self.Field]));
|
|
end;
|
|
end;
|
|
|
|
procedure TPluginPanel.SetValue(AValue: Variant);
|
|
var
|
|
Index: Integer;
|
|
WdxField: TWdxField;
|
|
begin
|
|
if VarIsBool(AValue) then
|
|
begin
|
|
if AValue then
|
|
FComboValue.Text := rsSimpleWordTrue
|
|
else
|
|
FComboValue.Text := rsSimpleWordFalse;
|
|
end
|
|
else begin
|
|
WdxField:= TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]);
|
|
if (WdxField.FType <> FT_MULTIPLECHOICE) then
|
|
FComboValue.Text := AValue
|
|
else begin
|
|
Index:= WdxField.GetUnitIndex(AValue);
|
|
if Index < 0 then
|
|
FComboValue.Text := AValue
|
|
else
|
|
FComboValue.Text := WdxField.LUnits[Index];
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TPluginPanel.SetComboBox(ComboBox: TComboBox; const Value, Error: String);
|
|
var
|
|
Index: Integer;
|
|
begin
|
|
Index:= ComboBox.Items.IndexOf(Value);
|
|
if Index < 0 then
|
|
msgError(Error)
|
|
else begin
|
|
ComboBox.ItemIndex:= Index;
|
|
if Assigned(ComboBox.OnChange) then ComboBox.OnChange(ComboBox);
|
|
end;
|
|
end;
|
|
|
|
procedure TPluginPanel.ComboValueKeyPress(Sender: TObject; var Key: Char);
|
|
var
|
|
WdxField: TWdxField;
|
|
begin
|
|
if (FComboField.ItemIndex < 0) then Exit;
|
|
WdxField:= TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]);
|
|
case WdxField.FType of
|
|
FT_NUMERIC_32,
|
|
FT_NUMERIC_64:
|
|
begin
|
|
if not (Key in ['0'..'9', Chr(VK_BACK)]) then
|
|
Key:= #0;
|
|
end;
|
|
FT_NUMERIC_FLOATING:
|
|
begin
|
|
if not (Key in ['0'..'9', Chr(VK_BACK), DefaultFormatSettings.DecimalSeparator]) then
|
|
Key:= #0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TPluginPanel.ComboValueUTF8KeyPress(Sender: TObject; var UTF8Key: TUTF8Char);
|
|
var
|
|
WdxField: TWdxField;
|
|
begin
|
|
if (FComboField.ItemIndex < 0) then Exit;
|
|
WdxField:= TWdxField(FComboField.Items.Objects[FComboField.ItemIndex]);
|
|
case WdxField.FType of
|
|
FT_NUMERIC_32,
|
|
FT_NUMERIC_64,
|
|
FT_NUMERIC_FLOATING:
|
|
begin
|
|
if (Length(UTF8Key) > 1) then UTF8Key:= #0;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
constructor TPluginPanel.Create(TheOwner: TComponent);
|
|
var
|
|
I: Integer;
|
|
begin
|
|
inherited Create(TheOwner);
|
|
AutoSize:= True;
|
|
BevelOuter:= bvNone;
|
|
ChildSizing.ControlsPerLine:= 5;
|
|
ChildSizing.Layout:= cclLeftToRightThenTopToBottom;
|
|
ChildSizing.EnlargeHorizontal:= crsScaleChilds;
|
|
|
|
FComboPlugin:= TComboBox.Create(Self);
|
|
FComboPlugin.Parent:= Self;
|
|
FComboPlugin.Style:= csDropDownList;
|
|
FComboPlugin.OnChange:= @PluginChange;
|
|
|
|
FComboField:= TComboBox.Create(Self);
|
|
FComboField.Parent:= Self;
|
|
FComboField.Style:= csDropDownList;
|
|
FComboField.OnChange:= @FieldChange;
|
|
|
|
FComboOperator:= TComboBox.Create(Self);
|
|
FComboOperator.Parent:= Self;
|
|
FComboOperator.Style:= csDropDownList;
|
|
|
|
FComboValue:= TComboBox.Create(Self);
|
|
FComboValue.OnKeyPress:= @ComboValueKeyPress;
|
|
FComboValue.OnUTF8KeyPress:= @ComboValueUTF8KeyPress;
|
|
FComboValue.Parent:= Self;
|
|
|
|
FComboUnit:= TComboBox.Create(Self);
|
|
FComboUnit.Style:= csDropDownList;
|
|
FComboUnit.Parent:= Self;
|
|
|
|
for I:= 0 to gWDXPlugins.Count - 1do
|
|
begin
|
|
if gWdxPlugins.GetWdxModule(I).IsLoaded or gWdxPlugins.GetWdxModule(I).LoadModule then
|
|
begin
|
|
FComboPlugin.Items.Add(gWdxPlugins.GetWdxModule(I).Name);
|
|
end;
|
|
end;
|
|
if FComboPlugin.Items.Count > 0 then
|
|
begin
|
|
FComboPlugin.ItemIndex:= 0;
|
|
PluginChange(FComboPlugin);
|
|
end;
|
|
end;
|
|
|
|
destructor TPluginPanel.Destroy;
|
|
begin
|
|
FComboPlugin.Free;
|
|
FComboField.Free;
|
|
FComboOperator.Free;
|
|
FComboValue.Free;
|
|
FComboUnit.Free;
|
|
inherited Destroy;
|
|
end;
|
|
|
|
end.
|
|
|