浏览代码

FIX: Bug [0002525] Feed to listbox does not show archive search results

Alexander Koblov 4 年之前
父节点
当前提交
3553c11ffc
共有 3 个文件被更改,包括 50 次插入29 次删除
  1. 21 12
      src/fFindDlg.pas
  2. 2 1
      src/filesources/searchresult/usearchresultfilesource.pas
  3. 27 16
      src/ufindthread.pas

+ 21 - 12
src/fFindDlg.pas

@@ -3,7 +3,7 @@
    -------------------------------------------------------------------------
    -------------------------------------------------------------------------
    Find dialog, with searching in thread
    Find dialog, with searching in thread
 
 
-   Copyright (C) 2006-2020 Alexander Koblov ([email protected])
+   Copyright (C) 2006-2021 Alexander Koblov ([email protected])
    Copyright (C) 2003-2004 Radek Cervinka ([email protected])
    Copyright (C) 2003-2004 Radek Cervinka ([email protected])
 
 
    This program is free software; you can redistribute it and/or modify
    This program is free software; you can redistribute it and/or modify
@@ -32,7 +32,7 @@ uses
   fAttributesEdit, uDsxModule, DsxPlugin, uFindThread, uFindFiles,
   fAttributesEdit, uDsxModule, DsxPlugin, uFindThread, uFindFiles,
   uSearchTemplate, fSearchPlugin, uFileView, types, DCStrUtils,
   uSearchTemplate, fSearchPlugin, uFileView, types, DCStrUtils,
   ActnList, uOSForms, uShellContextMenu, uExceptions, uFileSystemFileSource,
   ActnList, uOSForms, uShellContextMenu, uExceptions, uFileSystemFileSource,
-  uFormCommands, uHotkeyManager, LCLVersion, uWcxModule;
+  uFormCommands, uHotkeyManager, LCLVersion, uWcxModule, uFileSource;
 
 
 {$IF DEFINED(LCLGTK2) or DEFINED(LCLQT) or DEFINED(LCLQT5)}
 {$IF DEFINED(LCLGTK2) or DEFINED(LCLQT) or DEFINED(LCLQT5)}
   {$DEFINE FIX_DEFAULT}
   {$DEFINE FIX_DEFAULT}
@@ -290,6 +290,7 @@ type
     FSearchWithWDXPluginInProgress: boolean;
     FSearchWithWDXPluginInProgress: boolean;
     FFreeOnClose: boolean;
     FFreeOnClose: boolean;
     FAtLeastOneSearchWasDone: boolean;
     FAtLeastOneSearchWasDone: boolean;
+    FFileSource: IFileSource;
     FWcxModule: TWcxModule;
     FWcxModule: TWcxModule;
 
 
     property Commands: TFormCommands read FCommands implements IFormCommands;
     property Commands: TFormCommands read FCommands implements IFormCommands;
@@ -390,7 +391,7 @@ implementation
 
 
 uses
 uses
   LCLProc, LCLType, LConvEncoding, StrUtils, HelpIntfs, fViewer, fMain,
   LCLProc, LCLType, LConvEncoding, StrUtils, HelpIntfs, fViewer, fMain,
-  uLng, uGlobs, uShowForm, uDCUtils, uFileSource, uFileSourceUtil,
+  uLng, uGlobs, uShowForm, uDCUtils, uFileSourceUtil,
   uSearchResultFileSource, uFile, uFileProperty, uColumnsFileView,
   uSearchResultFileSource, uFile, uFileProperty, uColumnsFileView,
   uFileViewNotebook, uKeyboard, uOSUtils, uArchiveFileSourceUtil,
   uFileViewNotebook, uKeyboard, uOSUtils, uArchiveFileSourceUtil,
   DCOSUtils, RegExpr, uDebug, uShowMsg, uConvEncoding, uColumns,
   DCOSUtils, RegExpr, uDebug, uShowMsg, uConvEncoding, uColumns,
@@ -641,6 +642,7 @@ begin
   DsxPlugins := TDSXModuleList.Create;
   DsxPlugins := TDSXModuleList.Create;
   DsxPlugins.Assign(gDSXPlugins);
   DsxPlugins.Assign(gDSXPlugins);
   FoundedStringCopy := TStringListTemp.Create;
   FoundedStringCopy := TStringListTemp.Create;
+  FoundedStringCopy.OwnsObjects := True;
   FFreeOnClose := False;
   FFreeOnClose := False;
   FAtLeastOneSearchWasDone := False;
   FAtLeastOneSearchWasDone := False;
   FSearchWithDSXPluginInProgress := False;
   FSearchWithDSXPluginInProgress := False;
