mirror of
https://github.com/doublecmd/doublecmd.git
synced 2026-06-21 09:58:13 +00:00
ADD: FsExtractCustomIcon function support
This commit is contained in:
parent
4e993732ef
commit
a824defefe
14 changed files with 317 additions and 60 deletions
|
|
@ -207,6 +207,20 @@ type
|
|||
HICON = THandle;
|
||||
HWND = THandle;
|
||||
|
||||
const
|
||||
FS_ICON_FORMAT_HICON = 0; // Load icon from HICON (Windows only)
|
||||
FS_ICON_FORMAT_FILE = 1; // Load icon from file name returned by plugin in the RemoteName
|
||||
FS_ICON_FORMAT_BINARY = 2; // Load icon from Data byte array (PNG or ICO), destroy data using Free if FS_ICON_EXTRACTED_DESTROY returned
|
||||
|
||||
type
|
||||
PWfxIcon = ^TWfxIcon;
|
||||
TWfxIcon = packed record
|
||||
Data: Pointer; // Icon data
|
||||
Size: UIntPtr; // Input: suggested icon size (width/height), output: size of Data byte array
|
||||
Format: UIntPtr; // See FS_ICON_FORMAT_*
|
||||
Free: procedure(Data: Pointer); {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF}; // Procedure used to destroy Data byte array
|
||||
end;
|
||||
|
||||
type
|
||||
{$IFDEF MSWINDOWS}
|
||||
FILETIME = Windows.FILETIME;
|
||||
|
|
@ -407,21 +421,21 @@ procedure FsGetDefRootName(DefRootName:pchar;maxlen:integer); {$IFDEF MSWINDOWS}
|
|||
|
||||
function FsExtractCustomIcon(RemoteName:pchar;ExtractFlags:integer;
|
||||
|
||||
var TheIcon:hicon):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
TheIcon: PWfxIcon):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
|
||||
function FsExtractCustomIconW(RemoteName:pwidechar;ExtractFlags:integer;
|
||||
|
||||
var TheIcon:hicon):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
TheIcon: PWfxIcon):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
|
||||
procedure FsSetDefaultParams(dps:pFsDefaultParamStruct); {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
|
||||
function FsGetPreviewBitmap(RemoteName:pchar;width,height:integer,
|
||||
|
||||
var ReturnedBitmap:hbitmap):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
ReturnedBitmap: PWfxIcon):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
|
||||
function FsGetPreviewBitmapW(RemoteName:pwidechar;width,height:integer,
|
||||
|
||||
var ReturnedBitmap:hbitmap):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
ReturnedBitmap: PWfxIcon):integer; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
|
||||
function FsLinksToLocalFiles:bool; {$IFDEF MSWINDOWS}stdcall{$ELSE}cdecl{$ENDIF};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ unit uFileSource;
|
|||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, DCStrUtils, syncobjs, LCLProc, URIParser, Menus,
|
||||
Classes, SysUtils, DCStrUtils, syncobjs, LCLProc, URIParser, Menus, Graphics,
|
||||
uFile, uDisplayFile, uFileProperty,
|
||||
uFileSourceWatcher,
|
||||
uFileSourceOperation, uFileSourceOperationTypes, uFileSourceProperty;
|
||||
|
|
@ -180,6 +180,7 @@ type
|
|||
function GetRootDir(sPath : String): String; overload;
|
||||
function GetRootDir: String; overload;
|
||||
function GetPathType(sPath : String): TPathType;
|
||||
function GetCustomIcon(aFile: TFile; AIconSize: Integer; out AIcon: TBitmap): IntPtr;
|
||||
function GetFreeSpace(Path: String; out FreeSize, TotalSize : Int64) : Boolean;
|
||||
function GetRealPath(const path: String): String;
|
||||
function GetLocalName(var aFile: TFile): Boolean;
|
||||
|
|
@ -381,6 +382,7 @@ type
|
|||
|
||||
function CreateDirectory(const Path: String): Boolean; virtual;
|
||||
function FileSystemEntryExists(const Path: String): Boolean; virtual;
|
||||
function GetCustomIcon(aFile: TFile; AIconSize: Integer; out AIcon: TBitmap): PtrInt; virtual;
|
||||
function GetFreeSpace(Path: String; out FreeSize, TotalSize : Int64) : Boolean; virtual;
|
||||
function QueryContextMenu(AFiles: TFiles; var AMenu: TPopupMenu): Boolean; virtual;
|
||||
function GetDefaultView(out DefaultView: TFileSourceFields): Boolean; virtual;
|
||||
|
|
@ -702,6 +704,13 @@ begin
|
|||
Result := True;
|
||||
end;
|
||||
|
||||
function TFileSource.GetCustomIcon(aFile: TFile; AIconSize: Integer; out
|
||||
AIcon: TBitmap): PtrInt;
|
||||
begin
|
||||
AIcon:= nil;
|
||||
Result:= -1;
|
||||
end;
|
||||
|
||||
function TFileSource.GetFreeSpace(Path: String; out FreeSize, TotalSize : Int64) : Boolean;
|
||||
begin
|
||||
Result := False; // not supported by default
|
||||
|
|
|
|||
|
|
@ -73,7 +73,11 @@ type
|
|||
{en
|
||||
Set, if the file source supports custom context menu.
|
||||
}
|
||||
fspContextMenu
|
||||
fspContextMenu,
|
||||
{en
|
||||
Set, if the file source supports custom file icons.
|
||||
}
|
||||
fspCustomIcon
|
||||
);
|
||||
|
||||
TFileSourceProperties = set of TFileSourceProperty;
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ unit uWfxPluginFileSource;
|
|||
interface
|
||||
|
||||
uses
|
||||
Classes, SysUtils, URIParser, uWFXModule, WfxPlugin,
|
||||
Classes, SysUtils, URIParser, Graphics, uWFXModule, WfxPlugin,
|
||||
uFile, uFileSourceProperty, uFileSourceOperationTypes,
|
||||
uFileProperty, uFileSource, uFileSourceOperation;
|
||||
|
||||
|
|
@ -129,6 +129,7 @@ type
|
|||
function GetLocalName(var aFile: TFile): Boolean; override;
|
||||
function CreateDirectory(const Path: String): Boolean; override;
|
||||
function GetDefaultView(out DefaultView: TFileSourceFields): Boolean; override;
|
||||
function GetCustomIcon(aFile: TFile; AIconSize: Integer; out AIcon: TBitmap): PtrInt; override;
|
||||
|
||||
class function IsSupportedPath(const Path: String): Boolean; override;
|
||||
class function CreateByRootName(aRootName: String): IWfxPluginFileSource;
|
||||
|
|
@ -170,7 +171,7 @@ uses
|
|||
uWfxPluginCopyInOperation, uWfxPluginCopyOutOperation, uWfxPluginMoveOperation, uVfsModule,
|
||||
uWfxPluginExecuteOperation, uWfxPluginListOperation, uWfxPluginCreateDirectoryOperation,
|
||||
uWfxPluginDeleteOperation, uWfxPluginSetFilePropertyOperation, uWfxPluginCopyOperation,
|
||||
DCConvertEncoding, uWfxPluginCalcStatisticsOperation, uFileFunctions;
|
||||
DCConvertEncoding, uWfxPluginCalcStatisticsOperation, uFileFunctions, uPixMapManager;
|
||||
|
||||
const
|
||||
connCopyIn = 0;
|
||||
|
|
@ -642,6 +643,8 @@ begin
|
|||
if (BackgroundFlags and BG_DOWNLOAD = 0) then
|
||||
Result:= Result + [fspCopyOutOnMainThread];
|
||||
end;
|
||||
if Assigned(FsExtractCustomIcon) or Assigned(FsExtractCustomIconW) then
|
||||
Result := Result + [fspCustomIcon];
|
||||
if Assigned(FsContentGetDefaultView) or Assigned(FsContentGetDefaultViewW) then
|
||||
Result := Result + [fspDefaultView];
|
||||
end;
|
||||
|
|
@ -949,6 +952,29 @@ begin
|
|||
Result:= FWFXModule.WfxContentGetDefaultView(DefaultView);
|
||||
end;
|
||||
|
||||
function TWfxPluginFileSource.GetCustomIcon(aFile: TFile; AIconSize: Integer;
|
||||
out AIcon: TBitmap): PtrInt;
|
||||
var
|
||||
Status: Integer;
|
||||
TheIcon: TWfxIcon;
|
||||
AIconName: String;
|
||||
UniqueName: String;
|
||||
begin
|
||||
AIconName:= aFile.FullPath;
|
||||
Status:= FWfxModule.WfxExtractCustomIcon(AIconName, AIconSize, TheIcon);
|
||||
|
||||
if Status in [FS_ICON_EXTRACTED, FS_ICON_EXTRACTED_DESTROY] then
|
||||
begin
|
||||
if AIconName <> aFile.FullPath then
|
||||
UniqueName:= AIconName
|
||||
else begin
|
||||
UniqueName:= EmptyStr;
|
||||
end;
|
||||
Result:= PixmapManager.CheckAddPixmap(UniqueName, AIconSize, (Status = FS_ICON_EXTRACTED_DESTROY), @TheIcon, AIcon);
|
||||
end;
|
||||
|
||||
end;
|
||||
|
||||
class function TWfxPluginFileSource.IsSupportedPath(const Path: String): Boolean;
|
||||
begin
|
||||
Result:= Pos('wfx://', Path) = 1;
|
||||
|
|
|
|||
|
|
@ -485,16 +485,10 @@ var
|
|||
procedure DrawIconCell;
|
||||
//------------------------------------------------------
|
||||
var
|
||||
IconID: PtrInt;
|
||||
targetWidth: Integer;
|
||||
begin
|
||||
if (gShowIcons <> sim_none) then
|
||||
begin
|
||||
IconID := AFile.IconID;
|
||||
// Draw default icon if there is no icon for the file.
|
||||
if IconID = -1 then
|
||||
IconID := PixMapManager.GetDefaultIcon(AFile.FSFile);
|
||||
|
||||
// center icon vertically
|
||||
params.iconRect.Left:= aRect.Left + CELL_PADDING;
|
||||
params.iconRect.Top:= aRect.Top + (aRect.Height - gIconsSize) div 2;
|
||||
|
|
@ -502,14 +496,14 @@ var
|
|||
params.iconRect.Height:= gIconsSize;
|
||||
|
||||
if gShowHiddenDimmed and FBriefView.FileSource.IsHiddenFile(AFile.FSFile) then
|
||||
PixMapManager.DrawBitmapAlpha(IconID,
|
||||
PixMapManager.DrawBitmapAlpha(AFile,
|
||||
Canvas,
|
||||
params.iconRect.Left,
|
||||
params.iconRect.Top
|
||||
)
|
||||
else
|
||||
// Draw icon for a file
|
||||
PixMapManager.DrawBitmap(IconID,
|
||||
PixMapManager.DrawBitmap(AFile,
|
||||
Canvas,
|
||||
params.iconRect.Left,
|
||||
params.iconRect.Top
|
||||
|
|
|
|||
|
|
@ -1567,16 +1567,10 @@ var
|
|||
procedure DrawIconCell;
|
||||
//------------------------------------------------------
|
||||
var
|
||||
IconID: PtrInt;
|
||||
targetWidth: Integer;
|
||||
begin
|
||||
if (gShowIcons <> sim_none) then
|
||||
begin
|
||||
IconID := AFile.IconID;
|
||||
// Draw default icon if there is no icon for the file.
|
||||
if IconID = -1 then
|
||||
IconID := PixMapManager.GetDefaultIcon(AFile.FSFile);
|
||||
|
||||
// center icon vertically
|
||||
params.iconRect.Left:= aRect.Left + CELL_PADDING;
|
||||
params.iconRect.Top:= aRect.Top + (aRect.Height - gIconsSize) div 2;
|
||||
|
|
@ -1584,14 +1578,14 @@ var
|
|||
params.iconRect.Height:= gIconsSize;
|
||||
|
||||
if gShowHiddenDimmed and ColumnsView.FileSource.isHiddenFile(AFile.FSFile) then
|
||||
PixMapManager.DrawBitmapAlpha(IconID,
|
||||
PixMapManager.DrawBitmapAlpha(AFile,
|
||||
Canvas,
|
||||
params.iconRect.Left,
|
||||
params.iconRect.Top
|
||||
)
|
||||
else
|
||||
// Draw icon for a file
|
||||
PixMapManager.DrawBitmap(IconID,
|
||||
PixMapManager.DrawBitmap(AFile,
|
||||
Canvas,
|
||||
params.iconRect.Left,
|
||||
params.iconRect.Top
|
||||
|
|
|
|||
|
|
@ -1156,6 +1156,7 @@ begin
|
|||
FHashedNames.Remove(OldFileKey);
|
||||
FHashedNames.Add(NewFileKey, ADisplayFile);
|
||||
ADisplayFile.Busy:= [];
|
||||
ADisplayFile.Icon:= nil;
|
||||
ADisplayFile.IconID := -1;
|
||||
ADisplayFile.Selected := False;
|
||||
ADisplayFile.IconOverlayID := -1;
|
||||
|
|
@ -2032,6 +2033,12 @@ begin
|
|||
aFile.Properties[propType] := UpdatedFile.FSFile.ReleaseProperty(propType);
|
||||
end;
|
||||
|
||||
if UpdatedFile.Icon <> nil then
|
||||
begin
|
||||
OrigDisplayFile.Icon := TBitmap.Create;
|
||||
OrigDisplayFile.Icon.Assign(UpdatedFile.Icon);
|
||||
end;
|
||||
|
||||
if UpdatedFile.IconID <> -1 then
|
||||
OrigDisplayFile.IconID := UpdatedFile.IconID;
|
||||
|
||||
|
|
|
|||
|
|
@ -777,7 +777,8 @@ begin
|
|||
|
||||
if HaveIcons then
|
||||
begin
|
||||
AFile.IconID := PixMapManager.GetIconByFile(AFile.FSFile,
|
||||
AFile.IconID := PixMapManager.GetIconByFile(fs,
|
||||
AFile,
|
||||
DirectAccess,
|
||||
not gLoadIconsSeparately,
|
||||
gShowIcons,
|
||||
|
|
@ -831,7 +832,8 @@ begin
|
|||
|
||||
if HaveIcons then
|
||||
begin
|
||||
AFile.IconID := PixMapManager.GetIconByFile(AFile.FSFile,
|
||||
AFile.IconID := PixMapManager.GetIconByFile(fs,
|
||||
AFile,
|
||||
DirectAccess,
|
||||
not gLoadIconsSeparately,
|
||||
gShowIcons,
|
||||
|
|
@ -947,9 +949,10 @@ begin
|
|||
|
||||
if HaveIcons then
|
||||
begin
|
||||
if FWorkingFile.IconID < 0 then
|
||||
if (FWorkingFile.IconID < 0) and (FWorkingFile.Icon = nil) then
|
||||
FWorkingFile.IconID := PixMapManager.GetIconByFile(
|
||||
FWorkingFile.FSFile,
|
||||
FFileSource,
|
||||
FWorkingFile,
|
||||
DirectAccess,
|
||||
True,
|
||||
gShowIcons,
|
||||
|
|
|
|||
|
|
@ -399,6 +399,7 @@ var
|
|||
AFile: TDisplayFile;
|
||||
HaveIcons: Boolean;
|
||||
DirectAccess: Boolean;
|
||||
AFileSource: IFileSource;
|
||||
AFilePropertiesNeeded: TFilePropertiesTypes;
|
||||
begin
|
||||
if (csDestroying in ComponentState) or
|
||||
|
|
@ -406,10 +407,11 @@ begin
|
|||
IsEmpty then
|
||||
Exit;
|
||||
|
||||
AFileSource := FileSource;
|
||||
HaveIcons := gShowIcons <> sim_none;
|
||||
VisibleFiles := GetVisibleFilesIndexes;
|
||||
AFilePropertiesNeeded := FilePropertiesNeeded;
|
||||
DirectAccess := fspDirectAccess in FileSource.Properties;
|
||||
DirectAccess := fspDirectAccess in AFileSource.Properties;
|
||||
|
||||
// Property fpComment should be retrieved in main thread
|
||||
if gListFilesInThread and (fpComment in AFilePropertiesNeeded) then
|
||||
|
|
@ -417,9 +419,9 @@ begin
|
|||
for i := VisibleFiles.First to VisibleFiles.Last do
|
||||
begin
|
||||
AFile := FFiles[i];
|
||||
if FileSource.CanRetrieveProperties(AFile.FSFile, [fpComment]) then
|
||||
if AFileSource.CanRetrieveProperties(AFile.FSFile, [fpComment]) then
|
||||
try
|
||||
FileSource.RetrieveProperties(AFile.FSFile, [fpComment], []);
|
||||
AFileSource.RetrieveProperties(AFile.FSFile, [fpComment], []);
|
||||
except
|
||||
on EFileNotFound do;
|
||||
end;
|
||||
|
|
@ -442,20 +444,20 @@ begin
|
|||
begin
|
||||
if HaveIcons then
|
||||
begin
|
||||
if AFile.IconID < 0 then
|
||||
AFile.IconID := PixMapManager.GetIconByFile(AFile.FSFile,
|
||||
DirectAccess, True, gShowIcons, not gIconOverlays);
|
||||
if (AFile.IconID < 0) and (AFile.Icon = nil) then
|
||||
begin
|
||||
AFile.IconID := PixMapManager.GetIconByFile(AFileSource, AFile, DirectAccess, True, gShowIcons, not gIconOverlays);
|
||||
end;
|
||||
{$IF DEFINED(MSWINDOWS) OR DEFINED(RabbitVCS)}
|
||||
if gIconOverlays and (AFile.IconOverlayID < 0) then
|
||||
begin
|
||||
AFile.IconOverlayID := PixMapManager.GetIconOverlayByFile(AFile.FSFile,
|
||||
DirectAccess);
|
||||
AFile.IconOverlayID := PixMapManager.GetIconOverlayByFile(AFile.FSFile, DirectAccess);
|
||||
end;
|
||||
{$ENDIF}
|
||||
end;
|
||||
if FileSource.CanRetrieveProperties(AFile.FSFile, FilePropertiesNeeded) then
|
||||
if AFileSource.CanRetrieveProperties(AFile.FSFile, FilePropertiesNeeded) then
|
||||
try
|
||||
FileSource.RetrieveProperties(AFile.FSFile, FilePropertiesNeeded, GetVariantFileProperties);
|
||||
AFileSource.RetrieveProperties(AFile.FSFile, FilePropertiesNeeded, GetVariantFileProperties);
|
||||
except
|
||||
on EFileNotFound do;
|
||||
end;
|
||||
|
|
@ -469,9 +471,9 @@ begin
|
|||
begin
|
||||
AFile := FFiles[i];
|
||||
if (AFile.FSFile.Name <> '..') and (AFile.Busy * [bsProp] = []) and
|
||||
(FileSource.CanRetrieveProperties(AFile.FSFile, AFilePropertiesNeeded) or
|
||||
(AFileSource.CanRetrieveProperties(AFile.FSFile, AFilePropertiesNeeded) or
|
||||
(AFile.TextColor = clNone) or
|
||||
(HaveIcons and ((AFile.IconID < 0)
|
||||
(HaveIcons and ( ((AFile.IconID < 0) and (AFile.Icon = nil))
|
||||
{$IF DEFINED(MSWINDOWS) OR DEFINED(RabbitVCS)}
|
||||
or (gIconOverlays and (AFile.IconOverlayID < 0))
|
||||
{$ENDIF}
|
||||
|
|
@ -487,7 +489,7 @@ begin
|
|||
if Assigned(AFileList) and (AFileList.Count > 0) then
|
||||
begin
|
||||
Worker := TFilePropertiesRetriever.Create(
|
||||
FileSource,
|
||||
AFileSource,
|
||||
WorkersThread,
|
||||
AFilePropertiesNeeded,
|
||||
GetVariantFileProperties,
|
||||
|
|
|
|||
|
|
@ -489,17 +489,12 @@ var
|
|||
end
|
||||
else
|
||||
begin
|
||||
IconID := AFile.IconID;
|
||||
// Draw default icon if there is no icon for the file.
|
||||
if IconID = -1 then
|
||||
IconID := PixMapManager.GetDefaultIcon(AFile.FSFile);
|
||||
|
||||
// Center icon
|
||||
X:= aRect.Left + (aRect.Right - aRect.Left - gIconsSize) div 2;
|
||||
Y:= aRect.Top + (iTextTop - aRect.Top - gIconsSize) div 2;
|
||||
|
||||
// Draw icon for a file
|
||||
PixMapManager.DrawBitmap(IconID, Canvas, X, Y);
|
||||
PixMapManager.DrawBitmap(AFile, Canvas, X, Y);
|
||||
end;
|
||||
|
||||
// Draw overlay icon for a file if needed
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ interface
|
|||
uses
|
||||
Classes, SysUtils, Graphics, syncobjs, uFileSorting, DCStringHashListUtf8,
|
||||
uFile, uIconTheme, uDrive, uDisplayFile, uGlobs, uDCReadPSD, uOSUtils, FPImage,
|
||||
LCLVersion, uVectorImage, uMultiArc
|
||||
LCLVersion, uVectorImage, uMultiArc, uFileSource, WfxPlugin
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
, ShlObj
|
||||
{$ELSEIF DEFINED(MSWINDOWS) and DEFINED(LCLQT5)}
|
||||
|
|
@ -289,7 +289,8 @@ type
|
|||
}
|
||||
function GetBitmap(iIndex : PtrInt) : TBitmap;
|
||||
function DrawBitmap(iIndex: PtrInt; Canvas : TCanvas; X, Y: Integer) : Boolean;
|
||||
function DrawBitmapAlpha(iIndex: PtrInt; Canvas : TCanvas; X, Y: Integer) : Boolean;
|
||||
function DrawBitmap(AFile: TDisplayFile; Canvas : TCanvas; X, Y: Integer) : Boolean;
|
||||
function DrawBitmapAlpha(AFile: TDisplayFile; Canvas : TCanvas; X, Y: Integer) : Boolean;
|
||||
{en
|
||||
Draws bitmap stretching it if needed to Width x Height.
|
||||
If Width is 0 then full bitmap width is used.
|
||||
|
|
@ -298,6 +299,7 @@ type
|
|||
Index of pixmap manager's bitmap.)
|
||||
}
|
||||
function DrawBitmap(iIndex: PtrInt; Canvas : TCanvas; X, Y, Width, Height: Integer) : Boolean;
|
||||
function DrawBitmap(AFile: TDisplayFile; Canvas : TCanvas; X, Y, Width, Height: Integer) : Boolean;
|
||||
{en
|
||||
Draws overlay bitmap for a file.
|
||||
@param(AFile
|
||||
|
|
@ -306,6 +308,7 @@ type
|
|||
Whether the file is on a directly accessible file source.)
|
||||
}
|
||||
function DrawBitmapOverlay(AFile: TDisplayFile; DirectAccess: Boolean; Canvas : TCanvas; X, Y: Integer) : Boolean;
|
||||
function CheckAddPixmap(AUniqueName: String; AIconSize: Integer; ADestroy: Boolean; TheIcon: PWfxIcon; out AIcon: TBitmap): PtrInt;
|
||||
function GetIconBySortingDirection(SortingDirection: TSortDirection): PtrInt;
|
||||
{en
|
||||
Retrieves icon index in FPixmapList table for a file.
|
||||
|
|
@ -330,6 +333,8 @@ type
|
|||
}
|
||||
function GetIconByFile(AFile: TFile; DirectAccess: Boolean; LoadIcon: Boolean;
|
||||
IconsMode: TShowIconsMode; GetIconWithLink: Boolean): PtrInt;
|
||||
function GetIconByFile(constref AFileSource: IFileSource; AFile: TDisplayFile; DirectAccess: Boolean; LoadIcon: Boolean;
|
||||
IconsMode: TShowIconsMode; GetIconWithLink: Boolean): PtrInt; overload;
|
||||
{$IF DEFINED(MSWINDOWS) OR DEFINED(RabbitVCS)}
|
||||
{en
|
||||
Retrieves overlay icon index for a file.
|
||||
|
|
@ -380,8 +385,8 @@ function getBestNSImageWithSize( const srcImage:NSImage; const size:Integer ): N
|
|||
implementation
|
||||
|
||||
uses
|
||||
GraphType, LCLIntf, LCLType, LCLProc, Forms, uGlobsPaths, WcxPlugin,
|
||||
DCStrUtils, uDCUtils, uFileSystemFileSource, uReSample, uDebug,
|
||||
GraphType, LCLIntf, LCLType, LCLProc, Forms, uGlobsPaths, WcxPlugin, uClassesEx,
|
||||
DCStrUtils, uDCUtils, uFileSystemFileSource, uReSample, uDebug, uFileSourceProperty,
|
||||
IntfGraphics, DCOSUtils, DCClassesUtf8, LazUTF8, uGraphics, uHash, uSysFolders
|
||||
{$IFDEF GTK2_FIX}
|
||||
, uPixMapGtk, gdk2pixbuf, gdk2, glib2
|
||||
|
|
@ -1984,12 +1989,30 @@ begin
|
|||
Result := DrawBitmap(iIndex, Canvas, X, Y, gIconsSize, gIconsSize); // No bitmap stretching.
|
||||
end;
|
||||
|
||||
function TPixMapManager.DrawBitmapAlpha(iIndex: PtrInt; Canvas: TCanvas; X, Y: Integer): Boolean;
|
||||
function TPixMapManager.DrawBitmap(AFile: TDisplayFile; Canvas: TCanvas; X, Y: Integer): Boolean;
|
||||
begin
|
||||
Result := DrawBitmap(AFile, Canvas, X, Y, gIconsSize, gIconsSize); // No bitmap stretching.
|
||||
end;
|
||||
|
||||
function TPixMapManager.DrawBitmapAlpha(AFile: TDisplayFile; Canvas: TCanvas; X, Y: Integer): Boolean;
|
||||
var
|
||||
ARect: TRect;
|
||||
IconID: PtrInt;
|
||||
ABitmap: Graphics.TBitmap;
|
||||
begin
|
||||
ABitmap:= GetBitmap(iIndex);
|
||||
if Assigned(AFile.Icon) then
|
||||
begin
|
||||
ABitmap:= TBitmap.Create;
|
||||
ABitmap.Assign(AFile.Icon);
|
||||
end
|
||||
else begin
|
||||
if AFile.IconID < 0 then
|
||||
IconID:= GetDefaultIcon(AFile.FSFile)
|
||||
else begin
|
||||
IconID:= AFile.IconID;
|
||||
end;
|
||||
ABitmap:= GetBitmap(IconID);
|
||||
end;
|
||||
Result := Assigned(ABitmap);
|
||||
if Result then
|
||||
begin
|
||||
|
|
@ -2098,6 +2121,29 @@ begin
|
|||
{$ENDIF}
|
||||
end;
|
||||
|
||||
function TPixMapManager.DrawBitmap(AFile: TDisplayFile; Canvas: TCanvas; X, Y, Width, Height: Integer): Boolean;
|
||||
var
|
||||
aRect: TRect;
|
||||
IconID: PtrInt;
|
||||
begin
|
||||
if (AFile.Icon = nil) then
|
||||
begin
|
||||
// Draw default icon if there is no icon for the file
|
||||
if AFile.IconID < 0 then
|
||||
IconID:= GetDefaultIcon(AFile.FSFile)
|
||||
else begin
|
||||
IconID:= AFile.IconID;
|
||||
end;
|
||||
Result:= DrawBitmap(IconID, Canvas, X, Y, Width, Height);
|
||||
end
|
||||
else begin
|
||||
if Width = 0 then Width:= AFile.Icon.Width;
|
||||
if Height = 0 then Height:= AFile.Icon.Height;
|
||||
aRect:= Classes.Bounds(X, Y, Width, Height);
|
||||
Canvas.StretchDraw(aRect, AFile.Icon);
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPixMapManager.DrawBitmapOverlay(AFile: TDisplayFile; DirectAccess: Boolean; Canvas: TCanvas; X, Y: Integer): Boolean;
|
||||
var
|
||||
I: Integer;
|
||||
|
|
@ -2133,6 +2179,84 @@ begin
|
|||
;
|
||||
end;
|
||||
|
||||
function TPixMapManager.CheckAddPixmap(AUniqueName: String; AIconSize: Integer;
|
||||
ADestroy: Boolean; TheIcon: PWfxIcon; out AIcon: TBitmap): PtrInt;
|
||||
var
|
||||
Index: PtrInt;
|
||||
Picture: TPicture;
|
||||
Stream: TBlobStream;
|
||||
begin
|
||||
AIcon:= nil;
|
||||
// Icon has a unique name
|
||||
if Length(AUniqueName) > 0 then
|
||||
begin
|
||||
FPixmapsLock.Acquire;
|
||||
try
|
||||
// Try to find in the cache
|
||||
Index:= FPixmapsFileNames.Find(AUniqueName);
|
||||
if (Index >= 0) then
|
||||
begin
|
||||
if ADestroy then
|
||||
begin
|
||||
case TheIcon^.Format of
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
FS_ICON_FORMAT_HICON: DestroyIcon(HICON(TheIcon^.Data));
|
||||
{$ENDIF}
|
||||
FS_ICON_FORMAT_BINARY: TheIcon^.Free(TheIcon^.Data);
|
||||
end;
|
||||
end;
|
||||
Exit(PtrInt(FPixmapsFileNames.List[Index]^.Data));
|
||||
end;
|
||||
finally
|
||||
FPixmapsLock.Release;
|
||||
end;
|
||||
end;
|
||||
Result:= -1;
|
||||
|
||||
case TheIcon^.Format of
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
FS_ICON_FORMAT_HICON:
|
||||
begin
|
||||
AIcon:= BitmapCreateFromHICON(HICON(TheIcon^.Data));
|
||||
if ADestroy then DestroyIcon(HICON(TheIcon^.Data));
|
||||
end;
|
||||
{$ENDIF}
|
||||
FS_ICON_FORMAT_FILE:
|
||||
begin
|
||||
Result:= CheckAddPixmap(AUniqueName, AIconSize);
|
||||
end;
|
||||
FS_ICON_FORMAT_BINARY:
|
||||
begin
|
||||
Picture:= TPicture.Create;
|
||||
try
|
||||
Stream:= TBlobStream.Create(TheIcon^.Data, TheIcon^.Size);
|
||||
try
|
||||
Picture.LoadFromStream(Stream);
|
||||
AIcon:= Graphics.TBitmap.Create;
|
||||
BitmapAssign(AIcon, TRasterImage(Picture.Graphic));
|
||||
finally
|
||||
Stream.Free;
|
||||
end;
|
||||
except
|
||||
// Ignore;
|
||||
end;
|
||||
Picture.Free;
|
||||
if ADestroy then TheIcon^.Free(TheIcon^.Data);
|
||||
end;
|
||||
end;
|
||||
// Icon has a unique name, save to the cache
|
||||
if Assigned(AIcon) and (Length(AUniqueName) > 0) then
|
||||
begin
|
||||
FPixmapsLock.Acquire;
|
||||
try
|
||||
Result := FPixmapList.Add(AIcon);
|
||||
FPixmapsFileNames.Add(AUniqueName, Pointer(Result));
|
||||
finally
|
||||
FPixmapsLock.Release;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
function TPixMapManager.GetIconBySortingDirection(SortingDirection: TSortDirection): PtrInt;
|
||||
begin
|
||||
case SortingDirection of
|
||||
|
|
@ -2150,7 +2274,7 @@ begin
|
|||
end;
|
||||
|
||||
function TPixMapManager.GetIconByFile(AFile: TFile; DirectAccess: Boolean; LoadIcon: Boolean;
|
||||
IconsMode: TShowIconsMode; GetIconWithLink: Boolean): PtrInt;
|
||||
IconsMode: TShowIconsMode; GetIconWithLink: Boolean): PtrInt;
|
||||
var
|
||||
Ext: String;
|
||||
{$IFDEF MSWINDOWS}
|
||||
|
|
@ -2436,6 +2560,33 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TPixMapManager.GetIconByFile(constref AFileSource: IFileSource; AFile: TDisplayFile;
|
||||
DirectAccess: Boolean; LoadIcon: Boolean; IconsMode: TShowIconsMode; GetIconWithLink: Boolean): PtrInt;
|
||||
var
|
||||
ABitmap: TBitmap;
|
||||
begin
|
||||
if Assigned(AFile.Icon) then Exit(-1);
|
||||
|
||||
if (fspCustomIcon in AFileSource.Properties) and AFileSource.IsPathAtRoot(AFile.FSFile.Path) then
|
||||
begin
|
||||
if AFile.FSFile.Name = '..' then
|
||||
begin
|
||||
Result := FiUpDirIconID;
|
||||
Exit;
|
||||
end;
|
||||
|
||||
Result:= AFileSource.GetCustomIcon(AFile.FSFile, gIconsSize, ABitmap);
|
||||
if (Result >= 0) then Exit;
|
||||
if Assigned(ABitmap) then
|
||||
begin
|
||||
AFile.Icon:= ABitmap;
|
||||
Exit(-1);
|
||||
end;
|
||||
end;
|
||||
|
||||
Result:= GetIconByFile(AFile.FSFile, DirectAccess, LoadIcon, IconsMode, GetIconWithLink);
|
||||
end;
|
||||
|
||||
{$IF DEFINED(MSWINDOWS)}
|
||||
procedure TPixMapManager.ClearSystemCache;
|
||||
var
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ type
|
|||
FTag: PtrInt; //<en File view related info
|
||||
FSelected: Boolean; //<en If is selected
|
||||
FBusy: TDisplayFileBusy; //<en File properties is busy
|
||||
FIcon: TBitmap; //<en File icon (local cache)
|
||||
FIconID: PtrInt; //<en Icon ID for PixmapManager
|
||||
FIconOverlayID: PtrInt; //<en Overlay icon ID for PixmapManager
|
||||
FTextColor: TColor; //<en Text color in file list
|
||||
|
|
@ -42,6 +43,7 @@ type
|
|||
|
||||
// Cache of displayed strings.
|
||||
FDisplayStrings: TStringList;
|
||||
procedure SetIcon(AValue: TBitmap);
|
||||
|
||||
public
|
||||
{en
|
||||
|
|
@ -72,6 +74,7 @@ type
|
|||
property FSFile: TFile read FFSFile write FFSFile;
|
||||
property DisplayItem: TDisplayItemPtr read FDisplayItem write FDisplayItem;
|
||||
property Selected: Boolean read FSelected write FSelected;
|
||||
property Icon: TBitmap read FIcon write SetIcon;
|
||||
property IconID: PtrInt read FIconID write FIconID;
|
||||
property IconOverlayID: PtrInt read FIconOverlayID write FIconOverlayID;
|
||||
property TextColor: TColor read FTextColor write FTextColor;
|
||||
|
|
@ -126,6 +129,12 @@ type
|
|||
|
||||
implementation
|
||||
|
||||
procedure TDisplayFile.SetIcon(AValue: TBitmap);
|
||||
begin
|
||||
FIcon.Free;
|
||||
FIcon:= AValue;
|
||||
end;
|
||||
|
||||
constructor TDisplayFile.Create(ReferenceFile: TFile);
|
||||
begin
|
||||
FTag := -1;
|
||||
|
|
@ -141,6 +150,7 @@ begin
|
|||
inherited Destroy;
|
||||
FDisplayStrings.Free;
|
||||
FSFile.Free;
|
||||
FIcon.Free;
|
||||
end;
|
||||
|
||||
function TDisplayFile.Clone(NewReferenceFile: TFile): TDisplayFile;
|
||||
|
|
@ -170,6 +180,13 @@ begin
|
|||
AFile.FIconOverlayID := FIconOverlayID;
|
||||
AFile.FTextColor := FTextColor;
|
||||
|
||||
if (FIcon = nil) then
|
||||
AFile.Icon:= nil
|
||||
else begin
|
||||
AFile.Icon:= TBitmap.Create;
|
||||
AFile.FIcon.Assign(FIcon);
|
||||
end;
|
||||
|
||||
if Assigned(AFile.FFSFile) then
|
||||
begin
|
||||
AFile.FDisplayStrings.AddStrings(FDisplayStrings);
|
||||
|
|
|
|||
|
|
@ -30,7 +30,7 @@ unit uWFXmodule;
|
|||
interface
|
||||
|
||||
uses
|
||||
SysUtils, Classes, WfxPlugin, uWFXprototypes,
|
||||
SysUtils, Classes, Graphics, WfxPlugin, uWFXprototypes,
|
||||
dynlibs, DCClassesUtf8, Extension, DCBasicTypes, DCXmlConfig,
|
||||
uWdxPrototypes, uWdxModule, uFileSource;
|
||||
|
||||
|
|
@ -63,6 +63,7 @@ type
|
|||
TWFXModule = class(TPluginWDX)
|
||||
private
|
||||
FBackgroundFlags: Integer;
|
||||
FIconMutex: TRTLCriticalSection;
|
||||
public
|
||||
{ Mandatory }
|
||||
FsInit : TFsInit;
|
||||
|
|
@ -137,6 +138,7 @@ type
|
|||
function WfxGetLocalName(var sFileName: String): Boolean;
|
||||
function WfxDisconnect(const DisconnectRoot: String): Boolean;
|
||||
function WfxContentGetDefaultView(out DefaultView: TFileSourceFields): Boolean;
|
||||
function WfxExtractCustomIcon(var RemoteName: String; AIconSize: Integer; out TheIcon: TWfxIcon): Integer;
|
||||
private
|
||||
function LoadModule(const sName: String):Boolean; overload; {Load plugin}
|
||||
procedure UnloadModule; override;
|
||||
|
|
@ -191,7 +193,7 @@ uses
|
|||
LazUTF8, FileUtil,
|
||||
|
||||
//DC
|
||||
uDCUtils, uLng, uGlobsPaths, uOSUtils, uWfxPluginUtil, fDialogBox, DCOSUtils,
|
||||
uDCUtils, uLng, uGlobsPaths, uOSUtils, uWfxPluginUtil, DCOSUtils,
|
||||
DCStrUtils, DCConvertEncoding, uComponentsSignature, uOSForms, uExtension;
|
||||
|
||||
const
|
||||
|
|
@ -614,10 +616,48 @@ begin
|
|||
end;
|
||||
end;
|
||||
|
||||
function TWFXModule.WfxExtractCustomIcon(var RemoteName: String; AIconSize: Integer; out TheIcon: TWfxIcon): Integer;
|
||||
var
|
||||
Flags: Integer = FS_ICONFLAG_BACKGROUND;
|
||||
asFileName: array[0..MAX_PATH] of AnsiChar;
|
||||
wsFileName: array[0..MAX_PATH] of WideChar;
|
||||
begin
|
||||
TheIcon:= Default(TWfxIcon);
|
||||
|
||||
if (AIconSize = 16) then begin
|
||||
Flags:= Flags or FS_ICONFLAG_SMALL;
|
||||
end;
|
||||
TheIcon.Size:= AIconSize;
|
||||
|
||||
EnterCriticalSection(FIconMutex);
|
||||
try
|
||||
if Assigned(FsExtractCustomIconW) then
|
||||
begin
|
||||
StrPLCopy(wsFileName, CeUtf8ToUtf16(RemoteName), MAX_PATH);
|
||||
Result:= FsExtractCustomIconW(wsFileName, Flags, @TheIcon);
|
||||
if Result in [FS_ICON_EXTRACTED, FS_ICON_EXTRACTED_DESTROY] then
|
||||
RemoteName:= CeUtf16ToUtf8(UnicodeString(wsFileName));
|
||||
end
|
||||
else if Assigned(FsExtractCustomIcon) then
|
||||
begin
|
||||
StrPLCopy(asFileName, CeUtf8ToSys(RemoteName), MAX_PATH);
|
||||
Result:= FsExtractCustomIcon(asFileName, Flags, @TheIcon);
|
||||
if Result in [FS_ICON_EXTRACTED, FS_ICON_EXTRACTED_DESTROY] then
|
||||
RemoteName:= CeSysToUtf8(StrPas(asFileName));
|
||||
end
|
||||
else begin
|
||||
Result:= FS_ICON_USEDEFAULT;
|
||||
end;
|
||||
finally
|
||||
LeaveCriticalSection(FIconMutex);
|
||||
end;
|
||||
end;
|
||||
|
||||
constructor TWFXModule.Create;
|
||||
begin
|
||||
inherited;
|
||||
FName:= 'FS';
|
||||
InitCriticalSection(FIconMutex);
|
||||
end;
|
||||
|
||||
destructor TWFXModule.Destroy;
|
||||
|
|
@ -630,6 +670,7 @@ begin
|
|||
ExtensionFinalize(nil);
|
||||
end;
|
||||
inherited Destroy;
|
||||
DoneCriticalSection(FIconMutex);
|
||||
end;
|
||||
|
||||
function TWFXModule.LoadModule(const sName: String): Boolean;
|
||||
|
|
|
|||
|
|
@ -32,10 +32,10 @@ type
|
|||
//------------------------------------------------------
|
||||
{R} TFsSetAttr=function (RemoteName:pansichar;NewAttr:integer):bool;
|
||||
{R} TFsSetTime=Function(RemoteName:pansichar;CreationTime,LastAccessTime,LastWriteTime:PWfxFileTime):bool;
|
||||
{U} TFsExtractCustomIcon=function(RemoteName:pansichar;ExtractFlags:integer;var TheIcon:hicon):integer;
|
||||
{U} TFsExtractCustomIcon=function(RemoteName:pansichar;ExtractFlags:integer; TheIcon: PWfxIcon):integer;
|
||||
{R} TFsRenMovFile= function(OldName,NewName:pansichar; Move, OverWrite:bool; ri:pRemoteInfo):Integer;
|
||||
{U} TFsDisconnect = function (DisconnectRoot:pansichar):bool;
|
||||
{U} TFsGetPreviewBitmap = function ( RemoteName:pansichar; width,height:integer; ReturnedBitmap:HBITMAP):integer;
|
||||
{U} TFsGetPreviewBitmap = function ( RemoteName:pansichar; width,height:integer; ReturnedBitmap: PWfxIcon):integer;
|
||||
{R} TFsLinksToLocalFiles = function:bool;
|
||||
{R} TFsGetLocalName = function (RemoteName:pansichar;maxlen:integer):bool;
|
||||
//------------------------------------------------------
|
||||
|
|
@ -68,8 +68,8 @@ type
|
|||
TFsSetAttrW = function(RemoteName:pwidechar;NewAttr:integer):bool;
|
||||
TFsSetTimeW = function(RemoteName:pwidechar;CreationTime,LastAccessTime, LastWriteTime:PWfxFileTime):bool;
|
||||
TFsStatusInfoW = procedure(RemoteDir:pwidechar;InfoStartEnd,InfoOperation:integer);
|
||||
TFsExtractCustomIconW = function(RemoteName:pwidechar;ExtractFlags:integer; var TheIcon:hicon):integer;
|
||||
TFsGetPreviewBitmapW = function(RemoteName:pwidechar;width,height:integer; var ReturnedBitmap:hbitmap):integer;
|
||||
TFsExtractCustomIconW = function(RemoteName:pwidechar;ExtractFlags:integer; TheIcon: PWfxIcon):integer;
|
||||
TFsGetPreviewBitmapW = function(RemoteName:pwidechar;width,height:integer; ReturnedBitmap: PWfxIcon):integer;
|
||||
TFsGetLocalNameW = function(RemoteName:pwidechar;maxlen:integer):bool;
|
||||
//------------------------------------------------------
|
||||
TFsContentGetValueW = function(FileName:pwidechar;FieldIndex,UnitIndex:integer;FieldValue:pbyte; maxlen,flags:integer):integer;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue