mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
761 lines
22 KiB
ObjectPascal
761 lines
22 KiB
ObjectPascal
{
|
|
Seksi Commander
|
|
----------------------------
|
|
Implementing of storing Files and main file operation
|
|
|
|
Licence : GNU GPL v 2.0
|
|
Author : radek.cervinka@centrum.cz
|
|
|
|
contributors:
|
|
|
|
Copyright (C) 2006-2008 Alexander Koblov (Alexx2000@mail.ru)
|
|
|
|
Vitaly Zotov (vitalyzotov@mail.ru)
|
|
}
|
|
|
|
unit uFilePanel;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
uses
|
|
StdCtrls, Grids, uFileList, uTypes, uPathHistory, Classes, uVFS;
|
|
|
|
type
|
|
TOnBeforeChangeDirectory = function (Sender: TObject; const NewDir : String): Boolean of object;
|
|
TOnAfterChangeDirectory = procedure (Sender: TObject; const NewDir : String) of object;
|
|
|
|
{ TFilePanel }
|
|
|
|
TFilePanel=Class
|
|
private
|
|
fOwner : TObject;
|
|
fFileList:TFileList;
|
|
fVFS : TVFS;
|
|
flblPath:TLabel;
|
|
fPanel:TDrawGrid;
|
|
fSortCol:Integer;
|
|
fSortDirect:Boolean;
|
|
fPrevActiveDir: String;
|
|
fActiveDir:String;
|
|
fLastActive:String;
|
|
|
|
fPanelMode: TPanelMode; // file, archive or VFS?
|
|
fPathHistory: TPathHistory;
|
|
fRefList:TList; // list of ptr (showed in grid) to FileRecItem
|
|
fVFSmoduleList : TStringList; // list of VFS modules (used in sub archive)
|
|
|
|
|
|
fFilesInDir:Integer; //must call UpdateCountStatus first
|
|
fFilesSelected:Integer; //must call UpdateCountStatus first
|
|
fSizeInDir:Int64; //must call UpdateCountStatus first
|
|
fSizeSelected:Int64; //must call UpdateCountStatus first
|
|
flblCurPath:TLabel; // label before Command line
|
|
flblFree:TLabel;
|
|
fedtCommand:TComboBox; // only for place correction after Chdir
|
|
FOnBeforeChangeDirectory : TOnBeforeChangeDirectory;
|
|
FOnAfterChangeDirectory : TOnAfterChangeDirectory;
|
|
public
|
|
// iLastDrawnIndex :Integer; // fucking dirty hack (OnDrawItem
|
|
|
|
constructor Create(AOwner : TObject; APanel:TDrawGrid; AlblPath: TLabel; AlblCurPath, AlblFree:TLabel; AedtCommand:TComboBox);
|
|
Destructor Destroy; override;
|
|
procedure LoadPanel;
|
|
procedure LoadPanelVFS(frp:PFileRecItem);
|
|
procedure LoadVFSListInPanel;
|
|
procedure SortByCol(iCol:Integer);
|
|
procedure Sort;
|
|
procedure UpdatePanel;
|
|
// procedure ChDir(sDir:String);
|
|
procedure TryOpenArchive(pfri:PFileRecItem);
|
|
procedure ChooseFile(pfri:PFileRecItem); // main input node
|
|
function GetFileItem(iIndex:Integer):TFileRecItem;
|
|
function GetFileItemPtr(iIndex:Integer):PFileRecItem;
|
|
function GetReferenceItemPtr(iIndex:Integer):PFileRecItem;
|
|
function GetActiveItem:PFileRecItem;
|
|
function GetSelectedCount:Integer;
|
|
procedure InvertFileSection(frp:PFileRecItem);
|
|
procedure MarkAllFiles(bMarked:Boolean);
|
|
procedure MarkFile(frp:PFileRecItem; bMarked:Boolean);
|
|
procedure InvertAllFiles;
|
|
procedure UpdateCountStatus;
|
|
procedure cdUpLevel;
|
|
procedure cdDownLevel(frp:PFileRecItem);
|
|
procedure MarkGroup(const sMask:String; bSelect:Boolean); // second parametr is switch sel/uns
|
|
procedure UpdatePrompt;
|
|
function ProcessExtCommand(sCmd:String{; pfr:PFileRecItem}) : Boolean;
|
|
procedure ReplaceExtCommand(var sCmd:String; pfr:PFileRecItem);
|
|
procedure SetActiveDir(const AValue:String);
|
|
function GetActiveDir:String;
|
|
property OnBeforeChangeDirectory : TOnBeforeChangeDirectory read FOnBeforeChangeDirectory write FOnBeforeChangeDirectory;
|
|
property OnAfterChangeDirectory : TOnAfterChangeDirectory read FOnAfterChangeDirectory write FOnAfterChangeDirectory;
|
|
|
|
published
|
|
property SortDirection:Boolean read fSortDirect write fSortDirect; // maybe write method
|
|
property SortColumn : Integer read fSortCol write SortByCol;
|
|
property ActiveDir:String read GetActiveDir write SetActiveDir;
|
|
property LastActive:String read fLastActive write fLastActive;
|
|
property FileList: TFileList read fFileList write fFileList;
|
|
property SelectedCount:Integer read GetSelectedCount;
|
|
property FilesInDir:Integer read fFilesInDir;
|
|
property FilesSelected:Integer read fFilesSelected;
|
|
property SizeInDir:Int64 read fSizeInDir;
|
|
property SizeSelected:Int64 read fSizeSelected;
|
|
property PanelMode : TPanelMode read fPanelMode;
|
|
property VFS : TVFS read fVFS;
|
|
end;
|
|
|
|
implementation
|
|
|
|
uses
|
|
LCLProc, SysUtils, Masks, uFileOp, uGlobs, uVFSutil,
|
|
uShowMsg, Controls, uLng, uShowForm, uVFSmodule, uDCUtils,
|
|
uOSUtils;
|
|
|
|
constructor TFilePanel.Create(AOwner : TObject; APanel:TDrawGrid; AlblPath: TLabel; AlblCurPath, AlblFree:TLabel; AedtCommand:TComboBox);
|
|
begin
|
|
fOwner := AOwner;
|
|
fPanel:=APanel;
|
|
fRefList:=TList.Create;
|
|
fVFS := TVFS.Create;
|
|
flblPath:=AlblPath;
|
|
flblCurPath:=AlblCurPath;
|
|
flblFree:=AlblFree;
|
|
fedtCommand:=AedtCommand;
|
|
fFileList:=TFileList.Create;
|
|
GetDir(0,fActiveDir);
|
|
fActiveDir:=ExtractFilePath(fActiveDir);
|
|
fPathHistory:=TPathHistory.Create;
|
|
fPanelMode:=pmDirectory;
|
|
fVFSmoduleList := TStringList.Create;
|
|
// LastActive:='';
|
|
// iLastDrawnIndex:=-1;
|
|
end;
|
|
|
|
Destructor TFilePanel.Destroy;
|
|
begin
|
|
if assigned(fFileList) then
|
|
FreeAndNil(fFileList);
|
|
if assigned(fVFS) then
|
|
FreeAndNil(fVFS);
|
|
if assigned(fPathHistory) then
|
|
FreeAndNil(fPathHistory);
|
|
if assigned(fRefList) then
|
|
FreeAndNil(fRefList);
|
|
if Assigned(fVFSmoduleList) then
|
|
FreeAndNil(fVFSmoduleList);
|
|
end;
|
|
|
|
|
|
procedure TFilePanel.UpdatePanel;
|
|
var
|
|
i:Integer;
|
|
pfri:PFileRecItem;
|
|
bAnyRow:Boolean;
|
|
begin
|
|
case fPanelMode of
|
|
pmDirectory:
|
|
flblPath.Caption:=' '+MinimizeFilePath(ActiveDir, flblPath.Canvas, flblPath.Width);
|
|
pmArchive,
|
|
pmVFS:
|
|
flblPath.Caption:=' ' + ActiveDir;
|
|
else
|
|
Raise Exception.Create('fix me:UpdatePanel:bad panelmode');
|
|
end;
|
|
|
|
if fPanel.FixedRows <> Integer(gTabHeader) then
|
|
fPanel.FixedRows:= Integer(gTabHeader);
|
|
|
|
bAnyRow:=fPanel.Row>=0;
|
|
fRefList.Clear;
|
|
for i:=0 to fFileList.Count-1 do
|
|
begin
|
|
pfri:=fFileList.GetItem(i);
|
|
with pfri^ do
|
|
begin
|
|
if (not gShowSystemFiles) and bSysFile then Continue;
|
|
if ((pfri^.sPath='') and (pfri^.sName='..') and (ActiveDir='/')) then Continue;
|
|
fRefList.Add(pfri);
|
|
end;
|
|
end;
|
|
|
|
fPanel.RowCount:=fRefList.Count+fPanel.FixedRows; // one is header
|
|
UpdatePrompt;
|
|
if bAnyRow then
|
|
begin
|
|
if (LastActive<>'') then // find correct cursor position in Panel (drawgrid)
|
|
begin
|
|
for i:=0 to fRefList.Count-1 do
|
|
begin
|
|
with GetReferenceItemPtr(i)^ do
|
|
if pos(LastActive, sName)=1 then
|
|
begin
|
|
fPanel.Row:=i+1;
|
|
Break;
|
|
end;
|
|
end;
|
|
end
|
|
else
|
|
fPanel.Row:=0;
|
|
if (fPanel.Row<0)then
|
|
fPanel.Row:=0;
|
|
end;
|
|
// fPanel.Selected.MakeVisible;}
|
|
UpdateCountStatus;
|
|
end;
|
|
|
|
procedure TFilePanel.LoadPanelVFS(frp:PFileRecItem);
|
|
var
|
|
sDir:String;
|
|
sDummy:String;
|
|
VFSFileList : TFileList;
|
|
sTempDir,
|
|
sFileName : String;
|
|
I, iIndex : Integer;
|
|
begin
|
|
with frp^ do
|
|
begin
|
|
if (fPanelMode in [pmArchive, pmVFS]) then
|
|
begin
|
|
if sName = '..' then
|
|
begin
|
|
fActiveDir := fVFS.ArcFullName + sPath;
|
|
|
|
//DebugLn('UpDir = ' + sPath);
|
|
|
|
if not fVFS.cdUpLevel(frp, fFileList) then
|
|
begin
|
|
if fVFSmoduleList.Count <> 0 then // if in sub archive then return in parent VFS
|
|
begin
|
|
mbDeleteFile(fVFS.ArcFullName);
|
|
I := fVFSmoduleList.Count - 1;
|
|
fVFS.VFSmodule := TVFSmodule(fVFSmoduleList.Objects[I]); // load VFS module
|
|
fVFS.ArcFullName := fVFSmoduleList.Names[I]; // load archive name
|
|
sTempDir := fVFSmoduleList.ValueFromIndex[I]; // load archive subdirectory
|
|
fVFSmoduleList.Delete(I);
|
|
fVFS.VFSmodule.VFSList(sTempDir, fFileList);
|
|
case fVFS.VFSType of
|
|
vtWCX: fPanelMode := pmArchive;
|
|
vtWFX: fPanelMode := pmVFS;
|
|
end;
|
|
fActiveDir := fVFS.ArcFullName + sTempDir;
|
|
end
|
|
else // exit from VFS
|
|
begin
|
|
case fPanelMode of
|
|
pmVFS:
|
|
LoadVFSListInPanel;
|
|
pmArchive:
|
|
begin
|
|
fPanelMode := pmDirectory;
|
|
fActiveDir := ExtractFilePath(fVFS.ArcFullName);
|
|
mbSetCurrentDir(fActiveDir);
|
|
if Assigned(FOnAfterChangeDirectory) then
|
|
FOnAfterChangeDirectory(fOwner, fActiveDir);
|
|
LoadFilesbyDir(fActiveDir, fFileList);
|
|
end;
|
|
end; // case
|
|
end;
|
|
end;
|
|
end
|
|
else // is directory
|
|
if FPS_ISDIR(iMode) then
|
|
begin
|
|
fActiveDir := fVFS.ArcFullName + sPath + sName + DirectorySeparator;
|
|
fVFS.cdDownLevel(frp, fFileList);
|
|
end
|
|
else // Is file
|
|
begin
|
|
if fVFS.FindModule(sName, False) then // if archive
|
|
begin
|
|
iIndex := fVFSmoduleList.AddObject(fVFS.ArcFullName + '=' + sPath, fVFS.VFSmodule);
|
|
|
|
//DebugLn('sPath ==' + sPath);
|
|
|
|
VFSFileList := TFileList.Create;
|
|
VFSFileList.CurrentDirectory := ActiveDir;
|
|
|
|
//DebugLn('ActiveDir == ' + ActiveDir);
|
|
|
|
sName := ActiveDir + sName;
|
|
sFileName := sName;
|
|
VFSFileList.AddItem(frp);
|
|
sTempDir := GetTempFolder;
|
|
{if }fVFS.VFSmodule.VFSCopyOut(VFSFileList, sTempDir, 0);{ then}
|
|
begin
|
|
if not fVFS.LoadAndOpen(sTempDir + ExtractDirLevel(ActiveDir, sFileName)) then
|
|
begin
|
|
// restore old plugin module and delete it from list
|
|
fVFS.VFSmodule := TVFSmodule(fVFSmoduleList.Objects[iIndex]);
|
|
fVFS.ArcFullName := fVFSmoduleList.Names[iIndex];
|
|
fVFSmoduleList.Delete(iIndex);
|
|
Exit;
|
|
end;
|
|
//DebugLn('sTempDir + sName == ' + sTempDir + sName);
|
|
|
|
fVFS.VFSmodule.VFSList(PathDelim, fFileList);
|
|
fPanelMode:=pmArchive;
|
|
fActiveDir := fVFS.ArcFullName + DirectorySeparator;
|
|
|
|
end;
|
|
end
|
|
else
|
|
fVFS.VFSmodule.VFSRun(sName);
|
|
end;
|
|
end
|
|
else // Is not in VFS
|
|
begin
|
|
fVFS.VFSmodule.VFSList(PathDelim, fFileList);
|
|
case fVFS.VFSType of
|
|
vtWCX: fPanelMode := pmArchive;
|
|
vtWFX: fPanelMode := pmVFS;
|
|
end;
|
|
fActiveDir := fVFS.ArcFullName + DirectorySeparator;
|
|
end;
|
|
if gShowIcons then
|
|
fFileList.UpdateFileInformation(fPanelMode);
|
|
Sort;
|
|
Exit;
|
|
end;
|
|
end;
|
|
|
|
procedure TFilePanel.LoadVFSListInPanel;
|
|
begin
|
|
if fVFS.LoadVFSList(fFileList) then
|
|
begin
|
|
fPanelMode := pmDirectory;
|
|
fActiveDir := PathDelim;
|
|
if gShowIcons then
|
|
fFileList.UpdateFileInformation(PanelMode);
|
|
Sort;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFilePanel.LoadPanel;
|
|
begin
|
|
// DebugLn('TFilePanel.LoadPanel');
|
|
if fPanelMode in [pmArchive, pmVFS] then
|
|
fPanelMode := pmDirectory;
|
|
|
|
if Assigned(FOnBeforeChangeDirectory) then
|
|
if not FOnBeforeChangeDirectory(fOwner, ActiveDir) then
|
|
begin
|
|
fActiveDir:= fPrevActiveDir;
|
|
Exit;
|
|
end;
|
|
|
|
if not mbSetCurrentDir(ActiveDir) then
|
|
begin
|
|
GetDir(0,fActiveDir);
|
|
IncludeTrailingBackslash(fActiveDir);
|
|
Exit; // chdir failed
|
|
end;
|
|
if Assigned(FOnAfterChangeDirectory) then
|
|
FOnAfterChangeDirectory(fOwner, fActiveDir);
|
|
LoadFilesbyDir(fActiveDir, fFileList);
|
|
|
|
if gShowIcons then
|
|
fFileList.UpdateFileInformation(fPanelMode);
|
|
Sort; // and Update panel
|
|
fPanel.Invalidate;
|
|
// DebugLn('TFilePanel.LoadPanel DONE');
|
|
end;
|
|
|
|
|
|
procedure TFilePanel.SortByCol(iCol:Integer);
|
|
begin
|
|
fSortCol:=iCol;
|
|
Sort;
|
|
end;
|
|
|
|
procedure TFilePanel.Sort;
|
|
begin
|
|
fFileList.Sort(fSortCol, fSortDirect, gCaseSensitiveSort);
|
|
UpDatePanel;
|
|
end;
|
|
|
|
function TFilePanel.GetFileItem(iIndex:Integer):TFileRecItem;
|
|
begin
|
|
Result:=fFilelist.GetItem(iIndex)^;
|
|
end;
|
|
|
|
function TFilePanel.GetFileItemPtr(iIndex:Integer):PFileRecItem;
|
|
begin
|
|
Result:=fFilelist.GetItem(iIndex);
|
|
end;
|
|
|
|
|
|
procedure TFilePanel.InvertFileSection(frp:PFileRecItem);
|
|
begin
|
|
if not gShowSystemFiles and (frp^.bSysFile) then Exit;
|
|
frp^.bSelected:=not frp^.bSelected;
|
|
end;
|
|
|
|
procedure TFilePanel.InvertAllFiles;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
for i:=0 to fFileList.Count-1 do
|
|
InvertFileSection(fFileList.GetItem(i));
|
|
end;
|
|
|
|
procedure TFilePanel.TryOpenArchive(pfri:PFileRecItem);
|
|
var
|
|
VFSFileList : TFileList;
|
|
sTempDir,
|
|
sFileName : String;
|
|
iIndex : Integer;
|
|
begin
|
|
with pfri^ do
|
|
if fPanelMode = pmDirectory then // in real file system
|
|
begin
|
|
if fVFS.TryFindModule(sPath + sName) then
|
|
begin
|
|
fVFS.VFSmodule.VFSList(PathDelim, fFileList);
|
|
fPanelMode := pmArchive;
|
|
fActiveDir := fVFS.ArcFullName + DirectorySeparator;
|
|
end;
|
|
end
|
|
else // in Virtual File System
|
|
begin
|
|
iIndex := fVFSmoduleList.AddObject(fVFS.ArcFullName + '=' + sPath, fVFS.VFSmodule);
|
|
|
|
//DebugLn('sPath ==' + sPath);
|
|
|
|
VFSFileList := TFileList.Create;
|
|
VFSFileList.CurrentDirectory := ActiveDir;
|
|
|
|
//DebugLn('ActiveDir == ' + ActiveDir);
|
|
|
|
sName := ActiveDir + sName;
|
|
sFileName := sName;
|
|
|
|
//DebugLn('sFileName = ', sFileName);
|
|
|
|
VFSFileList.AddItem(pfri);
|
|
sTempDir := GetTempFolder;
|
|
{if }fVFS.VFSmodule.VFSCopyOut(VFSFileList, sTempDir, 0);{ then}
|
|
begin
|
|
//DebugLn('sTempDir + sName == ' + sTempDir + ExtractDirLevel(ActiveDir, sFileName));
|
|
if not fVFS.TryFindModule(sTempDir + ExtractDirLevel(ActiveDir, sFileName)) then
|
|
begin
|
|
// restore old plugin module and delete it from list
|
|
fVFS.VFSmodule := TVFSmodule(fVFSmoduleList.Objects[iIndex]);
|
|
fVFSmoduleList.Delete(iIndex);
|
|
Exit;
|
|
end;
|
|
|
|
fVFS.VFSmodule.VFSList(PathDelim, fFileList);
|
|
fPanelMode:=pmArchive;
|
|
fActiveDir := fVFS.ArcFullName + DirectorySeparator;
|
|
end;
|
|
end; // in VFS
|
|
if gShowIcons then
|
|
fFileList.UpdateFileInformation(fPanelMode);
|
|
Sort;
|
|
end;
|
|
|
|
procedure TFilePanel.ChooseFile(pfri:PFileRecItem);
|
|
var
|
|
sOpenCmd:String;
|
|
begin
|
|
// main file input point for decision
|
|
// DebugLn(pfri^.sName);
|
|
|
|
with pfri^ do
|
|
begin
|
|
if (sName='..') then
|
|
begin
|
|
cdUpLevel;
|
|
Exit;
|
|
end;
|
|
|
|
if (fPanelMode=pmVFS) or ((sModeStr = 'wfx') and fVFS.FindModule(sPath + sName)) then
|
|
begin
|
|
LastActive:= '';
|
|
LoadPanelVFS(pfri);
|
|
Exit;
|
|
end;
|
|
if (fPanelMode=pmArchive) or (not FPS_ISDIR(iMode) and fVFS.FindModule(sPath + sName)) then
|
|
begin
|
|
LastActive:= '';
|
|
LoadPanelVFS(pfri);
|
|
Exit;
|
|
end;
|
|
|
|
if FPS_ISDIR(iMode) or bLinkIsDir then // deeper and deeper
|
|
begin
|
|
cdDownLevel(pfri);
|
|
Exit;
|
|
end;
|
|
//now test if exists Open command in doublecmd.ext :)
|
|
sOpenCmd:=gExts.GetExtActionCmd(lowercase(ExtractFileExt(sName)),'open');
|
|
if (sOpenCmd<>'') then
|
|
begin
|
|
if Pos('{!VFS}',sOpenCmd)>0 then
|
|
begin
|
|
if fVFS.FindModule(sName) then
|
|
begin
|
|
LoadPanelVFS(pfri);
|
|
Exit;
|
|
end;
|
|
end;
|
|
LastActive:=sName;
|
|
|
|
ReplaceExtCommand(sOpenCmd, pfri);
|
|
ProcessExtCommand(sOpenCmd{, frp});
|
|
Exit;
|
|
end;
|
|
// and at the end try if it is executable
|
|
if bExecutable then
|
|
begin
|
|
mbSetCurrentDir(ActiveDir);
|
|
LastActive:=sName;
|
|
|
|
ExecCmdFork(Format('"%s"', [sName]));
|
|
LoadPanel;
|
|
Exit;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TFilePanel.MarkAllFiles(bMarked:Boolean);
|
|
var
|
|
i:Integer;
|
|
fr:PFileRecItem;
|
|
|
|
begin
|
|
for i:=0 to fFileList.Count-1 do
|
|
begin
|
|
fr:=fFileList.GetItem(i);
|
|
if not gShowSystemFiles and (fr^.bSysFile) then
|
|
// system files is always not selected if not showed
|
|
fr^.bSelected:=False
|
|
else
|
|
fr^.bSelected:=bMarked;
|
|
end;
|
|
end;
|
|
|
|
procedure TFilePanel.MarkFile(frp:PFileRecItem; bMarked:Boolean);
|
|
begin
|
|
if not gShowSystemFiles and (frp^.bSysFile) then
|
|
begin
|
|
// system files is always not selected if not showed
|
|
frp^.bSelected:=False
|
|
end
|
|
else
|
|
begin
|
|
frp^.bSelected:=bMarked;
|
|
end;
|
|
end;
|
|
|
|
function TFilePanel.GetSelectedCount:Integer;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
Result:=0;
|
|
for i:=0 to fFileList.Count-1 do
|
|
if fFileList.GetItem(i)^.bSelected then
|
|
inc(Result);
|
|
end;
|
|
|
|
procedure TFilePanel.UpdateCountStatus;
|
|
var
|
|
i:Integer;
|
|
begin
|
|
fFilesInDir:=0;
|
|
fFilesSelected:=0;
|
|
fSizeInDir:=0;
|
|
fSizeSelected:=0;
|
|
for i:=0 to fFileList.Count-1 do
|
|
begin
|
|
with fFileList.GetItem(i)^ do
|
|
begin
|
|
// if S_ISDIR(fMode) then Continue;
|
|
if sName='..' then Continue;
|
|
if bSelected then
|
|
begin
|
|
inc(fFilesSelected);
|
|
if not FPS_ISDIR(iMode) then
|
|
fSizeSelected:=Cardinal(fSizeSelected)+iSize
|
|
else
|
|
if iDirSize<>0 then
|
|
fSizeSelected:=Cardinal(fSizeSelected)+iDirSize;
|
|
end;
|
|
inc(fFilesInDir);
|
|
if not FPS_ISDIR(iMode) then
|
|
fSizeInDir:=Cardinal(fSizeInDir)+iSize
|
|
else
|
|
if iDirSize<>0 then
|
|
fSizeInDir:=Cardinal(fSizeInDir)+iDirSize;
|
|
end;
|
|
end;
|
|
end;
|
|
|
|
procedure TFilePanel.cdUpLevel;
|
|
var
|
|
i:Integer;
|
|
bPathFound:Boolean;
|
|
begin
|
|
if fPanelMode = pmDirectory then
|
|
begin
|
|
bPathFound:=False;
|
|
fActiveDir:=ExcludeTrailingPathDelimiter(fActiveDir);
|
|
for i:=length(fActiveDir) downto 1 do
|
|
begin
|
|
if fActiveDir[i] = DirectorySeparator then
|
|
begin
|
|
LastActive:=Copy(fActiveDir,i+1,length(fActiveDir)-i+1);
|
|
fActiveDir:=Copy(fActiveDir,1, i);
|
|
bPathFound:=True;
|
|
Break;
|
|
end;
|
|
end;
|
|
|
|
if glsDirHistory.IndexOf(ActiveDir)=-1 then
|
|
glsDirHistory.Insert(0,ActiveDir);
|
|
|
|
LoadPanel;
|
|
end
|
|
else // if VFS
|
|
begin
|
|
LastActive:= ExtractFileName(ExcludeTrailingPathDelimiter(fActiveDir));
|
|
LoadPanelVFS(fFileList.GetItem(0)); // get '..' item
|
|
fPanel.Invalidate;
|
|
end;
|
|
end;
|
|
|
|
|
|
procedure TFilePanel.cdDownLevel(frp:PFileRecItem);
|
|
begin
|
|
if fPanelMode = pmDirectory then
|
|
begin
|
|
with frp^ do
|
|
begin
|
|
ActiveDir:=ActiveDir+sName+DirectorySeparator;
|
|
LastActive:='';
|
|
if glsDirHistory.IndexOf(ActiveDir)=-1 then
|
|
glsDirHistory.Insert(0,ActiveDir);
|
|
end; // with frp^
|
|
|
|
LoadPanel;
|
|
end
|
|
else // if VFS
|
|
begin
|
|
LastActive:='';
|
|
LoadPanelVFS(frp);
|
|
fPanel.Invalidate;
|
|
end;
|
|
end;
|
|
|
|
function TFilePanel.GetActiveItem:PFileRecItem;
|
|
begin
|
|
Result:= nil;
|
|
if fPanel.Row < fPanel.FixedRows then
|
|
fPanel.Row:= fPanel.FixedRows;
|
|
// DebugLn(fPanel.Row, ' ', fRefList.Count);
|
|
if fPanel.Row > fRefList.Count then
|
|
fPanel.Row:= fPanel.FixedRows;
|
|
Result:= fRefList.Items[fPanel.Row-fPanel.FixedRows]; // minus fixed header
|
|
end;
|
|
|
|
procedure TFilePanel.MarkGroup(const sMask:String; bSelect:Boolean);
|
|
var
|
|
i:Integer;
|
|
frp:PFileRecItem;
|
|
begin
|
|
for i:=0 to fFileList.Count-1 do
|
|
begin
|
|
frp:=fFileList.GetItem(i);
|
|
if (frp^.sName='..') then Continue;
|
|
if MatchesMaskList(frp^.sName, sMask) then
|
|
frp^.bSelected := bSelect;
|
|
end;
|
|
end;
|
|
|
|
procedure TFilePanel.UpdatePrompt;
|
|
const PTLen=40;
|
|
var
|
|
FreeSize,
|
|
TotalSize : Int64;
|
|
begin
|
|
with flblCurPath do
|
|
begin
|
|
AutoSize:=False;
|
|
if length(ActiveDir)>PTLen then
|
|
Caption:='['+copy(ActiveDir,length(ActiveDir)-PTLen,PTLen)+']$:'
|
|
else
|
|
Caption:='['+ActiveDir+']$:';
|
|
AutoSize:=True;
|
|
Left:=1;
|
|
end;
|
|
|
|
fedtCommand.Left:=flblCurPath.Width+5;
|
|
fedtCommand.Width:=TControl(fedtCommand.Parent).Width-fedtCommand.Left;
|
|
if fPanelMode=pmDirectory then
|
|
begin
|
|
GetDiskFreeSpace(fActiveDir, FreeSize, TotalSize);
|
|
flblFree.Caption := Format(rsFreeMsg,[cnvFormatFileSize(FreeSize),cnvFormatFileSize(TotalSize)]);
|
|
end
|
|
else
|
|
//TODO
|
|
flblFree.Caption:=Format(rsFreeMsg,[cnvFormatFileSize(0),cnvFormatFileSize(0)]);
|
|
end;
|
|
|
|
procedure TFilePanel.ReplaceExtCommand(var sCmd:String; pfr:PFileRecItem);
|
|
begin
|
|
with pfr^ do
|
|
begin
|
|
sCmd:=StringReplace(sCmd,'%f',ExtractFileName(sName),[rfReplaceAll]);
|
|
sCmd:=StringReplace(sCmd,'%d',ActiveDir,[rfReplaceAll]);
|
|
sCmd:=Trim(StringReplace(sCmd,'%p',ActiveDir+ExtractFileName(sName),[rfReplaceAll]));
|
|
end;
|
|
end;
|
|
|
|
function TFilePanel.ProcessExtCommand(sCmd:String{; pfr:PFileRecItem}) : Boolean;
|
|
begin
|
|
Result := False;
|
|
if Pos('{!SHELL}', sCmd)>0 then
|
|
begin
|
|
sCmd:=StringReplace(sCmd,'{!SHELL}','',[rfReplaceAll]);
|
|
sCmd:=Format(gTerm,[sCmd]);
|
|
Result := True;
|
|
end;
|
|
if Pos('{!EDITOR}',sCmd)>0 then
|
|
begin
|
|
sCmd:=StringReplace(sCmd,'{!EDITOR}','',[rfReplaceAll]);
|
|
uShowForm.ShowEditorByGlob(sCmd);
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
if Pos('{!VIEWER}',sCmd)>0 then
|
|
begin
|
|
sCmd:=StringReplace(sCmd,'{!VIEWER}','',[rfReplaceAll]);
|
|
uShowForm.ShowViewerByGlob(sCmd);
|
|
Result := True;
|
|
Exit;
|
|
end;
|
|
mbSetCurrentDir(ActiveDir);
|
|
Result := ExecCmdFork(sCmd);
|
|
end;
|
|
|
|
procedure TFilePanel.SetActiveDir(const AValue:String);
|
|
begin
|
|
fPrevActiveDir:= fActiveDir;
|
|
fActiveDir := IncludeTrailingBackslash(AValue);
|
|
end;
|
|
|
|
function TFilePanel.GetActiveDir:String;
|
|
begin
|
|
Result := IncludeTrailingBackslash(fActiveDir);
|
|
end;
|
|
|
|
function TFilePanel.GetReferenceItemPtr(iIndex:Integer):PFileRecItem;
|
|
begin
|
|
Result:=nil;
|
|
if iIndex>=fRefList.Count then Exit;
|
|
Result:=PFileRecItem(fRefList.Items[iIndex]);
|
|
end;
|
|
end.
|
|
|