@@ -1334,7 +1336,8 @@ var
   AEnabled: Boolean;
   AEnabled: Boolean;
   AFileSource: IWcxArchiveFileSource;
   AFileSource: IWcxArchiveFileSource;
 begin
 begin
-  AEnabled:= aFileView.FileSource.IsClass(TWcxArchiveFileSource);
+  FFileSource:= aFileView.FileSource;
+  AEnabled:= FFileSource.IsClass(TWcxArchiveFileSource);
 
 
   cbOpenedTabs.Visible:= not AEnabled;
   cbOpenedTabs.Visible:= not AEnabled;
   cbSelectedFiles.Visible:= not AEnabled;
   cbSelectedFiles.Visible:= not AEnabled;
@@ -1351,7 +1354,7 @@ begin
   if not AEnabled then
   if not AEnabled then
     FWcxModule:= nil
     FWcxModule:= nil
   else begin
   else begin
-    AFileSource:= (aFileView.FileSource as IWcxArchiveFileSource);
+    AFileSource:= (FFileSource as IWcxArchiveFileSource);
     FWcxModule:= AFileSource.WcxModule;
     FWcxModule:= AFileSource.WcxModule;
   end;
   end;
 
 
@@ -1822,19 +1825,26 @@ var
   AProperty: TFileVariantProperty;
   AProperty: TFileVariantProperty;
   ANewSet: TPanelColumnsClass;
   ANewSet: TPanelColumnsClass;
   NewSorting: TFileSortings;
   NewSorting: TFileSortings;
+  AHeader: TWCXHeader;
 begin
 begin
   StopSearch;
   StopSearch;
 
 
   FileList := TFileTree.Create;
   FileList := TFileTree.Create;
   for i := 0 to lsFoundedFiles.Items.Count - 1 do
   for i := 0 to lsFoundedFiles.Items.Count - 1 do
   begin
   begin
-    sFileName := lsFoundedFiles.Items[I];
-    try
+    if Assigned(FWcxModule) then
+    begin
+      AHeader:= TWCXHeader(lsFoundedFiles.Items.Objects[I]);
+      aFile := TWcxArchiveFileSource.CreateFile(ExtractFilePath(AHeader.FileName), AHeader);
+      FileList.AddSubNode(aFile);
+    end
+    else try
+      sFileName := lsFoundedFiles.Items[I];
       aFile := TFileSystemFileSource.CreateFileFromFile(sFileName);
       aFile := TFileSystemFileSource.CreateFileFromFile(sFileName);
       if FLastSearchTemplate.SearchRecord.Duplicates then
       if FLastSearchTemplate.SearchRecord.Duplicates then
       begin
       begin
         AProperty:= TFileVariantProperty.Create(PluginDuplicate);
         AProperty:= TFileVariantProperty.Create(PluginDuplicate);
-        AProperty.Value:= IntPtr(lsFoundedFiles.Items.Objects[I]);
+        AProperty.Value:= TDuplicate(lsFoundedFiles.Items.Objects[I]).Index;
         aFile.Properties[fpVariant]:= AProperty;
         aFile.Properties[fpVariant]:= AProperty;
       end;
       end;
       FileList.AddSubNode(aFile);
       FileList.AddSubNode(aFile);
@@ -1846,7 +1856,7 @@ begin
   // Create search result file source.
   // Create search result file source.
   // Currently only searching FileSystem is supported.
   // Currently only searching FileSystem is supported.
   SearchResultFS := TSearchResultFileSource.Create;
   SearchResultFS := TSearchResultFileSource.Create;
-  SearchResultFS.AddList(FileList, TFileSystemFileSource.GetFileSource);
+  SearchResultFS.AddList(FileList, FFileSource);
 
 
   // Add new tab for search results.
   // Add new tab for search results.
   Notebook := frmMain.ActiveNotebook;
   Notebook := frmMain.ActiveNotebook;
@@ -2060,12 +2070,11 @@ end;
 function TfrmFindDlg.ObjectType(Index: Integer): TCheckBoxState;
 function TfrmFindDlg.ObjectType(Index: Integer): TCheckBoxState;
 var
 var
   ATemp: TObject;
   ATemp: TObject;
-  AValue: PtrInt absolute ATemp;
 begin
 begin
   ATemp:= lsFoundedFiles.Items.Objects[Index];
   ATemp:= lsFoundedFiles.Items.Objects[Index];
