FIX: Quick view for non FileSystemFileSource

This commit is contained in:
Alexander Koblov 2009-12-23 14:47:27 +00:00
commit 357ec151dd
4 changed files with 440 additions and 455 deletions

View file

@ -409,7 +409,6 @@ type
function FileViewBeforeChangeDirectory(Sender: TFileView; const NewDir : String): Boolean;
procedure FileViewAfterChangeDirectory(Sender: TFileView; const NewDir : String);
procedure FileViewChangeActiveFile(Sender: TFileView; const aFile : TFile);
procedure FileViewChangeFileSource(Sender: TFileView);
procedure FileViewActivate(Sender: TFileView);
procedure FileViewReload(Sender: TFileView);
@ -546,8 +545,7 @@ uses
uFileSourceOperationTypes, uFileSourceCopyOperation, uFileSourceMoveOperation,
fFileOpDlg, uFileSystemCopyOperation, uFileSystemMoveOperation,
uArchiveFileSource, uShellExecute, uActs, uFileSystemFile, uFileSourceOperation,
fSymLink, fHardLink, uExceptions, uUniqueInstance, uTempFileSystemFileSource,
uFileSourceProperty
fSymLink, fHardLink, uExceptions, uUniqueInstance
{$IFDEF LCLQT}
, qtwidgets
{$ENDIF}
@ -2277,60 +2275,6 @@ begin
end;
end;
procedure TfrmMain.FileViewChangeActiveFile(Sender: TFileView; const aFile : TFile);
var
ActiveFile: TFile = nil;
TempFiles: TFiles = nil;
TempFileSource: ITempFileSystemFileSource = nil;
Operation: TFileSourceOperation;
aFileSource: IFileSource;
begin
try
// If files not directly accessible copy them to temp file source.
if not (fspDirectAccess in Sender.FileSource.Properties) then
begin
if not (fsoCopyOut in Sender.FileSource.GetOperationsTypes) then
begin
Exit;
end;
ActiveFile:= aFile.Clone;
TempFiles := Sender.FileSource.CreateFiles;
TempFiles.Add(aFile);
TempFileSource := TTempFileSystemFileSource.GetFileSource;
Operation := ActiveFrame.FileSource.CreateCopyOutOperation(
TempFileSource,
TempFiles,
TempFileSource.FileSystemRoot);
if Assigned(Operation) then
begin
Operation.Execute;
FreeAndNil(Operation);
aFileSource := TempFileSource;
ActiveFile.Path:= TempFileSource.FileSystemRoot;
end
else
begin
Exit;
end;
end
else
begin
// We can use the file source directly.
aFileSource := ActiveFrame.FileSource;
ActiveFile:= aFile.Clone;
end;
QuickViewLoadFile(ActiveFile.FullPath, aFileSource);
finally
FreeThenNil(TempFiles);
FreeThenNil(ActiveFile);
end;
end;
procedure TfrmMain.FileViewChangeFileSource(Sender: TFileView);
var
ANoteBook : TFileViewNotebook;

View file

@ -1275,8 +1275,8 @@ begin
else if (param <> 'Close') then
begin
QuickViewShow(NotActiveNotebook.ActivePage, ActiveFrame.FileSource);
FileViewChangeActiveFile(ActiveFrame, ActiveFrame.ActiveFile);
ActiveFrame.OnChangeActiveFile:= @FileViewChangeActiveFile;
QuickViewPanel.FileViewChangeActiveFile(ActiveFrame, ActiveFrame.ActiveFile);
ActiveFrame.OnChangeActiveFile:= @QuickViewPanel.FileViewChangeActiveFile;
end;
end;
end;

View file

