mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
2948 lines
89 KiB
ObjectPascal
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.
|
|
|