-  if (ATemp) = nil then
+  if (ATemp = nil) then
     Result:= cbUnchecked
     Result:= cbUnchecked
-  else if (AValue = High(PtrInt)) then
+  else if (ATemp is TWcxHeader) then
     Result:= cbChecked
     Result:= cbChecked
   else
   else
     Result:= cbGrayed;
     Result:= cbGrayed;

+ 2 - 1
src/filesources/searchresult/usearchresultfilesource.pas

@@ -49,7 +49,8 @@ end;
 
 
 function TSearchResultFileSource.GetProperties: TFileSourceProperties;
 function TSearchResultFileSource.GetProperties: TFileSourceProperties;
 begin
 begin
-  Result := inherited GetProperties + [fspLinksToLocalFiles] - [fspNoneParent, fspListFlatView];
+  Result := inherited GetProperties - [fspNoneParent, fspListFlatView];
+  if (fspDirectAccess in Result) then Result+= [fspLinksToLocalFiles];
 end;
 end;
 
 
 function TSearchResultFileSource.SetCurrentWorkingDirectory(NewDir: String): Boolean;
 function TSearchResultFileSource.SetCurrentWorkingDirectory(NewDir: String): Boolean;

+ 27 - 16
src/ufindthread.pas

@@ -33,10 +33,13 @@ uses
 
 
 type
 type
 
 
+  { TDuplicate }
+
   TDuplicate = class
   TDuplicate = class
     Name: String;
     Name: String;
     Index: IntPtr;
     Index: IntPtr;
     Count: Integer;
     Count: Integer;
+    function Clone: TDuplicate;
   end;
   end;
 
 
   { TFindThread }
   { TFindThread }
@@ -62,6 +65,7 @@ type
     FExcludeFilesRegExp: TRegExprW;
     FExcludeFilesRegExp: TRegExprW;
     FRegExpr: TRegExpr;
     FRegExpr: TRegExpr;
     FArchive: TWcxModule;
     FArchive: TWcxModule;
+    FHeader: TWcxHeader;
 
 
     FTimeSearchStart:TTime;
     FTimeSearchStart:TTime;
     FTimeSearchEnd:TTime;
     FTimeSearchEnd:TTime;
@@ -126,6 +130,14 @@ begin
     Result:= 1;
     Result:= 1;
 end;
 end;
 
 
+{ TDuplicate }
+
+function TDuplicate.Clone: TDuplicate;
+begin
+  Result:= TDuplicate.Create;
+  Result.Index:= Self.Index;
+end;
+
 { TFindThread }
 { TFindThread }
 
 
 constructor TFindThread.Create(const AFindOptions: TSearchTemplateRec; SelectedFiles: TStringList);
 constructor TFindThread.Create(const AFindOptions: TSearchTemplateRec; SelectedFiles: TStringList);
@@ -283,7 +295,7 @@ end;
 
 
 procedure TFindThread.AddArchiveFile;
 procedure TFindThread.AddArchiveFile;
 begin
 begin
-  FItems.AddObject(FFoundFile, TObject(High(IntPtr)));
+  FItems.AddObject(FFoundFile, FHeader.Clone);
 end;
 end;
 
 
 procedure TFindThread.AddDuplicateFile;
 procedure TFindThread.AddDuplicateFile;
@@ -294,10 +306,10 @@ begin
   if AData.Count = 1 then
   if AData.Count = 1 then
   begin
   begin
     Inc(FFilesFound);
     Inc(FFilesFound);
-    FItems.AddObject(AData.Name, TObject(AData.Index));
+    FItems.AddObject(AData.Name, AData.Clone);
   end;
   end;
   Inc(FFilesFound);
   Inc(FFilesFound);
-  FItems.AddObject(FFoundFile, TObject(AData.Index));
+  FItems.AddObject(FFoundFile, AData.Clone);
 end;
 end;
 
 
 function TFindThread.CheckDirectory(const CurrentDir, FolderName : String): Boolean;
 function TFindThread.CheckDirectory(const CurrentDir, FolderName : String): Boolean;
@@ -491,7 +503,6 @@ end;
 procedure TFindThread.FindInArchive(const FileName: String);
 procedure TFindThread.FindInArchive(const FileName: String);
 var
 var
   Index: Integer;
   Index: Integer;
-  Header: TWcxHeader;
 
 
   function CheckHeader: Boolean;
   function CheckHeader: Boolean;
   var
   var
@@ -505,28 +516,28 @@ var
       if IsFindText then
       if IsFindText then
       begin
       begin
         // Skip directories
         // Skip directories
