doublecmd/src/umaincommands.pas

2948 lines
89 KiB
ObjectPascal

{
Double Commander
-------------------------------------------------------------------------
This unit contains DC actions of the main form
Copyright (C) 2008 Dmitry Kolomiets (B4rr4cuda@rambler.ru)
Copyright (C) 2008-2013 Koblov Alexander (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 uMainCommands;
{$mode objfpc}{$H+}
interface
uses
Classes, SysUtils, ActnList, uFileView, uFileViewNotebook, uFileSourceOperation,
uFileFunctions, uFormCommands;
type
{ TMainCommands }
TMainCommands = class(TComponent{$IF FPC_FULLVERSION >= 020501}, IFormCommands{$ENDIF})
private
FCommands: TFormCommands;
// Filters out commands.
function CommandsFilter(Command: String): Boolean;
procedure OnCopyOutStateChanged(Operation: TFileSourceOperation;
State: TFileSourceOperationState);
procedure OnCalcStatisticsStateChanged(Operation: TFileSourceOperation;
State: TFileSourceOperationState);
procedure OnCalcChecksumStateChanged(Operation: TFileSourceOperation;
State: TFileSourceOperationState);
public
constructor Create(TheOwner: TComponent; ActionList: TActionList = nil); reintroduce;
property Commands: TFormCommands read FCommands{$IF FPC_FULLVERSION >= 020501} implements IFormCommands{$ENDIF};
//---------------------
// The Do... functions are cm_... functions' counterparts which are to be
// executed directly from the code with specific - especially non-string
// - arguments (instead of calling cm_... functions, in which case
// parameters would have to be converted to and from strings).
//
procedure DoOpenVirtualFileSystemList(Panel: TFileView);
procedure DoPanelsSplitterPerPos(SplitPos: Integer);
procedure DoCloseTab(Notebook: TFileViewNotebook; PageIndex: Integer);
procedure DoCopySelectedFileNamesToClipboard(FileView: TFileView; FullNames: Boolean);
procedure DoNewTab(Notebook: TFileViewNotebook);
procedure DoRenameTab(Page: TFileViewPage);
procedure DoContextMenu(Panel: TFileView; X, Y: Integer; Background: Boolean);
procedure DoTransferPath(SourcePage: TFileViewPage; TargetPage: TFileViewPage; FromActivePanel: Boolean);
procedure DoSortByFunctions(View: TFileView; FileFunctions: TFileFunctions);
procedure DoShowMainMenu(bShow: Boolean);
procedure DoShowCmdLineHistory(bNextCmdLine: Boolean);
//---------------------
published
//--------------------------------------------------------------------------
// All commands can be split into three groups:
// 1. Commands intended for the application (cm_VisitHomePage,
// cm_About, cm_Exit, ...).
//
// 2. Commands intended for file views (cm_QuickSearch, cm_EditPath, etc.).
// Those commands are simply redirected to the currently active file view by calling:
// frmMain.ActiveFrame.ExecuteCommand(CommandName, Param);
// If they are supported by the given file view they are executed there.
//
// If in future there will be a need to pass specific parameters to the
// commands, i.e. not string, they should be implemented by creating
// an interface for each command, and each file view implementing those
// interfaces which commands it supports.
//
// 3. Commands intended for file sources (cm_Copy, cm_Rename, cm_MakeDir).
// The file operations will mostly work only for non-virtual file sources.
//
procedure cm_AddPathToCmdLine(const Params: array of string);
procedure cm_AddFilenameToCmdLine(const Params: array of string);
procedure cm_AddPathAndFilenameToCmdLine(const Params: array of string);
procedure cm_CmdLineNext(const Params: array of string);
procedure cm_CmdLinePrev(const Params: array of string);
procedure cm_ContextMenu(const Params: array of string);
procedure cm_CopyFullNamesToClip(const Params: array of string);
procedure cm_Exchange(const Params: array of string);
procedure cm_OpenArchive(const Params: array of string);
procedure cm_TestArchive(const Params: array of string);
procedure cm_OpenDirInNewTab(const Params: array of string);
procedure cm_Open(const Params: array of string);
procedure cm_ShellExecute(const Params: array of string);
procedure cm_OpenVirtualFileSystemList(const Params: array of string);
procedure cm_TargetEqualSource(const Params: array of string);
procedure cm_LeftEqualRight(const Params: array of string);
procedure cm_RightEqualLeft(const Params: array of string);
procedure cm_PackFiles(const Params: array of string);
procedure cm_ExtractFiles(const Params: array of string);
procedure cm_QuickSearch(const Params: array of string);
procedure cm_QuickFilter(const Params: array of string);
procedure cm_LeftOpenDrives(const Params: array of string);
procedure cm_RightOpenDrives(const Params: array of string);
procedure cm_OpenBar(const Params: array of string);
procedure cm_ShowButtonMenu(const Params: array of string);
procedure cm_TransferLeft(const Params: array of string);
procedure cm_TransferRight(const Params: array of string);
procedure cm_GoToFirstFile(const Params: array of string);
procedure cm_GoToLastFile(const Params: array of string);
procedure cm_Minimize(const Params: array of string);
procedure cm_Wipe(const Params: array of string);
procedure cm_Exit(const Params: array of string);
procedure cm_NewTab(const Params: array of string);
procedure cm_RenameTab(const Params: array of string);
procedure cm_CloseTab(const Params: array of string);
procedure cm_CloseAllTabs(const Params: array of string);
procedure cm_NextTab(const Params: array of string);
procedure cm_PrevTab(const Params: array of string);
procedure cm_SetTabOptionNormal(const Params: array of string);
procedure cm_SetTabOptionPathLocked(const Params: array of string);
procedure cm_SetTabOptionPathResets(const Params: array of string);
procedure cm_SetTabOptionDirsInNewTab(const Params: array of string);
procedure cm_Copy(const Params: array of string);
procedure cm_CopyNoAsk(const Params: array of string);
procedure cm_Delete(const Params: array of string);
procedure cm_CheckSumCalc(const Params: array of string);
procedure cm_CheckSumVerify(const Params: array of string);
procedure cm_Edit(const Params: array of string);
procedure cm_EditPath(const Params: array of string);
procedure cm_MakeDir(const Params: array of string);
procedure cm_Rename(const Params: array of string);
procedure cm_RenameNoAsk(const Params: array of string);
procedure cm_View(const Params: array of string);
procedure cm_QuickView(const Params: array of string);
procedure cm_BriefView(const Params: array of string);
procedure cm_ColumnsView(const Params: array of string);
procedure cm_ThumbnailsView(const Params: array of string);
procedure cm_CopyNamesToClip(const Params: array of string);
procedure cm_FocusCmdLine(const Params: array of string);
procedure cm_FileAssoc(const Params: array of string);
procedure cm_HelpIndex(const Params: array of string);
procedure cm_Keyboard(const Params: array of string);
procedure cm_VisitHomePage(const Params: array of string);
procedure cm_About(const Params: array of string);
procedure cm_ShowSysFiles(const Params: array of string);
procedure cm_SwitchIgnoreList(const Params: array of string);
procedure cm_Options(const Params: array of string);
procedure cm_CompareContents(const Params: array of string);
procedure cm_Refresh(const Params: array of string);
procedure cm_ShowMainMenu(const Params: array of string);
procedure cm_DirHotList(const Params: array of string);
procedure cm_MarkInvert(const Params: array of string);
procedure cm_MarkMarkAll(const Params: array of string);
procedure cm_MarkUnmarkAll(const Params: array of string);
procedure cm_MarkPlus(const Params: array of string);
procedure cm_MarkMinus(const Params: array of string);
procedure cm_MarkCurrentExtension(const Params: array of string);
procedure cm_UnmarkCurrentExtension(const Params: array of string);
procedure cm_SaveSelection(const Params: array of string);
procedure cm_RestoreSelection(const Params: array of string);
procedure cm_SaveSelectionToFile(const Params: array of string);
procedure cm_LoadSelectionFromFile(const Params: array of string);
procedure cm_LoadSelectionFromClip(const Params: array of string);
procedure cm_Search(const Params: array of string);
procedure cm_HardLink(const Params: array of string);
procedure cm_MultiRename(const Params: array of string);
procedure cm_ReverseOrder(const Params: array of string);
procedure cm_SortByAttr(const Params: array of string);
procedure cm_SortByDate(const Params: array of string);
procedure cm_SortByExt(const Params: array of string);
procedure cm_SortByName(const Params: array of string);
procedure cm_SortBySize(const Params: array of string);
procedure cm_SymLink(const Params: array of string);
procedure cm_CopySamePanel(const Params: array of string);
procedure cm_DirHistory(const Params: array of string);
procedure cm_ViewHistory(const Params: array of string);
procedure cm_ViewHistoryPrev(const Params: array of string);
procedure cm_ViewHistoryNext(const Params: array of string);
procedure cm_EditNew(const Params: array of string);
procedure cm_RenameOnly(const Params: array of string);
procedure cm_RunTerm(const Params: array of string);
procedure cm_ShowCmdLineHistory(const Params: array of string);
procedure cm_CalculateSpace(const Params: array of string);
procedure cm_CountDirContent(const Params: array of string);
procedure cm_SetFileProperties(const Params: array of string);
procedure cm_FileProperties(const Params: array of string);
procedure cm_FileLinker(const Params: array of string);
procedure cm_FileSpliter(const Params: array of string);
procedure cm_PanelsSplitterPerPos(const Params: array of string);
procedure cm_EditComment(const Params: array of string);
procedure cm_CopyToClipboard(const Params: array of string);
procedure cm_CutToClipboard(const Params: array of string);
procedure cm_PasteFromClipboard(const Params: array of string);
procedure cm_ChangeDirToRoot(const Params: array of string);
procedure cm_ChangeDirToParent(const Params: array of string);
procedure cm_ChangeDir(const Params: array of string);
procedure cm_ClearLogWindow(const Params: array of string);
procedure cm_ClearLogFile(const Params: array of string);
procedure cm_NetworkConnect(const Params: array of string);
procedure cm_NetworkDisconnect(const Params: array of string);
procedure cm_HorizontalFilePanels(const Params: array of string);
procedure cm_OperationsViewer(const Params: array of string);
procedure cm_CompareDirectories(const Params: array of string);
// Internal commands
procedure cm_ExecuteToolbarItem(const Params: array of string);
end;
implementation
uses Forms, Controls, Dialogs, Clipbrd, strutils, LCLProc, HelpIntfs, StringHashList,
dmHelpManager, typinfo, fMain, fPackDlg, fMkDir, fFileAssoc,
fExtractDlg, fAbout, fOptions, fDiffer, fFindDlg, fSymLink, fHardLink, fMultiRename,
fLinker, fSplitter, fDescrEdit, fCheckSumVerify, fCheckSumCalc, fSetFileProperties,
uGlobs, uLng, uLog, uShowMsg, uOSForms, uOSUtils, uDCUtils, uBriefFileView,
uShowForm, uShellExecute, uClipboard, uHash, uDisplayFile, uColumnsFileView,
uFilePanelSelect, uFile, uFileSystemFileSource, uQuickViewPanel,
uOperationsManager, uFileSourceOperationTypes, uWfxPluginFileSource,
uFileSystemDeleteOperation, uFileSourceExecuteOperation, uSearchResultFileSource,
uFileSourceOperationMessageBoxesUI, uFileSourceCalcChecksumOperation,
uFileSourceCalcStatisticsOperation, uFileSource, uFileSourceProperty,
uVfsFileSource, uFileSourceUtil, uArchiveFileSourceUtil, uThumbFileView,
uTempFileSystemFileSource, uFileProperty, uFileSourceSetFilePropertyOperation,
uFileSorting, uShellContextMenu, uTrash, uFileSystemCopyOperation,
fViewOperations, uVfsModule, uMultiListFileSource, uExceptions,
DCOSUtils, DCStrUtils, DCBasicTypes, uFileSourceCopyOperation
{$IFDEF COLUMNSFILEVIEW_VTV}
, uColumnsFileViewVtv
{$ENDIF}
;
procedure ReadCopyRenameParams(
const Params: array of string;
var Confirmation: Boolean;
out HasQueueId: Boolean;
out QueueIdentifier: TOperationsManagerQueueIdentifier);
var
Param, sQueueId: String;
BoolValue: Boolean;
iQueueId: Integer;
begin
HasQueueId := False;
for Param in Params do
begin
if GetParamBoolValue(Param, 'confirmation', BoolValue) then
Confirmation := BoolValue
else if GetParamValue(Param, 'queueid', sQueueId) then
begin
HasQueueId := TryStrToInt(sQueueId, iQueueId);
if HasQueueId then
QueueIdentifier := iQueueId;
end;
end;
end;
{ TMainCommands }
constructor TMainCommands.Create(TheOwner: TComponent; ActionList: TActionList = nil);
begin
inherited Create(TheOwner);
FCommands := TFormCommands.Create(Self, ActionList);
FCommands.FilterFunc := @CommandsFilter;
end;
function TMainCommands.CommandsFilter(Command: String): Boolean;
begin
Result := Command = 'cm_ExecuteToolbarItem';
end;
//------------------------------------------------------
procedure TMainCommands.OnCopyOutStateChanged(Operation: TFileSourceOperation;
State: TFileSourceOperationState);
var
I: Integer;
aFile: TFile;
sViewCmd: String;
aFileList: TStringList;
aFileSource: ITempFileSystemFileSource;
aCopyOutOperation: TFileSourceCopyOutOperation;
begin
if (State = fsosStopped) and (Operation.Result = fsorFinished) then
begin
aFileList := TStringList.Create;
try
aCopyOutOperation := Operation as TFileSourceCopyOutOperation;
aFileSource := aCopyOutOperation.TargetFileSource as ITempFileSystemFileSource;
ChangeFileListRoot(aFileSource.FileSystemRoot, aCopyOutOperation.SourceFiles);
try
for I := 0 to aCopyOutOperation.SourceFiles.Count - 1 do
begin
aFile := aCopyOutOperation.SourceFiles[I];
if not (aFile.IsDirectory or aFile.IsLinkToDirectory) then
begin
// Try to find 'view' command in internal associations
sViewCmd:= gExts.GetExtActionCmd(aFile, 'view');
if Length(sViewCmd) = 0 then
aFileList.Add(aFile.FullPath)
else
begin
sViewCmd := PrepareParameter(sViewCmd, aFile);
ProcessExtCommand(sViewCmd, aCopyOutOperation.SourceFiles.Path);
// TODO:
// If TempFileSource is used, create a wait thread that will
// keep the TempFileSource alive until the command is finished.
end;
end; // if selected
end; // for
// if aFileList has files then view it
if aFileList.Count > 0 then
ShowViewerByGlobList(aFileList, aFileSource);
except
on e: EInvalidCommandLine do
MessageDlg(rsToolErrorOpeningViewer,
rsMsgInvalidCommandLine + ' (' + rsToolViewer + '):' + LineEnding + e.Message,
mtError, [mbOK], 0);
end;
finally
FreeAndNil(aFileList);
end;
end;
end;
procedure TMainCommands.OnCalcStatisticsStateChanged(Operation: TFileSourceOperation;
State: TFileSourceOperationState);
var
CalcStatisticsOperation: TFileSourceCalcStatisticsOperation;
CalcStatisticsOperationStatistics: TFileSourceCalcStatisticsOperationStatistics;
begin
if (State = fsosStopped) and (Operation.Result = fsorFinished) then
begin
CalcStatisticsOperation := Operation as TFileSourceCalcStatisticsOperation;
CalcStatisticsOperationStatistics := CalcStatisticsOperation.RetrieveStatistics;
with CalcStatisticsOperationStatistics do
begin
msgOK(Format(rsSpaceMsg, [Files, Directories, cnvFormatFileSize(Size), Numb2USA(IntToStr(Size))]));
end;
end;
end;
procedure TMainCommands.OnCalcChecksumStateChanged(Operation: TFileSourceOperation;
State: TFileSourceOperationState);
var
CalcChecksumOperation: TFileSourceCalcChecksumOperation;
begin
if (State = fsosStopped) and (Operation.Result = fsorFinished) then
begin
CalcChecksumOperation := Operation as TFileSourceCalcChecksumOperation;
if CalcChecksumOperation.Mode = checksum_verify then
ShowVerifyCheckSum(CalcChecksumOperation.Result);
end;
end;
//------------------------------------------------------
procedure TMainCommands.DoCloseTab(Notebook: TFileViewNotebook; PageIndex: Integer);
begin
with frmMain do
begin
RemovePage(Notebook, PageIndex);
ActiveFrame.SetFocus;
end;
end;
procedure TMainCommands.DoShowCmdLineHistory(bNextCmdLine: Boolean);
begin
with frmMain do
begin
if edtCommand.Visible then
begin
if not (gCmdLine and frmMain.IsCommandLineVisible) then
pnlCommand.Show;
edtCommand.SetFocus;
if bNextCmdLine then
begin
if edtCommand.ItemIndex > 0 then
edtCommand.ItemIndex := edtCommand.ItemIndex - 1;
end
else
begin
if edtCommand.ItemIndex < edtCommand.Items.Count - 1 then
edtCommand.ItemIndex := edtCommand.ItemIndex + 1;
end;
end;
end;
end;
procedure TMainCommands.DoCopySelectedFileNamesToClipboard(FileView: TFileView; FullNames: Boolean);
var
I: Integer;
sl: TStringList = nil;
SelectedFiles: TFiles = nil;
PathToAdd: String;
begin
SelectedFiles := FileView.CloneSelectedOrActiveFiles;
try
if SelectedFiles.Count > 0 then
begin
sl := TStringList.Create;
for I := 0 to SelectedFiles.Count - 1 do
begin
if FullNames then
begin
// Workaround for not fully implemented TMultiListFileSource.
if not FileView.FileSource.IsClass(TMultiListFileSource) then
PathToAdd := FileView.CurrentAddress
else
PathToAdd := '';
PathToAdd := PathToAdd + SelectedFiles[I].Path;
end
else
PathToAdd := '';
sl.Add(PathToAdd + SelectedFiles[I].Name);
end;
Clipboard.Clear; // prevent multiple formats in Clipboard (specially synedit)
Clipboard.AsText:= TrimRightLineEnding(sl.Text, sl.TextLineBreakStyle);
end;
finally
if Assigned(sl) then
FreeAndNil(sl);
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
end;
end;
procedure TMainCommands.DoNewTab(Notebook: TFileViewNotebook);
var
NewPage: TFileViewPage;
begin
NewPage := Notebook.NewPage(Notebook.ActiveView);
NewPage.MakeActive;
end;
procedure TMainCommands.DoRenameTab(Page: TFileViewPage);
var
sCaption: UTF8String;
begin
sCaption := Page.CurrentTitle;
if InputQuery(rsMsgTabRenameCaption, rsMsgTabRenamePrompt, sCaption) then
Page.PermanentTitle := sCaption;
end;
procedure TMainCommands.DoOpenVirtualFileSystemList(Panel: TFileView);
var
FileSource: IFileSource;
begin
FileSource:= TVfsFileSource.Create(gWFXPlugins);
if Assigned(FileSource) then
Panel.AddFileSource(FileSource, FileSource.GetRootDir);
end;
procedure TMainCommands.DoPanelsSplitterPerPos(SplitPos: Integer);
begin
with frmMain do
begin
if (SplitPos >= 0) and (SplitPos <= 100) then
begin
// Calculate panel width
if not gHorizontalFilePanels then
pnlLeft.Width:= (pnlNoteBooks.Width - MainSplitter.Width) * SplitPos div 100
else
pnlLeft.Height:= (pnlNoteBooks.Height - MainSplitter.Height) * SplitPos div 100;
// Update splitter position
MainSplitterPos:= SplitPos;
end;
end;
end;
procedure TMainCommands.DoContextMenu(Panel: TFileView; X, Y: Integer; Background: Boolean);
var
aFile: TFile = nil;
aFiles: TFiles = nil;
sPath, sName: UTF8String;
begin
with frmMain do
begin
if not (fspDirectAccess in Panel.FileSource.Properties) then
begin
if not Background then pmContextMenu.PopUp(X, Y);
Exit;
end;
if not Panel.HasSelectedFiles then
begin
aFile:= Panel.CloneActiveFile;
if Assigned(aFile) then
begin
sName:= aFile.Name;
FreeAndNil(aFile);
end;
end;
if (Background = True) or (sName = '..') then
begin
sName:= ExcludeTrailingPathDelimiter(Panel.CurrentPath);
sPath:= ExtractFilePath(sName);
aFiles:= TFiles.Create(sPath);
aFile:= Panel.FileSource.CreateFileObject(sPath);
aFile.Attributes:= faFolder;
aFile.Name:= ExtractFileName(sName);
aFiles.Add(aFile);
end
else
begin
aFiles:= Panel.CloneSelectedOrActiveFiles;
end;
if Assigned(aFiles) then
try
if aFiles.Count > 0 then
try
ShowContextMenu(frmMain, aFiles, X, Y, Background, nil);
except
on e: EContextMenuException do
ShowException(e);
end;
finally
if Assigned(aFiles) then
FreeAndNil(aFiles);
end;
end;
end;
procedure TMainCommands.DoTransferPath(SourcePage: TFileViewPage; TargetPage: TFileViewPage; FromActivePanel: Boolean);
var
aFile: TFile;
NewPath: String;
begin
if FromActivePanel then
begin
aFile := SourcePage.FileView.CloneActiveFile;
if Assigned(aFile) then
try
if (fspLinksToLocalFiles in SourcePage.FileView.FileSource.GetProperties) and
(SourcePage.FileView.FileSource.GetLocalName(aFile)) then
begin
if aFile.IsDirectory then
ChooseFileSource(TargetPage.FileView, aFile.FullPath)
else if not ChooseFileSource(TargetPage.FileView, aFile) then
begin
ChooseFileSource(TargetPage.FileView, aFile.Path);
TargetPage.FileView.SetActiveFile(aFile.Name);
end;
end
else if aFile.IsDirectory then
begin
if aFile.Name = '..' then
begin
NewPath := GetParentDir(SourcePage.FileView.CurrentPath)
end
else
begin
// Change to a subdirectory.
NewPath := aFile.FullPath;
end;
if NewPath <> EmptyStr then
TargetPage.FileView.AddFileSource(SourcePage.FileView.FileSource, NewPath);
end
else
begin
// Change file source, if the file under cursor can be opened as another file source.
try
if not ChooseFileSource(TargetPage.FileView, aFile) then
TargetPage.FileView.AddFileSource(SourcePage.FileView.FileSource,
SourcePage.FileView.CurrentPath);
except
on e: EFileSourceException do
MessageDlg('Error', e.Message, mtError, [mbOK], 0);
end;
end;
finally
FreeAndNil(aFile);
end;
end
else
begin
TargetPage.FileView.AddFileSource(SourcePage.FileView.FileSource, SourcePage.FileView.CurrentPath);
end;
end;
procedure TMainCommands.DoSortByFunctions(View: TFileView; FileFunctions: TFileFunctions);
var
NewSorting: TFileSortings = nil;
CurrentSorting: TFileSortings;
SortDirection: TSortDirection = sdNone;
i: Integer;
begin
if Length(FileFunctions) = 0 then
Exit;
CurrentSorting := View.Sorting;
// Check if there is already sorting by one of the functions.
// If it is then reverse direction of sorting.
for i := 0 to Length(FileFunctions) - 1 do
begin
SortDirection := GetSortDirection(CurrentSorting, FileFunctions[i]);
if SortDirection <> sdNone then
begin
SortDirection := ReverseSortDirection(SortDirection);
Break;
end;
end;
if SortDirection = sdNone then
SortDirection := sdAscending;
SetLength(NewSorting, 1);
SetLength(NewSorting[0].SortFunctions, 1);
NewSorting[0].SortFunctions[0] := FileFunctions[0]; // Sort by single function.
NewSorting[0].SortDirection := SortDirection;
View.Sorting := NewSorting;
end;
procedure TMainCommands.DoShowMainMenu(bShow: Boolean);
begin
gMainMenu := bShow;
with frmMain do
begin
if bShow then
begin
Menu := mnuMain;
end
else if Assigned(Menu) then
begin
Menu := nil;
{$IFDEF MSWINDOWS}
// Workaround: on Windows need to recreate window to properly recalculate children sizes.
RecreateWnd(frmMain);
{$ENDIF}
end;
end;
end;
//------------------------------------------------------
//Published methods
//------------------------------------------------------
procedure TMainCommands.cm_AddPathToCmdLine(const Params: array of string);
var
OldPosition: Integer;
AddedString: String;
begin
with frmMain do
begin
OldPosition := edtCommand.SelStart;
AddedString := QuoteStr(ActiveFrame.CurrentPath);
edtCommand.Text := edtCommand.Text + AddedString;
edtCommand.SelStart := OldPosition + Length(AddedString);
end;
end;
procedure TMainCommands.cm_AddFilenameToCmdLine(const Params: array of string);
var
AddedString: String;
OldPosition: Integer;
aFile: TFile;
begin
with frmMain do
begin
aFile := ActiveFrame.CloneActiveFile;
if Assigned(aFile) then
try
OldPosition := edtCommand.SelStart;
AddedString := QuoteStr(aFile.Name) + ' ';
edtCommand.Text := edtCommand.Text + AddedString;
edtCommand.SelStart := OldPosition + Length(AddedString);
finally
FreeAndNil(aFile);
end;
end;
end;
procedure TMainCommands.cm_AddPathAndFilenameToCmdLine(const Params: array of string);
var
AddedString: String;
OldPosition: Integer;
aFile: TFile;
begin
with frmMain do
begin
aFile := ActiveFrame.CloneActiveFile;
if Assigned(aFile) then
try
if aFile.Name = '..' then
AddedString := QuoteStr(ActiveFrame.CurrentPath) + ' '
else
AddedString := QuoteStr(aFile.FullPath) + ' ';
OldPosition := edtCommand.SelStart;
edtCommand.Text := edtCommand.Text + AddedString;
edtCommand.SelStart := OldPosition + Length(AddedString);
finally
FreeAndNil(aFile);
end;
end;
end;
procedure TMainCommands.cm_ContextMenu(const Params: array of string);
begin
// Let file view handle displaying context menu at appropriate position.
frmMain.ActiveFrame.ExecuteCommand('cm_ContextMenu', []);
end;
procedure TMainCommands.cm_CopyFullNamesToClip(const Params: array of string);
begin
DoCopySelectedFileNamesToClipboard(frmMain.ActiveFrame, True);
end;
procedure TMainCommands.cm_CopyNamesToClip(const Params: array of string);
begin
DoCopySelectedFileNamesToClipboard(frmMain.ActiveFrame, False);
end;
//------------------------------------------------------
procedure TMainCommands.cm_Exchange(const Params: array of string);
var
sDir: String;
begin
sDir:= FrmMain.ActiveFrame.CurrentPath;
FrmMain.ActiveFrame.CurrentPath:= FrmMain.NotActiveFrame.CurrentPath;
FrmMain.NotActiveFrame.CurrentPath:= sDir;
end;
procedure TMainCommands.cm_ExecuteToolbarItem(const Params: array of string);
var
ToolItemID: String;
begin
if GetParamValue(Params, 'ToolItemID', ToolItemID) then
frmMain.MainToolBar.ClickItem(ToolItemID);
end;
procedure TMainCommands.cm_OpenDirInNewTab(const Params: array of string);
procedure OpenTab(const aFullPath: string);
var
NewPage: TFileViewPage;
begin
NewPage := FrmMain.ActiveNotebook.NewPage(FrmMain.ActiveFrame);
// Workaround for Search Result File Source
if NewPage.FileView.FileSource is TSearchResultFileSource then
SetFileSystemPath(NewPage.FileView, aFullPath)
else
NewPage.FileView.CurrentPath := aFullPath;
if tb_open_new_in_foreground in gDirTabOptions then
NewPage.MakeActive;
end;
var
aFile: TFile;
begin
aFile := FrmMain.ActiveFrame.CloneActiveFile;
if Assigned(aFile) then
try
if aFile.IsNameValid and (aFile.IsDirectory or aFile.IsLinkToDirectory) then
OpenTab(aFile.FullPath)
else
OpenTab(FrmMain.ActiveFrame.CurrentPath);
finally
FreeAndNil(aFile);
end
else
OpenTab(FrmMain.ActiveFrame.CurrentPath);
end;
procedure TMainCommands.cm_TargetEqualSource(const Params: array of string);
begin
with frmMain do
begin
NotActiveNotebook.ActivePage.FileView := nil;
ActiveFrame.Clone(NotActiveNotebook.ActivePage);
end;
end;
procedure TMainCommands.cm_LeftEqualRight(const Params: array of string);
begin
with frmMain do
begin
LeftTabs.ActivePage.FileView := nil;
FrameRight.Clone(LeftTabs.ActivePage);
// Destroying active view may have caused losing focus. Restore it if needed.
if SelectedPanel = fpLeft then
FrameLeft.SetFocus;
end;
end;
procedure TMainCommands.cm_RightEqualLeft(const Params: array of string);
begin
with frmMain do
begin
RightTabs.ActivePage.FileView := nil;
FrameLeft.Clone(RightTabs.ActivePage);
// Destroying active view may have caused losing focus. Restore it if needed.
if SelectedPanel = fpRight then
FrameRight.SetFocus;
end;
end;
procedure TMainCommands.cm_OpenArchive(const Params: array of string);
var
aFile: TFile;
begin
with frmMain.ActiveFrame do
begin
aFile := CloneActiveFile;
if Assigned(aFile) then
try
if aFile.IsNameValid then
begin
if aFile.IsDirectory or aFile.IsLinkToDirectory then
ChangePathToChild(aFile)
else
ChooseArchive(frmMain.ActiveFrame, aFile, True);
end;
finally
FreeAndNil(aFile);
end;
end;
end;
procedure TMainCommands.cm_TestArchive(const Params: array of string);
var
SelectedFiles: TFiles;
begin
with frmMain do
begin
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
try
TestArchive(ActiveFrame, SelectedFiles);
finally
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
end;
end;
end;
procedure TMainCommands.cm_Open(const Params: array of string);
begin
frmMain.ActiveFrame.OpenActiveFile;
end;
procedure TMainCommands.cm_ShellExecute(const Params: array of string);
var
aFile: TFile;
begin
if Length(Params) > 0 then
with frmMain do
ShellExecute(PrepareParameter(Params[0], FrameLeft, FrameRight, ActiveFrame, []))
else
with frmMain.ActiveFrame do
begin
aFile := CloneActiveFile;
if Assigned(aFile) then
try
if aFile.IsNameValid then
begin
ShellExecute(aFile.FullPath);
end;
finally
FreeAndNil(aFile);
end;
end;
end;
procedure TMainCommands.cm_OpenVirtualFileSystemList(const Params: array of string);
begin
DoOpenVirtualFileSystemList(frmMain.ActiveFrame);
end;
//------------------------------------------------------
(* Pack files in archive by creating a new archive *)
procedure TMainCommands.cm_PackFiles(const Params: array of string);
var
SelectedFiles: TFiles;
begin
with frmMain do
begin
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
try
if SelectedFiles.Count > 0 then
ShowPackDlg(ActiveFrame.FileSource,
nil, // No specific target (create new)
SelectedFiles,
NotActiveFrame.CurrentPath,
PathDelim { Copy to root of archive } {NotActiveFrame.FileSource.GetRootString}
)
else
msgWarning(rsMsgNoFilesSelected);
finally
FreeAndNil(SelectedFiles);
end;
end;
end;
// This command is needed for extracting whole archive by Alt+F9 (without opening it).
procedure TMainCommands.cm_ExtractFiles(const Params: array of string);
var
SelectedFiles: TFiles;
begin
with frmMain do
begin
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
if Assigned(SelectedFiles) then
try
if SelectedFiles.Count > 0 then
ShowExtractDlg(ActiveFrame.FileSource, SelectedFiles,
NotActiveFrame.FileSource, NotActiveFrame.CurrentPath)
else
msgWarning(rsMsgNoFilesSelected);
finally
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
end;
end;
end;
procedure TMainCommands.cm_QuickSearch(const Params: array of string);
begin
FrmMain.ActiveFrame.ExecuteCommand('cm_QuickSearch', Params);
end;
procedure TMainCommands.cm_QuickFilter(const Params: array of string);
begin
FrmMain.ActiveFrame.ExecuteCommand('cm_QuickFilter', Params);
end;
procedure TMainCommands.cm_LeftOpenDrives(const Params: array of string);
begin
frmMain.ShowDrivesList(fpLeft);
end;
procedure TMainCommands.cm_RightOpenDrives(const Params: array of string);
begin
frmMain.ShowDrivesList(fpRight);
end;
procedure TMainCommands.cm_OpenBar(const Params: array of string);
begin
// Deprecated.
end;
procedure TMainCommands.cm_ShowButtonMenu(const Params: array of string);
begin
// Deprecated.
end;
procedure TMainCommands.cm_TransferLeft(const Params: array of string);
begin
DoTransferPath(frmMain.RightTabs.ActivePage,
frmMain.LeftTabs.ActivePage,
frmMain.SelectedPanel = fpRight);
end;
procedure TMainCommands.cm_TransferRight(const Params: array of string);
begin
DoTransferPath(frmMain.LeftTabs.ActivePage,
frmMain.RightTabs.ActivePage,
frmMain.SelectedPanel = fpLeft);
end;
procedure TMainCommands.cm_GoToFirstFile(const Params: array of string);
begin
frmMain.ActiveFrame.ExecuteCommand('cm_GoToFirstFile', []);
end;
procedure TMainCommands.cm_GoToLastFile(const Params: array of string);
begin
frmMain.ActiveFrame.ExecuteCommand('cm_GoToLastFile', []);
end;
procedure TMainCommands.cm_Minimize(const Params: array of string);
begin
FrmMain.MinimizeWindow;
end;
procedure TMainCommands.cm_Wipe(const Params: array of string);
var
theFilesToWipe: TFiles;
Operation: TFileSourceOperation;
begin
with frmMain.ActiveFrame do
begin
if not (fsoWipe in FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
// ------------------------------------------------------
theFilesToWipe := CloneSelectedOrActiveFiles; // free at Thread end by thread
if Assigned(theFilesToWipe) then
try
if theFilesToWipe.Count = 0 then
Exit;
if not msgYesNo(frmMain.GetFileDlgStr(rsMsgWipeSel, rsMsgWipeFlDr, theFilesToWipe)) then
Exit;
Operation := FileSource.CreateWipeOperation(theFilesToWipe);
if Assigned(Operation) then
begin
// Start operation.
OperationsManager.AddOperation(Operation);
end
else
begin
msgWarning(rsMsgNotImplemented);
end;
finally
if Assigned(theFilesToWipe) then
FreeAndNil(theFilesToWipe);
end;
end;
end;
procedure TMainCommands.cm_Exit(const Params: array of string);
begin
frmMain.Close; // application.Terminate not save settings.
end;
procedure TMainCommands.cm_NewTab(const Params: array of string);
begin
DoNewTab(frmMain.ActiveNotebook);
end;
procedure TMainCommands.cm_RenameTab(const Params: array of string);
begin
DoRenameTab(frmMain.ActiveNotebook.ActivePage);
end;
procedure TMainCommands.cm_CloseTab(const Params: array of string);
begin
with frmMain do
DoCloseTab(ActiveNotebook, ActiveNotebook.PageIndex);
end;
procedure TMainCommands.cm_CloseAllTabs(const Params: array of string);
var
I: Integer;
ANotebook: TFileViewNotebook;
Param: String;
begin
with frmMain do
begin
if (tb_confirm_close_all in gDirTabOptions) then
if not msgYesNo(rsMsgCloseAllInActiveTabs) then Exit;
Param := GetDefaultParam(Params);
if Param = 'LeftTabs' then
ANotebook := LeftTabs
else if Param = 'RightTabs' then
ANotebook := RightTabs
else
ANotebook := ActiveNotebook;
for I := ANotebook.PageCount - 1 downto 0 do
if I <> ANotebook.PageIndex then
case RemovePage(ANotebook, I, False) of
1: Continue; // skip tab
2: Break; // cancel operation
end;
ActiveFrame.SetFocus;
end;
end;
procedure TMainCommands.cm_NextTab(const Params: array of string);
begin
frmMain.ActiveNotebook.ActivateNextTab;
end;
procedure TMainCommands.cm_PrevTab(const Params: array of string);
begin
frmMain.ActiveNotebook.ActivatePrevTab;
end;
procedure TMainCommands.cm_SetTabOptionNormal(const Params: array of string);
begin
with frmMain.ActiveNotebook.ActivePage do
LockState := tlsNormal;
end;
procedure TMainCommands.cm_SetTabOptionPathLocked(const Params: array of string);
begin
with frmMain.ActiveNotebook.ActivePage do
LockState := tlsPathLocked;
end;
procedure TMainCommands.cm_SetTabOptionPathResets(const Params: array of string);
begin
with frmMain.ActiveNotebook.ActivePage do
LockState := tlsPathResets;
end;
procedure TMainCommands.cm_SetTabOptionDirsInNewTab(const Params: array of string);
begin
with frmMain.ActiveNotebook.ActivePage do
LockState := tlsDirsInNewTab;
end;
//------------------------------------------------------
procedure TMainCommands.cm_View(const Params: array of string);
var
sl: TStringList = nil;
i, n: Integer;
sViewCmd: String;
ActiveFile: TFile = nil;
AllFiles: TFiles = nil;
SelectedFiles: TFiles = nil;
TempFiles: TFiles = nil;
aFile: TFile;
TempFileSource: ITempFileSystemFileSource = nil;
Operation: TFileSourceOperation;
aFileSource: IFileSource;
begin
with frmMain do
try
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
ActiveFile := ActiveFrame.CloneActiveFile;
// Enter directories using View command.
if Assigned(ActiveFile) and
(ActiveFile.IsDirectory or ActiveFile.IsLinkToDirectory) then
begin
ActiveFrame.ExecuteCommand('cm_Open', []);
Exit;
end;
if SelectedFiles.Count = 0 then
begin
msgWarning(rsMsgNoFilesSelected);
Exit;
end;
// Default to using the file source directly.
aFileSource := ActiveFrame.FileSource;
// If files are links to local files
if (fspLinksToLocalFiles in ActiveFrame.FileSource.Properties) then
begin
for I := 0 to SelectedFiles.Count - 1 do
begin
aFile := SelectedFiles[I];
ActiveFrame.FileSource.GetLocalName(aFile);
end;
end
// If files not directly accessible copy them to temp file source.
else if not (fspDirectAccess in ActiveFrame.FileSource.Properties) then
begin
if not (fsoCopyOut in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
TempFiles := SelectedFiles.Clone;
TempFileSource := TTempFileSystemFileSource.GetFileSource;
Operation := ActiveFrame.FileSource.CreateCopyOutOperation(
TempFileSource,
TempFiles,
TempFileSource.FileSystemRoot);
if Assigned(Operation) then
begin
Operation.AddStateChangedListener([fsosStopped], @OnCopyOutStateChanged);
OperationsManager.AddOperation(Operation);
end
else
begin
msgWarning(rsMsgErrNotSupported);
end;
Exit;
end;
try
sl := TStringList.Create;
for i := 0 to SelectedFiles.Count - 1 do
begin
aFile := SelectedFiles[i];
if not (aFile.IsDirectory or aFile.IsLinkToDirectory) then
begin
// Try to find 'view' command in internal associations
sViewCmd:= gExts.GetExtActionCmd(aFile, 'view');
if Length(sViewCmd) = 0 then
sl.Add(aFile.FullPath)
else
begin
sViewCmd := PrepareParameter(sViewCmd, aFile);
ProcessExtCommand(sViewCmd, ActiveFrame.CurrentPath);
end;
end; // if selected
end; // for
// If only one file was selected then add all files in panel to the list.
// Works only for directly accessible files and only when using internal viewer.
if (sl.Count=1) and
(not gExternalTools[etViewer].Enabled) and
([fspDirectAccess, fspLinksToLocalFiles] * ActiveFrame.FileSource.Properties <> []) then
begin
AllFiles := ActiveFrame.CloneFiles;
if (fspLinksToLocalFiles in ActiveFrame.FileSource.Properties) then
begin
for I := 0 to AllFiles.Count - 1 do
begin
aFile := AllFiles[I];
ActiveFrame.FileSource.GetLocalName(aFile);
end;
end;
n:=0;
for i := 0 to AllFiles.Count - 1 do
begin
aFile := AllFiles[i];
if not (aFile.IsDirectory or aFile.IsLinkToDirectory) then
begin
if n>0 then sl.Add(aFile.FullPath);
if aFile.Name = ActiveFile.Name then n:=i;
end;
end;
for i:=0 to n-1 do
begin
aFile := AllFiles[i];
if not (aFile.IsDirectory or aFile.IsLinkToDirectory) then
sl.Add(aFile.FullPath);
end;
end;
// if sl has files then view it
if sl.Count > 0 then
ShowViewerByGlobList(sl, aFileSource);
except
on e: EInvalidCommandLine do
MessageDlg(rsToolErrorOpeningViewer,
rsMsgInvalidCommandLine + ' (' + rsToolViewer + '):' + LineEnding + e.Message,
mtError, [mbOK], 0);
end;
finally
if Assigned(sl) then
FreeAndNil(sl);
if Assigned(AllFiles) then
FreeAndNil(AllFiles);
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
if Assigned(TempFiles) then
FreeAndNil(TempFiles);
if Assigned(ActiveFile) then
FreeAndNil(ActiveFile);
end;
end;
procedure TMainCommands.cm_QuickView(const Params: array of string);
var
Param: String;
begin
with frmMain do
begin
Param := GetDefaultParam(Params);
if Assigned(QuickViewPanel) then
begin
QuickViewClose;
end
else if (param <> 'Close') then
begin
QuickViewShow(NotActiveNotebook.ActivePage, ActiveFrame);
end;
end;
end;
procedure TMainCommands.cm_BriefView(const Params: array of string);
var
aFileView: TFileView;
begin
with frmMain do
begin
aFileView:= TBriefFileView.Create(ActiveNotebook.ActivePage, ActiveFrame);
ActiveNotebook.ActivePage.FileView:= aFileView;
ActiveFrame.SetFocus;
end;
end;
procedure TMainCommands.cm_ColumnsView(const Params: array of string);
var
aFileView: TFileView;
begin
with frmMain do
begin
{$IFDEF COLUMNSFILEVIEW_VTV}
aFileView:= TColumnsFileViewVTV.Create(ActiveNotebook.ActivePage, ActiveFrame);
{$ELSE}
aFileView:= TColumnsFileView.Create(ActiveNotebook.ActivePage, ActiveFrame);
{$ENDIF}
ActiveNotebook.ActivePage.FileView:= aFileView;
ActiveFrame.SetFocus;
end;
end;
procedure TMainCommands.cm_ThumbnailsView(const Params: array of string);
var
aFileView: TFileView;
begin
with frmMain do
begin
aFileView:= TThumbFileView.Create(ActiveNotebook.ActivePage, ActiveFrame);
ActiveNotebook.ActivePage.FileView:= aFileView;
ActiveFrame.SetFocus;
end;
end;
procedure TMainCommands.cm_Edit(const Params: array of string);
var
i: Integer;
sEditCmd: String;
aFile: TFile;
SelectedFiles: TFiles = nil;
begin
with frmMain do
try
// If files are links to local files
if (fspLinksToLocalFiles in ActiveFrame.FileSource.Properties) then
begin
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
for I := 0 to SelectedFiles.Count - 1 do
begin
aFile := SelectedFiles[I];
ActiveFrame.FileSource.GetLocalName(aFile);
end;
end
// If files not directly accessible copy them to temp file source.
else if not (fspDirectAccess in ActiveFrame.FileSource.Properties) then
begin
msgWarning(rsMsgNotImplemented);
Exit;
end
else
begin
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
end;
try
for i := 0 to SelectedFiles.Count - 1 do
begin
aFile := SelectedFiles[i];
// For now we only process one file.
if not (aFile.IsDirectory or aFile.IsLinkToDirectory) then
begin
//now test if exists View command in doublecmd.ext :)
sEditCmd:= gExts.GetExtActionCmd(aFile, 'edit');
if (sEditCmd <> '') then
begin
sEditCmd := PrepareParameter(sEditCmd, aFile);
ProcessExtCommand(sEditCmd, aFile.Path);
end
else
begin
ShowEditorByGlob(aFile.FullPath);
end;
Break;
end;
end;
except
on e: EInvalidCommandLine do
MessageDlg(rsToolErrorOpeningEditor,
rsMsgInvalidCommandLine + ' (' + rsToolEditor + '):' + LineEnding + e.Message,
mtError, [mbOK], 0);
end;
finally
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
end;
end;
procedure TMainCommands.cm_EditPath(const Params: array of string);
begin
frmMain.ActiveFrame.ExecuteCommand('cm_EditPath', Params);
end;
// Parameters:
// confirmation=
// 1/true - show confirmation
// 0/false - don't show confirmation
// queueid= - by default put to this queue
// <queue_identifier>
procedure TMainCommands.cm_Copy(const Params: array of string);
var
bConfirmation, HasQueueId: Boolean;
QueueIdentifier: TOperationsManagerQueueIdentifier;
begin
bConfirmation := focCopy in gFileOperationsConfirmations;
ReadCopyRenameParams(Params, bConfirmation, HasQueueId, QueueIdentifier);
if HasQueueId then
frmMain.CopyFiles(frmMain.NotActiveFrame.CurrentPath, bConfirmation, QueueIdentifier)
else
frmMain.CopyFiles(frmMain.NotActiveFrame.CurrentPath, bConfirmation);
end;
procedure TMainCommands.cm_CopyNoAsk(const Params: array of string);
begin
frmMain.CopyFiles(frmMain.NotActiveFrame.CurrentPath, False);
end;
// Parameters:
// confirmation=
// 1/true - show confirmation
// 0/false - don't show confirmation
// queueid= - by default put to this queue
// <queue_identifier>
procedure TMainCommands.cm_Rename(const Params: array of string);
var
bConfirmation, HasQueueId: Boolean;
QueueIdentifier: TOperationsManagerQueueIdentifier;
begin
bConfirmation := focMove in gFileOperationsConfirmations;
ReadCopyRenameParams(Params, bConfirmation, HasQueueId, QueueIdentifier);
if HasQueueId then
frmMain.MoveFiles(frmMain.NotActiveFrame.CurrentPath, bConfirmation, QueueIdentifier)
else
frmMain.MoveFiles(frmMain.NotActiveFrame.CurrentPath, bConfirmation);
end;
procedure TMainCommands.cm_RenameNoAsk(const Params: array of string);
begin
frmMain.MoveFiles(frmMain.NotActiveFrame.CurrentPath, False);
end;
procedure TMainCommands.cm_MakeDir(const Params: array of string);
var
sPath: UTF8String;
ActiveFile: TFile = nil;
Operation: TFileSourceOperation = nil;
UI: TFileSourceOperationMessageBoxesUI = nil;
begin
with frmMain do
try
if not (fsoCreateDirectory in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
ActiveFile := ActiveFrame.CloneActiveFile;
if Assigned(ActiveFile) and ActiveFile.IsNameValid then
sPath := ActiveFile.Name // 21.05.2009 - pass name from cursor to makedir form
else
sPath := EmptyStr;
if not frmMkDir.ShowMkDir(sPath) then Exit; // show makedir dialog
if (sPath = EmptyStr) then Exit;
Operation := ActiveFrame.FileSource.CreateCreateDirectoryOperation(ActiveFrame.CurrentPath, sPath);
if Assigned(Operation) then
begin
// Call directly - not through operations manager.
UI := TFileSourceOperationMessageBoxesUI.Create;
Operation.AddUserInterface(UI);
Operation.Execute;
sPath := ExtractFileName(ExcludeTrailingPathDelimiter(sPath));
ActiveFrame.SetActiveFile(sPath);
end;
finally
FreeAndNil(Operation);
FreeAndNil(UI);
FreeAndNil(ActiveFile);
end;
end;
// Parameters:
// trashcan=
// 1/true - delete to trash can
// 0/false - delete directly
// setting - if gUseTrash then delete to trash, otherwise delete directly
// reversesetting - if gUseTrash then delete directly, otherwise delete to trash
// confirmation=
// 1/true - show confirmation
// 0/false - don't show confirmation
//
// Deprecated:
// "recycle" - delete to trash can
// "norecycle" - delete directly
// "recyclesetting" - if gUseTrash then delete to trash, otherwise delete directly
// "recyclesettingrev" - if gUseTrash then delete directly, otherwise delete to trash
procedure TMainCommands.cm_Delete(const Params: array of string);
var
I: Integer;
theFilesToDelete: TFiles;
// 12.05.2009 - if delete to trash, then show another messages
MsgDelSel, MsgDelFlDr : string;
Operation: TFileSourceOperation;
bRecycle: Boolean;
bConfirmation, HasConfirmationParam: Boolean;
Param, ParamTrashCan: String;
BoolValue: Boolean;
begin
with frmMain.ActiveFrame do
begin
if not (fsoDelete in FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
bRecycle := gUseTrash;
HasConfirmationParam := False;
for Param in Params do
begin
if Param = 'recycle' then
bRecycle := True
else if Param = 'norecycle' then
bRecycle := False
else if Param = 'recyclesetting' then
bRecycle := gUseTrash
else if Param = 'recyclesettingrev' then
bRecycle := not gUseTrash
else if GetParamValue(Param, 'trashcan', ParamTrashCan) then
begin
if ParamTrashCan = 'setting' then
bRecycle := gUseTrash
else if ParamTrashCan = 'reversesetting' then
bRecycle := not gUseTrash
else if GetBoolValue(ParamTrashCan, BoolValue) then
bRecycle := BoolValue;
end
else if GetParamBoolValue(Param, 'confirmation', BoolValue) then
begin
HasConfirmationParam := True;
bConfirmation := BoolValue;
end;
end;
if bRecycle then
bRecycle := FileSource.IsClass(TFileSystemFileSource) and
mbCheckTrash(CurrentPath);
if not HasConfirmationParam then
begin
if not bRecycle then
bConfirmation := focDelete in gFileOperationsConfirmations
else
bConfirmation := focDeleteToTrash in gFileOperationsConfirmations;
end;
// 12.05.2009
// Showing delete dialog: to trash or to /dev/null :)
If bRecycle then
begin
MsgDelSel := rsMsgDelSelT;
MsgDelFlDr := rsMsgDelFlDrT;
end
else
begin
MsgDelSel := rsMsgDelSel;
MsgDelFlDr := rsMsgDelFlDr;
end;
// ------------------------------------------------------
theFilesToDelete := CloneSelectedOrActiveFiles; // free at Thread end by thread
if Assigned(theFilesToDelete) then
try
if (theFilesToDelete.Count > 0) and
((not bConfirmation) or
(QuestionDlg('', frmMain.GetFileDlgStr(MsgDelSel,MsgDelFlDr,theFilesToDelete),
mtConfirmation, [mrYes, mrNo], 0) = mrYes)) then
begin
if FileSource.IsClass(TFileSystemFileSource) and
frmMain.NotActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
begin
for I:= 0 to theFilesToDelete.Count - 1 do
begin
if (theFilesToDelete[I].IsDirectory or theFilesToDelete[I].IsLinkToDirectory) and
IsInPath(theFilesToDelete[I].FullPath, frmMain.NotActiveFrame.CurrentPath, True, True) then
begin
frmMain.NotActiveFrame.CurrentPath:= theFilesToDelete.Path;
Break;
end;
end;
end;
Operation := FileSource.CreateDeleteOperation(theFilesToDelete);
if Assigned(Operation) then
begin
// Special case for filesystem - 'recycle' parameter.
if Operation is TFileSystemDeleteOperation then
with Operation as TFileSystemDeleteOperation do
begin
// 30.04.2009 - передаем параметр корзины в поток.
Recycle := bRecycle;
end;
// Start operation.
OperationsManager.AddOperation(Operation);
end
else
begin
msgWarning(rsMsgNotImplemented);
end;
end;
finally
if Assigned(theFilesToDelete) then
FreeAndNil(theFilesToDelete);
end;
end;
end;
procedure TMainCommands.cm_CheckSumCalc(const Params: array of string);
var
I: Integer;
bSeparateFile: Boolean;
HashAlgorithm: THashAlgorithm;
sFileName: UTF8String;
SelectedFiles: TFiles;
Operation: TFileSourceCalcChecksumOperation;
begin
// This will work only for filesystem.
// For other file sources use temp file system when it's done.
with frmMain do
begin
if not (fsoCalcChecksum in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgNotImplemented);
Exit;
// Create temp file source.
// CopyOut ActiveFrame.FileSource to TempFileSource.
// Do command on TempFileSource and later delete it (or leave cached on disk?)
end;
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
try
if SelectedFiles.Count = 0 then
begin
msgWarning(rsMsgNoFilesSelected);
Exit;
end;
bSeparateFile:= False;
for I := 0 to SelectedFiles.Count - 1 do // find files in selection
if not SelectedFiles[I].IsDirectory then
begin
bSeparateFile:= True;
Break;
end;
if SelectedFiles.Count > 1 then
sFileName:= ActiveFrame.CurrentPath + MakeFileName(ActiveFrame.CurrentPath, 'checksum')
else
sFileName:= ActiveFrame.CurrentPath + SelectedFiles[0].Name;
if ShowCalcCheckSum(sFileName, bSeparateFile, HashAlgorithm) then
begin
Operation := ActiveFrame.FileSource.CreateCalcChecksumOperation(
SelectedFiles, ActiveFrame.CurrentPath, sFileName) as TFileSourceCalcChecksumOperation;
if Assigned(Operation) then
begin
Operation.Mode := checksum_calc;
Operation.OneFile := not bSeparateFile;
Operation.Algorithm := HashAlgorithm;
// Start operation.
OperationsManager.AddOperation(Operation);
end
else
begin
msgWarning(rsMsgNotImplemented);
end;
end;
finally
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
end;
end;
end;
procedure TMainCommands.cm_CheckSumVerify(const Params: array of string);
var
I: Integer;
SelectedFiles: TFiles;
Operation: TFileSourceCalcChecksumOperation;
begin
// This will work only for filesystem.
// For other file sources use temp file system when it's done.
with frmMain do
begin
if not (fsoCalcChecksum in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgNotImplemented);
Exit;
// Create temp file source.
// CopyOut ActiveFrame.FileSource to TempFileSource.
// Do command on TempFileSource and later delete it (or leave cached on disk?)
end;
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
try
if SelectedFiles.Count = 0 then
begin
msgWarning(rsMsgNoFilesSelected);
Exit;
end;
for I := 0 to SelectedFiles.Count - 1 do // find files in selection
if not FileExtIsHash(SelectedFiles[I].Extension) then
begin
msgError(rsMsgSelectOnlyCheckSumFiles);
Exit;
end;
Operation := ActiveFrame.FileSource.CreateCalcChecksumOperation(
SelectedFiles, '', '') as TFileSourceCalcChecksumOperation;
if Assigned(Operation) then
begin
Operation.AddStateChangedListener([fsosStopped], @OnCalcChecksumStateChanged);
Operation.Mode := checksum_verify;
// Start operation.
OperationsManager.AddOperation(Operation);
end
else
begin
msgWarning(rsMsgNotImplemented);
end;
finally
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
end;
end;
end;
procedure TMainCommands.cm_FocusCmdLine(const Params: array of string);
begin
if frmMain.edtCommand.Visible then
begin
// Show temporarily command line on user request.
if (not gCmdLine) and (frmMain.IsCommandLineVisible = False) then
begin
frmMain.pnlCommand.Show;
end;
frmMain.edtCommand.SetFocus;
end;
end;
procedure TMainCommands.cm_FileAssoc(const Params: array of string);
begin
ShowFileAssocDlg;
end;
procedure TMainCommands.cm_HelpIndex(const Params: array of string);
begin
ShowHelpOrErrorForKeyword('', '/index.html');
end;
procedure TMainCommands.cm_Keyboard(const Params: array of string);
begin
ShowHelpOrErrorForKeyword('', '/shortcuts.html');
end;
procedure TMainCommands.cm_VisitHomePage(const Params: array of string);
var
ErrMsg: String;
begin
dmHelpMgr.HTMLHelpDatabase.ShowURL('http://doublecmd.sourceforge.net','Double Commander Web Site', ErrMsg);
end;
procedure TMainCommands.cm_About(const Params: array of string);
begin
ShowAboutBox;
end;
procedure TMainCommands.cm_ShowSysFiles(const Params: array of string);
begin
with frmMain do
begin
uGlobs.gShowSystemFiles:= not uGlobs.gShowSystemFiles;
actShowSysFiles.Checked:= uGlobs.gShowSystemFiles;
//repaint both panels
FrameLeft.Reload;
FrameRight.Reload;
end;
end;
procedure TMainCommands.cm_SwitchIgnoreList(const Params: array of string);
begin
with frmMain do
begin
gIgnoreListFileEnabled:= not gIgnoreListFileEnabled;
actSwitchIgnoreList.Checked:= gIgnoreListFileEnabled;
//repaint both panels
FrameLeft.Reload;
FrameRight.Reload;
end;
end;
// Parameter is name of TOptionsEditorClass.
procedure TMainCommands.cm_Options(const Params: array of string);
begin
ShowOptions(GetDefaultParam(Params));
end;
procedure TMainCommands.cm_CompareContents(const Params: array of string);
var
FilesToCompare: TStringList = nil;
DirsToCompare: TStringList = nil;
procedure AddItem(const aFile: TFile);
begin
if not aFile.IsDirectory then
FilesToCompare.Add(aFile.FullPath)
else
DirsToCompare.Add(aFile.FullPath);
end;
procedure RunExtDiffer(CompareList: TStringList);
var
i : Integer;
sCommand: String;
begin
with gExternalTools[etDiffer] do
begin
sCommand := QuoteStr(ReplaceEnvVars(Path));
if Parameters <> EmptyStr then
sCommand := sCommand + ' ' + Parameters;
for i := 0 to CompareList.Count - 1 do
sCommand := sCommand + ' ' + QuoteStr(CompareList.Strings[i]);
try
ExecCmdFork(sCommand, RunInTerminal, '', KeepTerminalOpen);
except
on e: EInvalidCommandLine do
MessageDlg(rsToolErrorOpeningDiffer,
rsMsgInvalidCommandLine + ' (' + rsToolDiffer + '):' + LineEnding + e.Message,
mtError, [mbOK], 0);
end;
end;
end;
var
i : Integer;
ActiveSelectedFiles: TFiles = nil;
NotActiveSelectedFiles: TFiles = nil;
Param: String;
begin
with frmMain do
begin
// For now work only for filesystem.
// Later use temporary file system for other file sources.
try
FilesToCompare := TStringList.Create;
DirsToCompare := TStringList.Create;
Param := GetDefaultParam(Params);
if Param = 'dir' then
begin
DirsToCompare.Add(FrameLeft.CurrentPath);
DirsToCompare.Add(FrameRight.CurrentPath);
end
else
begin
// For now work only for filesystem.
if not (ActiveFrame.FileSource.IsClass(TFileSystemFileSource)) then
begin
msgWarning(rsMsgNotImplemented);
Exit;
end;
try
ActiveSelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
if ActiveSelectedFiles.Count = 1 then
begin
// If no files selected in the opposite panel then try to get file
// with the same name.
if not NotActiveFrame.HasSelectedFiles then
begin
for i := 0 to NotActiveFrame.DisplayFiles.Count - 1 do
if NotActiveFrame.DisplayFiles[i].FSFile.Name = ActiveSelectedFiles[0].Name then
begin
NotActiveSelectedFiles := TFiles.Create(NotActiveFrame.CurrentPath);
NotActiveSelectedFiles.Add(NotActiveFrame.DisplayFiles[i].FSFile.Clone);
Break;
end;
end;
if not Assigned(NotActiveSelectedFiles) then
NotActiveSelectedFiles := NotActiveFrame.CloneSelectedOrActiveFiles;
if NotActiveSelectedFiles.Count = 1 then
begin
// For now work only for filesystem.
if not (NotActiveFrame.FileSource.IsClass(TFileSystemFileSource)) then
begin
msgWarning(rsMsgNotImplemented);
Exit;
end;
{ compare single selected files in both panels }
AddItem(ActiveSelectedFiles[0]);
AddItem(NotActiveSelectedFiles[0]);
end
else
begin
// Only one file selected in active panel.
MsgWarning(rsMsgInvalidSelection);
Exit;
end;
end
else if ActiveSelectedFiles.Count > 1 then
begin
{ compare all selected files in active frame }
for i := 0 to ActiveSelectedFiles.Count - 1 do
AddItem(ActiveSelectedFiles[i]);
end;
finally
if Assigned(ActiveSelectedFiles) then
FreeAndNil(ActiveSelectedFiles);
if Assigned(NotActiveSelectedFiles) then
FreeAndNil(NotActiveSelectedFiles);
end;
end;
if ((FilesToCompare.Count > 0) and (DirsToCompare.Count > 0))
or ((FilesToCompare.Count = 1) or (DirsToCompare.Count = 1)) then
begin
// Either files or directories must be selected and more than one.
MsgWarning(rsMsgInvalidSelection)
end
else if FilesToCompare.Count > 0 then
begin
if gExternalTools[etDiffer].Enabled then
RunExtDiffer(FilesToCompare)
else if FilesToCompare.Count = 2 then
ShowDiffer(FilesToCompare.Strings[0], FilesToCompare.Strings[1])
else
MsgWarning(rsMsgTooManyFilesSelected);
end
else if DirsToCompare.Count > 0 then
begin
if gExternalTools[etDiffer].Enabled then
RunExtDiffer(DirsToCompare)
else
MsgWarning(rsMsgNotImplemented);
end
else
msgWarning(rsMsgNoFilesSelected);
finally
if Assigned(FilesToCompare) then
FreeAndNil(FilesToCompare);
if Assigned(DirsToCompare) then
FreeAndNil(DirsToCompare);
end;
end;
end;
procedure TMainCommands.cm_ShowMainMenu(const Params: array of string);
begin
DoShowMainMenu(not gMainMenu);
end;
procedure TMainCommands.cm_Refresh(const Params: array of string);
begin
frmMain.ActiveFrame.Reload;
end;
//------------------------------------------------------
procedure TMainCommands.cm_MarkInvert(const Params: array of string);
begin
frmMain.ActiveFrame.InvertAll;
end;
procedure TMainCommands.cm_MarkMarkAll(const Params: array of string);
begin
frmMain.ActiveFrame.MarkFiles(True);
end;
procedure TMainCommands.cm_MarkUnmarkAll(const Params: array of string);
begin
frmMain.ActiveFrame.MarkFiles(False);
end;
procedure TMainCommands.cm_MarkPlus(const Params: array of string);
begin
frmMain.ActiveFrame.MarkGroup(True);
end;
procedure TMainCommands.cm_MarkMinus(const Params: array of string);
begin
frmMain.ActiveFrame.MarkGroup(False);
end;
procedure TMainCommands.cm_MarkCurrentExtension(const Params: array of string);
begin
frmMain.ActiveFrame.MarkCurrentExtension(True);
end;
procedure TMainCommands.cm_UnmarkCurrentExtension(const Params: array of string);
begin
frmMain.ActiveFrame.MarkCurrentExtension(False);
end;
procedure TMainCommands.cm_SaveSelection(const Params: array of string);
begin
frmMain.ActiveFrame.SaveSelection;
end;
procedure TMainCommands.cm_RestoreSelection(const Params: array of string);
begin
frmMain.ActiveFrame.RestoreSelection;
end;
procedure TMainCommands.cm_SaveSelectionToFile(const Params: array of string);
begin
frmMain.ActiveFrame.SaveSelectionToFile(GetDefaultParam(Params));
end;
procedure TMainCommands.cm_LoadSelectionFromFile(const Params: array of string);
begin
frmMain.ActiveFrame.LoadSelectionFromFile(GetDefaultParam(Params));
end;
procedure TMainCommands.cm_LoadSelectionFromClip(const Params: array of string);
begin
frmMain.ActiveFrame.LoadSelectionFromClipboard;
end;
//------------------------------------------------------
procedure TMainCommands.cm_DirHotList(const Params: array of string);
var
p:TPoint;
begin
frmMain.CreatePopUpHotDir;// TODO: i thing in future this must call on create or change
p:=frmMain.ActiveFrame.ClientToScreen(Classes.Point(0,0));
frmMain.pmHotList.Popup(p.X,p.Y);
end;
procedure TMainCommands.cm_Search(const Params: array of string);
begin
ShowFindDlg(frmMain.ActiveFrame);
end;
//------------------------------------------------------
procedure TMainCommands.cm_SymLink(const Params: array of string);
var
sExistingFile, sLinkToCreate: String;
SelectedFiles: TFiles;
begin
with frmMain do
begin
// Symlinks work only for file system.
if not (ActiveFrame.FileSource.IsClass(TFileSystemFileSource)) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
// Or create a symlink in temp filesystem and CopyIn to target file source.
end;
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
try
if SelectedFiles.Count > 1 then
msgWarning(rsMsgTooManyFilesSelected)
else if SelectedFiles.Count = 0 then
msgWarning(rsMsgNoFilesSelected)
else
begin
sExistingFile := SelectedFiles[0].Path + SelectedFiles[0].Name;
if Length(Params) > 0 then
sLinkToCreate := Params[0]
else
begin
if NotActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
sLinkToCreate := NotActiveFrame.CurrentPath
else
sLinkToCreate := ActiveFrame.CurrentPath
end;
sLinkToCreate := sLinkToCreate + SelectedFiles[0].Name;
if ShowSymLinkForm(sExistingFile, sLinkToCreate, ActiveFrame.CurrentPath) then
begin
ActiveFrame.Reload;
if NotActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
NotActiveFrame.Reload;
end;
end;
finally
FreeAndNil(SelectedFiles);
end;
end;
end;
procedure TMainCommands.cm_HardLink(const Params: array of string);
var
sExistingFile, sLinkToCreate: String;
SelectedFiles: TFiles;
begin
with frmMain do
begin
// Hard links work only for file system.
if not (ActiveFrame.FileSource.IsClass(TFileSystemFileSource)) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
try
if SelectedFiles.Count > 1 then
msgWarning(rsMsgTooManyFilesSelected)
else if SelectedFiles.Count = 0 then
msgWarning(rsMsgNoFilesSelected)
else
begin
sExistingFile := SelectedFiles[0].Path + SelectedFiles[0].Name;
if Length(Params) > 0 then
sLinkToCreate := Params[0]
else
begin
if NotActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
sLinkToCreate := NotActiveFrame.CurrentPath
else
sLinkToCreate := ActiveFrame.CurrentPath
end;
sLinkToCreate := sLinkToCreate + SelectedFiles[0].Name;
if ShowHardLinkForm(sExistingFile, sLinkToCreate, ActiveFrame.CurrentPath) then
begin
ActiveFrame.Reload;
if NotActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
NotActiveFrame.Reload;
end;
end;
finally
FreeAndNil(SelectedFiles);
end;
end;
end;
// Uses to change sort direction when columns header is disabled
procedure TMainCommands.cm_ReverseOrder(const Params: array of string);
begin
with frmMain.ActiveFrame do
Sorting := ReverseSortDirection(Sorting);
end;
procedure TMainCommands.cm_SortByName(const Params: array of string);
var
FileFunctions: TFileFunctions = nil;
begin
AddSortFunction(FileFunctions, fsfNameNoExtension);
DoSortByFunctions(frmMain.ActiveFrame, FileFunctions);
end;
procedure TMainCommands.cm_SortByExt(const Params: array of string);
var
FileFunctions: TFileFunctions = nil;
begin
AddSortFunction(FileFunctions, fsfExtension);
DoSortByFunctions(frmMain.ActiveFrame, FileFunctions);
end;
procedure TMainCommands.cm_SortBySize(const Params: array of string);
var
FileFunctions: TFileFunctions = nil;
begin
AddSortFunction(FileFunctions, fsfSize);
DoSortByFunctions(frmMain.ActiveFrame, FileFunctions);
end;
procedure TMainCommands.cm_SortByDate(const Params: array of string);
var
FileFunctions: TFileFunctions = nil;
begin
AddSortFunction(FileFunctions, fsfModificationTime);
DoSortByFunctions(frmMain.ActiveFrame, FileFunctions);
end;
procedure TMainCommands.cm_SortByAttr(const Params: array of string);
var
FileFunctions: TFileFunctions = nil;
begin
AddSortFunction(FileFunctions, fsfAttr);
DoSortByFunctions(frmMain.ActiveFrame, FileFunctions);
end;
procedure TMainCommands.cm_MultiRename(const Params: array of string);
var
aFiles: TFiles;
begin
with frmMain do
begin
if not (fsoSetFileProperty in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
aFiles:= ActiveFrame.CloneSelectedOrActiveFiles;
if Assigned(aFiles) then
try
if aFiles.Count > 0 then
ShowMultiRenameForm(ActiveFrame.FileSource, aFiles)
else
msgWarning(rsMsgNoFilesSelected);
finally
FreeAndNil(aFiles);
end;
end;
end;
//------------------------------------------------------
procedure TMainCommands.cm_CopySamePanel(const Params: array of string);
begin
frmMain.CopyFiles('', True);
end;
procedure TMainCommands.cm_RenameOnly(const Params: array of string);
begin
frmMain.ActiveFrame.ExecuteCommand('cm_RenameOnly', Params);
end;
procedure TMainCommands.cm_EditNew(const Params: array of string);
var
sNewFile: String;
hFile: System.THandle = 0;
aFile: TFile;
Attrs: TFileAttrs;
begin
frmMain.ActiveFrame.ExecuteCommand('cm_EditNew', Params);
// For now only works for FileSystem.
with frmMain do
if ActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
begin
aFile := ActiveFrame.CloneActiveFile;
if Assigned(aFile) then
try
if aFile.IsNameValid then
sNewFile:= aFile.Name
else
sNewFile:= rsEditNewFile;
finally
FreeAndNil(aFile);
end;
if not InputQuery(rsEditNewOpen, rsEditNewFileName, sNewFile) then Exit;
// If user entered only a filename prepend it with current directory.
if ExtractFilePath(sNewFile) = '' then
sNewFile:= ActiveFrame.CurrentPath + sNewFile;
Attrs := mbFileGetAttr(sNewFile);
if Attrs = faInvalidAttributes then
begin
hFile := mbFileCreate(sNewFile);
if hFile = feInvalidHandle then
begin
MessageDlg(rsMsgErrECreate, mbSysErrorMessage(GetLastOSError), mtWarning, [mbOK], 0);
Exit;
end;
FileClose(hFile);
ActiveFrame.FileSource.Reload(ExtractFilePath(sNewFile));
end
else if FPS_ISDIR(Attrs) then
begin
MessageDlg(rsMsgErrECreate, Format(rsMsgErrCreateFileDirectoryExists,
[ExtractFileName(sNewFile)]), mtWarning, [mbOK], 0);
Exit;
end;
aFile := TFileSystemFileSource.CreateFileFromFile(sNewFile);
try
// Try to find Edit command in doublecmd.ext
sNewFile := gExts.GetExtActionCmd(aFile, 'edit');
// If command not found then use default editor
if Length(sNewFile) = 0 then
ShowEditorByGlob(aFile.FullPath)
else
begin
sNewFile := PrepareParameter(sNewFile, aFile);
ProcessExtCommand(sNewFile, aFile.Path);
end;
finally
FreeAndNil(aFile);
end;
end
else
msgWarning(rsMsgNotImplemented);
end;
// Shows recently visited directories (global).
procedure TMainCommands.cm_DirHistory(const Params: array of string);
var
p:TPoint;
begin
frmMain.CreatePopUpDirHistory;
p:=frmMain.ActiveFrame.ClientToScreen(Classes.Point(0,0));
frmMain.pmDirHistory.Popup(p.X,p.Y);
end;
// Shows browser-like history for active file view.
procedure TMainCommands.cm_ViewHistory(const Params: array of string);
begin
frmMain.ShowFileViewHistory;
end;
procedure TMainCommands.cm_ViewHistoryPrev(const Params: array of string);
begin
with frmMain do
begin
ActiveFrame.GoToPrevHistory;
end;
end;
procedure TMainCommands.cm_ViewHistoryNext(const Params: array of string);
begin
with frmMain do
begin
ActiveFrame.GoToNextHistory;
end;
end;
procedure TMainCommands.cm_ShowCmdLineHistory(const Params: array of string);
begin
with frmMain do
begin
if IsCommandLineVisible then
begin
edtCommand.SetFocus;
if edtCommand.Items.Count>0 then
edtCommand.DroppedDown:=True;
end;
end;
end;
procedure TMainCommands.cm_RunTerm(const Params: array of string);
begin
with frmMain do
if not edtCommand.Focused then
try
mbSetCurrentDir(ActiveFrame.CurrentPath);
ExecCmdFork(PrepareParameter(gRunTerm, FrameLeft, FrameRight, ActiveFrame, []));
except
on e: EInvalidCommandLine do
MessageDlg(rsToolErrorOpeningTerminal,
rsMsgInvalidCommandLine + ' (' + rsToolTerminal + '):' + LineEnding + e.Message,
mtError, [mbOK], 0);
end;
end;
procedure TMainCommands.cm_CalculateSpace(const Params: array of string);
var
SelectedFiles: TFiles;
Operation: TFileSourceOperation;
begin
with frmMain do
begin
if not (fsoCalcStatistics in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
try
Operation := ActiveFrame.FileSource.CreateCalcStatisticsOperation(SelectedFiles);
if not Assigned(Operation) then
msgWarning(rsMsgErrNotSupported)
else
begin
Operation.AddStateChangedListener([fsosStopped], @OnCalcStatisticsStateChanged);
OperationsManager.AddOperation(Operation);
end;
finally
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
end;
end;
end;
procedure TMainCommands.cm_CountDirContent(const Params: array of string);
begin
frmMain.ActiveFrame.CalculateSpaceOfAllDirectories;
end;
procedure TMainCommands.cm_SetFileProperties(const Params: array of string);
var
ActiveFile: TFile = nil;
SelectedFiles: TFiles = nil;
aFileProperties: TFileProperties;
Operation: TFileSourceSetFilePropertyOperation = nil;
begin
with frmMain do
try
if not (fsoSetFileProperty in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
ActiveFile := ActiveFrame.CloneActiveFile;
if Assigned(ActiveFile) then
begin
FillByte(aFileProperties, SizeOf(aFileProperties), 0);
if fpAttributes in ActiveFile.SupportedProperties then
aFileProperties[fpAttributes]:= ActiveFile.Properties[fpAttributes].Clone;
if fpModificationTime in ActiveFile.SupportedProperties then
aFileProperties[fpModificationTime]:= ActiveFile.Properties[fpModificationTime].Clone;
if fpCreationTime in ActiveFile.SupportedProperties then
aFileProperties[fpCreationTime]:= ActiveFile.Properties[fpCreationTime].Clone;
if fpLastAccessTime in ActiveFile.SupportedProperties then
aFileProperties[fpLastAccessTime]:= ActiveFile.Properties[fpLastAccessTime].Clone;
Operation:= ActiveFrame.FileSource.CreateSetFilePropertyOperation(
SelectedFiles,
aFileProperties) as TFileSourceSetFilePropertyOperation;
if Assigned(Operation) then
begin
if ShowChangeFilePropertiesDialog(Operation) then
begin
OperationsManager.AddOperation(Operation);
Operation := nil; // So it doesn't get destroyed below.
end;
end;
end;
finally
if Assigned(SelectedFiles) then
FreeAndNil(SelectedFiles);
if Assigned(ActiveFile) then
FreeAndNil(ActiveFile);
if Assigned(Operation) then
FreeAndNil(Operation);
end;
end;
procedure TMainCommands.cm_FileProperties(const Params: array of string);
var
SelectedFiles: TFiles;
Operation: TFileSourceExecuteOperation;
aFile: TFile;
begin
with frmMain do
begin
if ActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
begin
SelectedFiles := ActiveFrame.CloneSelectedOrActiveFiles;
if Assigned(SelectedFiles) then
try
if SelectedFiles.Count > 0 then
try
ShowFilePropertiesDialog(ActiveFrame.FileSource, SelectedFiles);
except
on e: EContextMenuException do
ShowException(e);
end;
finally
FreeAndNil(SelectedFiles);
end;
end
else if (fsoExecute in ActiveFrame.FileSource.GetOperationsTypes) then
begin
aFile:= ActiveFrame.CloneActiveFile;
if Assigned(aFile) then
try
Operation:= ActiveFrame.FileSource.CreateExecuteOperation(
aFile,
ActiveFrame.CurrentPath,
'properties') as TFileSourceExecuteOperation;
if Assigned(Operation) then
Operation.Execute;
finally
FreeThenNil(Operation);
FreeThenNil(aFile);
end;
end;
end;
end;
procedure TMainCommands.cm_FileLinker(const Params: array of string);
var
I: Integer;
aSelectedFiles: TFiles = nil;
aFile: TFile;
begin
with frmMain, frmMain.ActiveFrame do
begin
if not (fsoCombine in FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
try
aSelectedFiles := CloneSelectedOrActiveFiles;
for I := 0 to aSelectedFiles.Count - 1 do
begin
aFile := aSelectedFiles[I];
if (aFile.IsDirectory or aFile.IsLinkToDirectory) then
begin
msgWarning(rsMsgInvalidSelection);
Exit;
end;
end;
if aSelectedFiles.Count > 1 then
ShowLinkerFilesForm(FileSource, aSelectedFiles, NotActiveFrame.CurrentPath)
else
msgWarning(rsMsgInvalidSelection);
finally
FreeThenNil(aSelectedFiles);
end; // try
end; // with
end;
procedure TMainCommands.cm_FileSpliter(const Params: array of string);
var
aFile: TFile = nil;
begin
with frmMain, frmMain.ActiveFrame do
begin
if not (fsoSplit in FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
try
aFile := CloneActiveFile;
if (not Assigned(aFile)) or (aFile.IsDirectory or aFile.IsLinkToDirectory) then
msgWarning(rsMsgInvalidSelection)
else
ShowSplitterFileForm(FileSource, aFile, NotActiveFrame.CurrentPath);
finally
FreeThenNil(aFile);
end; // try
end; // with
end;
procedure TMainCommands.cm_PanelsSplitterPerPos(const Params: array of string);
var
Split: Integer = -1;
Param, SplitPct: String;
begin
for Param in Params do
begin
if GetParamValue(Param, 'splitpct', SplitPct) then
Split := StrToIntDef(SplitPct, Split)
else if Split = -1 then
Split := StrToIntDef(Param, Split); // deprecated
end;
DoPanelsSplitterPerPos(Split);
end;
procedure TMainCommands.cm_EditComment(const Params: array of string);
var
aFile: TFile;
begin
with frmMain.ActiveFrame do
begin
if (fspDirectAccess in FileSource.GetProperties) then
begin
aFile:= CloneActiveFile;
if Assigned(aFile) then
try
if aFile.IsNameValid then
ShowDescrEditDlg(CurrentPath + aFile.Name)
else
msgWarning(rsMsgNoFilesSelected);
finally
FreeAndNil(aFile);
end;
end
else if (fspLinksToLocalFiles in FileSource.GetProperties) then
begin
aFile:= CloneActiveFile;
if Assigned(aFile) then
try
if aFile.IsNameValid then
begin
if FileSource.GetLocalName(aFile) then
ShowDescrEditDlg(aFile.FullPath)
else
msgWarning(rsMsgErrNotSupported);
end
else
begin
msgWarning(rsMsgNoFilesSelected);
end;
finally
FreeAndNil(aFile);
end;
end
else
msgWarning(rsMsgErrNotSupported);
end;
end;
function SendToClipboard(ClipboardMode: uClipboard.TClipboardOperation):Boolean;
var
sl: TStringList = nil;
i : Integer;
theSelectedFiles: TFiles = nil;
begin
// Only works for file system.
Result := False;
with frmMain.ActiveFrame do
if FileSource.IsClass(TFileSystemFileSource) then
begin
sl := TStringList.Create;
try
theSelectedFiles := CloneSelectedOrActiveFiles;
for i := 0 to theSelectedFiles.Count - 1 do
sl.Add(CurrentPath + theSelectedFiles[i].Name);
case ClipboardMode of
uClipboard.ClipboardCut:
Result := uClipboard.CutToClipboard(sl);
uClipboard.ClipboardCopy:
Result := uClipboard.CopyToClipboard(sl);
end;
finally
if Assigned(sl) then
FreeAndNil(sl);
if Assigned(theSelectedFiles) then
FreeAndNil(theSelectedFiles);
end;
end
else
msgWarning(rsMsgErrNotSupported);
end;
procedure TMainCommands.cm_CopyToClipboard(const Params: array of string);
begin
SendToClipboard(ClipboardCopy);
end;
procedure TMainCommands.cm_CutToClipboard(const Params: array of string);
begin
SendToClipboard(ClipboardCut);
end;
procedure TMainCommands.cm_PasteFromClipboard(const Params: array of string);
var
ClipboardOp: TClipboardOperation;
filenamesList: TStringList;
Files: TFiles = nil;
Operation: TFileSourceOperation = nil;
SourceFileSource: IFileSource = nil;
begin
with frmMain do
begin
if PasteFromClipboard(ClipboardOp, filenamesList) = True then
try
// fill file list with files
Files := TFileSystemFileSource.CreateFilesFromFileList(
ExtractFilePath(filenamesList[0]), fileNamesList, True);
if Files.Count > 0 then
begin
case ClipboardOp of
uClipboard.ClipboardCut:
begin
SourceFileSource := TFileSystemFileSource.GetFileSource;
if ActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
begin
if not (fsoMove in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
Operation := SourceFileSource.CreateMoveOperation(
Files, ActiveFrame.CurrentPath);
end
else
begin
if (not (fsoCopyIn in ActiveFrame.FileSource.GetOperationsTypes)) or
(not (fsoDelete in SourceFileSource.GetOperationsTypes)) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
{
// Meta-operation: CopyIn + Delete
Operation := ActiveFrame.FileSource.CreateCopyInOperation(
SourceFileSource, Files,
ActiveFrame.CurrentPath);
}
end;
end;
uClipboard.ClipboardCopy:
begin
if not (fsoCopyIn in ActiveFrame.FileSource.GetOperationsTypes) then
begin
msgWarning(rsMsgErrNotSupported);
Exit;
end;
SourceFileSource := TFileSystemFileSource.GetFileSource;
if ActiveFrame.FileSource.IsClass(TFileSystemFileSource) then
begin
Operation := SourceFileSource.CreateCopyOutOperation(
ActiveFrame.FileSource, Files,
ActiveFrame.CurrentPath);
end
else
begin
Operation := ActiveFrame.FileSource.CreateCopyInOperation(
SourceFileSource, Files,
ActiveFrame.CurrentPath);
end;
end;
else
// Invalid clipboard operation.
Exit;
end;
if Assigned(Operation) then
begin
if Operation is TFileSystemCopyOperation then
(Operation as TFileSystemCopyOperation).AutoRenameItSelf:= True;
OperationsManager.AddOperation(Operation);
// Files have been moved so clear the clipboard because
// the files location in the clipboard is invalid now.
if ClipboardOp = uClipboard.ClipboardCut then
uClipboard.ClearClipboard;
end
else
msgWarning(rsMsgNotImplemented);
end;
finally
FreeAndNil(fileNamesList);
if Assigned(Files) then
FreeAndNil(Files);
end;
end;
end;
procedure TMainCommands.cm_ChangeDirToRoot(const Params: array of string);
begin
with frmMain.ActiveFrame do
begin
CurrentPath := FileSource.GetRootDir(CurrentPath);
end;
end;
procedure TMainCommands.cm_ChangeDirToParent(const Params: array of string);
begin
frmMain.ActiveFrame.ChangePathToParent(True);
end;
// Parameters:
// Full path to a directory.
procedure TMainCommands.cm_ChangeDir(const Params: array of string);
begin
if Length(Params) > 0 then
FrmMain.ActiveFrame.CurrentPath := ReplaceEnvVars(Params[0]);
end;
procedure TMainCommands.cm_ClearLogWindow(const Params: array of string);
begin
frmMain.seLogWindow.Lines.Clear;
end;
procedure TMainCommands.cm_CmdLineNext(const Params: array of string);
begin
DoShowCmdLineHistory(True);
end;
procedure TMainCommands.cm_CmdLinePrev(const Params: array of string);
begin
DoShowCmdLineHistory(False);
end;
procedure TMainCommands.cm_ClearLogFile(const Params: array of string);
begin
mbDeleteFile(gLogFileName);
end;
procedure TMainCommands.cm_NetworkConnect(const Params: array of string);
begin
{
ShowConnectionManager(frmMain.ActiveFrame);
}
end;
procedure TMainCommands.cm_NetworkDisconnect(const Params: array of string);
begin
{
if frmMain.ActiveFrame.FileSource.IsClass(TWfxPluginFileSource) then
with frmMain.ActiveFrame.FileSource as IWfxPluginFileSource do
begin
if param <> EmptyStr then
WfxModule.WfxNetworkCloseConnection(param);
end;
}
end;
procedure TMainCommands.cm_HorizontalFilePanels(const Params: array of string);
begin
gHorizontalFilePanels := not gHorizontalFilePanels;
frmMain.actHorizontalFilePanels.Checked := gHorizontalFilePanels;
frmMain.UpdateWindowView;
end;
procedure TMainCommands.cm_OperationsViewer(const Params: array of string);
begin
ShowOperationsViewer;
end;
procedure TMainCommands.cm_CompareDirectories(const Params: array of string);
var
I: LongWord;
SourceFile: TDisplayFile;
TargetFile: TDisplayFile;
SourceList: TStringHashList;
SourceFiles: TDisplayFiles = nil;
TargetFiles: TDisplayFiles = nil;
FileTimeDiff: TDateTime;
begin
SourceList:= TStringHashList.Create(FileNameCaseSensitive);
with frmMain do
try
SourceFiles:= ActiveFrame.DisplayFiles;
TargetFiles:= NotActiveFrame.DisplayFiles;
for I:= 0 to SourceFiles.Count - 1 do
begin
SourceFile:= SourceFiles[I];
if SourceFile.FSFile.IsDirectory or SourceFile.FSFile.IsLinkToDirectory then
Continue;
ActiveFrame.MarkFile(SourceFile, True);
SourceList.Add(SourceFile.FSFile.Name, SourceFile);
end;
for I:= 0 to TargetFiles.Count - 1 do
begin
TargetFile:= TargetFiles[I];
if TargetFile.FSFile.IsDirectory or TargetFile.FSFile.IsLinkToDirectory then
Continue;
SourceFile:= TDisplayFile(SourceList.Data[TargetFile.FSFile.Name]);
if (SourceFile = nil) then
NotActiveFrame.MarkFile(TargetFile, True)
else
begin
FileTimeDiff:= SourceFile.FSFile.ModificationTime - TargetFile.FSFile.ModificationTime;
if FileTimeDiff = 0 then
ActiveFrame.MarkFile(SourceFile, False)
else if FileTimeDiff > 0 then
NotActiveFrame.MarkFile(TargetFile, False)
else if FileTimeDiff < 0 then
begin
ActiveFrame.MarkFile(SourceFile, False);
NotActiveFrame.MarkFile(TargetFile, True);
end;
end;
end;
finally
SourceList.Free;
ActiveFrame.UpdateView;
NotActiveFrame.UpdateView;
end;
end;
end.