doublecmd/src/ftweakplugin.pas
Denis Bisson b3143b2aca CHG: Few modifications regarding plugins configuration.
ADD: Warn the user when attempting to quit the plugin configuration without having saved possible unsaved modification.
ADD: In the plugin configuration table, if a text is too large to fit in a column, a tooltip is displayed showing the complete text.
ADD: Individual configuration pages for DSX, WCX, WDX, WFX and WLX plugins.
ADD: Plugin tweak dialog windows now remember their dimensions from a session to another.
ADD: Double-click on an item in the list of plugins in the configuration now trigs the tweak window for selected plugin.
ADD: When we just add a plugin, it is now the selected one in the list.
ADD: Add an option to go to tweak dialog window right after a plugin in added.
CHG: The path to the plugin is now *loaded*, *displayed* and *saved* as what the user sees.
CHG: The path for the plugin files may now be defined with full relative path based on either windows special folders, environment variables or full complete path. It is not simply on a path deeper than %COMMANDERPATH% like it was before.
ADD: In the plugin tweak dialog window, we now have an actual "TFileNameEdit" with a button and the file requester to select our plugin location.
ADD: In the plugin tweak dialog window, we now have a button with a popup menu to help to adapt the path of the plugin location like to make it relative to a specified location.
ADD: There is now an option to make DC automatically use relative path to what we want when we add a plugin file. We may also apply that retro-active.
ADD: In the plugin configuration, do not display a column if not pertinent (like column 2 in WFX).
ADD: In the WCX plugin configuration window, we may display plugins grouped by plugin file or by file extension as they appear in config file AND how they are actually used when searching for a qualified one.
ADD: Add the internal command "cm_ConfigPlugins".
FIX: Added WCX plugin associated with an empty extension was not displayed at first in the grid and needed to close and reopen the configuration window. This is fixed.
FIX: Adding a file extension associated with a WCX plugin in the tweaking window from a WCX where previously *just one* extension was associated was not switching enabled the "Remove" button. This is fixed.
UPD: Languages files have been modified, but efforts have been made to re-use existing translations and to avoid "fuzzy" attributes.
2018-11-03 20:17:43 +00:00

411 lines
13 KiB
ObjectPascal

