diff options
| author | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-11-16 18:23:23 +0100 |
|---|---|---|
| committer | Tomas Bzatek <tbzatek@users.sourceforge.net> | 2008-11-16 18:23:23 +0100 |
| commit | 6212b2355152eeef10f3352276a41d5fbad77f6f (patch) | |
| tree | 7c5694238403193de5c54b7c36491418fe1373f8 /UMain.pas | |
| parent | 10fe4e8b1aad19fbd0356cd3195c7fbaa812a5c7 (diff) | |
| download | tuxcmd-0.6.59.tar.xz | |
Nested VFS archiving engines supportv0.6.59
Diffstat (limited to 'UMain.pas')
| -rw-r--r-- | UMain.pas | 309 |
1 files changed, 187 insertions, 122 deletions
@@ -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; |