@ -1,380 +1,380 @@
{
Seksi Commander
----------------------------
Implementing of Generic File operation thread
(copying, moving ... is inherited from this)
Licence : GNU GPL v 2.0
Author : radek.cervinka@centrum.cz
contributors:
Copyright (C) 2006-2009 Koblov Alexander (Alexx2000@mail.ru)
}
unit uFileOpThread;
{$mode objfpc}{$H+}
interface
uses
Classes, uFileList, fFileOpDlg, uTypes, uDescr, uShowMsg;
type
{ TFileOpThread }
TFileOpThread = class(TThread)
private
{ Private declarations }
FPaused: Boolean;
procedure SetPaused(const Value: Boolean);
protected
FFileList: TFileList; // input filelist (not rekursive walked)
NewFileList: TFileList; // fill it with complete list of all files
FFilesCount: Integer;
FFilesSize: Int64;
FDirCount :Integer;
FBeginTime: TDateTime;
FDownTo: Boolean; // browse list backward (for deleting)
FReplaceAll:Boolean;
FSkipAll:Boolean;
FDstNameMask:String;
FDstExtMask:String;
FAppend: Boolean; // used mainly for pass information between move and copy
FSymLinkAll, // process all symlinks
FNotSymLinkAll : Boolean; // process all real files/folders
FDescr: TDescription;
procedure Execute; override;
procedure MainExecute; virtual; abstract; // main loop for copy /delete ...
procedure FillAndCount;
procedure FillAndCountRec(const srcPath, dstPath:String); // rekursive called
procedure EstimateTime(iSizeCoped:Int64);
function GetCaptionLng:String; virtual;
function GetFileOpDlgLook: TFileOpDlgLook; virtual;
function CheckFile(FileRecItem: PFileRecItem): Boolean; virtual;
procedure CorrectMask;
function CorrectDstName(const sName:String):String;
function CorrectDstExt(const sExt:String):String;
public
FFileOpDlg: TfrmFileOp; // progress window
sDstPath: String;
sDstMask: String;
bDropReadOnlyFlag : Boolean; // for copy operation
constructor Create(aFileList:TFileList);virtual;
destructor Destroy; override;
function FreeAtEnd:Boolean; virtual;
function DlgFileExist(const sMsg:String):Boolean; // result=true > rewrite file
function DlgFollowSymLink(const sMsg:String):Boolean;
property Paused: Boolean read FPaused write SetPaused;
end;
const
FMyMsgButtons : array[0..5] of TMyMsgButton = (msmbRewrite, msmbNo, msmbSkip, msmbAppend, msmbRewriteAll, msmbSkipAll); //Alexx2000
FSymLinkBtns : array[0..3] of TMyMsgButton = (msmbYes, msmbNo, msmbAll, msmbSkipAll); //Alexx2000
implementation
uses
SysUtils, uLng, uFindEx, uDCUtils, uOSUtils, uGlobs;
{ TFileOpThread }
constructor TFileOpThread.Create(aFileList:TFileList);
begin
inherited Create(True); // create Suspended
FFileList := aFileList;
FreeOnTerminate:=FreeAtEnd;
sDstMask:='*.*';
FSymLinkAll := False;
FNotSymLinkAll := False;
end;
destructor TFileOpThread.Destroy;
begin
if Assigned(FFileList) then
FreeAndNil(FFileList);
inherited;
end;
procedure TFileOpThread.FillAndCountRec(const srcPath, dstPath:String);
var
sr:TSearchRecEx;
fr:TFileRecItem;
begin
if FindFirstEx(srcPath+'*',faAnyFile,sr)<>0 then
begin
FindCloseEx(sr);
Exit;
end;
repeat
if (sr.Name='.') or (sr.Name='..') then Continue;
fr.sName:=srcPath+sr.Name;
// write(fr.sName,': ');
fr.sPath:=dstPath;
fr.sNameNoExt:=sr.Name; // we use to save dstname
// DebugLn(sr.Name);
fr.iSize:= sr.Size;
fr.iMode:= sr.Attr;
fr.fTimeI:= FileDateToDateTime(sr.Time);
fr.sTime:=''; // not interested
fr.bIsLink:=FPS_ISLNK(fr.iMode);
fr.sLinkTo:='';
fr.bSelected:=False;
fr.sModeStr:=''; // not interested
// fr.sPath:=srcPath;
// For process symlinks, read only files etc.
CheckFile(@fr);
NewFileList.AddItem(@fr);
if fr.bIsLink then
Continue;
if FPS_ISDIR(fr.iMode) then
begin
inc(FDirCount);
FillAndCountRec(srcPath+sr.Name+DirectorySeparator, dstPath+sr.Name+DirectorySeparator);
end
else
begin
inc(FFilesSize, fr.iSize);
inc(FFilesCount);
end;
until FindNextEx(sr)<>0;
FindCloseEx(sr);
end;
procedure TFileOpThread.FillAndCount;
var
I: Integer;
ptr: PFileRecItem;
begin
NewFileList.Clear;
FFilesCount:= 0;
FFilesSize:= 0;
FDirCount:= 0;
for I:= 0 to FFileList.Count-1 do
begin
ptr:= FFileList.GetItem(I);
// For process symlinks, read only files etc.
CheckFile(ptr);
if FPS_ISDIR(ptr^.iMode) and (not ptr^.bLinkIsDir) then
begin
inc(FDirCount);
NewFileList.AddItem(ptr); // add DIR to List
FillAndCountRec(ptr^.sName+DirectorySeparator,ptr^.sNameNoExt+DirectorySeparator); // rekursive browse child dir
end
else
begin
NewFileList.AddItem(ptr);
inc(FFilesCount);
inc(FFilesSize, ptr^.iSize); // in first level we know file size -> use it
end;
end;
end;
procedure TFileOpThread.SetPaused(const Value: Boolean);
begin
if Value <> FPaused then
begin
FPaused:= Value;
if not FPaused then
Resume;
end;
end;
procedure TFileOpThread.Execute;
begin
// main thread code started here
try
FReplaceAll:=False;
FSkipAll:=False;
NewFileList:=TFileList.Create;
try
if gProcessComments then
FDescr:= TDescription.Create(True);
FBeginTime:=Now;
FillAndCount; // gets full list of files (rekursive)
MainExecute; // main executive (virtual)
finally
if gProcessComments and Assigned(FDescr) then
begin
FDescr.SaveDescription;
FreeAndNil(FDescr);
end;
if Assigned(NewFileList) then
FreeAndNil(NewFileList);
end;
except
on E:Exception do
msgOK(Self, E.Message);
end;
end;
function TFileOpThread.FreeAtEnd:Boolean;
begin
Result:= True;
{ if we use WaitFor, we don't use FreeOnTerminate
possible SIGSEV!!!!!!!!!!
}
// Result:=False;
end;
procedure TFileOpThread.EstimateTime(iSizeCoped: Int64);
begin
end;
function TFileOpThread.DlgFileExist(const sMsg:String):Boolean; // result=true > rewrite file
begin
FAppend:= False;
Result:= False;
case MsgBox(Self,sMsg, FMyMsgButtons, msmbYes, msmbNo) of
mmrNo, mmrSkip:;
mmrRewrite:
begin
Result:= True;
end;
mmrRewriteAll:
begin
FReplaceAll:=True;
Result:= True;
end;
mmrAppend:
begin
FAppend:= True;
Result:= True;
end;
mmrSkipAll:
begin
FSkipAll:= True;
end;
else
Raise Exception.Create('bad handling msg result');
end; //case
end;
{ Dialog for process symlink or real file/folder }
function TFileOpThread.DlgFollowSymLink(const sMsg:String):Boolean; // result=true > follow symlink
begin
FAppend:= False;
Result:= False;
case MsgBox(Self, sMsg, FSymLinkBtns, msmbYes, msmbNo) of
mmrNo:;
mmrYes:
begin
Result:=True;
end;
mmrAll:
begin
FNotSymLinkAll:=True;
Result:=True;
end;
mmrSkipAll:
begin
FSymLinkAll:=True;
end;
else
Raise Exception.Create('bad handling msg result');
end; //case
end;
function TFileOpThread.GetCaptionLng: String;
begin
Result:= '';
end;
function TFileOpThread.GetFileOpDlgLook: TFileOpDlgLook;
begin
Result:= [fodl_from_lbl, fodl_to_lbl, fodl_first_pb, fodl_second_pb];
end;
function TFileOpThread.CheckFile(FileRecItem: PFileRecItem): Boolean;
var
sRealName: String;
sr: TSearchRecEx;
begin
Result:= True;
// For process symlink or real file/folder
if FPS_ISLNK(FileRecItem^.iMode) then
if (not FSymLinkAll) and (FNotSymLinkAll or DlgFollowSymLink(Format(rsMsgFollowSymlink, [FileRecItem^.sName]))) then
begin
sRealName:=ReadSymLink(FileRecItem^.sName);
sRealName := GetAbsoluteFileName(ExtractFilePath(FileRecItem^.sName), sRealName);
FindFirstEx(sRealName, faAnyFile, sr);
with FileRecItem^ do
begin
iSize := sr.Size;
sTime := DateTimeToStr(Trunc(FileDateToDateTime(sr.Time)));
iMode := sr.Attr;
bLinkIsDir:=False;
bSelected:=False;
end;
DivFileName(sRealName, FileRecItem^.sNameNoExt, FileRecItem^.sExt);
FileRecItem^.sNameNoExt := sr.Name;
FileRecItem^.sName := sRealName;
end;
//DebugLn('sNameNoExt == ' + FileRecItem^.sNameNoExt);
end;
procedure TFileOpThread.CorrectMask;
begin
DivFileName(sDstMask,FDstNameMask,FDstExtMask);
if FDstNameMask='' then
FDstNameMask:='*';
if FDstExtMask='' then
FDstExtMask:='.*';
end;
function TFileOpThread.CorrectDstName(const sName:String):String;
var
i:Integer;
begin
Result:='';
for i:=1 to length(FDstNameMask) do
begin
if FDstNameMask[i]= '?' then
Result:=Result+sName[i]
else
if FDstNameMask[i]= '*' then
Result:=Result+Copy(sName,i,length(sName)-i+1)
else
Result:=Result+FDstNameMask[i];
end;
end;
function TFileOpThread.CorrectDstExt(const sExt:String):String;
var
i:Integer;
begin
Result:='';
for i:=1 to length(FDstExtMask) do
begin
if FDstExtMask[i]= '?' then
Result:=Result+sExt[i]
else
if FDstExtMask[i]= '*' then
Result:=Result+Copy(sExt,i,length(sExt)-i+1)
else
Result:=Result+FDstExtMask[i];
end;
end;
end.
{
Seksi Commander
----------------------------
Implementing of Generic File operation thread
(copying, moving ... is inherited from this)
Licence : GNU GPL v 2.0
Author : radek.cervinka@centrum.cz
contributors:
Copyright (C) 2006-2009 Koblov Alexander (Alexx2000@mail.ru)
}
unit uFileOpThread;
{$mode objfpc}{$H+}
interface
uses
Classes, uFileList, fFileOpDlg, uTypes, uDescr, uShowMsg;
type
{ TFileOpThread }
TFileOpThread = class(TThread)
private
{ Private declarations }
FPaused: Boolean;
procedure SetPaused(const Value: Boolean);
protected
FFileList: TFileList; // input filelist (not rekursive walked)
NewFileList: TFileList; // fill it with complete list of all files
FFilesCount: Integer;
FFilesSize: Int64;
FDirCount :Integer;
FBeginTime: TDateTime;
FDownTo: Boolean; // browse list backward (for deleting)
FReplaceAll:Boolean;
FSkipAll:Boolean;
FDstNameMask:String;
FDstExtMask:String;
FAppend: Boolean; // used mainly for pass information between move and copy
FSymLinkAll, // process all symlinks
FNotSymLinkAll : Boolean; // process all real files/folders
FDescr: TDescription;
procedure Execute; override;
procedure MainExecute; virtual; abstract; // main loop for copy /delete ...
procedure FillAndCount;
procedure FillAndCountRec(const srcPath, dstPath:String); // rekursive called
procedure EstimateTime(iSizeCoped:Int64);
function GetCaptionLng:String; virtual;
function GetFileOpDlgLook: TFileOpDlgLook; virtual;
function CheckFile(FileRecItem: PFileRecItem): Boolean; virtual;
procedure CorrectMask;
function CorrectDstName(const sName:String):String;
function CorrectDstExt(const sExt:String):String;
public
FFileOpDlg: TfrmFileOp; // progress window
sDstPath: String;
sDstMask: String;
bDropReadOnlyFlag : Boolean; // for copy operation
constructor Create(aFileList:TFileList);virtual;
destructor Destroy; override;
function FreeAtEnd:Boolean; virtual;
function DlgFileExist(const sMsg:String):Boolean; // result=true > rewrite file
function DlgFollowSymLink(const sMsg:String):Boolean;
property Paused: Boolean read FPaused write SetPaused;
end;
const
FMyMsgButtons : array[0..5] of TMyMsgButton = (msmbRewrite, msmbNo, msmbSkip, msmbAppend, msmbRewriteAll, msmbSkipAll); //Alexx2000
FSymLinkBtns : array[0..3] of TMyMsgButton = (msmbYes, msmbNo, msmbAll, msmbSkipAll); //Alexx2000
implementation
uses
SysUtils, uLng, uFindEx, uDCUtils, uOSUtils, uGlobs, uDateTimeUtils;
{ TFileOpThread }
constructor TFileOpThread.Create(aFileList:TFileList);
begin
inherited Create(True); // create Suspended
FFileList := aFileList;
FreeOnTerminate:=FreeAtEnd;
sDstMask:='*.*';
FSymLinkAll := False;
FNotSymLinkAll := False;
end;
destructor TFileOpThread.Destroy;
begin
if Assigned(FFileList) then
FreeAndNil(FFileList);
inherited;
end;
procedure TFileOpThread.FillAndCountRec(const srcPath, dstPath:String);
var
sr:TSearchRecEx;
fr:TFileRecItem;
begin
if FindFirstEx(srcPath+'*',faAnyFile,sr)<>0 then
begin
FindCloseEx(sr);
Exit;
end;
repeat
if (sr.Name='.') or (sr.Name='..') then Continue;
fr.sName:=srcPath+sr.Name;
// write(fr.sName,': ');
fr.sPath:=dstPath;
fr.sNameNoExt:=sr.Name; // we use to save dstname
// DebugLn(sr.Name);
fr.iSize:= sr.Size;
fr.iMode:= sr.Attr;
fr.fTimeI:= FileTimeToDateTime(sr.Time);
fr.sTime:=''; // not interested
fr.bIsLink:=FPS_ISLNK(fr.iMode);
fr.sLinkTo:='';
fr.bSelected:=False;
fr.sModeStr:=''; // not interested
// fr.sPath:=srcPath;
// For process symlinks, read only files etc.
CheckFile(@fr);
NewFileList.AddItem(@fr);
if fr.bIsLink then
Continue;
if FPS_ISDIR(fr.iMode) then
begin
inc(FDirCount);
FillAndCountRec(srcPath+sr.Name+DirectorySeparator, dstPath+sr.Name+DirectorySeparator);
end
else
begin
inc(FFilesSize, fr.iSize);
inc(FFilesCount);
end;
until FindNextEx(sr)<>0;
FindCloseEx(sr);
end;
procedure TFileOpThread.FillAndCount;
var
I: Integer;
ptr: PFileRecItem;
begin
NewFileList.Clear;
FFilesCount:= 0;
FFilesSize:= 0;
FDirCount:= 0;
for I:= 0 to FFileList.Count-1 do
begin
ptr:= FFileList.GetItem(I);
// For process symlinks, read only files etc.
CheckFile(ptr);
if FPS_ISDIR(ptr^.iMode) and (not ptr^.bLinkIsDir) then
begin
inc(FDirCount);
NewFileList.AddItem(ptr); // add DIR to List
FillAndCountRec(ptr^.sName+DirectorySeparator,ptr^.sNameNoExt+DirectorySeparator); // rekursive browse child dir
end
else
begin
NewFileList.AddItem(ptr);
inc(FFilesCount);
inc(FFilesSize, ptr^.iSize); // in first level we know file size -> use it
end;
end;
end;
procedure TFileOpThread.SetPaused(const Value: Boolean);
begin
if Value <> FPaused then
begin
FPaused:= Value;
if not FPaused then
Resume;
end;
end;
procedure TFileOpThread.Execute;
begin
// main thread code started here
try
FReplaceAll:=False;
FSkipAll:=False;
NewFileList:=TFileList.Create;
try
if gProcessComments then
FDescr:= TDescription.Create(True);
FBeginTime:=Now;
FillAndCount; // gets full list of files (rekursive)
MainExecute; // main executive (virtual)
finally
if gProcessComments and Assigned(FDescr) then
begin
FDescr.SaveDescription;
FreeAndNil(FDescr);
end;
if Assigned(NewFileList) then
FreeAndNil(NewFileList);
end;
except
on E:Exception do
msgOK(Self, E.Message);
end;
end;
function TFileOpThread.FreeAtEnd:Boolean;
begin
Result:= True;
{ if we use WaitFor, we don't use FreeOnTerminate
possible SIGSEV!!!!!!!!!!
}
// Result:=False;
end;
procedure TFileOpThread.EstimateTime(iSizeCoped: Int64);
begin
end;
function TFileOpThread.DlgFileExist(const sMsg:String):Boolean; // result=true > rewrite file
begin
FAppend:= False;
Result:= False;
case MsgBox(Self,sMsg, FMyMsgButtons, msmbYes, msmbNo) of
mmrNo, mmrSkip:;
mmrRewrite:
begin
Result:= True;
end;
mmrRewriteAll:
begin
FReplaceAll:=True;
Result:= True;
end;
mmrAppend:
begin
FAppend:= True;
Result:= True;
end;
mmrSkipAll:
begin
FSkipAll:= True;
end;
else
Raise Exception.Create('bad handling msg result');
end; //case
end;
{ Dialog for process symlink or real file/folder }
function TFileOpThread.DlgFollowSymLink(const sMsg:String):Boolean; // result=true > follow symlink
begin
FAppend:= False;
Result:= False;
case MsgBox(Self, sMsg, FSymLinkBtns, msmbYes, msmbNo) of
mmrNo:;
mmrYes:
begin
Result:=True;
end;
mmrAll:
begin
FNotSymLinkAll:=True;
Result:=True;
end;
mmrSkipAll:
begin
FSymLinkAll:=True;
end;
else
Raise Exception.Create('bad handling msg result');
end; //case
end;
function TFileOpThread.GetCaptionLng: String;
begin
Result:= '';
end;
function TFileOpThread.GetFileOpDlgLook: TFileOpDlgLook;
begin
Result:= [fodl_from_lbl, fodl_to_lbl, fodl_first_pb, fodl_second_pb];
end;
function TFileOpThread.CheckFile(FileRecItem: PFileRecItem): Boolean;
var
sRealName: String;
sr: TSearchRecEx;
begin
Result:= True;
// For process symlink or real file/folder
if FPS_ISLNK(FileRecItem^.iMode) then
if (not FSymLinkAll) and (FNotSymLinkAll or DlgFollowSymLink(Format(rsMsgFollowSymlink, [FileRecItem^.sName]))) then
begin
sRealName:=ReadSymLink(FileRecItem^.sName);
sRealName := GetAbsoluteFileName(ExtractFilePath(FileRecItem^.sName), sRealName);
FindFirstEx(sRealName, faAnyFile, sr);
with FileRecItem^ do
begin
iSize := sr.Size;
sTime := DateTimeToStr(Trunc(FileDateToDateTime(sr.Time)));
iMode := sr.Attr;
bLinkIsDir:=False;
bSelected:=False;
end;
DivFileName(sRealName, FileRecItem^.sNameNoExt, FileRecItem^.sExt);
FileRecItem^.sNameNoExt := sr.Name;
FileRecItem^.sName := sRealName;
end;
//DebugLn('sNameNoExt == ' + FileRecItem^.sNameNoExt);
end;
procedure TFileOpThread.CorrectMask;
begin
DivFileName(sDstMask,FDstNameMask,FDstExtMask);
if FDstNameMask='' then
FDstNameMask:='*';
if FDstExtMask='' then
FDstExtMask:='.*';
end;
function TFileOpThread.CorrectDstName(const sName:String):String;
var
i:Integer;
begin
Result:='';
for i:=1 to length(FDstNameMask) do
begin
if FDstNameMask[i]= '?' then
Result:=Result+sName[i]
else
if FDstNameMask[i]= '*' then
Result:=Result+Copy(sName,i,length(sName)-i+1)
else
Result:=Result+FDstNameMask[i];
end;
end;
function TFileOpThread.CorrectDstExt(const sExt:String):String;
var
i:Integer;
begin
Result:='';
for i:=1 to length(FDstExtMask) do
begin
if FDstExtMask[i]= '?' then
Result:=Result+sExt[i]
else
if FDstExtMask[i]= '*' then
Result:=Result+Copy(sExt,i,length(sExt)-i+1)
else
Result:=Result+FDstExtMask[i];
end;
end;
end.

