mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
1484 lines
50 KiB
ObjectPascal
1484 lines
50 KiB
ObjectPascal
{
|
|
Double Commander
|
|
-------------------------------------------------------------------------
|
|
File associations configuration
|
|
|
|
Copyright (C) 2008-2019 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 fOptionsFileAssoc;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
//Lazarus, Free-Pascal, etc.
|
|
Classes, SysUtils, Forms, Controls, Graphics, Dialogs, StdCtrls, Buttons,
|
|
ExtCtrls, EditBtn, ExtDlgs, Menus, ActnList, Types,
|
|
|
|
//DC
|
|
uGlobs, uExts, fOptionsFrame;
|
|
|
|
type
|
|
|
|
{ TfrmOptionsFileAssoc }
|
|
TfrmOptionsFileAssoc = class(TOptionsEditor)
|
|
btnAddAct: TButton;
|
|
btnCloneAct: TButton;
|
|
btnCommands: TSpeedButton;
|
|
btnInsertExt: TButton;
|
|
btnInsertAct: TButton;
|
|
btnAddExt: TButton;
|
|
btnAddNewType: TButton;
|
|
btnDownAct: TButton;
|
|
btnEditExt: TButton;
|
|
btnParametersHelper: TSpeedButton;
|
|
btnRelativePathIcon: TSpeedButton;
|
|
btnIconSelectFilename: TSpeedButton;
|
|
btnStartPathVarHelper: TSpeedButton;
|
|
btnRelativeCommand: TSpeedButton;
|
|
btnStartPathPathHelper: TSpeedButton;
|
|
btnUpAct: TButton;
|
|
btnRemoveAct: TButton;
|
|
btnRemoveExt: TButton;
|
|
btnRemoveType: TButton;
|
|
btnRenameType: TButton;
|
|
deStartPath: TDirectoryEdit;
|
|
edbActionName: TEditButton;
|
|
edIconFileName: TEdit;
|
|
edtParams: TEdit;
|
|
fneCommand: TFileNameEdit;
|
|
gbActionDescription: TGroupBox;
|
|
gbFileTypes: TGroupBox;
|
|
gbIcon: TGroupBox;
|
|
gbExts: TGroupBox;
|
|
gbActions: TGroupBox;
|
|
lbActions: TListBox;
|
|
lbExts: TListBox;
|
|
lbFileTypes: TListBox;
|
|
lblAction: TLabel;
|
|
lblCommand: TLabel;
|
|
lblExternalParameters: TLabel;
|
|
lblStartPath: TLabel;
|
|
MenuItem1: TMenuItem;
|
|
miInternalViewer: TMenuItem;
|
|
miInternalEditor: TMenuItem;
|
|
miSeparator: TMenuItem;
|
|
miCustom: TMenuItem;
|
|
MenuItem3: TMenuItem;
|
|
miOpenWith: TMenuItem;
|
|
miViewWith: TMenuItem;
|
|
miEditWith: TMenuItem;
|
|
miGetOutputFromCommand: TMenuItem;
|
|
miShell: TMenuItem;
|
|
miViewer: TMenuItem;
|
|
miEditor: TMenuItem;
|
|
miEdit: TMenuItem;
|
|
miView: TMenuItem;
|
|
miOpen: TMenuItem;
|
|
OpenDialog: TOpenDialog;
|
|
OpenPictureDialog: TOpenPictureDialog;
|
|
pnlBottomSettings: TPanel;
|
|
pmPathHelper: TPopupMenu;
|
|
pnlLeftSettings: TPanel;
|
|
pnlActsEdits: TPanel;
|
|
pnlActsButtons: TPanel;
|
|
pnlExtsButtons: TPanel;
|
|
pnlRightSettings: TPanel;
|
|
pnlSettings: TPanel;
|
|
pmActions: TPopupMenu;
|
|
pmCommands: TPopupMenu;
|
|
sbtnIcon: TSpeedButton;
|
|
procedure btnActionsClick(Sender: TObject);
|
|
procedure btnCloneActClick(Sender: TObject);
|
|
procedure btnInsertAddActClick(Sender: TObject);
|
|
procedure btnInsertAddExtClick(Sender: TObject);
|
|
procedure btnParametersHelperClick(Sender: TObject);
|
|
procedure btnRelativeCommandClick(Sender: TObject);
|
|
procedure btnRelativePathIconClick(Sender: TObject);
|
|
procedure btnStartPathPathHelperClick(Sender: TObject);
|
|
procedure btnStartPathVarHelperClick(Sender: TObject);
|
|
procedure deStartPathAcceptDirectory(Sender: TObject; var Value: String);
|
|
procedure deStartPathChange(Sender: TObject);
|
|
procedure edtParamsChange(Sender: TObject);
|
|
procedure edIconFileNameChange(Sender: TObject);
|
|
procedure fneCommandAcceptFileName(Sender: TObject; var Value: String);
|
|
procedure FrameResize(Sender: TObject);
|
|
function InsertAddSingleExtensionToLists(sExt: string; iInsertPosition: integer): boolean;
|
|
procedure InsertAddExtensionToLists(sParamExt: string; iPositionToInsert: integer);
|
|
procedure btnAddNewTypeClick(Sender: TObject);
|
|
procedure btnCommandsClick(Sender: TObject);
|
|
procedure btnDownActClick(Sender: TObject);
|
|
procedure btnEditExtClick(Sender: TObject);
|
|
procedure btnRemoveActClick(Sender: TObject);
|
|
procedure btnRemoveExtClick(Sender: TObject);
|
|
procedure btnRemoveTypeClick(Sender: TObject);
|
|
procedure btnRemoveTypeResize(Sender: TObject);
|
|
procedure btnRenameTypeClick(Sender: TObject);
|
|
procedure btnRenameTypeResize(Sender: TObject);
|
|
procedure btnUpActClick(Sender: TObject);
|
|
procedure lbActionsDragDrop(Sender, {%H-}Source: TObject; {%H-}X, Y: integer);
|
|
procedure lbActionsSelectionChange(Sender: TObject; {%H-}User: boolean);
|
|
procedure lbExtsDragDrop(Sender, {%H-}Source: TObject; X, Y: integer);
|
|
procedure lbGenericListDrawItem(Control: TWinControl; Index: integer; ARect: TRect; State: TOwnerDrawState);
|
|
procedure lbExtsSelectionChange(Sender: TObject; {%H-}User: boolean);
|
|
procedure lbFileTypesDragDrop(Sender, {%H-}Source: TObject; {%H-}X, Y: integer);
|
|
procedure lbGenericDragOver(Sender, Source: TObject; {%H-}X, Y: integer; {%H-}State: TDragState; var Accept: boolean);
|
|
procedure lbFileTypesDrawItem(Control: TWinControl; Index: integer; ARect: TRect; State: TOwnerDrawState);
|
|
procedure lbFileTypesSelectionChange(Sender: TObject; {%H-}User: boolean);
|
|
procedure edbActionNameChange(Sender: TObject);
|
|
procedure fneCommandChange(Sender: TObject);
|
|
procedure miActionsClick(Sender: TObject);
|
|
procedure miCommandsClick(Sender: TObject);
|
|
procedure pnlRightSettingsResize(Sender: TObject);
|
|
procedure pnlSettingsResize(Sender: TObject);
|
|
procedure sbtnIconClick(Sender: TObject);
|
|
procedure MakeUsInPositionToWorkWithActiveFile;
|
|
procedure actSelectFileTypeExecute(Sender: TObject);
|
|
procedure actSelectIconExecute(Sender: TObject);
|
|
procedure actSelectExtensionsExecute(Sender: TObject);
|
|
procedure actSelectActionsExecute(Sender: TObject);
|
|
procedure actSelectActionDescriptionExecute(Sender: TObject);
|
|
|
|
private
|
|
Exts: TExts;
|
|
FUpdatingControls: boolean;
|
|
liveActionList: TActionList;
|
|
actSelectFileType: TAction;
|
|
actSelectIcon: TAction;
|
|
actSelectExtensions: TAction;
|
|
actSelectActions: TAction;
|
|
actSelectActionDescription: TAction;
|
|
procedure UpdateEnabledButtons;
|
|
{en
|
|
Frees icon cached in lbFileTypes.Items.Objects[Index].
|
|
}
|
|
procedure FreeIcon(iIndex: integer);
|
|
procedure SetIconFileName(const sFileName: string);
|
|
procedure SetMinimumSize;
|
|
|
|
protected
|
|
procedure Init; override;
|
|
procedure Done; override;
|
|
procedure Load; override;
|
|
function Save: TOptionsEditorSaveFlags; override;
|
|
public
|
|
class function GetIconIndex: integer; override;
|
|
class function GetTitle: string; override;
|
|
function IsSignatureComputedFromAllWindowComponents: boolean; override;
|
|
function ExtraOptionsSignature(CurrentSignature: dword): dword; override;
|
|
procedure ScanFileAssocForFilenameAndPath;
|
|
function GetFileAssocFilenameToSave(AFileAssocPathModifierElement: tFileAssocPathModifierElement; sParamFilename: string): string;
|
|
end;
|
|
|
|
implementation
|
|
|
|
{$R *.lfm}
|
|
|
|
uses
|
|
//Lazarus, Free-Pascal, etc.
|
|
LCLProc, Math, LCLType, LazUTF8,
|
|
|
|
//DC
|
|
uVariableMenuSupport, DCStrUtils, uOSForms, fMain, uFile, uPixMapManager,
|
|
uLng, uDCUtils, DCOSUtils, uShowMsg, uSpecialDir;
|
|
|
|
const
|
|
ACTUAL_ADD_ACTION = 1;
|
|
SET_ACTION_WORD = 2;
|
|
|
|
{ TfrmOptionsFileAssoc }
|
|
|
|
{ TfrmOptionsFileAssoc.Init }
|
|
procedure TfrmOptionsFileAssoc.Init;
|
|
begin
|
|
inherited Init;
|
|
Exts := TExts.Create;
|
|
FUpdatingControls := False;
|
|
btnIconSelectFilename.Hint := sbtnIcon.Hint;
|
|
OpenDialog.Filter := ParseLineToFileFilter([rsFilterExecutableFiles, '*.exe;*.com;*.bat', rsFilterAnyFiles, AllFilesMask]);
|
|
|
|
// The following section is to help to speed up the the user with keyboard to pass to a section to another.
|
|
// Each TGroupBox has their caption with 1, 2, 3... with underscore under each digit.
|
|
// This suggest to user keyboard accelerator shortcut so he will type Alt+1, Alt+2, etc to pass to a section to another.
|
|
// Unfortunately, at this moment in Windows at least, even if we have underscore, it does not work as keyboard accelerator...
|
|
// It does not switch focus to the proper TGroupbox...
|
|
// So what we will do is to mimic that.
|
|
// We will display the caption of the TGroupBox with underscore to suggest the Alt+1, Alt+2, etc.
|
|
// And we will add in our TActionList function to set the focus on proper TGroupBox and set the keyboard shortcut to Alt+1, Alt+2, etc.
|
|
// So at the end it does the job.
|
|
// If we defined that run-time here instead of having it in the form itself it's to avoid to have annoying empty caption yo appear in the languages files.
|
|
liveActionList := TActionList.Create(Self);
|
|
actSelectFileType := TAction.Create(nil);
|
|
actSelectFileType.OnExecute := @actSelectFileTypeExecute;
|
|
actSelectFileType.ShortCut := 32817; //Alt+1
|
|
actSelectFileType.ActionList := liveActionList;
|
|
actSelectIcon := TAction.Create(nil);
|
|
actSelectIcon.OnExecute := @actSelectIconExecute;
|
|
actSelectIcon.ShortCut := 32818; //Alt+2
|
|
actSelectIcon.ActionList := liveActionList;
|
|
actSelectExtensions := TAction.Create(nil);
|
|
actSelectExtensions.OnExecute := @actSelectExtensionsExecute;
|
|
actSelectExtensions.ShortCut := 32819; //Alt+3
|
|
actSelectExtensions.ActionList := liveActionList;
|
|
actSelectActions := TAction.Create(nil);
|
|
actSelectActions.OnExecute := @actSelectActionsExecute;
|
|
actSelectActions.ShortCut := 32820; //Alt-4
|
|
actSelectActions.ActionList := liveActionList;
|
|
actSelectActionDescription := TAction.Create(nil);
|
|
actSelectActionDescription.OnExecute := @actSelectActionDescriptionExecute;
|
|
actSelectActionDescription.ShortCut := 32821; //Alt-5
|
|
actSelectActionDescription.ActionList := liveActionList;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.Done }
|
|
procedure TfrmOptionsFileAssoc.Done;
|
|
var
|
|
I: integer;
|
|
begin
|
|
for I := 0 to lbFileTypes.Items.Count - 1 do
|
|
FreeIcon(I);
|
|
FreeAndNil(Exts);
|
|
FreeAndNil(actSelectActionDescription);
|
|
FreeAndNil(actSelectActions);
|
|
FreeAndNil(actSelectExtensions);
|
|
FreeAndNil(actSelectIcon);
|
|
FreeAndNil(actSelectFileType);
|
|
FreeAndNil(liveActionList);
|
|
inherited Done;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.Load }
|
|
procedure TfrmOptionsFileAssoc.Load;
|
|
var
|
|
I: integer;
|
|
sName: string;
|
|
Bitmap: TBitmap;
|
|
begin
|
|
//Let's preserve the precious legacy .po translated groupbox name that we will re-use with dialog window concerning them
|
|
gbFileTypes.hint := gbFileTypes.Caption;
|
|
gbIcon.hint := gbIcon.Caption;
|
|
gbExts.hint := gbExts.Caption;
|
|
gbActions.hint := gbActions.Caption;
|
|
gbActionDescription.hint := gbActionDescription.Caption;
|
|
|
|
// Give some numerical step number to help user without losing legacy .po translated groubox name
|
|
gbFileTypes.Caption := '&1 - ' + gbFileTypes.Caption;
|
|
gbIcon.Caption := '&2 - ' + gbIcon.Caption;
|
|
gbExts.Caption := '&3 - ' + gbExts.Caption;
|
|
gbActions.Caption := '&4 - ' + gbActions.Caption;
|
|
gbActionDescription.Caption := '&5 - ' + gbActionDescription.Caption;
|
|
|
|
// load extension file
|
|
Exts.Load;
|
|
|
|
//'Pp'! A letter with the upper part and a letter with the lower part! This should give us approximation of highest room required! :-)
|
|
lbFileTypes.ItemHeight := Max(gIconsSize, lbFileTypes.Canvas.TextHeight('Pp')) + 4;
|
|
|
|
// fill file types list box
|
|
for I := 0 to Exts.Count - 1 do
|
|
begin
|
|
sName := Exts.Items[I].Name;
|
|
|
|
// load icon for use in OnDrawItem procedure
|
|
Bitmap := PixMapManager.LoadBitmapEnhanced(Exts.Items[I].Icon, gIconsSize, True, lbFileTypes.Color);
|
|
lbFileTypes.Items.AddObject(sName, Bitmap);
|
|
end;
|
|
|
|
if Exts.Count > 0 then
|
|
lbFileTypes.ItemIndex := 0;
|
|
|
|
UpdateEnabledButtons;
|
|
|
|
// Populate helper menu
|
|
gSpecialDirList.PopulateMenuWithSpecialDir(pmPathHelper, mp_PATHHELPER, nil);
|
|
|
|
inherited Load;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.Save }
|
|
function TfrmOptionsFileAssoc.Save: TOptionsEditorSaveFlags;
|
|
var
|
|
iExt: integer;
|
|
begin
|
|
Exts.SaveXMLFile;
|
|
gExts.Clear;
|
|
gExts.Load;
|
|
|
|
// The "gExts.Clear" has flush the "IconIndex" that have been set via "Load" of PixMapManager.
|
|
// Since it has been lost AND PixMapManager.Load won't set again our iconindex, let's do manually here.
|
|
// It is required so the icon next to our actions in SheelContextMenu will be the correct ones.
|
|
for iExt := 0 to pred(gExts.Count) do
|
|
TExtAction(gExts.Items[iExt]).IconIndex := PixMapManager.GetIconByName(TExtAction(gExts.Items[iExt]).Icon);
|
|
|
|
Result := inherited Save;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.GetIconIndex }
|
|
class function TfrmOptionsFileAssoc.GetIconIndex: integer;
|
|
begin
|
|
Result := 34;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.GetTitle }
|
|
class function TfrmOptionsFileAssoc.GetTitle: string;
|
|
begin
|
|
Result := rsOptionsEditorFileAssoc;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.IsSignatureComputedFromAllWindowComponents }
|
|
function TfrmOptionsFileAssoc.IsSignatureComputedFromAllWindowComponents: boolean;
|
|
begin
|
|
Result := False;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.ExtraOptionsSignature }
|
|
function TfrmOptionsFileAssoc.ExtraOptionsSignature(CurrentSignature: dword): dword;
|
|
begin
|
|
Result := Exts.ComputeSignature(CurrentSignature);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.UpdateEnabledButtons }
|
|
procedure TfrmOptionsFileAssoc.UpdateEnabledButtons;
|
|
begin
|
|
if (lbFileTypes.Items.Count = 0) or (lbFileTypes.ItemIndex = -1) then
|
|
begin
|
|
sbtnIcon.Enabled := False;
|
|
btnInsertExt.Enabled := False;
|
|
btnAddExt.Enabled := False;
|
|
btnInsertAct.Enabled := False;
|
|
btnAddAct.Enabled := False;
|
|
end
|
|
else
|
|
begin
|
|
btnInsertExt.Enabled := (lbExts.Items.Count > 0);
|
|
btnAddExt.Enabled := True;
|
|
btnInsertAct.Enabled := (lbExts.Items.Count > 0) and (lbActions.ItemIndex <> -1);
|
|
btnAddAct.Enabled := btnInsertExt.Enabled;
|
|
sbtnIcon.Enabled := btnInsertExt.Enabled;
|
|
end;
|
|
|
|
btnRemoveExt.Enabled := ((lbExts.Items.Count <> 0) and (lbExts.ItemIndex <> -1));
|
|
btnEditExt.Enabled := btnRemoveExt.Enabled;
|
|
|
|
if (lbActions.Items.Count = 0) or (lbActions.ItemIndex = -1) then
|
|
begin
|
|
btnUpAct.Enabled := False;
|
|
btnDownAct.Enabled := False;
|
|
btnRemoveAct.Enabled := False;
|
|
edbActionName.Enabled := False;
|
|
fneCommand.Enabled := False;
|
|
edtParams.Enabled := False;
|
|
deStartPath.Enabled := False;
|
|
btnCommands.Enabled := False;
|
|
btnRelativeCommand.Enabled := False;
|
|
btnParametersHelper.Enabled := False;
|
|
btnStartPathPathHelper.Enabled := False;
|
|
btnStartPathVarHelper.Enabled := False;
|
|
edbActionName.Text := '';
|
|
fneCommand.FileName := '';
|
|
edtParams.Text := '';
|
|
deStartPath.Text := '';
|
|
end
|
|
else
|
|
begin
|
|
btnUpAct.Enabled := (lbActions.ItemIndex > 0);
|
|
btnDownAct.Enabled := (lbActions.ItemIndex < lbActions.Items.Count - 1);
|
|
btnRemoveAct.Enabled := True;
|
|
edbActionName.Enabled := True;
|
|
fneCommand.Enabled := True;
|
|
btnRelativeCommand.Enabled := True;
|
|
btnParametersHelper.Enabled := True;
|
|
btnStartPathPathHelper.Enabled := True;
|
|
btnStartPathVarHelper.Enabled := True;
|
|
edtParams.Enabled := True;
|
|
deStartPath.Enabled := True;
|
|
btnCommands.Enabled := True;
|
|
end;
|
|
|
|
btnCloneAct.Enabled := btnRemoveAct.Enabled;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnAddNewTypeClick }
|
|
procedure TfrmOptionsFileAssoc.btnAddNewTypeClick(Sender: TObject);
|
|
var
|
|
ExtAction: TExtAction;
|
|
s: string;
|
|
begin
|
|
s := InputBox(GetTitle + ' - ' + gbFileTypes.Hint, rsMsgEnterName, '');
|
|
if s = '' then exit;
|
|
ExtAction := TExtAction.Create;
|
|
ExtAction.IconIndex := -1;
|
|
with lbFileTypes do
|
|
begin
|
|
ExtAction.Name := s;
|
|
Items.AddObject(ExtAction.Name, nil);
|
|
|
|
// add file type to TExts object
|
|
Exts.AddItem(ExtAction);
|
|
ItemIndex := Items.Count - 1;
|
|
end;
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRemoveTypeClick }
|
|
procedure TfrmOptionsFileAssoc.btnRemoveTypeClick(Sender: TObject);
|
|
var
|
|
iIndex: integer;
|
|
begin
|
|
with lbFileTypes do
|
|
begin
|
|
iIndex := ItemIndex;
|
|
if iIndex < 0 then Exit;
|
|
FreeIcon(iIndex);
|
|
Items.Delete(iIndex);
|
|
Exts.DeleteItem(iIndex);
|
|
if Items.Count = 0 then
|
|
begin
|
|
lbExts.Clear;
|
|
lbActions.Clear;
|
|
end
|
|
else
|
|
begin
|
|
if iIndex = 0 then
|
|
ItemIndex := 0
|
|
else
|
|
ItemIndex := iIndex - 1;
|
|
end;
|
|
end;
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRemoveTypeResize }
|
|
procedure TfrmOptionsFileAssoc.btnRemoveTypeResize(Sender: TObject);
|
|
begin
|
|
SetMinimumSize;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRenameTypeClick }
|
|
procedure TfrmOptionsFileAssoc.btnRenameTypeClick(Sender: TObject);
|
|
var
|
|
iIndex: integer;
|
|
sName: string;
|
|
begin
|
|
iIndex := lbFileTypes.ItemIndex;
|
|
if iIndex < 0 then Exit;
|
|
sName := lbFileTypes.Items[iIndex];
|
|
sName := InputBox(GetTitle + ' - ' + gbFileTypes.Hint, rsMsgEnterName, sName);
|
|
lbFileTypes.Items[iIndex] := sName;
|
|
// rename file type in TExts object
|
|
Exts.Items[iIndex].Name := sName;
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRenameTypeResize }
|
|
procedure TfrmOptionsFileAssoc.btnRenameTypeResize(Sender: TObject);
|
|
begin
|
|
SetMinimumSize;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbActionsSelectionChange }
|
|
procedure TfrmOptionsFileAssoc.lbActionsSelectionChange(Sender: TObject; User: boolean);
|
|
var
|
|
iIndex: integer;
|
|
begin
|
|
iIndex := lbActions.ItemIndex;
|
|
if (iIndex < 0) or (lbActions.Tag = 1) then Exit;
|
|
edbActionName.Tag := 1;
|
|
edbActionName.Text := TExtActionCommand(lbActions.Items.Objects[iIndex]).ActionName;
|
|
fneCommand.FileName := TExtActionCommand(lbActions.Items.Objects[iIndex]).CommandName;
|
|
edtParams.Text := TExtActionCommand(lbActions.Items.Objects[iIndex]).Params;
|
|
deStartPath.Text := TExtActionCommand(lbActions.Items.Objects[iIndex]).StartPath;
|
|
edbActionName.Tag := 0;
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbExtsDragDrop }
|
|
procedure TfrmOptionsFileAssoc.lbExtsDragDrop(Sender, Source: TObject; X, Y: integer);
|
|
var
|
|
SrcIndex, DestIndex: integer;
|
|
begin
|
|
// exchange positions in extensions listbox
|
|
SrcIndex := lbExts.ItemIndex;
|
|
if SrcIndex = -1 then
|
|
Exit;
|
|
DestIndex := lbExts.GetIndexAtXY(X, Y);
|
|
if (DestIndex < 0) or (DestIndex >= lbExts.Count) then
|
|
DestIndex := lbExts.Count - 1;
|
|
|
|
lbExts.Items.Move(SrcIndex, DestIndex);
|
|
lbExts.ItemIndex := DestIndex;
|
|
|
|
// change extension in TExts object
|
|
Exts.Items[lbFileTypes.ItemIndex].Extensions.Move(SrcIndex, DestIndex);
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.lbGenericListDrawItem(Control: TWinControl; Index: integer; ARect: TRect; State: TOwnerDrawState);
|
|
begin
|
|
with (Control as TListBox) do
|
|
begin
|
|
if (odSelected in State) then
|
|
begin
|
|
if focused then
|
|
begin
|
|
Canvas.Font.Color := clHighlightText;
|
|
Canvas.Brush.Color := clHighlight;
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Font.Color := clWindowText;
|
|
Canvas.Brush.Color := clGradientActiveCaption;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Font.Color := Font.Color;
|
|
Canvas.Brush.Color := Color;
|
|
end;
|
|
Canvas.FillRect(ARect);
|
|
Canvas.TextOut(ARect.Left, ARect.Top, Items[Index]);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbExtsSelectionChange }
|
|
procedure TfrmOptionsFileAssoc.lbExtsSelectionChange(Sender: TObject; User: boolean);
|
|
begin
|
|
if (lbExts.ItemIndex < 0) then Exit;
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbFileTypesDragDrop }
|
|
procedure TfrmOptionsFileAssoc.lbFileTypesDragDrop(Sender, Source: TObject; X, Y: integer);
|
|
var
|
|
SrcIndex, DestIndex: integer;
|
|
begin
|
|
// Validate if the move is okay
|
|
SrcIndex := lbFileTypes.ItemIndex;
|
|
if SrcIndex = -1 then
|
|
Exit;
|
|
DestIndex := lbFileTypes.GetIndexAtY(Y);
|
|
if (DestIndex < 0) or (DestIndex >= lbFileTypes.Count) then
|
|
DestIndex := lbFileTypes.Count - 1;
|
|
|
|
// exchange positions in actions listbox
|
|
lbActions.Tag := 1; // start moving
|
|
try
|
|
lbFileTypes.Items.Move(SrcIndex, DestIndex);
|
|
lbFileTypes.ItemIndex := DestIndex;
|
|
|
|
// exchange actions in TExts object
|
|
Exts.MoveItem(SrcIndex, DestIndex);
|
|
finally
|
|
lbActions.Tag := 0; // end moving
|
|
end;
|
|
|
|
// trig the "SelectionChange" event to refresh extension and action lists
|
|
lbFileTypesSelectionChange(lbFileTypes, False);
|
|
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbGenericDragOver }
|
|
procedure TfrmOptionsFileAssoc.lbGenericDragOver(Sender, Source: TObject; X, Y: integer; State: TDragState; var Accept: boolean);
|
|
begin
|
|
//Accept if it's coming from the same ListBox
|
|
Accept := (Source is TListBox) and (TListBox(Source).Name = TListBox(Sender).Name);
|
|
|
|
//Let's scroll up/down if user is dragging near the top/bottom
|
|
if Y > (TListBox(Sender).Height - 15) then
|
|
TListBox(Sender).TopIndex := TListBox(Sender).TopIndex + 1
|
|
else
|
|
if Y < 15 then
|
|
TListBox(Sender).TopIndex := TListBox(Sender).TopIndex - 1;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbFileTypesDrawItem }
|
|
procedure TfrmOptionsFileAssoc.lbFileTypesDrawItem(Control: TWinControl; Index: integer; ARect: TRect; State: TOwnerDrawState);
|
|
var
|
|
iDrawTop: integer;
|
|
begin
|
|
with (Control as TListBox) do
|
|
begin
|
|
if odSelected in State then
|
|
begin
|
|
if focused then
|
|
begin
|
|
Canvas.Font.Color := clHighlightText;
|
|
Canvas.Brush.Color := clHighlight;
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Font.Color := clWindowText;
|
|
Canvas.Brush.Color := clGradientActiveCaption;
|
|
end;
|
|
Canvas.FillRect(ARect);
|
|
end
|
|
else
|
|
begin
|
|
Canvas.Font.Color := Font.Color;
|
|
Canvas.Brush.Color := Color;
|
|
Canvas.FillRect(ARect);
|
|
end;
|
|
|
|
if (Canvas.Locked = False) and (Assigned(Items.Objects[Index])) then
|
|
begin
|
|
iDrawTop := ARect.Top + ((lbFileTypes.ItemHeight - gIconsSize) div 2);
|
|
Canvas.Draw(ARect.Left + 2, iDrawTop, TBitmap(Items.Objects[Index]));
|
|
end;
|
|
iDrawTop := ARect.Top + ((lbFileTypes.ItemHeight - Canvas.TextHeight(Items[Index])) div 2);
|
|
Canvas.TextOut(ARect.Left + gIconsSize + 6, iDrawTop, Items[Index]);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbFileTypesSelectionChange }
|
|
procedure TfrmOptionsFileAssoc.lbFileTypesSelectionChange(Sender: TObject; User: boolean);
|
|
var
|
|
ExtCommand: TExtAction;
|
|
I: integer;
|
|
bmpTemp: TBitmap = nil;
|
|
begin
|
|
if (lbFileTypes.ItemIndex >= 0) and (lbFileTypes.ItemIndex < Exts.Count) then
|
|
begin
|
|
lbActions.Items.Clear;
|
|
Application.ProcessMessages;
|
|
lbExts.Items.Clear;
|
|
Application.ProcessMessages;
|
|
|
|
ExtCommand := Exts.Items[lbFileTypes.ItemIndex];
|
|
lbExts.Items.Assign(ExtCommand.Extensions);
|
|
if lbExts.Count > 0 then lbExts.ItemIndex := 0;
|
|
for I := 0 to pred(ExtCommand.ActionList.Count) do
|
|
begin
|
|
lbActions.Items.AddObject(ExtCommand.ActionList.ExtActionCommand[I].ActionName, ExtCommand.ActionList.ExtActionCommand[I]);
|
|
end;
|
|
if lbActions.Count > 0 then lbActions.ItemIndex := 0;
|
|
|
|
bmpTemp := PixMapManager.LoadBitmapEnhanced(ExtCommand.Icon, 32, True, sbtnIcon.Color);
|
|
try
|
|
sbtnIcon.Glyph := bmpTemp;
|
|
finally
|
|
if Assigned(bmpTemp) then
|
|
FreeAndNil(bmpTemp);
|
|
end;
|
|
|
|
FUpdatingControls := True; // Don't trigger OnChange
|
|
edIconFileName.Text := ExtCommand.Icon;
|
|
FUpdatingControls := False;
|
|
end
|
|
else
|
|
begin
|
|
lbExts.Items.Clear;
|
|
lbActions.Items.Clear;
|
|
sbtnIcon.Glyph.Clear;
|
|
edIconFileName.Text := '';
|
|
end;
|
|
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.edbActionChange }
|
|
procedure TfrmOptionsFileAssoc.edbActionNameChange(Sender: TObject);
|
|
var
|
|
iIndex: integer;
|
|
begin
|
|
if edbActionName.Tag = 1 then exit;
|
|
iIndex := lbActions.ItemIndex;
|
|
if (iIndex < 0) or (edbActionName.Text = '') then Exit;
|
|
TExtActionCommand(lbActions.Items.Objects[iIndex]).ActionName := edbActionName.Text;
|
|
lbActions.Items[iIndex] := edbActionName.Text;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.fneCommandChange }
|
|
procedure TfrmOptionsFileAssoc.fneCommandChange(Sender: TObject);
|
|
var
|
|
iIndex: integer;
|
|
begin
|
|
iIndex := lbActions.ItemIndex;
|
|
if (edbActionName.Tag = 1) or (iIndex < 0) then Exit;
|
|
TExtActionCommand(lbActions.Items.Objects[iIndex]).CommandName := fneCommand.Text;
|
|
if fneCommand.InitialDir <> ExtractFilePath(fneCommand.Text) then
|
|
fneCommand.InitialDir := ExtractFilePath(fneCommand.Text);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.edtExternalParametersChange }
|
|
procedure TfrmOptionsFileAssoc.edtParamsChange(Sender: TObject);
|
|
var
|
|
iIndex: integer;
|
|
begin
|
|
iIndex := lbActions.ItemIndex;
|
|
if (edbActionName.Tag = 1) or (iIndex < 0) then Exit;
|
|
TExtActionCommand(lbActions.Items.Objects[iIndex]).Params := edtParams.Text;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.deStartPathChange }
|
|
procedure TfrmOptionsFileAssoc.deStartPathChange(Sender: TObject);
|
|
var
|
|
iIndex: integer;
|
|
begin
|
|
iIndex := lbActions.ItemIndex;
|
|
if (edbActionName.Tag = 1) or (iIndex < 0) then Exit;
|
|
TExtActionCommand(lbActions.Items.Objects[iIndex]).StartPath := deStartPath.Text;
|
|
if deStartPath.Directory <> deStartPath.Text then
|
|
deStartPath.Directory := deStartPath.Text;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.miActionsClick }
|
|
// The "tag" of the menu item calling this will give us information about the task to do.
|
|
|
|
// xxxx xx10 : Bit 1 & 0 indicate if user wants "Open", "View", "Edit" or "Custom action".
|
|
// xxx4 xxxx : Bit 4 indicates if user wants to specify immediately a .exe file for the command. (0=no, 1=yes).
|
|
// xx5x xxxx : Bit 5 indicates if user wants to "Add" or "Insert" action in the current list. (0=add, 1=insert).
|
|
|
|
procedure TfrmOptionsFileAssoc.miActionsClick(Sender: TObject);
|
|
var
|
|
miMenuItem: TMenuItem absolute Sender;
|
|
I, iDispatcher: integer;
|
|
ExtAction: TExtAction;
|
|
sActionWords: string = '';
|
|
sCommandFilename: string = '';
|
|
begin
|
|
with Sender as TComponent do iDispatcher := tag;
|
|
|
|
// Transform the task in "add" if currently there is no action, nothing selected, any incoherence.
|
|
if (Exts.Items[lbFileTypes.ItemIndex].ActionList.Count = 0) or (lbActions.Items.Count = 0) or (lbActions.ItemIndex = -1) then iDispatcher := (iDispatcher and $DF);
|
|
|
|
if iDispatcher and $03 = $03 then
|
|
gFileAssociationLastCustomAction := InputBox(GetTitle + ' - ' + gbActions.Hint, rsMsgEnterCustomAction, gFileAssociationLastCustomAction);
|
|
|
|
case (iDispatcher and $DF) of
|
|
$00: sActionWords := 'Open';
|
|
$01: sActionWords := 'View';
|
|
$02: sActionWords := 'Edit';
|
|
$03: sActionWords := gFileAssociationLastCustomAction;
|
|
$10: OpenDialog.Title := rsMsgSelectExecutableFile + ' "Open"...';
|
|
$11: OpenDialog.Title := rsMsgSelectExecutableFile + ' "View"...';
|
|
$12: OpenDialog.Title := rsMsgSelectExecutableFile + ' "Edit"...';
|
|
$13: OpenDialog.Title := rsMsgSelectExecutableFile + ' "' + gFileAssociationLastCustomAction + '"...';
|
|
end;
|
|
|
|
case iDispatcher and $10 of
|
|
$10:
|
|
begin
|
|
if OpenDialog.Execute then
|
|
begin
|
|
sCommandFilename := GetFileAssocFilenameToSave(fameCommand, OpenDialog.Filename);
|
|
|
|
case (iDispatcher and $03) of
|
|
$00: sActionWords := 'Open ' + rsMsgWithActionWith + ' ' + ExtractFilename(OpenDialog.Filename);
|
|
$01: sActionWords := 'View ' + rsMsgWithActionWith + ' ' + ExtractFilename(OpenDialog.Filename);
|
|
$02: sActionWords := 'Edit ' + rsMsgWithActionWith + ' ' + ExtractFilename(OpenDialog.Filename);
|
|
$03: sActionWords := gFileAssociationLastCustomAction + ' ' + rsMsgWithActionWith + ' ' + ExtractFilename(OpenDialog.Filename);
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
case pmActions.Tag of
|
|
ACTUAL_ADD_ACTION:
|
|
begin
|
|
ExtAction := Exts.Items[lbFileTypes.ItemIndex];
|
|
|
|
// insert/add action to TExts object
|
|
case iDispatcher and $20 of
|
|
$20: // it is an "insert"
|
|
begin
|
|
I := lbActions.ItemIndex;
|
|
|
|
case (iDispatcher and $DF) of
|
|
$00, $01, $02, $03: ExtAction.ActionList.Insert(I, TExtActionCommand.Create(sActionWords, '', '', ''));
|
|
$10, $11, $12, $13: ExtAction.ActionList.Insert(I, TExtActionCommand.Create(sActionWords, sCommandFilename, '%p', ''));
|
|
end;
|
|
|
|
// add action to actions listbox
|
|
lbActions.Items.InsertObject(I, '', ExtAction.ActionList.ExtActionCommand[I]);
|
|
end
|
|
else
|
|
begin // it is a "add"
|
|
case (iDispatcher and $DF) of
|
|
$00, $01, $02, $03: I := ExtAction.ActionList.Add(TExtActionCommand.Create(sActionWords, '', '', ''));
|
|
$10, $11, $12, $13: I := ExtAction.ActionList.Add(TExtActionCommand.Create(sActionWords, sCommandFilename, '%p', ''));
|
|
end;
|
|
|
|
// add action to actions listbox
|
|
lbActions.Items.AddObject(ExtAction.ActionList.ExtActionCommand[I].ActionName, ExtAction.ActionList.ExtActionCommand[I]);
|
|
end;
|
|
end;
|
|
|
|
lbActions.ItemIndex := I;
|
|
edbActionNameChange(edbActionName); //<--Trig this event to force redraw of lbActions current selected element because in case of switch from "open" to identical "open" for exemple, "edbActionChange" is not trig and so our element in the list is not drawn!
|
|
|
|
// Update icon if possible, if necessary
|
|
case (iDispatcher and $10) of
|
|
$10: if Exts.Items[lbFileTypes.ItemIndex].Icon = '' then edIconFileName.Text := GetFileAssocFilenameToSave(fameIcon, OpenDialog.FileName); //No quote required here! So "sCommandFilename" is not used.
|
|
end;
|
|
|
|
UpdateEnabledButtons;
|
|
|
|
if edbActionName.CanFocus then
|
|
begin
|
|
edbActionName.SetFocus;
|
|
edbActionName.SelStart := UTF8Length(edbActionName.Text);
|
|
end;
|
|
end;
|
|
|
|
SET_ACTION_WORD:
|
|
begin
|
|
case (iDispatcher and $DF) of
|
|
$00, $01, $02, $03: edbActionName.Text := sActionWords;
|
|
$10, $11, $12, $13:
|
|
begin
|
|
edbActionName.Text := sActionWords;
|
|
fneCommand.Text := sCommandFilename;
|
|
edtParams.Text := '%p';
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
else
|
|
begin
|
|
if miMenuItem.Name = 'miOpen' then
|
|
edbActionName.Text := 'Open'
|
|
else if miMenuItem.Name = 'miView' then
|
|
edbActionName.Text := 'View'
|
|
else if miMenuItem.Name = 'miEdit' then
|
|
edbActionName.Text := 'Edit';
|
|
end;
|
|
end;
|
|
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.miCommandsClick }
|
|
procedure TfrmOptionsFileAssoc.miCommandsClick(Sender: TObject);
|
|
begin
|
|
with Sender as TComponent do
|
|
begin
|
|
case tag of
|
|
2: fneCommand.SelText := '{!VIEWER}';
|
|
3: fneCommand.SelText := '{!DC-VIEWER}';
|
|
4: fneCommand.SelText := '{!EDITOR}';
|
|
5: fneCommand.SelText := '{!DC-EDITOR}';
|
|
6: fneCommand.SelText := '{!SHELL}';
|
|
7:
|
|
begin
|
|
fneCommand.SelText := fneCommand.Text + '<??>';
|
|
fneCommand.SetFocus;
|
|
fneCommand.SelStart := Pos('?>', fneCommand.Text) - 1;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.pnlRightSettingsResize }
|
|
procedure TfrmOptionsFileAssoc.pnlRightSettingsResize(Sender: TObject);
|
|
begin
|
|
gbExts.Height := pnlRightSettings.ClientHeight div 4;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.pnlSettingsResize }
|
|
procedure TfrmOptionsFileAssoc.pnlSettingsResize(Sender: TObject);
|
|
begin
|
|
pnlLeftSettings.Width := pnlSettings.ClientWidth div 3;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.sbtnIconClick }
|
|
procedure TfrmOptionsFileAssoc.sbtnIconClick(Sender: TObject);
|
|
var
|
|
sFileName: string;
|
|
begin
|
|
sFileName := mbExpandFileName(edIconFileName.Text);
|
|
if ShowOpenIconDialog(Self, sFileName) then
|
|
edIconFileName.Text := GetFileAssocFilenameToSave(fameIcon, sFileName);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.InsertAddSingleExtensionToLists }
|
|
function TfrmOptionsFileAssoc.InsertAddSingleExtensionToLists(sExt: string; iInsertPosition: integer): boolean;
|
|
begin
|
|
Result := False;
|
|
|
|
if (sExt <> '') then
|
|
begin
|
|
if Exts.Items[lbFileTypes.ItemIndex].Extensions.IndexOf(sExt) = -1 then
|
|
begin
|
|
if iInsertPosition = -1 then
|
|
iInsertPosition := lbExts.Items.Add(sExt)
|
|
else
|
|
lbExts.Items.Insert(iInsertPosition, sExt);
|
|
|
|
lbExts.ItemIndex := iInsertPosition;
|
|
|
|
//add extension in TExts object
|
|
Exts.Items[lbFileTypes.ItemIndex].Extensions.Insert(iInsertPosition, sExt);
|
|
|
|
Result := True;
|
|
end
|
|
else
|
|
begin
|
|
lbExts.ItemIndex := Exts.Items[lbFileTypes.ItemIndex].Extensions.IndexOf(sExt);
|
|
end;
|
|
|
|
UpdateEnabledButtons;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.InsertAddExtensionToLists }
|
|
procedure TfrmOptionsFileAssoc.InsertAddExtensionToLists(sParamExt: string; iPositionToInsert: integer);
|
|
var
|
|
iIndex: integer;
|
|
sExt: string;
|
|
begin
|
|
sParamExt := sParamExt + '|';
|
|
while Pos('|', sParamExt) <> 0 do
|
|
begin
|
|
iIndex := Pos('|', sParamExt);
|
|
sExt := Copy(sParamExt, 1, iIndex - 1);
|
|
Delete(sParamExt, 1, iIndex);
|
|
if InsertAddSingleExtensionToLists(sExt, iPositionToInsert) then
|
|
if iPositionToInsert <> -1 then Inc(iPositionToInsert);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnInsertAddExtClick }
|
|
procedure TfrmOptionsFileAssoc.btnInsertAddExtClick(Sender: TObject);
|
|
var
|
|
sExt: string;
|
|
Dispatcher: integer;
|
|
begin
|
|
with Sender as TComponent do Dispatcher := tag;
|
|
if (lbExts.Items.Count = 0) or (lbExts.ItemIndex = -1) then Dispatcher := 0;
|
|
sExt := InputBox(GetTitle + ' - ' + gbExts.Hint, rsMsgEnterFileExt, '');
|
|
InsertAddExtensionToLists(sExt, ifthen((Dispatcher = 0), -1, lbExts.ItemIndex));
|
|
if lbExts.CanFocus then lbExts.SetFocus;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnParametersHelperClick }
|
|
procedure TfrmOptionsFileAssoc.btnParametersHelperClick(Sender: TObject);
|
|
begin
|
|
BringPercentVariablePopupMenu(edtParams);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRelativeCommandClick }
|
|
procedure TfrmOptionsFileAssoc.btnRelativeCommandClick(Sender: TObject);
|
|
begin
|
|
fneCommand.SetFocus;
|
|
gSpecialDirList.SetSpecialDirRecipientAndItsType(fneCommand, pfFILE);
|
|
pmPathHelper.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRelativePathIconClick }
|
|
procedure TfrmOptionsFileAssoc.btnRelativePathIconClick(Sender: TObject);
|
|
begin
|
|
edIconFileName.SetFocus;
|
|
gSpecialDirList.SetSpecialDirRecipientAndItsType(edIconFileName, pfFILE);
|
|
pmPathHelper.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnStartPathPathHelperClick }
|
|
procedure TfrmOptionsFileAssoc.btnStartPathPathHelperClick(Sender: TObject);
|
|
begin
|
|
deStartPath.SetFocus;
|
|
gSpecialDirList.SetSpecialDirRecipientAndItsType(deStartPath, pfPATH);
|
|
pmPathHelper.PopUp(Mouse.CursorPos.X, Mouse.CursorPos.Y);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnStartPathVarHelperClick }
|
|
procedure TfrmOptionsFileAssoc.btnStartPathVarHelperClick(Sender: TObject);
|
|
begin
|
|
BringPercentVariablePopupMenu(deStartPath);
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.deStartPathAcceptDirectory(Sender: TObject; var Value: String);
|
|
begin
|
|
Value := GetFileAssocFilenameToSave(fameStartingPath, Value);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.edIconFileNameChange }
|
|
procedure TfrmOptionsFileAssoc.edIconFileNameChange(Sender: TObject);
|
|
begin
|
|
if not FUpdatingControls then
|
|
SetIconFileName(edIconFileName.Text);
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.fneCommandAcceptFileName(Sender: TObject; var Value: String);
|
|
begin
|
|
Value := GetFileAssocFilenameToSave(fameCommand, Value);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.FrameResize }
|
|
procedure TfrmOptionsFileAssoc.FrameResize(Sender: TObject);
|
|
begin
|
|
lbExts.Columns := (lbExts.Width div 120);
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRemoveExtClick }
|
|
procedure TfrmOptionsFileAssoc.btnRemoveExtClick(Sender: TObject);
|
|
var
|
|
I: integer;
|
|
begin
|
|
// remove extension from extensions listbox
|
|
with lbExts do
|
|
begin
|
|
I := ItemIndex;
|
|
if I < 0 then Exit;
|
|
Items.Delete(I);
|
|
if I < Items.Count then
|
|
ItemIndex := I
|
|
else
|
|
if (I - 1) < Items.Count then
|
|
ItemIndex := (I - 1);
|
|
end;
|
|
// remove extension from TExts object
|
|
Exts.Items[lbFileTypes.ItemIndex].Extensions.Delete(I);
|
|
UpdateEnabledButtons;
|
|
if lbExts.CanFocus then lbExts.SetFocus;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnUpActClick }
|
|
procedure TfrmOptionsFileAssoc.btnUpActClick(Sender: TObject);
|
|
var
|
|
I: integer;
|
|
begin
|
|
// move action in actions listbox
|
|
with lbActions do
|
|
begin
|
|
Tag := 1; // start moving
|
|
I := ItemIndex;
|
|
if I = -1 then exit;
|
|
if I > 0 then
|
|
begin
|
|
Items.Move(I, I - 1);
|
|
ItemIndex := I - 1;
|
|
end;
|
|
end;
|
|
|
|
// move action in TExts object
|
|
with lbFileTypes do
|
|
begin
|
|
Exts.Items[ItemIndex].ActionList.Move(I, I - 1);
|
|
end;
|
|
lbActions.Tag := 0; // end moving
|
|
UpdateEnabledButtons;
|
|
if lbActions.CanFocus then lbActions.SetFocus;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.lbActionsDragDrop }
|
|
procedure TfrmOptionsFileAssoc.lbActionsDragDrop(Sender, Source: TObject; X, Y: integer);
|
|
var
|
|
SrcIndex, DestIndex: integer;
|
|
begin
|
|
// Validate if the move is okay
|
|
SrcIndex := lbActions.ItemIndex;
|
|
if SrcIndex = -1 then
|
|
Exit;
|
|
DestIndex := lbActions.GetIndexAtY(Y);
|
|
if (DestIndex < 0) or (DestIndex >= lbActions.Count) then
|
|
DestIndex := lbActions.Count - 1;
|
|
|
|
// exchange positions in actions listbox
|
|
lbActions.Tag := 1; // start moving
|
|
|
|
try
|
|
lbActions.Items.Move(SrcIndex, DestIndex);
|
|
lbActions.ItemIndex := DestIndex;
|
|
|
|
// exchange actions in TExts object
|
|
Exts.Items[lbFileTypes.ItemIndex].ActionList.Move(SrcIndex, DestIndex);
|
|
finally
|
|
lbActions.Tag := 0; // end moving
|
|
end;
|
|
|
|
UpdateEnabledButtons;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnDownActClick }
|
|
procedure TfrmOptionsFileAssoc.btnDownActClick(Sender: TObject);
|
|
var
|
|
I: integer;
|
|
begin
|
|
// move action in actions listbox
|
|
with lbActions do
|
|
begin
|
|
Tag := 1; // start moving
|
|
I := ItemIndex;
|
|
if I = -1 then exit;
|
|
if (I < Items.Count - 1) and (I > -1) then
|
|
begin
|
|
Items.Move(I, I + 1);
|
|
ItemIndex := I + 1;
|
|
end;
|
|
end;
|
|
// move action in TExts object
|
|
with lbFileTypes do
|
|
begin
|
|
Exts.Items[ItemIndex].ActionList.Move(I, I + 1);
|
|
end;
|
|
lbActions.Tag := 0; // end moving
|
|
UpdateEnabledButtons;
|
|
if lbActions.CanFocus then lbActions.SetFocus;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnEditExtClick }
|
|
procedure TfrmOptionsFileAssoc.btnEditExtClick(Sender: TObject);
|
|
var
|
|
iRememberIndex: integer;
|
|
sExt: string;
|
|
begin
|
|
iRememberIndex := lbExts.ItemIndex;
|
|
if iRememberIndex < 0 then Exit;
|
|
|
|
// change extension from extensions listbox
|
|
sExt := InputBox(GetTitle + ' - ' + gbExts.Hint, rsMsgEnterFileExt, lbExts.Items[iRememberIndex]);
|
|
if sExt <> lbExts.Items[iRememberIndex] then
|
|
begin
|
|
btnRemoveExtClick(btnRemoveExt); //We remove the old value
|
|
if iRememberIndex >= lbExts.Items.Count then iRememberIndex := -1;
|
|
InsertAddExtensionToLists(sExt, iRememberIndex); //We may add new one, maybe not, maybe bunch of them, etc.
|
|
end;
|
|
if lbExts.CanFocus then lbExts.SetFocus;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnInsertAddActClick }
|
|
procedure TfrmOptionsFileAssoc.btnInsertAddActClick(Sender: TObject);
|
|
var
|
|
iSubMenu: integer;
|
|
begin
|
|
pmActions.Tag := ACTUAL_ADD_ACTION;
|
|
for iSubMenu := 0 to pred(pmActions.Items.Count) do
|
|
with pmActions.Items[iSubMenu] do
|
|
Tag := ifthen((TComponent(Sender).Tag = $20), (Tag or $20), (Tag and $DF));
|
|
pmActions.PopUp();
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnActionsClick }
|
|
procedure TfrmOptionsFileAssoc.btnActionsClick(Sender: TObject);
|
|
begin
|
|
pmActions.tag := SET_ACTION_WORD;
|
|
pmActions.PopUp();
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnCloneActClick }
|
|
procedure TfrmOptionsFileAssoc.btnCloneActClick(Sender: TObject);
|
|
var
|
|
ExtAction: TExtAction;
|
|
I: integer;
|
|
begin
|
|
ExtAction := Exts.Items[lbFileTypes.ItemIndex];
|
|
|
|
I := lbActions.ItemIndex;
|
|
if (I + 1) <= pred(ExtAction.ActionList.Count) then
|
|
begin
|
|
ExtAction.ActionList.Insert(I + 1, ExtAction.ActionList.ExtActionCommand[I].CloneExtAction); // add action to TExtAction
|
|
lbActions.Items.InsertObject(I + 1, '', ExtAction.ActionList.ExtActionCommand[I + 1]); // add action to actions listbox
|
|
end
|
|
else
|
|
begin
|
|
ExtAction.ActionList.Add(ExtAction.ActionList.ExtActionCommand[I].CloneExtAction); // add action to TExtAction
|
|
lbActions.Items.AddObject(ExtAction.ActionList.ExtActionCommand[I + 1].ActionName, ExtAction.ActionList.ExtActionCommand[I + 1]); // add action to actions listbox
|
|
end;
|
|
|
|
lbActions.ItemIndex := I + 1;
|
|
edbActionNameChange(edbActionName); //<--Trig this event to force redraw of lbActions current selected element because in case of switch from "open" to identical "open" for exemple, "edbActionChange" is not trig and so our element in the list is not drawn!
|
|
|
|
UpdateEnabledButtons;
|
|
|
|
if edbActionName.CanFocus then
|
|
begin
|
|
edbActionName.SetFocus;
|
|
edbActionName.SelStart := UTF8Length(edbActionName.Text);
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnRemoveActClick }
|
|
procedure TfrmOptionsFileAssoc.btnRemoveActClick(Sender: TObject);
|
|
var
|
|
I: integer;
|
|
begin
|
|
// remove action from actions listbox
|
|
with lbActions do
|
|
begin
|
|
I := ItemIndex;
|
|
if I < 0 then Exit;
|
|
Items.Delete(I);
|
|
|
|
if I < Items.Count then
|
|
ItemIndex := I
|
|
else
|
|
if (I - 1) < Items.Count then
|
|
ItemIndex := (I - 1);
|
|
end;
|
|
// remove action from TExts object
|
|
with lbFileTypes do
|
|
begin
|
|
Exts.Items[ItemIndex].ActionList.Delete(I);
|
|
end;
|
|
|
|
UpdateEnabledButtons;
|
|
if lbActions.CanFocus then lbActions.SetFocus;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.btnCommandsClick }
|
|
procedure TfrmOptionsFileAssoc.btnCommandsClick(Sender: TObject);
|
|
begin
|
|
pmCommands.PopUp();
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.FreeIcon }
|
|
procedure TfrmOptionsFileAssoc.FreeIcon(iIndex: integer);
|
|
begin
|
|
with lbFileTypes do
|
|
begin
|
|
Canvas.Lock;
|
|
try
|
|
if Assigned(Items.Objects[iIndex]) then
|
|
begin
|
|
Items.Objects[iIndex].Free;
|
|
Items.Objects[iIndex] := nil;
|
|
end;
|
|
finally
|
|
Canvas.Unlock;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.SetIconFileName }
|
|
procedure TfrmOptionsFileAssoc.SetIconFileName(const sFileName: string);
|
|
var
|
|
bmpTemp: TBitmap;
|
|
Index: integer;
|
|
begin
|
|
if sFileName <> EmptyStr then
|
|
begin
|
|
bmpTemp := PixMapManager.LoadBitmapEnhanced(sFileName, 32, True, sbtnIcon.Color);
|
|
if Assigned(bmpTemp) then
|
|
begin
|
|
sbtnIcon.Glyph.Assign(bmpTemp);
|
|
FreeAndNil(bmpTemp);
|
|
end
|
|
else
|
|
sbtnIcon.Glyph.Clear;
|
|
end
|
|
else
|
|
sbtnIcon.Glyph.Clear;
|
|
|
|
Index := lbFileTypes.ItemIndex;
|
|
if (Index >= 0) and (Index < Exts.Count) then
|
|
begin
|
|
FreeIcon(Index);
|
|
// save icon for use in OnDrawItem procedure
|
|
if sFileName <> EmptyStr then lbFileTypes.Items.Objects[Index] := PixMapManager.LoadBitmapEnhanced(sFileName, gIconsSize, True, Color);
|
|
lbFileTypes.Repaint;
|
|
|
|
Exts.Items[Index].Icon := sFileName;
|
|
Exts.Items[Index].IconIndex := -1;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.SetMinimumSize }
|
|
procedure TfrmOptionsFileAssoc.SetMinimumSize;
|
|
begin
|
|
gbFileTypes.Constraints.MinWidth :=
|
|
gbFileTypes.BorderSpacing.Left + btnRemoveType.Left + btnRemoveType.Width + 5 + // space between
|
|
btnRenameType.Width + gbFileTypes.Width - (btnRenameType.Left + btnRenameType.Width) + gbFileTypes.BorderSpacing.Right;
|
|
|
|
pnlLeftSettings.Constraints.MinWidth :=
|
|
gbFileTypes.Constraints.MinWidth + gbFileTypes.BorderSpacing.Around;
|
|
|
|
Constraints.MinWidth :=
|
|
pnlLeftSettings.Constraints.MinWidth + pnlLeftSettings.BorderSpacing.Left + pnlLeftSettings.BorderSpacing.Right + pnlLeftSettings.BorderSpacing.Around + pnlRightSettings.Constraints.MinWidth + pnlRightSettings.BorderSpacing.Left +
|
|
pnlRightSettings.BorderSpacing.Right + pnlRightSettings.BorderSpacing.Around;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.MakeUsInPositionToWorkWithActiveFile }
|
|
procedure TfrmOptionsFileAssoc.MakeUsInPositionToWorkWithActiveFile;
|
|
var
|
|
aFile: TFile;
|
|
InnerActionList: TExtActionList;
|
|
IndexOfFirstPossibleFileType: integer;
|
|
sFileType, sDummy: string;
|
|
ExtAction: TExtAction;
|
|
iInsertPosition: integer;
|
|
iSelectedFileType: integer = -1;
|
|
InnerFileTypeNameList: TStringList;
|
|
begin
|
|
aFile := frmMain.ActiveFrame.CloneActiveFile;
|
|
if Assigned(aFile) then
|
|
begin
|
|
if (not aFile.IsDirectory) and (not aFile.IsLink) and (not (aFile.Extension = '')) then
|
|
begin
|
|
InnerActionList := TExtActionList.Create;
|
|
try
|
|
if gExts.GetExtActions(aFile, InnerActionList, @IndexOfFirstPossibleFileType) then
|
|
begin
|
|
if (IndexOfFirstPossibleFileType <> -1) and (lbFileTypes.Items.Count > IndexOfFirstPossibleFileType) then //Double verification, but unnecessary.
|
|
begin
|
|
lbFileTypes.ItemIndex := IndexOfFirstPossibleFileType;
|
|
lbFileTypesSelectionChange(lbFileTypes, False);
|
|
lbExts.ItemIndex := lbExts.Items.IndexOf(aFile.Extension);
|
|
if (lbExts.ItemIndex = -1) and (lbExts.Items.Count > 0) then lbExts.ItemIndex := 0;
|
|
end;
|
|
end
|
|
else
|
|
begin
|
|
// Extension of current selected file is not in our file associations list.
|
|
if gOfferToAddToFileAssociations then
|
|
begin
|
|
InnerFileTypeNameList := TStringList.Create;
|
|
try
|
|
InnerFileTypeNameList.Assign(lbFileTypes.Items);
|
|
InnerFileTypeNameList.Insert(0, Format(rsMsgCreateANewFileType, [UpperCase(aFile.Extension)]));
|
|
|
|
if ShowInputListBox(rsMsgTitleExtNotInFileType, Format(rsMsgSekectFileType, [aFile.Extension]), InnerFileTypeNameList, sDummy, iSelectedFileType) then
|
|
begin
|
|
if iSelectedFileType <> -1 then
|
|
begin
|
|
if iSelectedFileType <> 0 then
|
|
begin
|
|
Dec(iSelectedFileType);
|
|
|
|
//1. Select the specified file type
|
|
lbFileTypes.ItemIndex := iSelectedFileType;
|
|
lbFileTypesSelectionChange(lbFileTypes, False);
|
|
|
|
//2. Add the extension to listbox AND structure
|
|
iInsertPosition := lbExts.Items.Add(aFile.Extension);
|
|
lbExts.ItemIndex := iInsertPosition;
|
|
Exts.Items[lbFileTypes.ItemIndex].Extensions.Add(aFile.Extension);
|
|
end
|
|
else
|
|
begin
|
|
sFileType := UpperCase(aFile.Extension) + ' ' + rsSimpleWordFiles;
|
|
|
|
if InputQuery(rsMsgTitleExtNotInFileType, Format(rsMsgEnterNewFileTypeName, [aFile.Extension]), sFileType) then
|
|
begin
|
|
//1. Create the file type
|
|
ExtAction := TExtAction.Create;
|
|
ExtAction.IconIndex := -1;
|
|
ExtAction.Name := sFileType;
|
|
lbFileTypes.Items.AddObject(ExtAction.Name, nil);
|
|
|
|
//2. Add it to our structure AND listbox
|
|
Exts.AddItem(ExtAction);
|
|
lbFileTypes.ItemIndex := pred(lbFileTypes.Items.Count);
|
|
|
|
//3. Add the extension to listbox AND structure
|
|
iInsertPosition := lbExts.Items.Add(aFile.Extension);
|
|
lbExts.ItemIndex := iInsertPosition;
|
|
Exts.Items[lbFileTypes.ItemIndex].Extensions.Add(aFile.Extension);
|
|
|
|
//4. Select an action for "open"
|
|
pmActions.tag := ACTUAL_ADD_ACTION;
|
|
miActionsClick(miOpenWith);
|
|
|
|
//5. Refresh display to have appropriate button shown.
|
|
UpdateEnabledButtons;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
FreeAndNil(InnerFileTypeNameList);
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
finally
|
|
FreeAndNil(InnerActionList);
|
|
end;
|
|
|
|
FreeAndNil(aFile);
|
|
end;
|
|
end;
|
|
if lbFileTypes.CanFocus then lbFileTypes.SetFocus;
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.actSelectFileTypeExecute(Sender: TObject);
|
|
begin
|
|
if lbFileTypes.CanFocus then
|
|
lbFileTypes.SetFocus;
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.actSelectIconExecute(Sender: TObject);
|
|
begin
|
|
if edIconFileName.CanFocus then
|
|
edIconFileName.SetFocus;
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.actSelectExtensionsExecute(Sender: TObject);
|
|
begin
|
|
if lbExts.CanFocus then
|
|
lbExts.SetFocus;
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.actSelectActionsExecute(Sender: TObject);
|
|
begin
|
|
if lbActions.CanFocus then
|
|
lbActions.SetFocus;
|
|
end;
|
|
|
|
procedure TfrmOptionsFileAssoc.actSelectActionDescriptionExecute(Sender: TObject);
|
|
begin
|
|
if edbActionName.CanFocus then
|
|
edbActionName.SetFocus;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.GetFileAssocFilenameToSave }
|
|
function TfrmOptionsFileAssoc.GetFileAssocFilenameToSave(AFileAssocPathModifierElement:tFileAssocPathModifierElement; sParamFilename: string): string;
|
|
var
|
|
sMaybeBasePath, SubWorkingPath, MaybeSubstitionPossible: string;
|
|
begin
|
|
sParamFilename := mbExpandFileName(sParamFilename);
|
|
Result := sParamFilename;
|
|
|
|
if AFileAssocPathModifierElement in gFileAssocPathModifierElements then
|
|
begin
|
|
if gFileAssocFilenameStyle = pfsRelativeToDC then sMaybeBasePath := EnvVarCommanderPath else sMaybeBasePath := gFileAssocPathToBeRelativeTo;
|
|
case gFileAssocFilenameStyle of
|
|
pfsAbsolutePath: ;
|
|
pfsRelativeToDC, pfsRelativeToFollowingPath:
|
|
begin
|
|
SubWorkingPath := IncludeTrailingPathDelimiter(mbExpandFileName(sMaybeBasePath));
|
|
MaybeSubstitionPossible := ExtractRelativePath(IncludeTrailingPathDelimiter(SubWorkingPath), sParamFilename);
|
|
if MaybeSubstitionPossible <> sParamFilename then
|
|
Result := IncludeTrailingPathDelimiter(sMaybeBasePath) + MaybeSubstitionPossible;
|
|
end;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
{ TfrmOptionsFileAssoc.ScanFileAssocForFilenameAndPath }
|
|
procedure TfrmOptionsFileAssoc.ScanFileAssocForFilenameAndPath;
|
|
var
|
|
ActionList: TExtActionList;
|
|
iFileType, iAction: Integer;
|
|
begin
|
|
for iFileType := 0 to Pred(Exts.Count) do
|
|
begin
|
|
Exts.FileType[iFileType].Icon := GetFileAssocFilenameToSave(fameIcon, Exts.FileType[iFileType].Icon);
|
|
ActionList := Exts.FileType[iFileType].ActionList;
|
|
for iAction := 0 to Pred(ActionList.Count) do
|
|
begin
|
|
ActionList.ExtActionCommand[iAction].CommandName := GetFileAssocFilenameToSave(fameCommand, ActionList.ExtActionCommand[iAction].CommandName);
|
|
ActionList.ExtActionCommand[iAction].StartPath := GetFileAssocFilenameToSave(fameStartingPath, ActionList.ExtActionCommand[iAction].StartPath);
|
|
end;
|
|
end;
|
|
|
|
//Kind of refresh of what might be displayed.
|
|
if lbFileTypes.ItemIndex <> -1 then
|
|
lbFileTypesSelectionChange(lbFileTypes, True);
|
|
end;
|
|
|
|
end.
|