FIX: Loading the same Thumbnails multiple times in TThumbFileView (fixes #1295)

This commit is contained in:
Alexander Koblov 2023-10-02 20:11:08 +03:00
commit 9c22daae6a
5 changed files with 60 additions and 18 deletions

View file

@ -1147,7 +1147,7 @@ begin
ADisplayFile.FSFile.Name := NewFileName;
FHashedNames.Remove(OldFileKey);
FHashedNames.Add(NewFileKey, ADisplayFile);
ADisplayFile.Busy:= False;
ADisplayFile.Busy:= [];
ADisplayFile.IconID := -1;
ADisplayFile.Selected := False;
ADisplayFile.IconOverlayID := -1;
@ -1299,7 +1299,7 @@ begin
Exit;
end;
end;
ADisplayFile.Busy := False;
ADisplayFile.Busy := [];
ADisplayFile.TextColor := clNone;
ADisplayFile.IconOverlayID := -1;
ADisplayFile.DisplayStrings.Clear;
@ -1519,7 +1519,7 @@ var
Index: Integer;
begin
for Index := 0 to FFiles.Count - 1 do
FFiles[Index].Busy:= False;
FFiles[Index].Busy:= [];
end;
procedure TFileView.DoOnFileListChanged;
@ -2014,7 +2014,7 @@ begin
DoFileUpdated(OrigDisplayFile);
OrigDisplayFile.Busy:= False;
OrigDisplayFile.Busy:= OrigDisplayFile.Busy - [bsProp];
end;
function TFileView.GetActiveFileName: String;

View file

@ -68,6 +68,7 @@ type
property Count: Integer read GetCount;
property Files[Index: Integer]: TDisplayFile read GetFile;
property Data[Index: Integer]: Pointer read GetData;
property UserData: TFPList read FUserData;
end;
TSetFileListMethod = procedure (var NewAllDisplayFiles: TDisplayFiles;

View file

@ -468,7 +468,7 @@ begin
for i := VisibleFiles.First to VisibleFiles.Last do
begin
AFile := FFiles[i];
if (AFile.FSFile.Name <> '..') and (not AFile.Busy) and
if (AFile.FSFile.Name <> '..') and (AFile.Busy * [bsProp] = []) and
(FileSource.CanRetrieveProperties(AFile.FSFile, AFilePropertiesNeeded) or
(AFile.TextColor = clNone) or
(HaveIcons and ((AFile.IconID < 0)
@ -480,7 +480,7 @@ begin
if not Assigned(AFileList) then
AFileList := TFVWorkerFileList.Create;
AFileList.AddClone(AFile, AFile);
AFile.Busy := True;
AFile.Busy := AFile.Busy + [bsProp];
end;
end;
@ -923,7 +923,10 @@ begin
while AStart < AList.Count do
begin
ADisplayFile := TDisplayFile(AList[AStart]);
if IsReferenceValid(ADisplayFile) then ADisplayFile.Busy:= False;
if IsReferenceValid(ADisplayFile) then
begin
ADisplayFile.Busy:= ADisplayFile.Busy - [bsProp];
end;
Inc(AStart);
end;
end;

View file

@ -15,11 +15,13 @@ type
TFileThumbnailsRetriever = class(TFileViewWorker)
private
FIndex: Integer;
FWorkingFile: TDisplayFile;
FWorkingUserData: Pointer;
FFileList: TFVWorkerFileList;
FThumbnailManager: TThumbnailManager;
FUpdateFileMethod: TUpdateFileMethod;
FAbortFileMethod: TAbortFileMethod;
FFileSource: IFileSource;
FBitmapList: TBitmapList;
@ -28,6 +30,7 @@ type
It is called from GUI thread.
}
procedure DoUpdateFile;
procedure DoAbortFile;
protected
procedure Execute; override;
@ -37,6 +40,7 @@ type
AThread: TThread;
ABitmapList: TBitmapList;
AUpdateFileMethod: TUpdateFileMethod;
ABreakFileMethod: TAbortFileMethod;
AThumbnailManager: TThumbnailManager;
var AFileList: TFVWorkerFileList); reintroduce;
destructor Destroy; override;
@ -76,6 +80,7 @@ type
private
FBitmapList: TBitmapList;
FThumbnailManager: TThumbnailManager;
procedure ThumbnailsRetrieverOnAbort(AStart: Integer; AList: TFPList);
procedure ThumbnailsRetrieverOnUpdate(const UpdatedFile: TDisplayFile; const UserData: Pointer);
protected
procedure CreateDefault(AOwner: TWinControl); override;
@ -109,18 +114,22 @@ begin
FUpdateFileMethod(FWorkingFile, FWorkingUserData);
end;
procedure TFileThumbnailsRetriever.DoAbortFile;
begin
FAbortFileMethod(FIndex, FFileList.UserData);
end;
procedure TFileThumbnailsRetriever.Execute;
var
I: Integer;
Bitmap: TBitmap;
begin
for I := 0 to FFileList.Count - 1 do
while FIndex < FFileList.Count do
begin
if Aborted then
Exit;
Break;
FWorkingFile := FFileList.Files[I];
FWorkingUserData := FFileList.Data[I];
FWorkingFile := FFileList.Files[FIndex];
FWorkingUserData := FFileList.Data[FIndex];
try
if FWorkingFile.Tag < 0 then
@ -133,20 +142,25 @@ begin
end;
if Aborted then
Exit;
Break;
TThread.Synchronize(Thread, @DoUpdateFile);
except
on EFileNotFound do;
end;
Inc(FIndex);
end;
if Aborted and Assigned(FAbortFileMethod) then
begin
TThread.Synchronize(Thread, @DoAbortFile);
end;
end;
constructor TFileThumbnailsRetriever.Create(AFileSource: IFileSource;
AThread: TThread; ABitmapList: TBitmapList;
AUpdateFileMethod: TUpdateFileMethod; AThumbnailManager: TThumbnailManager;
var AFileList: TFVWorkerFileList);
AUpdateFileMethod: TUpdateFileMethod; ABreakFileMethod: TAbortFileMethod;
AThumbnailManager: TThumbnailManager; var AFileList: TFVWorkerFileList);
begin
inherited Create(AThread);
@ -155,6 +169,7 @@ begin
AFileList := nil;
FFileSource := AFileSource;
FBitmapList := ABitmapList;
FAbortFileMethod := ABreakFileMethod;
FThumbnailManager := AThumbnailManager;
FUpdateFileMethod := AUpdateFileMethod;
end;
@ -545,6 +560,22 @@ end;
{ TThumbFileView }
procedure TThumbFileView.ThumbnailsRetrieverOnAbort(AStart: Integer;
AList: TFPList);
var
ADisplayFile: TDisplayFile;
begin
while AStart < AList.Count do
begin
ADisplayFile := TDisplayFile(AList[AStart]);
if IsReferenceValid(ADisplayFile) then
begin
ADisplayFile.Busy:= ADisplayFile.Busy - [bsTag];
end;
Inc(AStart);
end;
end;
procedure TThumbFileView.ThumbnailsRetrieverOnUpdate(
const UpdatedFile: TDisplayFile; const UserData: Pointer);
var
@ -557,6 +588,8 @@ begin
OrigDisplayFile.Tag := UpdatedFile.Tag;
DoFileUpdated(OrigDisplayFile);
OrigDisplayFile.Busy:= OrigDisplayFile.Busy - [bsTag];
end;
procedure TThumbFileView.CreateDefault(AOwner: TWinControl);
@ -614,11 +647,12 @@ begin
for i := VisibleFiles.First to VisibleFiles.Last do
begin
AFile := FFiles[i];
if (AFile.Tag < 0) and AFile.FSFile.IsNameValid then
if (AFile.Tag < 0) and AFile.FSFile.IsNameValid and (AFile.Busy * [bsTag] = []) then
begin
if not Assigned(AFileList) then
AFileList := TFVWorkerFileList.Create;
AFileList.AddClone(AFile, AFile);
AFile.Busy := AFile.Busy + [bsTag];
end;
end;
@ -629,6 +663,7 @@ begin
WorkersThread,
FBitmapList,
@ThumbnailsRetrieverOnUpdate,
@ThumbnailsRetrieverOnAbort,
FThumbnailManager,
AFileList);

View file

@ -12,6 +12,9 @@ type
TDisplayItemPtr = Pointer;
TBusyState = (bsProp, bsTag);
TDisplayFileBusy = set of TBusyState;
{en
Describes the file displayed in the file view.
}
@ -27,7 +30,7 @@ type
// Other properties.
FTag: PtrInt; //<en File view related info
FSelected: Boolean; //<en If is selected
FBusy: Boolean; //<en File properties is busy
FBusy: TDisplayFileBusy; //<en File properties is busy
FIconID: PtrInt; //<en Icon ID for PixmapManager
FIconOverlayID: PtrInt; //<en Overlay icon ID for PixmapManager
FTextColor: TColor; //<en Text color in file list
@ -74,7 +77,7 @@ type
property TextColor: TColor read FTextColor write FTextColor;
property DisplayStrings: TStringList read FDisplayStrings;
property RecentlyUpdatedPct: Integer read FRecentlyUpdatedPct write FRecentlyUpdatedPct;
property Busy: Boolean read FBusy write FBusy;
property Busy: TDisplayFileBusy read FBusy write FBusy;
property Tag: PtrInt read FTag write FTag;
end;