{
Double commander
-------------------------------------------------------------------------
Plugin tweak window
Copyright (C) 2008-2018 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
}
unit fTweakPlugin;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, Forms, Controls, ExtCtrls, StdCtrls, EditBtn, Buttons,
Menus, uWCXModule, uGlobs;
type
{ TfrmTweakPlugin }
TfrmTweakPlugin = class(TForm)
btnAdd: TButton;
btnCancel: TButton;
btnChange: TButton;
btnDefault: TButton;
btnOK: TButton;
btnRelativePlugin2: TSpeedButton;
btnRelativePlugin1: TSpeedButton;
btnRemove: TButton;
cbExt: TComboBox;
cbPK_CAPS_BY_CONTENT: TCheckBox;
cbPK_CAPS_DELETE: TCheckBox;
cbPK_CAPS_ENCRYPT: TCheckBox;
cbPK_CAPS_HIDE: TCheckBox;
cbPK_CAPS_MEMPACK: TCheckBox;
cbPK_CAPS_MODIFY: TCheckBox;
cbPK_CAPS_MULTIPLE: TCheckBox;
cbPK_CAPS_NEW: TCheckBox;
cbPK_CAPS_OPTIONS: TCheckBox;
cbPK_CAPS_SEARCHTEXT: TCheckBox;
edtDescription: TEdit;
edtDetectStr: TEdit;
edtName: TEdit;
fnePlugin2: TFileNameEdit;
fnePlugin1: TFileNameEdit;
pmPathHelper: TPopupMenu;
pnlTweakOther: TPanel;
lblDescription: TLabel;
lblDetectStr: TLabel;
lblName: TLabel;
lblExtension: TLabel;
lblFlags: TLabel;
lblFlagsValue: TLabel;
lblPlugin2: TLabel;
lblPackerPlugin: TLabel;
lblPlugin: TLabel;
nbTweakAll: TNotebook;
pnlButtons: TPanel;
pnlFlags: TPanel;
pnlPackerExtsButtons: TPanel;
pgTweakPacker: TPage;
pgTweakOther: TPage;
pnlTweak: TPanel;
procedure btnAddClick(Sender: TObject);
procedure btnChangeClick(Sender: TObject);
procedure btnDefaultClick(Sender: TObject);
procedure btnRelativePlugin1Click(Sender: TObject);
procedure btnRelativePlugin2Click(Sender: TObject);
procedure btnRemoveClick(Sender: TObject);
procedure cbExtChange(Sender: TObject);
procedure cbPackerFlagsClick(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
FWCXPlugins: TWCXModuleList;
FPluginFileName: String;
iPrevIndex: Integer;
function GetDefaultFlags(PluginFileName: String): PtrInt;
public
constructor Create(TheOwner: TComponent); override;
procedure LoadConfiguration(PluginIndex:integer);
procedure SaveConfiguration(PluginIndex:integer);
destructor Destroy; override;
end;
function ShowTweakPluginDlg(PluginType: TPluginType; PluginIndex: Integer): Boolean;
implementation
{$R *.lfm}
uses
//Lazarus, Free-Pascal, etc.
Math, Dialogs, LCLVersion,
//DC
fOptionsPluginsDSX, fOptionsPluginsWCX, fOptionsPluginsWDX,
fOptionsPluginsWFX, fOptionsPluginsWLX, WcxPlugin, uDCUtils, uLng,
uSpecialDir;
function ShowTweakPluginDlg(PluginType: TPluginType; PluginIndex: Integer): Boolean;
var
I, iIndex: Integer;
begin
with TfrmTweakPlugin.Create(Application) do
try
case PluginType of
ptDSX:
begin
nbTweakAll.PageIndex:= 1;
fnePlugin2.Text:= tmpDSXPlugins.GetDsxModule(PluginIndex).FileName;
edtDescription.Text:= tmpDSXPlugins.GetDsxModule(PluginIndex).Descr;
edtName.Text:= tmpDSXPlugins.GetDsxModule(PluginIndex).Name;
lblDetectStr.Visible:= False;
edtDetectStr.Visible:= False;
ActiveControl:=fnePlugin2;
end;
ptWCX:
begin
nbTweakAll.PageIndex:= 0;
FWCXPlugins:= TWCXModuleList.Create;
FWCXPlugins.Assign(tmpWCXPlugins);
FPluginFileName := FWCXPlugins.FileName[PluginIndex];
fnePlugin1.FileName:= FPluginFileName;
for I:= 0 to FWCXPlugins.Count - 1 do
if FWCXPlugins.FileName[I] = fnePlugin1.FileName then
begin
if cbExt.Items.Count=0 then lblPlugin.Tag:=IfThen(FWCXPlugins.Enabled[I],1,0);
cbExt.Items.AddObject(FWCXPlugins.Ext[I], TObject(FWCXPlugins.Flags[I]));
end;
iPrevIndex:= -1;
cbExt.ItemIndex := cbExt.Items.IndexOf(FWCXPlugins.Ext[PluginIndex]);
if (cbExt.ItemIndex = -1) then cbExt.ItemIndex := 0;
cbExtChange(cbExt);
btnRemove.Enabled:= (cbExt.Items.Count > 1);
end;
ptWDX:
begin
nbTweakAll.PageIndex:= 1;
fnePlugin2.Text:= tmpWDXPlugins.GetWdxModule(PluginIndex).FileName;
edtDetectStr.Text:= tmpWDXPlugins.GetWdxModule(PluginIndex).DetectStr;
edtName.Text:= tmpWDXPlugins.GetWdxModule(PluginIndex).Name;
lblDescription.Visible:= False;
edtDescription.Visible:= False;
ActiveControl:=fnePlugin2;
end;
ptWFX:
begin
nbTweakAll.PageIndex:= 1;
fnePlugin2.Text:= tmpWFXPlugins.FileName[PluginIndex];
edtName.Text:= tmpWFXPlugins.Name[PluginIndex];
lblDetectStr.Visible:= False;
edtDetectStr.Visible:= False;
lblDescription.Visible:= False;
edtDescription.Visible:= False;
ActiveControl:=fnePlugin2;
end;
ptWLX:
begin
nbTweakAll.PageIndex:= 1;
fnePlugin2.Text:= tmpWLXPlugins.GetWlxModule(PluginIndex).FileName;
edtDetectStr.Text:= tmpWLXPlugins.GetWlxModule(PluginIndex).DetectStr;
edtName.Text:= tmpWLXPlugins.GetWlxModule(PluginIndex).Name;
lblDescription.Visible:= False;
edtDescription.Visible:= False;
ActiveControl:=fnePlugin2;
end;
end;
LoadConfiguration(ord(PluginType));
gSpecialDirList.PopulateMenuWithSpecialDir(pmPathHelper,mp_PATHHELPER,nil);
Result:= (ShowModal = mrOK);
if Result then
case PluginType of
ptDSX:
begin
tmpDSXPlugins.GetDsxModule(PluginIndex).FileName:= fnePlugin2.Text;
tmpDSXPlugins.GetDsxModule(PluginIndex).Descr := edtDescription.Text;
tmpDSXPlugins.GetDsxModule(PluginIndex).Name:= edtName.Text;
end;
ptWCX:
begin
for I:= 0 to cbExt.Items.Count - 1 do
begin
iIndex:= FWCXPlugins.Find(FPluginFileName, cbExt.Items[I]);
if iIndex >= 0 then
begin
FWCXPlugins.FileName[iIndex]:= fnePlugin1.FileName;
FWCXPlugins.Flags[iIndex]:= PtrInt(cbExt.Items.Objects[I]);
end;
end;
tmpWCXPlugins.Assign(FWCXPlugins);
end;
ptWDX:
begin
tmpWDXPlugins.GetWdxModule(PluginIndex).FileName:= fnePlugin2.Text;
tmpWDXPlugins.GetWdxModule(PluginIndex).DetectStr:= edtDetectStr.Text;
tmpWDXPlugins.GetWdxModule(PluginIndex).Name:= edtName.Text;
end;
ptWFX:
begin
tmpWFXPlugins.FileName[PluginIndex]:= fnePlugin2.Text;
tmpWFXPlugins.Name[PluginIndex]:= edtName.Text;
end;
ptWLX:
begin
tmpWLXPlugins.GetWlxModule(PluginIndex).FileName:= fnePlugin2.Text;
tmpWLXPlugins.GetWlxModule(PluginIndex).DetectStr:= edtDetectStr.Text;
tmpWLXPlugins.GetWlxModule(PluginIndex).Name:= edtName.Text;
end;
end;
SaveConfiguration(ord(PluginType));
finally
Free;
end;
end;
{ TfrmTweakPlugin }
constructor TfrmTweakPlugin.Create(TheOwner: TComponent);
begin
FWCXPlugins := nil;
iPrevIndex := -1;
inherited;
end;
{ TfrmTweakPlugin.LoadConfiguration }
// Just to save width.
// Firt time it opens according to "autosize" system will determine, then when we exit it will be saved and then it will be restore to next session.
procedure TfrmTweakPlugin.LoadConfiguration(PluginIndex:integer);
begin
if (gTweakPluginWidth[PluginIndex]<>0) AND (gTweakPluginHeight[PluginIndex]<>0) then
begin
AutoSize:=False;
width := gTweakPluginWidth[PluginIndex];
height := gTweakPluginHeight[PluginIndex];
end;
end;
procedure TfrmTweakPlugin.SaveConfiguration(PluginIndex:integer);
begin
gTweakPluginWidth[PluginIndex] := width;
gTweakPluginHeight[PluginIndex] := height;
end;
destructor TfrmTweakPlugin.Destroy;
begin
inherited;
if Assigned(FWCXPlugins) then
FreeAndNil(FWCXPlugins);
end;
procedure TfrmTweakPlugin.cbExtChange(Sender: TObject);
var
iFlags: PtrInt;
begin
iPrevIndex:= cbExt.ItemIndex;
iFlags:= PtrInt(cbExt.Items.Objects[cbExt.ItemIndex]);
lblFlagsValue.Caption:= '('+IntToStr(iFlags)+')';
cbPK_CAPS_NEW.Checked := (iFlags and PK_CAPS_NEW) <> 0;
cbPK_CAPS_MODIFY.Checked := (iFlags and PK_CAPS_MODIFY) <> 0;
cbPK_CAPS_MULTIPLE.Checked := (iFlags and PK_CAPS_MULTIPLE) <> 0;
cbPK_CAPS_DELETE.Checked := (iFlags and PK_CAPS_DELETE) <> 0;
cbPK_CAPS_OPTIONS.Checked := (iFlags and PK_CAPS_OPTIONS) <> 0;
cbPK_CAPS_MEMPACK.Checked := (iFlags and PK_CAPS_MEMPACK) <> 0;
cbPK_CAPS_BY_CONTENT.Checked := (iFlags and PK_CAPS_BY_CONTENT) <> 0;
cbPK_CAPS_SEARCHTEXT.Checked := (iFlags and PK_CAPS_SEARCHTEXT) <> 0;
cbPK_CAPS_HIDE.Checked := (iFlags and PK_CAPS_HIDE) <> 0;
cbPK_CAPS_ENCRYPT.Checked := (iFlags and PK_CAPS_ENCRYPT) <> 0;
end;
procedure TfrmTweakPlugin.cbPackerFlagsClick(Sender: TObject);
var
iFlags: PtrInt;
begin
if iPrevIndex >= 0 then // save new flags
begin
iFlags:= 0;
if cbPK_CAPS_NEW.Checked then
iFlags:= iFlags or PK_CAPS_NEW;
if cbPK_CAPS_MODIFY.Checked then
iFlags:= iFlags or PK_CAPS_MODIFY;
if cbPK_CAPS_MULTIPLE.Checked then
iFlags:= iFlags or PK_CAPS_MULTIPLE;
if cbPK_CAPS_DELETE.Checked then
iFlags:= iFlags or PK_CAPS_DELETE;
if cbPK_CAPS_OPTIONS.Checked then
iFlags:= iFlags or PK_CAPS_OPTIONS;
if cbPK_CAPS_MEMPACK.Checked then
iFlags:= iFlags or PK_CAPS_MEMPACK;
if cbPK_CAPS_BY_CONTENT.Checked then
iFlags:= iFlags or PK_CAPS_BY_CONTENT;
if cbPK_CAPS_SEARCHTEXT.Checked then
iFlags:= iFlags or PK_CAPS_SEARCHTEXT;
if cbPK_CAPS_HIDE.Checked then
iFlags:= iFlags or PK_CAPS_HIDE;
if cbPK_CAPS_ENCRYPT.Checked then
iFlags:= iFlags or PK_CAPS_ENCRYPT;
cbExt.Items.Objects[iPrevIndex]:= TObject(iFlags);
lblFlagsValue.Caption:= '('+IntToStr(iFlags)+')';
end;
end;
procedure TfrmTweakPlugin.FormCreate(Sender: TObject);
begin
{$if not declared(lcl_fullversion) or (lcl_fullversion < 093100)}
nbTweakAll.ShowTabs := False;
nbTweakAll.TabStop := True;
{$endif}
end;
procedure TfrmTweakPlugin.btnDefaultClick(Sender: TObject);
begin
cbExt.Items.Objects[cbExt.ItemIndex]:= TObject(GetDefaultFlags(fnePlugin1.FileName));
iPrevIndex:= -1;
cbExtChange(cbExt);
end;
procedure TfrmTweakPlugin.btnRelativePlugin1Click(Sender: TObject);
begin
fnePlugin1.SetFocus;
gSpecialDirList.SetSpecialDirRecipientAndItsType(fnePlugin1, pfFILE);
pmPathHelper.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;
procedure TfrmTweakPlugin.btnRelativePlugin2Click(Sender: TObject);
begin
fnePlugin2.SetFocus;
gSpecialDirList.SetSpecialDirRecipientAndItsType(fnePlugin2, pfFILE);
pmPathHelper.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
end;
procedure TfrmTweakPlugin.btnRemoveClick(Sender: TObject);
var
I, OldIndex: Integer;
begin
iPrevIndex:= -1; // Must be before cbExt.Items.Delete, because it may trigger cbExtChange.
OldIndex := cbExt.ItemIndex;
I:= FWCXPlugins.Find(FPluginFileName, cbExt.Text);
if I >= 0 then
FWCXPlugins.Delete(I);
cbExt.Items.Delete(cbExt.ItemIndex);
if OldIndex >= cbExt.Items.Count then
OldIndex := OldIndex - 1;
cbExt.ItemIndex := OldIndex;
if iPrevIndex = -1 then // Call only if not already triggerred.
cbExtChange(cbExt);
btnRemove.Enabled:= (cbExt.Items.Count > 1);
end;
procedure TfrmTweakPlugin.btnAddClick(Sender: TObject);
var
sExt: String = '';
iFlags: PtrInt;
I: Integer;
begin
if InputQuery(rsOptEnterExt,Format(rsOptAssocPluginWith, [fnePlugin1.FileName]), sExt) then
begin
iFlags:= GetDefaultFlags(fnePlugin1.FileName);
cbExt.ItemIndex:= cbExt.Items.AddObject(sExt, TObject(iFlags));
I := FWCXPlugins.Add(cbExt.Items[cbExt.ItemIndex], iFlags, FPluginFileName);
FWCXPlugins.Enabled[I] := (lblPlugin.Tag=1);
iPrevIndex:= -1;
cbExtChange(cbExt);
btnRemove.Enabled:= (cbExt.Items.Count > 1);
end;
end;
procedure TfrmTweakPlugin.btnChangeClick(Sender: TObject);
var
I: Integer;
sExt: String;
begin
sExt:= cbExt.Items[cbExt.ItemIndex];
I:= FWCXPlugins.Find(FPluginFileName, sExt);
if (I >= 0) and
InputQuery(rsOptEnterExt,Format(rsOptAssocPluginWith, [fnePlugin1.FileName]), sExt) then
begin
FWCXPlugins.Ext[I]:= sExt;
cbExt.Items[cbExt.ItemIndex]:= sExt;
end;
end;
function TfrmTweakPlugin.GetDefaultFlags(PluginFileName: String): PtrInt;
var
WcxModule: TWcxModule;
begin
WcxModule := gWCXPlugins.LoadModule(PluginFileName);
if not Assigned(WcxModule) then Exit(0);
Result := WcxModule.GetPluginCapabilities;
end;
end.