View file

@ -6,7 +6,7 @@ interface
uses
Classes, SysUtils, ExtCtrls, fViewer,
uFileViewNotebook, uFileSource;
uFileViewNotebook, uFile, uFileSource, uFileView;
type
@ -23,10 +23,10 @@ type
destructor Destroy; override;
procedure CreateViewer(aFileSource: IFileSource);
procedure LoadFile(const aFileName: UTF8String);
procedure FileViewChangeActiveFile(Sender: TFileView; const aFile : TFile);
end;
procedure QuickViewShow(aFileViewPage: TFileViewPage; const aFileSource: IFileSource);
procedure QuickViewLoadFile(const aFileName: UTF8String; const aFileSource: IFileSource);
procedure QuickViewClose;
var
@ -35,7 +35,8 @@ var
implementation
uses
LCLProc, Forms, Controls;
LCLProc, Forms, Controls, uTempFileSystemFileSource,
uFileSourceProperty, uFileSourceOperation, uFileSourceOperationTypes;
procedure QuickViewShow(aFileViewPage: TFileViewPage; const aFileSource: IFileSource);
begin
@ -43,18 +44,6 @@ begin
QuickViewPanel.CreateViewer(aFileSource);
end;
procedure QuickViewLoadFile(const aFileName: UTF8String; const aFileSource: IFileSource);
begin
{
if (not QuickViewPanel.FFileSource.IsInterface(aFileSource)) then
begin
QuickViewPanel.FViewer.Close;
QuickViewPanel.CreateViewer(aFileSource);
end;
}
QuickViewPanel.LoadFile(aFileName);
end;
procedure QuickViewClose;
begin
FreeThenNil(QuickViewPanel);
@ -81,13 +70,14 @@ end;
procedure TQuickViewPanel.CreateViewer(aFileSource: IFileSource);
begin
FViewer:= TfrmViewer.Create(Self, aFileSource);
FViewer:= TfrmViewer.Create(Self, nil);
FViewer.Parent:= Self;
FViewer.BorderStyle:= bsNone;
FViewer.Menu:= nil;
FViewer.Align:= alClient;
FViewer.QuickView:= True;
FFirstFile:= True;
FFileSource:= aFileSource;
FFileViewPage.FileView.Visible:= False;
end;
@ -105,5 +95,56 @@ begin
end;
end;
procedure TQuickViewPanel.FileViewChangeActiveFile(Sender: TFileView; const aFile: TFile);
var
ActiveFile: TFile = nil;
TempFiles: TFiles = nil;
TempFileSource: ITempFileSystemFileSource = nil;
Operation: TFileSourceOperation = nil;
begin
try
// If files not directly accessible copy them to temp file source.
if not (fspDirectAccess in Sender.FileSource.Properties) then
begin
if not (fsoCopyOut in Sender.FileSource.GetOperationsTypes) then Exit;
ActiveFile:= aFile.Clone;
TempFiles:= Sender.FileSource.CreateFiles;
TempFiles.Path:= Sender.CurrentPath;
TempFiles.Add(aFile.Clone);
if FFileSource.IsClass(TTempFileSystemFileSource) then
TempFileSource := (FFileSource as ITempFileSystemFileSource)
else
TempFileSource := TTempFileSystemFileSource.GetFileSource;
Operation := Sender.FileSource.CreateCopyOutOperation(
TempFileSource,
TempFiles,
TempFileSource.FileSystemRoot);
if not Assigned(Operation) then Exit;
Operation.Execute;
FreeAndNil(Operation);
FFileSource := TempFileSource;
ActiveFile.Path:= TempFileSource.FileSystemRoot;
end
else
begin
// We can use the file source directly.
FFileSource := Sender.FileSource;
ActiveFile:= aFile.Clone;
end;
LoadFile(ActiveFile.FullPath);
finally
FreeThenNil(TempFiles);
FreeThenNil(ActiveFile);
end;
end;
end.