FIX: Load folder system icon under Linux (fixes #2061)

This commit is contained in:
Alexander Koblov 2025-01-08 13:38:17 +03:00
commit 0135b6d4e8
2 changed files with 67 additions and 10 deletions

View file

@ -4,7 +4,7 @@
Interface to GIO - GLib Input, Output and Streaming Library
This unit loads all libraries dynamically so it can work without it
Copyright (C) 2011-2021 Alexander Koblov (alexx2000@mail.ru)
Copyright (C) 2011-2024 Alexander Koblov (alexx2000@mail.ru)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@ -35,6 +35,7 @@ function GioOpen(const Uri: String): Boolean;
function GioNewFile(const Address: String): PGFile;
function GioGetIconTheme(const Scheme: String): String;
function GioFileGetIcon(const FileName: String): String;
function GioMimeGetIcon(const MimeType: String): String;
function GioGetSetting(const Scheme, Key: String): String;
function GioFileGetEmblem(const FileName: String): String;
function GioMimeTypeGetActions(const MimeType: String): TDynamicStringArray;
@ -139,11 +140,40 @@ begin
Result:= GioGetSetting(Scheme, 'icon-theme');
end;
function GioGetIconName(GIcon: PGIcon): String;
var
AIconList: PPgchar;
begin
if g_type_check_instance_is_a(PGTypeInstance(GIcon), g_themed_icon_get_type()) then
begin
AIconList:= g_themed_icon_get_names(PGThemedIcon(GIcon));
if Assigned(AIconList) then Result:= AIconList[0];
end;
end;
function GioMimeGetIcon(const MimeType: String): String;
var
GIcon: PGIcon;
ContentType: Pgchar;
begin
Result:= EmptyStr;
ContentType:= g_content_type_from_mime_type(Pgchar(MimeType));
if Assigned(ContentType) then
begin
GIcon:= g_content_type_get_icon(ContentType);
if Assigned(GIcon) then
begin
Result:= GioGetIconName(GIcon);
g_object_unref(PGObject(GIcon));
end;
g_free(ContentType);
end;
end;
function GioFileGetIcon(const FileName: String): String;
var
GFile: PGFile;
GIcon: PGIcon;
AIconList: PPgchar;
GFileInfo: PGFileInfo;
begin
Result:= EmptyStr;
@ -152,11 +182,7 @@ begin
if Assigned(GFileInfo) then
begin
GIcon:= g_file_info_get_icon(GFileInfo);
if g_type_check_instance_is_a(PGTypeInstance(GIcon), g_themed_icon_get_type()) then
begin
AIconList:= g_themed_icon_get_names(PGThemedIcon(GIcon));
if Assigned(AIconList) then Result:= AIconList[0];
end;
Result:= GioGetIconName(GIcon);
g_object_unref(GFileInfo);
end;
g_object_unref(PGObject(GFile));

View file

@ -168,6 +168,10 @@ type
Safe to call without a lock.
}
function CheckAddThemePixmap(const AIconName: String; AIconSize: Integer = 0) : PtrInt;
{en
Loads an icon from default theme (DCTheme) and adds it to storage.
}
function AddDefaultThemePixmap(const AIconName: String; AIconSize: Integer = 0) : PtrInt;
{en
Loads an icon from the theme
}
@ -206,6 +210,7 @@ type
function GetSystemExecutableIcon: PtrInt; inline;
{$ENDIF}
{$IF DEFINED(UNIX) AND NOT (DEFINED(DARWIN) OR DEFINED(HAIKU))}
function GetSystemFolderIcon: PtrInt;
{en
Loads MIME icons names and creates a mapping: file extension -> MIME icon name.
Doesn't need to be synchronized as long as it's only called from Load().
@ -1015,6 +1020,18 @@ begin
end;
end;
function TPixMapManager.GetSystemFolderIcon: PtrInt;
var
AIconName: String;
begin
AIconName:= GioMimeGetIcon('inode/directory');
if Length(AIconName) = 0 then
Result:= -1
else begin
Result:= CheckAddThemePixmap(AIconName);
end;
end;
function TPixMapManager.GetIconByDesktopFile(sFileName: String; iDefaultIcon: PtrInt): PtrInt;
var
I: PtrInt;
@ -1204,6 +1221,21 @@ begin
Result := PtrInt(FThemePixmapsFileNames.List[fileIndex]^.Data);
end;
function TPixMapManager.AddDefaultThemePixmap(const AIconName: String;
AIconSize: Integer): PtrInt;
var
bmpBitmap: Graphics.TBitmap;
begin
if AIconSize = 0 then AIconSize := gIconsSize;
bmpBitmap := LoadThemeIcon(FDCIconTheme, AIconName, AIconSize);
if (bmpBitmap = nil) then
Result := -1
else begin
Result := FPixmapList.Add(bmpBitmap); // add to list
FThemePixmapsFileNames.Add(AIconName, Pointer(Result));
end;
end;
function TPixMapManager.LoadThemeIcon(AIconTheme: TIconTheme; const AIconName: String; AIconSize: Integer): Graphics.TBitmap;
var
FileName: String;
@ -1721,13 +1753,13 @@ begin
if FiShortcutIconID = -1 then
FiShortcutIconID := CheckAddThemePixmap('text-html');
{$ENDIF}
{$IF DEFINED(MSWINDOWS) or DEFINED(DARWIN)}
{$IF NOT DEFINED(HAIKU)}
FiDirIconID := -1;
if (gShowIcons > sim_standart) and (not (cimFolder in gCustomIcons)) then
FiDirIconID := GetSystemFolderIcon;
if FiDirIconID = -1 then
{$ENDIF}
FiDirIconID:= CheckAddThemePixmap('folder');
FiDirIconID:= AddDefaultThemePixmap('folder');
FiDirLinkBrokenIconID:= AddSpecial(FiDirIconID, FiEmblemUnreadableID);
FiLinkBrokenIconID:= AddSpecial(FiDefaultIconID, FiEmblemUnreadableID);
FiUpDirIconID:= CheckAddThemePixmap('go-up');
@ -2659,4 +2691,3 @@ finalization
end;
end.