-        if (Header.FileAttr and faFolder) <> 0 then Exit(False);
+        if (FHeader.FileAttr and faFolder) <> 0 then Exit(False);
         // Some plugins end directories with path delimiter.
         // Some plugins end directories with path delimiter.
         // And not set directory attribute. Process this case.
         // And not set directory attribute. Process this case.
-        NameLength := Length(Header.FileName);
-        if (NameLength > 0) and (Header.FileName[NameLength] = PathDelim) then
+        NameLength := Length(FHeader.FileName);
+        if (NameLength > 0) and (FHeader.FileName[NameLength] = PathDelim) then
           Exit(False);
           Exit(False);
       end;
       end;
 
 
-      DirectoryName:= ExtractFileName(ExtractFileDir(Header.FileName));
+      DirectoryName:= ExtractFileName(ExtractFileDir(FHeader.FileName));
       if not CheckDirectoryName(DirectoryName) then Exit(False);
       if not CheckDirectoryName(DirectoryName) then Exit(False);
 
 
-      if not CheckFileName(ExtractFileName(Header.FileName)) then
+      if not CheckFileName(ExtractFileName(FHeader.FileName)) then
         Exit(False);
         Exit(False);
 
 
       if (IsDateFrom or IsDateTo or IsTimeFrom or IsTimeTo or IsNotOlderThan) then
       if (IsDateFrom or IsDateTo or IsTimeFrom or IsTimeTo or IsNotOlderThan) then
-        Result := CheckFileDateTime(FFileChecks, WcxFileTimeToDateTime(Header.FileTime));
+        Result := CheckFileDateTime(FFileChecks, WcxFileTimeToDateTime(FHeader.FileTime));
 
 
       if (IsFileSizeFrom or IsFileSizeTo) and Result then
       if (IsFileSizeFrom or IsFileSizeTo) and Result then
-        Result := CheckFileSize(FFileChecks, Header.UnpSize);
+        Result := CheckFileSize(FFileChecks, FHeader.UnpSize);
 
 
       if Result then
       if Result then
-        Result := CheckFileAttributes(FFileChecks, Header.FileAttr);
+        Result := CheckFileAttributes(FFileChecks, FHeader.FileAttr);
     end;
     end;
   end;
   end;
 
 
@@ -581,12 +592,12 @@ begin
       WcxModule.WcxSetChangeVolProc(ArcHandle);
       WcxModule.WcxSetChangeVolProc(ArcHandle);
       WcxModule.WcxSetProcessDataProc(ArcHandle, @ProcessDataProcAG, @ProcessDataProcWG);
       WcxModule.WcxSetProcessDataProc(ArcHandle, @ProcessDataProcAG, @ProcessDataProcWG);
 
 
-      while (WcxModule.ReadWCXHeader(ArcHandle, Header) = E_SUCCESS) do
+      while (WcxModule.ReadWCXHeader(ArcHandle, FHeader) = E_SUCCESS) do
       begin
       begin
         Result:= CheckHeader;
         Result:= CheckHeader;
         if Terminated then Break;
         if Terminated then Break;
         Flags:= IfThen(Result, Operation, PK_SKIP);
         Flags:= IfThen(Result, Operation, PK_SKIP);
-        if Flags = PK_EXTRACT then TargetFileName:= TargetPath + PathDelim + ExtractFileName(Header.FileName);
+        if Flags = PK_EXTRACT then TargetFileName:= TargetPath + PathDelim + ExtractFileName(FHeader.FileName);
         if WcxModule.WcxProcessFile(ArcHandle, Flags, EmptyStr, TargetFileName) = E_SUCCESS then
         if WcxModule.WcxProcessFile(ArcHandle, Flags, EmptyStr, TargetFileName) = E_SUCCESS then
         begin
         begin
           with FSearchTemplate do
           with FSearchTemplate do
@@ -601,11 +612,11 @@ begin
         end;
         end;
         if Result then
         if Result then
         begin
         begin
-          FFoundFile := FileName + ReversePathDelim + Header.FileName;
+          FFoundFile := FileName + ReversePathDelim + FHeader.FileName;
           Synchronize(@AddArchiveFile);
           Synchronize(@AddArchiveFile);
           Inc(FFilesFound);
           Inc(FFilesFound);
         end;
         end;
-        FreeAndNil(Header);
+        FreeAndNil(FHeader);
       end;
       end;
       if Operation = PK_EXTRACT then mbRemoveDir(TargetPath);
       if Operation = PK_EXTRACT then mbRemoveDir(TargetPath);
     finally
     finally