summaryrefslogtreecommitdiff
path: root/UMain.pas
diff options
context:
space:
mode:
Diffstat (limited to 'UMain.pas')
-rw-r--r--UMain.pas309
1 files changed, 187 insertions, 122 deletions
diff --git a/UMain.pas b/UMain.pas
index 61e826e..c77ea4d 100644
--- a/UMain.pas
+++ b/UMain.pas
@@ -231,13 +231,14 @@ type
procedure SwitchTab(TabNo: integer; LeftPanel, SetFocus: boolean);
procedure CloseTab(TabNo: integer; LeftPanel: boolean);
procedure AddTabs(LeftPanel: boolean; TabList: TStringList; TabSortIDs, TabSortTypes: TList; SetTabActive: integer);
- function HandleVFSArchive(const FileName, FullPath, HighlightItem, TargetPath: string): boolean;
- procedure CloseVFS(LeftPanel, SurpressRefresh: boolean);
+ function HandleVFSArchive(LeftPanel: boolean; const FullPath, HighlightItem, TargetPath: string): boolean;
+ function CloseVFS(LeftPanel, SuppressRefresh: boolean): string;
procedure ShowBookmarkQuick(LeftPanel: boolean);
procedure SetTabLabel(Notebook: TEphyNotebook; PageIndex: integer; ALabel, Tooltip: string);
procedure NewTabInternal(LeftPanel: boolean; _Engine: TPanelEngine; _Path: string; NewTabPosition: integer);
procedure CopyFilenamesToClipboard(FullPaths, LeftPanel: boolean);
function HandleRunFromArchive(var APath: string; Engine: TPanelEngine; Command, FileTypeDesc: string; BypassDialog: boolean): boolean;
+ function ExtractFromArchive(var NewPath: string; Engine: TPanelEngine; const FilePath: string; ExtractAll: boolean): boolean;
function HandleKey(Key: Word; Shift: TShiftState; LeftPanel: boolean): boolean;
function IsEditing(AListView: TGTKListView): boolean;
function PanelFindEditableWidget(AListView: TGTKListView): PGtkWidget;
@@ -1117,13 +1118,14 @@ procedure TFMain.FormClose(Sender: TObject; var Action: TCloseAction);
Result := FallbackEngine;
if not Assigned(Engine.ParentEngine) or (not (Engine is TVFSEngine)) then Exit;
Result := Engine.ParentEngine;
-// if not TVFSEngine(Engine).VFSClose then DebugMsg(['Error closing the engine...']);
-// Engine.Free;
+ if not TVFSEngine(Engine).VFSClose then DebugMsg(['Error closing the engine...']);
+ Engine.Free;
end;
var i: integer;
b, DontShowAgain: boolean;
res: TMessageButton;
+ s: string;
begin
// Find all opened connections and warn user
b := False;
@@ -1156,27 +1158,42 @@ begin
// Close all active connections
if b then begin
- if (not LeftPanelNotebook.Visible) and (LeftPanelEngine is TVFSEngine) then CloseVFS(True, True)
- else
- for i := 0 to LeftTabEngines.Count - 1 do try
- if LeftPanelNotebook.PageIndex = i then CloseVFS(True, True) else
- if Assigned(LeftTabEngines[i]) and (TPanelEngine(LeftTabEngines[i]) is TVFSEngine) then begin
- LeftPanelTabs[i] := TPanelEngine(LeftTabEngines[i]).SavePath;
- LeftTabEngines[i] := InternalCloseEngine(LeftTabEngines[i], LeftLocalEngine);
- end;
- except end;
- if (not RightPanelNotebook.Visible) and (RightPanelEngine is TVFSEngine) then CloseVFS(False, True)
- else
- for i := 0 to RightTabEngines.Count - 1 do try
- if RightPanelNotebook.PageIndex = i then CloseVFS(False, True) else
- if TPanelEngine(RightTabEngines[i]) is TVFSEngine then begin
- RightPanelTabs[i] := TPanelEngine(RightTabEngines[i]).SavePath;
- RightTabEngines[i] := InternalCloseEngine(RightTabEngines[i], RightLocalEngine);
- end;
- except end;
+ if (not LeftPanelNotebook.Visible) and (LeftPanelEngine is TVFSEngine) then begin
+ while LeftPanelEngine is TVFSEngine do s := CloseVFS(True, True);
+ if LeftPanelEngine is TLocalTreeEngine then LeftPanelEngine.ChangeDir(s);
+ end else
+ for i := 0 to LeftTabEngines.Count - 1 do
+ if (TPanelEngine(LeftTabEngines[i]) <> nil) and (TPanelEngine(LeftTabEngines[i]) is TVFSEngine) then
+ try
+ if LeftPanelNotebook.PageIndex = i then begin
+ while LeftPanelEngine is TVFSEngine do s := CloseVFS(True, True);
+ LeftPanelTabs[i] := s;
+ end else
+ while Assigned(LeftTabEngines[i]) and (TPanelEngine(LeftTabEngines[i]) is TVFSEngine) do begin
+ LeftPanelTabs[i] := TPanelEngine(LeftTabEngines[i]).SavePath;
+ LeftTabEngines[i] := InternalCloseEngine(LeftTabEngines[i], LeftLocalEngine);
+ end;
+ except end;
+
+ if (not RightPanelNotebook.Visible) and (RightPanelEngine is TVFSEngine) then begin
+ while RightPanelEngine is TVFSEngine do s := CloseVFS(False, True);
+ if RightPanelEngine is TLocalTreeEngine then RightPanelEngine.ChangeDir(s);
+ end else
+ for i := 0 to RightTabEngines.Count - 1 do
+ if (TPanelEngine(RightTabEngines[i]) <> nil) and (TPanelEngine(RightTabEngines[i]) is TVFSEngine) then
+ try
+ if RightPanelNotebook.PageIndex = i then begin
+ while RightPanelEngine is TVFSEngine do s := CloseVFS(False, True);
+ RightPanelTabs[i] := s;
+ end else
+ while Assigned(RightTabEngines[i]) and (TPanelEngine(RightTabEngines[i]) is TVFSEngine) do begin
+ RightPanelTabs[i] := TPanelEngine(RightTabEngines[i]).SavePath;
+ RightTabEngines[i] := InternalCloseEngine(RightTabEngines[i], RightLocalEngine);
+ end;
+ except end;
end;
- // Unset the columns changed signal because it is called on window close
+ // Unset the columns changed signal because it's called on window close
LeftListView.OnColumnsChanged := nil;
RightListView.OnColumnsChanged := nil;
@@ -1265,10 +1282,14 @@ begin
end;
// Refresh the lists
- ChangingDir(True, ConfLeftPath, '', '', False, True); // AutoFallback
- ChangingDir(False, ConfRightPath, '', '', False, True);
- LeftListView.SetSortInfo(ConfMainWindowLeftSortColumn, TGTKTreeViewSortOrder(ConfMainWindowLeftSortType));
- RightListView.SetSortInfo(ConfMainWindowRightSortColumn, TGTKTreeViewSortOrder(ConfMainWindowRightSortType));
+ if not (LeftPanelNotebook.Visible and (LeftTabEngines.Count > 0)) then begin
+ ChangingDir(True, ConfLeftPath, '', '', False, True); // AutoFallback
+ LeftListView.SetSortInfo(ConfMainWindowLeftSortColumn, TGTKTreeViewSortOrder(ConfMainWindowLeftSortType));
+ end;
+ if not (RightPanelNotebook.Visible and (RightTabEngines.Count > 0)) then begin
+ ChangingDir(False, ConfRightPath, '', '', False, True);
+ RightListView.SetSortInfo(ConfMainWindowRightSortColumn, TGTKTreeViewSortOrder(ConfMainWindowRightSortType));
+ end;
// Set window position and size
SetDefaultSize(ConfMainWindowWidth, ConfMainWindowHeight);
@@ -1688,7 +1709,7 @@ begin
// Test for known internal functions
if ((Ext = 'SFV') or (Ext = 'MD5')) and (Engine is TLocalTreeEngine) then miVerifyChecksumsClick(Self) else
if ((Ext = 'CRC') or (Ext = '001')) and (Engine is TLocalTreeEngine) then miMergeFilesClick(Self) else
- if not ((Engine is TLocalTreeEngine) and HandleVFSArchive(String(Data^.FName), IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.FName), String(Data^.FName), '/')) then
+ if not HandleVFSArchive(LeftPanel, IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.FName), String(Data^.FName), '/') then
if (not ConfUseURI) or ((Engine is TVFSEngine) and TVFSEngine(Engine).ArchiveMode)
then RunFile(IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.FName), Engine, -1)
else RunFile(ExcludeTrailingPathDelimiter(Engine.GetPrefix) + IncludeTrailingPathDelimiter(Engine.Path) + String(Data^.FName), Engine, -1);
@@ -5536,7 +5557,7 @@ begin
SwitchTab(NewTabNum, LeftPanel, ShouldFocus);
if LeftPanel then LeftPanelEngine := TabEngines[NewTabNum]
else RightPanelEngine := TabEngines[NewTabNum];
- ChangingDir(LeftPanel, ATabList[NewTabNum], PathsHighlight[NewTabNum]);
+ ChangingDir(LeftPanel, ATabList[NewTabNum], PathsHighlight[NewTabNum], '', False, True);
AListView.SetSortInfo(Integer(TabSortIDs[NewTabNum]),
TGTKTreeViewSortOrder(Integer(TabSortTypes[NewTabNum])));
end;
@@ -5576,7 +5597,7 @@ var ATabList: TStringList;
AVBoxList: TList;
i, NewPageIndex: integer;
TabEngines: TList;
- Engine: TPanelEngine;
+ Engine, xEngine: TPanelEngine;
TabSortIDs: TList;
TabSortTypes: TList;
AListView: TGTKListView;
@@ -5624,10 +5645,12 @@ begin
TabSortIDs.Delete(TabNo);
TabSortTypes.Delete(TabNo);
// Try to close the VFS engine
- if Engine is TVFSEngine then
+ while Engine is TVFSEngine do
try
- if not TVFSEngine(Engine).VFSClose then DebugMsg(['Error closing the engine...']);
- Engine.Free;
+ xEngine := Engine;
+ Engine := xEngine.ParentEngine;
+ if not TVFSEngine(xEngine).VFSClose then DebugMsg(['Error closing the engine...']);
+ xEngine.Free;
except end;
end else begin // Close last/all tabs, hide the tab bar
@@ -5645,12 +5668,17 @@ begin
PathsHighlight.Clear;
for i := 0 to TabEngines.Count - 1 do
if (TPanelEngine(TabEngines[i]) is TVFSEngine) and ((LeftPanel and (LeftPanelEngine <> TabEngines[i])) or
- ((not LeftPanel) and (RightPanelEngine <> TabEngines[i]))) then
- try
- Engine := TabEngines[i];
- if not TVFSEngine(Engine).VFSClose then DebugMsg(['Error closing the engine...']);
- Engine.Free;
- except end;
+ ((not LeftPanel) and (RightPanelEngine <> TabEngines[i])))
+ then begin
+ Engine := TabEngines[i];
+ while Engine is TVFSEngine do
+ try
+ xEngine := Engine;
+ Engine := xEngine.ParentEngine;
+ if not TVFSEngine(xEngine).VFSClose then DebugMsg(['Error closing the engine...']);
+ xEngine.Free;
+ except end;
+ end;
TabEngines.Clear;
{ for i := 0 to AVBoxList.Count - 1 do
@@ -5678,6 +5706,7 @@ var ANotebook: TEphyNotebook;
i: integer;
ATabSortIDs: TList;
ATabSortTypes: TList;
+ OldEvent: TEphyNotebookTabSwitchedEvent;
begin
if LeftPanel then begin
ANotebook := LeftPanelNotebook;
@@ -5716,7 +5745,10 @@ begin
end;
if not ANotebook.Visible then ANotebook.Visible := True;
+ OldEvent := ANotebook.OnTabSwitched;
+ ANotebook.OnTabSwitched := nil;
ANotebook.PageIndex := SetTabActive;
+ ANotebook.OnTabSwitched := OldEvent;
TabNotebookSwitchPage(ANotebook, SetTabActive, True);
end;
@@ -5898,19 +5930,38 @@ end;
(********************************************************************************************************************************)
(********************************************************************************************************************************)
-function TFMain.HandleVFSArchive(const FileName, FullPath, HighlightItem, TargetPath: string): boolean;
+function TFMain.HandleVFSArchive(LeftPanel: boolean; const FullPath, HighlightItem, TargetPath: string): boolean;
var Plugin: TVFSPlugin;
+ Engine, NewEngine: TPanelEngine;
+ NewPath: string;
begin
- Plugin := FindVFSPlugin(FileName);
+ Plugin := FindVFSPlugin(ExtractFileName(FullPath));
Result := Plugin <> nil;
if Result then begin
- DebugMsg(['Found plugin ''', Plugin.VFSName, ''', trying to open the file ''', FullPath, '''']);
- ChangingDir(LeftLastFocused, TargetPath, FullPath, HighlightItem, False, False, Plugin);
+ if LeftPanel then Engine := LeftPanelEngine
+ else Engine := RightPanelEngine;
+
+ if Engine is TLocalTreeEngine then begin
+ DebugMsg(['Found plugin ''', Plugin.VFSName, ''', trying to open the file ''', FullPath, '''']);
+ ChangingDir(LeftPanel, TargetPath, FullPath, HighlightItem, False, False, Plugin);
+ end else begin
+ DebugMsg(['Found plugin ''', Plugin.VFSName, ''', archive is nested in another archive, extracting first.']);
+ NewPath := '';
+ Result := ExtractFromArchive(NewPath, Engine, FullPath, False);
+ if Result then begin
+ DebugMsg(['Extract OK, trying to open the file ''', NewPath, '''']);
+ ChangingDir(LeftPanel, TargetPath, NewPath, HighlightItem, False, False, Plugin);
+ if LeftPanel then NewEngine := LeftPanelEngine
+ else NewEngine := RightPanelEngine;
+ if (NewEngine is TVFSEngine) and (NewEngine.ParentEngine = Engine) then
+ (NewEngine as TVFSEngine).RemoveFileOnClose := NewPath;
+ end;
+ end;
end;
end;
-procedure TFMain.CloseVFS(LeftPanel, SurpressRefresh: boolean);
+function TFMain.CloseVFS(LeftPanel, SuppressRefresh: boolean): string;
var Engine: TPanelEngine;
begin
if LeftPanel then Engine := LeftPanelEngine
@@ -5918,8 +5969,10 @@ begin
if not Assigned(Engine.ParentEngine) or (not (Engine is TVFSEngine)) then Exit;
if LeftPanel then LeftPanelEngine := Engine.ParentEngine
else RightPanelEngine := Engine.ParentEngine;
- if not SurpressRefresh then ChangingDir(LeftPanel, Engine.SavePath, StrToUTF8(Engine.ParentEngine.LastHighlightItem),
- Engine.ParentEngine.LastHighlightItem, False, True);
+
+ Result := Engine.SavePath;
+ if not SuppressRefresh then
+ ChangingDir(LeftPanel, Engine.SavePath, StrToUTF8(Engine.ParentEngine.LastHighlightItem), Engine.ParentEngine.LastHighlightItem, False, True);
if not TVFSEngine(Engine).VFSClose then DebugMsg(['Error closing the engine...']);
Engine.Free;
@@ -5969,7 +6022,7 @@ begin
mbApply: begin
DebugMsg(['TFMain.miSearchClick: FSearch.GoToFileArchive = "', FSearch.GoToFileArchive, '", FSearch.GoToFile = "', FSearch.GoToFile, '"']);
if Length(FSearch.GoToFileArchive) > 0 then begin
- HandleVFSArchive(ExtractFileName(FSearch.GoToFileArchive), FSearch.GoToFileArchive, ExtractFileName(FSearch.GoToFileArchive), ExtractFilePath(FSearch.GoToFile));
+ HandleVFSArchive(LeftLastFocused, FSearch.GoToFileArchive, ExtractFileName(FSearch.GoToFileArchive), ExtractFilePath(FSearch.GoToFile));
if LeftLastFocused then begin
Engine := LeftPanelEngine;
@@ -6230,17 +6283,12 @@ begin
end;
(********************************************************************************************************************************)
+(********************************************************************************************************************************)
function TFMain.HandleRunFromArchive(var APath: string; Engine: TPanelEngine; Command, FileTypeDesc: string; BypassDialog: boolean): boolean;
var Res: TMessageButton;
Stat: PDataItemSl;
s: string;
- AWorkingThread: TWorkerThread;
- AFProgress: TFProgress;
- tmp: PChar;
- LocalEngine: TLocalTreeEngine;
AListView: TGTKListView;
- DataList: TList;
- err: integer;
begin
Result := False;
try
@@ -6293,77 +6341,12 @@ begin
Result := False;
if Res = mbYes then DebugMsg(['(II) HandleRunFromArchive: Selected extract and execute single item'])
else DebugMsg(['(II) HandleRunFromArchive: Selected extract all and execute']);
- s := IncludeTrailingPathDelimiter(ConfTempPath) + 'tuxcmd-XXXXXX';
- tmp := strdup(PChar(s));
- tmp := mkdtemp(tmp);
- if tmp = nil then begin
- err := errno;
- DebugMsg(['(EE) HandleRunFromArchive: Couldn''t create temporary directory: ', strerror(err)]);
- Application.MessageBox(PChar(Format(LANGHandleRunFromArchive_CouldntCreateTemporaryDirectory, [s, string(strerror(err))])), [mbOK], mbError, mbOK, mbOK);
- Result := False;
- Exit;
- end;
- DebugMsg(['(II) HandleRunFromArchive: Using temporary directory: ', tmp]);
- UsedTempPaths.Add(string(tmp));
-
+
+ if LeftLastFocused then AListView := LeftListView
+ else AListView := RightListView;
Engine.Path := ExtractFilePath(APath);
// Extract the files
- LocalEngine := TLocalTreeEngine.Create;
- AFProgress := TFProgress.Create(Self);
- AWorkingThread := TWorkerThread.Create;
- try
- DebugMsg(['TFMain.HandleRunFromArchive: Creating thread...']);
- AFProgress.Label1.Caption := LANGCopySC;
- AFProgress.SetNumBars(True);
- AFProgress.ProgressBar.Value := 0;
- AWorkingThread.ProgressForm := AFProgress;
- LocalEngine.SetPath(tmp);
- AWorkingThread.ExtractFromVFSMode := True;
- AWorkingThread.DestEngine := LocalEngine;
- AWorkingThread.SrcEngine := Engine;
- if LeftLastFocused then begin
- AListView := LeftListView;
- DataList := LeftPanelData;
- end else begin
- AListView := RightListView;
- DataList := RightPanelData;
- end;
- if Assigned(AListView.Selected) then AWorkingThread.SelectedItem := AListView.Selected.Data;
- AWorkingThread.ExtractFromVFSAll := Res = mbNo;
- AWorkingThread.LeftPanel := LeftLastFocused;
- AWorkingThread.DataList := DataList;
- AWorkingThread.WorkerProcedure := CopyFilesWorker;
- AWorkingThread.ParamBool3 := True;
- AWorkingThread.ParamBool4 := False;
- AWorkingThread.ParamBool5 := True;
- AWorkingThread.ParamString1 := string(tmp);
- AWorkingThread.ParamString2 := APath;
- AWorkingThread.ParamDataItem1 := nil;
- DebugMsg(['*** Copy: AWorkingThread.Resume']);
- AWorkingThread.Resume;
- DebugMsg(['*** Copy: AWorkingThread.Resumed.']);
- AFProgress.ParentForm := FMain;
- AFProgress.ShowModal;
- ProcessProgressThread(AWorkingThread, AFProgress);
- AFProgress.Close;
- Result := {(not AWorkingThread.Cancelled) and} (not AWorkingThread.ErrorHappened);
- finally
- DebugMsg(['TFMain.HandleRunFromArchive: Freeing thread...']);
- LocalEngine.Free;
- AFProgress.Free;
- AWorkingThread.Free;
- end;
-
- DebugMsg(['(II) HandleRunFromArchive: Old path = ', APath]);
- if Result then begin
- if Res = mbYes then APath := IncludeTrailingPathDelimiter(string(tmp)) + ExtractFileName(APath)
- else APath := ExcludeTrailingPathDelimiter(string(tmp)) + APath;
- end;
- DebugMsg(['(II) HandleRunFromArchive: New path = ', APath]);
-
-
- libc_free(tmp);
- DebugMsg(['(II) HandleRunFromArchive: Copy OK, Result = ', Result]);
+ Result := ExtractFromArchive(APath, Engine, IncludeTrailingPathDelimiter(Engine.Path) + string(PDataItem(AListView.Selected.Data)^.FName), Res = mbNo);
end;
finally
@@ -6371,6 +6354,88 @@ begin
end;
end;
+function TFMain.ExtractFromArchive(var NewPath: string; Engine: TPanelEngine; const FilePath: string; ExtractAll: boolean): boolean;
+var s: string;
+ AWorkingThread: TWorkerThread;
+ AFProgress: TFProgress;
+ tmp: PChar;
+ LocalEngine: TLocalTreeEngine;
+ DataList: TList;
+ err: integer;
+begin
+ Result := False;
+ s := IncludeTrailingPathDelimiter(ConfTempPath) + 'tuxcmd-XXXXXX';
+ tmp := strdup(PChar(s));
+ tmp := mkdtemp(tmp);
+ if tmp = nil then begin
+ err := errno;
+ DebugMsg(['(EE) ExtractFromArchive: Couldn''t create temporary directory: ', strerror(err)]);
+ Application.MessageBox(PChar(Format(LANGHandleRunFromArchive_CouldntCreateTemporaryDirectory, [s, string(strerror(err))])), [mbOK], mbError, mbOK, mbOK);
+ Result := False;
+ Exit;
+ end;
+ DebugMsg(['(II) ExtractFromArchive: Using temporary directory: ', tmp]);
+ UsedTempPaths.Add(string(tmp));
+
+ if LeftLastFocused then DataList := LeftPanelData
+ else DataList := RightPanelData;
+
+ LocalEngine := TLocalTreeEngine.Create;
+ AFProgress := TFProgress.Create(Self);
+ AWorkingThread := TWorkerThread.Create;
+ try
+ DebugMsg(['TFMain.ExtractFromArchive: Creating thread...']);
+ AFProgress.Label1.Caption := LANGCopySC;
+ AFProgress.SetNumBars(True);
+ AFProgress.ProgressBar.Value := 0;
+ AWorkingThread.ProgressForm := AFProgress;
+ LocalEngine.SetPath(tmp);
+ AWorkingThread.ExtractFromVFSMode := True;
+ AWorkingThread.DestEngine := LocalEngine;
+ AWorkingThread.SrcEngine := Engine;
+ AWorkingThread.ExtractFromVFSAll := ExtractAll;
+ AWorkingThread.LeftPanel := LeftLastFocused;
+ AWorkingThread.DataList := DataList;
+ AWorkingThread.WorkerProcedure := CopyFilesWorker;
+ AWorkingThread.ParamBool3 := True;
+ AWorkingThread.ParamBool4 := False;
+ AWorkingThread.ParamBool5 := True;
+ AWorkingThread.ParamString1 := string(tmp);
+ AWorkingThread.ParamString2 := FilePath;
+ AWorkingThread.ParamDataItem1 := nil;
+ DebugMsg(['*** Copy: AWorkingThread.Resume']);
+ AWorkingThread.Resume;
+ DebugMsg(['*** Copy: AWorkingThread.Resumed.']);
+ AFProgress.ParentForm := FMain;
+ AFProgress.ShowModal;
+ ProcessProgressThread(AWorkingThread, AFProgress);
+ AFProgress.Close;
+ Result := (not AWorkingThread.FCancelled) and (not AWorkingThread.ErrorHappened);
+ finally
+ DebugMsg(['TFMain.ExtractFromArchive: Freeing thread...']);
+ LocalEngine.Free;
+ AFProgress.Free;
+ AWorkingThread.Free;
+ end;
+
+ DebugMsg(['(II) ExtractFromArchive: Old path = ', FilePath]);
+ if Result then begin
+ if not ExtractAll then NewPath := IncludeTrailingPathDelimiter(string(tmp)) + ExtractFileName(FilePath)
+ else NewPath := ExcludeTrailingPathDelimiter(string(tmp)) + FilePath;
+ DebugMsg(['(II) ExtractFromArchive: New path = ', NewPath]);
+
+ // Test for read access to the new file
+ if (not ExtractAll) and (access(PChar(NewPath), R_OK) <> 0) then begin
+ Result := False;
+ DebugMsg(['(EE) ExtractFromArchive: access test to the new file failed.']);
+ end;
+ end;
+
+ libc_free(tmp);
+ DebugMsg(['(II) ExtractFromArchive: Copy OK, Result = ', Result]);
+end;
+
+(********************************************************************************************************************************)
procedure TFMain.PasswordButtonClick(Sender: TObject);
var Engine: TPanelEngine;
Password: PChar;