mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-10 07:50:19 +00:00
Merge pull request #99 from ZoiteChat/consistent-icons
icon-resolver unifies gtk icons; win32/ci now ships real hicolor theme
This commit is contained in:
9
.github/workflows/windows-build.yml
vendored
9
.github/workflows/windows-build.yml
vendored
@@ -45,6 +45,14 @@ jobs:
|
|||||||
Invoke-WebRequest https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.18.0-pre1/GTK3_Gvsbuild_zoitechat-2.18.0-pre1_${{ matrix.platform }}.7z -OutFile deps\gtk-${{ matrix.arch }}.7z
|
Invoke-WebRequest https://github.com/ZoiteChat/gvsbuild/releases/download/zoitechat-2.18.0-pre1/GTK3_Gvsbuild_zoitechat-2.18.0-pre1_${{ matrix.platform }}.7z -OutFile deps\gtk-${{ matrix.arch }}.7z
|
||||||
& 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk\x64\release
|
& 7z.exe x deps\gtk-${{ matrix.arch }}.7z -oC:\gtk-build\gtk\x64\release
|
||||||
|
|
||||||
|
Invoke-WebRequest https://repo.msys2.org/mingw/x86_64/mingw-w64-x86_64-hicolor-icon-theme-0.18-1-any.pkg.tar.zst -OutFile deps\hicolor-icon-theme.pkg.tar.zst
|
||||||
|
python -c "import tarfile,zstandard,pathlib;archive=pathlib.Path(r'deps\\hicolor-icon-theme.pkg.tar.zst');target=pathlib.Path(r'C:\\gtk-build\\gtk\\x64\\release');dctx=zstandard.ZstdDecompressor();f=archive.open('rb');reader=dctx.stream_reader(f);tf=tarfile.open(fileobj=reader,mode='r|');[tf.extract(m,path=target) for m in tf if m.name.startswith('mingw64/share/icons/hicolor/')];tf.close();reader.close();f.close()"
|
||||||
|
if (Test-Path C:\gtk-build\gtk\x64\release\mingw64\share\icons\hicolor) {
|
||||||
|
New-Item -Path C:\gtk-build\gtk\x64\release\share\icons -ItemType Directory -Force | Out-Null
|
||||||
|
Copy-Item -Path C:\gtk-build\gtk\x64\release\mingw64\share\icons\hicolor -Destination C:\gtk-build\gtk\x64\release\share\icons\hicolor -Recurse -Force
|
||||||
|
Remove-Item -Path C:\gtk-build\gtk\x64\release\mingw64 -Recurse -Force
|
||||||
|
}
|
||||||
|
|
||||||
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z
|
Invoke-WebRequest https://github.com/zoitechat/gvsbuild/releases/download/zoitechat-2.17.0/gendef-20111031.7z -OutFile deps\gendef.7z
|
||||||
& 7z.exe x deps\gendef.7z -oC:\gtk-build
|
& 7z.exe x deps\gendef.7z -oC:\gtk-build
|
||||||
|
|
||||||
@@ -66,6 +74,7 @@ jobs:
|
|||||||
|
|
||||||
python -m pip install --upgrade pip
|
python -m pip install --upgrade pip
|
||||||
python -m pip install cffi
|
python -m pip install cffi
|
||||||
|
python -m pip install zstandard
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
|
|||||||
<ClInclude Include="fe-gtk.h" />
|
<ClInclude Include="fe-gtk.h" />
|
||||||
<ClInclude Include="fkeys.h" />
|
<ClInclude Include="fkeys.h" />
|
||||||
<ClInclude Include="gtkutil.h" />
|
<ClInclude Include="gtkutil.h" />
|
||||||
|
<ClInclude Include="icon-resolver.h" />
|
||||||
<ClInclude Include="joind.h" />
|
<ClInclude Include="joind.h" />
|
||||||
<ClInclude Include="maingui.h" />
|
<ClInclude Include="maingui.h" />
|
||||||
<ClInclude Include="menu.h" />
|
<ClInclude Include="menu.h" />
|
||||||
@@ -88,6 +89,7 @@ powershell "Get-Content -Encoding UTF8 '$(ZoiteChatLib)zoitechat.rc.utf8' | Out-
|
|||||||
<ClCompile Include="fe-gtk.c" />
|
<ClCompile Include="fe-gtk.c" />
|
||||||
<ClCompile Include="fkeys.c" />
|
<ClCompile Include="fkeys.c" />
|
||||||
<ClCompile Include="gtkutil.c" />
|
<ClCompile Include="gtkutil.c" />
|
||||||
|
<ClCompile Include="icon-resolver.c" />
|
||||||
<ClCompile Include="ignoregui.c" />
|
<ClCompile Include="ignoregui.c" />
|
||||||
<ClCompile Include="joind.c" />
|
<ClCompile Include="joind.c" />
|
||||||
<ClCompile Include="maingui.c" />
|
<ClCompile Include="maingui.c" />
|
||||||
|
|||||||
@@ -42,6 +42,9 @@
|
|||||||
<ClInclude Include="gtkutil.h">
|
<ClInclude Include="gtkutil.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="icon-resolver.h">
|
||||||
|
<Filter>Header Files</Filter>
|
||||||
|
</ClInclude>
|
||||||
<ClInclude Include="joind.h">
|
<ClInclude Include="joind.h">
|
||||||
<Filter>Header Files</Filter>
|
<Filter>Header Files</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
@@ -128,6 +131,9 @@
|
|||||||
<ClCompile Include="gtkutil.c">
|
<ClCompile Include="gtkutil.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="icon-resolver.c">
|
||||||
|
<Filter>Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="ignoregui.c">
|
<ClCompile Include="ignoregui.c">
|
||||||
<Filter>Source Files</Filter>
|
<Filter>Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
|||||||
@@ -42,6 +42,7 @@
|
|||||||
#include "../common/zoitechatc.h"
|
#include "../common/zoitechatc.h"
|
||||||
#include "../common/typedef.h"
|
#include "../common/typedef.h"
|
||||||
#include "gtkutil.h"
|
#include "gtkutil.h"
|
||||||
|
#include "icon-resolver.h"
|
||||||
#include "pixmaps.h"
|
#include "pixmaps.h"
|
||||||
|
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
@@ -62,124 +63,28 @@ struct file_req
|
|||||||
int flags; /* FRF_* flags */
|
int flags; /* FRF_* flags */
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *
|
|
||||||
gtkutil_menu_custom_icon_from_stock (const char *stock_name)
|
|
||||||
{
|
|
||||||
static const struct
|
|
||||||
{
|
|
||||||
const char *stock;
|
|
||||||
const char *custom_icon;
|
|
||||||
} icon_map[] = {
|
|
||||||
{ "gtk-new", "zc-menu-new" },
|
|
||||||
{ "gtk-index", "zc-menu-network-list" },
|
|
||||||
{ "gtk-revert-to-saved", "zc-menu-load-plugin" },
|
|
||||||
{ "gtk-redo", "zc-menu-detach" },
|
|
||||||
{ "gtk-close", "zc-menu-close" },
|
|
||||||
{ "gtk-quit", "zc-menu-quit" },
|
|
||||||
{ "gtk-disconnect", "zc-menu-disconnect" },
|
|
||||||
{ "gtk-connect", "zc-menu-connect" },
|
|
||||||
{ "gtk-jump-to", "zc-menu-join" },
|
|
||||||
{ "gtk-preferences", "zc-menu-preferences" },
|
|
||||||
{ "gtk-clear", "zc-menu-clear" },
|
|
||||||
{ "gtk-copy", "zc-menu-copy" },
|
|
||||||
{ "gtk-delete", "zc-menu-delete" },
|
|
||||||
{ "gtk-add", "zc-menu-add" },
|
|
||||||
{ "gtk-remove", "zc-menu-remove" },
|
|
||||||
{ "gtk-spell-check", "zc-menu-spell-check" },
|
|
||||||
{ "gtk-save", "zc-menu-save" },
|
|
||||||
{ "gtk-save-as", "zc-menu-save-as" },
|
|
||||||
{ "gtk-refresh", "zc-menu-refresh" },
|
|
||||||
{ "gtk-justify-left", "zc-menu-search" },
|
|
||||||
{ "gtk-find", "zc-menu-find" },
|
|
||||||
{ "gtk-go-back", "zc-menu-previous" },
|
|
||||||
{ "gtk-go-forward", "zc-menu-next" },
|
|
||||||
{ "gtk-help", "zc-menu-help" },
|
|
||||||
{ "gtk-about", "zc-menu-about" },
|
|
||||||
{ "gtk-convert", "zc-menu-emoji" },
|
|
||||||
};
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!stock_name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (icon_map); i++)
|
|
||||||
{
|
|
||||||
if (strcmp (stock_name, icon_map[i].stock) == 0)
|
|
||||||
return icon_map[i].custom_icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
gtkutil_menu_custom_icon_from_icon_name (const char *icon_name)
|
|
||||||
{
|
|
||||||
static const struct
|
|
||||||
{
|
|
||||||
const char *icon;
|
|
||||||
const char *custom_icon;
|
|
||||||
} icon_map[] = {
|
|
||||||
{ "document-new", "zc-menu-new" },
|
|
||||||
{ "view-list", "zc-menu-network-list" },
|
|
||||||
{ "document-open", "zc-menu-load-plugin" },
|
|
||||||
{ "edit-redo", "zc-menu-detach" },
|
|
||||||
{ "window-close", "zc-menu-close" },
|
|
||||||
{ "application-exit", "zc-menu-quit" },
|
|
||||||
{ "network-disconnect", "zc-menu-disconnect" },
|
|
||||||
{ "network-connect", "zc-menu-connect" },
|
|
||||||
{ "go-jump", "zc-menu-join" },
|
|
||||||
{ "preferences-system", "zc-menu-preferences" },
|
|
||||||
{ "edit-clear", "zc-menu-clear" },
|
|
||||||
{ "edit-copy", "zc-menu-copy" },
|
|
||||||
{ "edit-delete", "zc-menu-delete" },
|
|
||||||
{ "list-add", "zc-menu-add" },
|
|
||||||
{ "list-remove", "zc-menu-remove" },
|
|
||||||
{ "tools-check-spelling", "zc-menu-spell-check" },
|
|
||||||
{ "document-save", "zc-menu-save" },
|
|
||||||
{ "document-save-as", "zc-menu-save-as" },
|
|
||||||
{ "view-refresh", "zc-menu-refresh" },
|
|
||||||
{ "edit-find", "zc-menu-find" },
|
|
||||||
{ "go-previous", "zc-menu-previous" },
|
|
||||||
{ "go-next", "zc-menu-next" },
|
|
||||||
{ "help-browser", "zc-menu-help" },
|
|
||||||
{ "help-about", "zc-menu-about" },
|
|
||||||
{ "face-smile", "zc-menu-emoji" },
|
|
||||||
{ "insert-emoticon", "zc-menu-emoji" },
|
|
||||||
{ "software-update-available", "zc-menu-update" },
|
|
||||||
{ "network-workgroup", "zc-menu-chanlist" },
|
|
||||||
};
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!icon_name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (icon_map); i++)
|
|
||||||
{
|
|
||||||
if (strcmp (icon_name, icon_map[i].icon) == 0)
|
|
||||||
return icon_map[i].custom_icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
gtkutil_menu_icon_pixbuf_new (const char *icon_name)
|
gtkutil_menu_icon_pixbuf_new (const char *icon_name)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf = NULL;
|
GdkPixbuf *pixbuf = NULL;
|
||||||
char *resource_path;
|
char *resource_path;
|
||||||
|
const char *system_icon_name = NULL;
|
||||||
|
int action;
|
||||||
|
|
||||||
if (!icon_name || !g_str_has_prefix (icon_name, "zc-menu-"))
|
if (!icon_name || !icon_resolver_menu_action_from_name (icon_name, &action))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
resource_path = g_strdup_printf ("/icons/menu/light/%s.png", icon_name + strlen ("zc-menu-"));
|
resource_path = icon_resolver_resolve_path (ICON_RESOLVER_ROLE_MENU_ACTION, action,
|
||||||
|
GTK_ICON_SIZE_MENU, "menu",
|
||||||
|
ICON_RESOLVER_THEME_SYSTEM,
|
||||||
|
&system_icon_name);
|
||||||
|
if (!resource_path)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (g_str_has_prefix (resource_path, "/icons/"))
|
||||||
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
|
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
|
||||||
if (!pixbuf)
|
else
|
||||||
{
|
pixbuf = gdk_pixbuf_new_from_file (resource_path, NULL);
|
||||||
g_free (resource_path);
|
|
||||||
resource_path = g_strdup_printf ("/icons/menu/light/%s.svg", icon_name + strlen ("zc-menu-"));
|
|
||||||
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
|
|
||||||
}
|
|
||||||
g_free (resource_path);
|
g_free (resource_path);
|
||||||
|
|
||||||
return pixbuf;
|
return pixbuf;
|
||||||
@@ -188,136 +93,26 @@ gtkutil_menu_icon_pixbuf_new (const char *icon_name)
|
|||||||
const char *
|
const char *
|
||||||
gtkutil_icon_name_from_stock (const char *stock_name)
|
gtkutil_icon_name_from_stock (const char *stock_name)
|
||||||
{
|
{
|
||||||
static const struct
|
return icon_resolver_icon_name_from_stock (stock_name);
|
||||||
{
|
|
||||||
const char *stock;
|
|
||||||
const char *icon;
|
|
||||||
} icon_map[] = {
|
|
||||||
{ "gtk-new", "document-new" },
|
|
||||||
{ "gtk-open", "document-open" },
|
|
||||||
{ "gtk-revert-to-saved", "document-open" },
|
|
||||||
{ "gtk-save", "document-save" },
|
|
||||||
{ "gtk-save-as", "document-save-as" },
|
|
||||||
{ "gtk-add", "list-add" },
|
|
||||||
{ "gtk-cancel", "dialog-cancel" },
|
|
||||||
{ "gtk-ok", "dialog-ok" },
|
|
||||||
{ "gtk-no", "dialog-cancel" },
|
|
||||||
{ "gtk-yes", "dialog-ok" },
|
|
||||||
{ "gtk-apply", "dialog-apply" },
|
|
||||||
{ "gtk-dialog-error", "dialog-error" },
|
|
||||||
{ "gtk-copy", "edit-copy" },
|
|
||||||
{ "gtk-delete", "edit-delete" },
|
|
||||||
{ "gtk-remove", "list-remove" },
|
|
||||||
{ "gtk-clear", "edit-clear" },
|
|
||||||
{ "gtk-redo", "edit-redo" },
|
|
||||||
{ "gtk-find", "edit-find" },
|
|
||||||
{ "gtk-justify-left", "edit-find" },
|
|
||||||
{ "gtk-refresh", "view-refresh" },
|
|
||||||
{ "gtk-go-back", "go-previous" },
|
|
||||||
{ "gtk-go-forward", "go-next" },
|
|
||||||
{ "gtk-index", "view-list" },
|
|
||||||
{ "gtk-jump-to", "go-jump" },
|
|
||||||
{ "gtk-media-play", "media-playback-start" },
|
|
||||||
{ "gtk-preferences", "preferences-system" },
|
|
||||||
{ "gtk-help", "help-browser" },
|
|
||||||
{ "gtk-about", "help-about" },
|
|
||||||
{ "gtk-close", "window-close" },
|
|
||||||
{ "gtk-quit", "application-exit" },
|
|
||||||
{ "gtk-connect", "network-connect" },
|
|
||||||
{ "gtk-disconnect", "network-disconnect" },
|
|
||||||
{ "gtk-network", "network-workgroup" },
|
|
||||||
{ "gtk-spell-check", "tools-check-spelling" },
|
|
||||||
};
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
if (!stock_name)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < G_N_ELEMENTS (icon_map); i++)
|
|
||||||
{
|
|
||||||
if (strcmp (stock_name, icon_map[i].stock) == 0)
|
|
||||||
return icon_map[i].icon;
|
|
||||||
}
|
|
||||||
|
|
||||||
return stock_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *
|
|
||||||
gtkutil_menu_icon_theme_variant (void)
|
|
||||||
{
|
|
||||||
GtkSettings *settings;
|
|
||||||
gboolean prefer_dark = FALSE;
|
|
||||||
char *theme_name = NULL;
|
|
||||||
char *theme_name_lower = NULL;
|
|
||||||
const char *theme_variant = "light";
|
|
||||||
|
|
||||||
settings = gtk_settings_get_default ();
|
|
||||||
if (settings)
|
|
||||||
{
|
|
||||||
g_object_get (G_OBJECT (settings), "gtk-application-prefer-dark-theme", &prefer_dark, NULL);
|
|
||||||
g_object_get (G_OBJECT (settings), "gtk-theme-name", &theme_name, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (theme_name)
|
|
||||||
theme_name_lower = g_ascii_strdown (theme_name, -1);
|
|
||||||
if (prefer_dark || (theme_name_lower && g_strrstr (theme_name_lower, "dark")))
|
|
||||||
theme_variant = "dark";
|
|
||||||
|
|
||||||
g_free (theme_name_lower);
|
|
||||||
g_free (theme_name);
|
|
||||||
|
|
||||||
return theme_variant;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static GtkWidget *
|
static GtkWidget *
|
||||||
gtkutil_menu_icon_image_new (const char *icon_name, GtkIconSize size)
|
gtkutil_menu_icon_image_new (const char *icon_name, GtkIconSize size)
|
||||||
{
|
{
|
||||||
GtkWidget *image = NULL;
|
GtkWidget *image = NULL;
|
||||||
GdkPixbuf *pixbuf = NULL;
|
GdkPixbuf *pixbuf;
|
||||||
char *resource_path;
|
|
||||||
const char *variant;
|
|
||||||
|
|
||||||
if (!icon_name || !g_str_has_prefix (icon_name, "zc-menu-"))
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
variant = gtkutil_menu_icon_theme_variant ();
|
|
||||||
resource_path = g_strdup_printf ("/icons/menu/%s/%s.png", variant, icon_name + strlen ("zc-menu-"));
|
|
||||||
if (!g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
|
|
||||||
{
|
|
||||||
g_free (resource_path);
|
|
||||||
resource_path = g_strdup_printf ("/icons/menu/light/%s.png", icon_name + strlen ("zc-menu-"));
|
|
||||||
}
|
|
||||||
|
|
||||||
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
|
|
||||||
if (!pixbuf)
|
|
||||||
{
|
|
||||||
g_free (resource_path);
|
|
||||||
resource_path = g_strdup_printf ("/icons/menu/%s/%s.svg", variant, icon_name + strlen ("zc-menu-"));
|
|
||||||
if (!g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL))
|
|
||||||
{
|
|
||||||
g_free (resource_path);
|
|
||||||
resource_path = g_strdup_printf ("/icons/menu/light/%s.svg", icon_name + strlen ("zc-menu-"));
|
|
||||||
}
|
|
||||||
pixbuf = gdk_pixbuf_new_from_resource (resource_path, NULL);
|
|
||||||
}
|
|
||||||
if (pixbuf)
|
|
||||||
{
|
|
||||||
image = gtk_image_new_from_pixbuf (pixbuf);
|
|
||||||
g_object_unref (pixbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
g_free (resource_path);
|
|
||||||
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
GtkIconSize tmp_size;
|
|
||||||
gint width;
|
gint width;
|
||||||
gint height;
|
gint height;
|
||||||
|
|
||||||
tmp_size = size;
|
pixbuf = gtkutil_menu_icon_pixbuf_new (icon_name);
|
||||||
if (gtk_icon_size_lookup (tmp_size, &width, &height))
|
if (!pixbuf)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
image = gtk_image_new_from_pixbuf (pixbuf);
|
||||||
|
g_object_unref (pixbuf);
|
||||||
|
|
||||||
|
if (gtk_icon_size_lookup (size, &width, &height))
|
||||||
gtk_image_set_pixel_size (GTK_IMAGE (image), MAX (width, height));
|
gtk_image_set_pixel_size (GTK_IMAGE (image), MAX (width, height));
|
||||||
}
|
|
||||||
|
|
||||||
return image;
|
return image;
|
||||||
}
|
}
|
||||||
@@ -327,26 +122,24 @@ gtkutil_image_new_from_stock (const char *stock, GtkIconSize size)
|
|||||||
{
|
{
|
||||||
GtkWidget *image;
|
GtkWidget *image;
|
||||||
const char *icon_name;
|
const char *icon_name;
|
||||||
|
const char *resolved_icon_name = NULL;
|
||||||
|
int action;
|
||||||
|
|
||||||
icon_name = gtkutil_icon_name_from_stock (stock);
|
icon_name = gtkutil_icon_name_from_stock (stock);
|
||||||
if (!icon_name && stock && g_str_has_prefix (stock, "zc-menu-"))
|
if (!icon_name && stock && g_str_has_prefix (stock, "zc-menu-"))
|
||||||
icon_name = stock;
|
icon_name = stock;
|
||||||
if (size == GTK_ICON_SIZE_MENU)
|
|
||||||
{
|
|
||||||
const char *menu_icon_name = gtkutil_menu_custom_icon_from_stock (stock);
|
|
||||||
|
|
||||||
if (!menu_icon_name)
|
|
||||||
menu_icon_name = gtkutil_menu_custom_icon_from_icon_name (icon_name);
|
|
||||||
|
|
||||||
if (menu_icon_name)
|
|
||||||
icon_name = menu_icon_name;
|
|
||||||
}
|
|
||||||
|
|
||||||
image = gtkutil_menu_icon_image_new (icon_name, size);
|
image = gtkutil_menu_icon_image_new (icon_name, size);
|
||||||
if (image)
|
if (image)
|
||||||
return image;
|
return image;
|
||||||
|
|
||||||
return gtk_image_new_from_icon_name (icon_name, size);
|
if (icon_resolver_menu_action_from_name (icon_name, &action))
|
||||||
|
resolved_icon_name = icon_resolver_system_icon_name (ICON_RESOLVER_ROLE_MENU_ACTION, action);
|
||||||
|
|
||||||
|
if (!resolved_icon_name)
|
||||||
|
resolved_icon_name = icon_name;
|
||||||
|
|
||||||
|
return gtk_image_new_from_icon_name (resolved_icon_name, size);
|
||||||
}
|
}
|
||||||
|
|
||||||
GtkWidget *
|
GtkWidget *
|
||||||
|
|||||||
397
src/fe-gtk/icon-resolver.c
Normal file
397
src/fe-gtk/icon-resolver.c
Normal file
@@ -0,0 +1,397 @@
|
|||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "fe-gtk.h"
|
||||||
|
#include "icon-resolver.h"
|
||||||
|
#include "../common/cfgfiles.h"
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
IconResolverRole role;
|
||||||
|
int item;
|
||||||
|
const char *custom_icon_name;
|
||||||
|
const char *system_icon_name;
|
||||||
|
const char *resource_name;
|
||||||
|
} IconRegistryEntry;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
const char *stock_name;
|
||||||
|
const char *system_icon_name;
|
||||||
|
} StockIconMap;
|
||||||
|
|
||||||
|
static const IconRegistryEntry icon_registry[] = {
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_NEW, "zc-menu-new", "document-new", "new" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_NETWORK_LIST, "zc-menu-network-list", "view-list", "network-list" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_LOAD_PLUGIN, "zc-menu-load-plugin", "document-open", "load-plugin" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_DETACH, "zc-menu-detach", "edit-redo", "detach" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CLOSE, "zc-menu-close", "window-close", "close" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_QUIT, "zc-menu-quit", "application-exit", "quit" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_DISCONNECT, "zc-menu-disconnect", "network-disconnect", "disconnect" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CONNECT, "zc-menu-connect", "network-connect", "connect" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_JOIN, "zc-menu-join", "go-jump", "join" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_PREFERENCES, "zc-menu-preferences", "preferences-system", "preferences" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CLEAR, "zc-menu-clear", "edit-clear", "clear" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_COPY, "zc-menu-copy", "edit-copy", "copy" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_DELETE, "zc-menu-delete", "edit-delete", "delete" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_ADD, "zc-menu-add", "list-add", "add" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_REMOVE, "zc-menu-remove", "list-remove", "remove" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SPELL_CHECK, "zc-menu-spell-check", "tools-check-spelling", "spell-check" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SAVE, "zc-menu-save", "document-save", "save" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SAVE_AS, "zc-menu-save-as", "document-save-as", "save-as" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_REFRESH, "zc-menu-refresh", "view-refresh", "refresh" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_SEARCH, "zc-menu-search", "edit-find", "search" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_FIND, "zc-menu-find", "edit-find", "find" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_PREVIOUS, "zc-menu-previous", "go-previous", "previous" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_NEXT, "zc-menu-next", "go-next", "next" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_HELP, "zc-menu-help", "help-browser", "help" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_ABOUT, "zc-menu-about", "help-about", "about" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_EMOJI, "zc-menu-emoji", "face-smile", "emoji" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_UPDATE, "zc-menu-update", "software-update-available", "update" },
|
||||||
|
{ ICON_RESOLVER_ROLE_MENU_ACTION, ICON_RESOLVER_MENU_ACTION_CHANLIST, "zc-menu-chanlist", "network-workgroup", "chanlist" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_NORMAL, NULL, "zoitechat", "tray_normal" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_FILEOFFER, NULL, "mail-attachment", "tray_fileoffer" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_HIGHLIGHT, NULL, "dialog-warning", "tray_highlight" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_MESSAGE, NULL, "mail-unread", "tray_message" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_CHANNEL, NULL, "folder", "tree_channel" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_DIALOG, NULL, "mail-message-new", "tree_dialog" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_SERVER, NULL, "network-server", "tree_server" },
|
||||||
|
{ ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_UTIL, NULL, "applications-utilities", "tree_util" },
|
||||||
|
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_VOICE, NULL, "emblem-ok", "ulist_voice" },
|
||||||
|
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_HALFOP, NULL, "emblem-shared", "ulist_halfop" },
|
||||||
|
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_OP, NULL, "emblem-default", "ulist_op" },
|
||||||
|
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_OWNER, NULL, "emblem-favorite", "ulist_owner" },
|
||||||
|
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_FOUNDER, NULL, "emblem-favorite", "ulist_founder" },
|
||||||
|
{ ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_NETOP, NULL, "emblem-system", "ulist_netop" }
|
||||||
|
};
|
||||||
|
|
||||||
|
static const StockIconMap stock_icon_map[] = {
|
||||||
|
{ "gtk-new", "document-new" },
|
||||||
|
{ "gtk-open", "document-open" },
|
||||||
|
{ "gtk-revert-to-saved", "document-open" },
|
||||||
|
{ "gtk-save", "document-save" },
|
||||||
|
{ "gtk-save-as", "document-save-as" },
|
||||||
|
{ "gtk-add", "list-add" },
|
||||||
|
{ "gtk-cancel", "dialog-cancel" },
|
||||||
|
{ "gtk-ok", "dialog-ok" },
|
||||||
|
{ "gtk-no", "dialog-cancel" },
|
||||||
|
{ "gtk-yes", "dialog-ok" },
|
||||||
|
{ "gtk-apply", "dialog-apply" },
|
||||||
|
{ "gtk-dialog-error", "dialog-error" },
|
||||||
|
{ "gtk-copy", "edit-copy" },
|
||||||
|
{ "gtk-delete", "edit-delete" },
|
||||||
|
{ "gtk-remove", "list-remove" },
|
||||||
|
{ "gtk-clear", "edit-clear" },
|
||||||
|
{ "gtk-redo", "edit-redo" },
|
||||||
|
{ "gtk-find", "edit-find" },
|
||||||
|
{ "gtk-justify-left", "edit-find" },
|
||||||
|
{ "gtk-refresh", "view-refresh" },
|
||||||
|
{ "gtk-go-back", "go-previous" },
|
||||||
|
{ "gtk-go-forward", "go-next" },
|
||||||
|
{ "gtk-index", "view-list" },
|
||||||
|
{ "gtk-jump-to", "go-jump" },
|
||||||
|
{ "gtk-media-play", "media-playback-start" },
|
||||||
|
{ "gtk-preferences", "preferences-system" },
|
||||||
|
{ "gtk-help", "help-browser" },
|
||||||
|
{ "gtk-about", "help-about" },
|
||||||
|
{ "gtk-close", "window-close" },
|
||||||
|
{ "gtk-quit", "application-exit" },
|
||||||
|
{ "gtk-connect", "network-connect" },
|
||||||
|
{ "gtk-disconnect", "network-disconnect" },
|
||||||
|
{ "gtk-network", "network-workgroup" },
|
||||||
|
{ "gtk-spell-check", "tools-check-spelling" }
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
menu_action_from_icon_name (const char *icon_name)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!icon_name)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
|
||||||
|
{
|
||||||
|
if (icon_registry[i].role != ICON_RESOLVER_ROLE_MENU_ACTION)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (icon_registry[i].system_icon_name && strcmp (icon_name, icon_registry[i].system_icon_name) == 0)
|
||||||
|
return icon_registry[i].item;
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IconRegistryEntry *
|
||||||
|
icon_registry_find (IconResolverRole role, int item)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
|
||||||
|
{
|
||||||
|
if (icon_registry[i].role == role && icon_registry[i].item == item)
|
||||||
|
return &icon_registry[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const IconRegistryEntry *
|
||||||
|
icon_registry_find_custom (const char *custom_icon_name)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!custom_icon_name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
|
||||||
|
{
|
||||||
|
if (icon_registry[i].custom_icon_name && strcmp (icon_registry[i].custom_icon_name, custom_icon_name) == 0)
|
||||||
|
return &icon_registry[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
icon_resolver_icon_name_from_stock (const char *stock_name)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!stock_name)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (stock_icon_map); i++)
|
||||||
|
{
|
||||||
|
if (strcmp (stock_name, stock_icon_map[i].stock_name) == 0)
|
||||||
|
return stock_icon_map[i].system_icon_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return stock_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
icon_resolver_menu_action_from_name (const char *name, int *action_out)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (!name)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (icon_registry); i++)
|
||||||
|
{
|
||||||
|
if (icon_registry[i].role != ICON_RESOLVER_ROLE_MENU_ACTION)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ((icon_registry[i].custom_icon_name && strcmp (name, icon_registry[i].custom_icon_name) == 0) ||
|
||||||
|
(icon_registry[i].system_icon_name && strcmp (name, icon_registry[i].system_icon_name) == 0))
|
||||||
|
{
|
||||||
|
if (action_out)
|
||||||
|
*action_out = icon_registry[i].item;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < G_N_ELEMENTS (stock_icon_map); i++)
|
||||||
|
{
|
||||||
|
if (strcmp (name, stock_icon_map[i].stock_name) == 0)
|
||||||
|
{
|
||||||
|
int action = menu_action_from_icon_name (stock_icon_map[i].system_icon_name);
|
||||||
|
|
||||||
|
if (action >= 0)
|
||||||
|
{
|
||||||
|
if (action_out)
|
||||||
|
*action_out = action;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
icon_resolver_icon_name_for_menu_custom (const char *custom_icon_name)
|
||||||
|
{
|
||||||
|
const IconRegistryEntry *entry = icon_registry_find_custom (custom_icon_name);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return entry->system_icon_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
icon_resolver_menu_action_from_custom (const char *custom_icon_name, int *action_out)
|
||||||
|
{
|
||||||
|
const IconRegistryEntry *entry = icon_registry_find_custom (custom_icon_name);
|
||||||
|
|
||||||
|
if (!entry || entry->role != ICON_RESOLVER_ROLE_MENU_ACTION)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
|
if (action_out)
|
||||||
|
*action_out = entry->item;
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *
|
||||||
|
icon_resolver_system_icon_name (IconResolverRole role, int item)
|
||||||
|
{
|
||||||
|
const IconRegistryEntry *entry = icon_registry_find (role, item);
|
||||||
|
|
||||||
|
if (!entry)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return entry->system_icon_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
IconResolverThemeVariant
|
||||||
|
icon_resolver_detect_theme_variant (void)
|
||||||
|
{
|
||||||
|
GtkSettings *settings;
|
||||||
|
gboolean prefer_dark = FALSE;
|
||||||
|
char *theme_name = NULL;
|
||||||
|
char *theme_name_lower = NULL;
|
||||||
|
IconResolverThemeVariant theme_variant = ICON_RESOLVER_THEME_LIGHT;
|
||||||
|
|
||||||
|
settings = gtk_settings_get_default ();
|
||||||
|
if (settings)
|
||||||
|
{
|
||||||
|
g_object_get (G_OBJECT (settings), "gtk-application-prefer-dark-theme", &prefer_dark, NULL);
|
||||||
|
g_object_get (G_OBJECT (settings), "gtk-theme-name", &theme_name, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (theme_name)
|
||||||
|
theme_name_lower = g_ascii_strdown (theme_name, -1);
|
||||||
|
if (prefer_dark || (theme_name_lower && g_strrstr (theme_name_lower, "dark")))
|
||||||
|
theme_variant = ICON_RESOLVER_THEME_DARK;
|
||||||
|
|
||||||
|
g_free (theme_name_lower);
|
||||||
|
g_free (theme_name);
|
||||||
|
|
||||||
|
return theme_variant;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
resource_exists (const char *resource_path)
|
||||||
|
{
|
||||||
|
return g_resources_get_info (resource_path, G_RESOURCE_LOOKUP_FLAGS_NONE, NULL, NULL, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
resolve_user_override (const IconRegistryEntry *entry, IconResolverThemeVariant variant)
|
||||||
|
{
|
||||||
|
const char *variant_name = variant == ICON_RESOLVER_THEME_DARK ? "dark" : "light";
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s" G_DIR_SEPARATOR_S "%s.png",
|
||||||
|
get_xdir (), variant_name, entry->resource_name);
|
||||||
|
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s-%s.png",
|
||||||
|
get_xdir (), entry->resource_name, variant_name);
|
||||||
|
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s.png",
|
||||||
|
get_xdir (), entry->resource_name);
|
||||||
|
if (g_file_test (path, G_FILE_TEST_EXISTS))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
resolve_bundled_variant (const IconRegistryEntry *entry, IconResolverThemeVariant variant)
|
||||||
|
{
|
||||||
|
const char *variant_name = variant == ICON_RESOLVER_THEME_DARK ? "dark" : "light";
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (entry->role == ICON_RESOLVER_ROLE_MENU_ACTION)
|
||||||
|
{
|
||||||
|
path = g_strdup_printf ("/icons/menu/%s/%s.png", variant_name, entry->resource_name);
|
||||||
|
if (resource_exists (path))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
path = g_strdup_printf ("/icons/menu/%s/%s.svg", variant_name, entry->resource_name);
|
||||||
|
if (resource_exists (path))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = g_strdup_printf ("/icons/%s-%s.png", entry->resource_name, variant_name);
|
||||||
|
if (resource_exists (path))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char *
|
||||||
|
resolve_bundled_neutral (const IconRegistryEntry *entry)
|
||||||
|
{
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
if (entry->role == ICON_RESOLVER_ROLE_MENU_ACTION)
|
||||||
|
{
|
||||||
|
path = g_strdup_printf ("/icons/menu/light/%s.png", entry->resource_name);
|
||||||
|
if (resource_exists (path))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
|
||||||
|
path = g_strdup_printf ("/icons/menu/light/%s.svg", entry->resource_name);
|
||||||
|
if (resource_exists (path))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
path = g_strdup_printf ("/icons/%s.png", entry->resource_name);
|
||||||
|
if (resource_exists (path))
|
||||||
|
return path;
|
||||||
|
g_free (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *
|
||||||
|
icon_resolver_resolve_path (IconResolverRole role, int item, GtkIconSize size,
|
||||||
|
const char *context, IconResolverThemeVariant variant,
|
||||||
|
const char **system_icon_name)
|
||||||
|
{
|
||||||
|
const IconRegistryEntry *entry;
|
||||||
|
IconResolverThemeVariant effective_variant = variant;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
(void)size;
|
||||||
|
(void)context;
|
||||||
|
|
||||||
|
entry = icon_registry_find (role, item);
|
||||||
|
if (!entry)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (system_icon_name)
|
||||||
|
*system_icon_name = entry->system_icon_name;
|
||||||
|
|
||||||
|
if (effective_variant == ICON_RESOLVER_THEME_SYSTEM)
|
||||||
|
effective_variant = icon_resolver_detect_theme_variant ();
|
||||||
|
|
||||||
|
path = resolve_user_override (entry, effective_variant);
|
||||||
|
if (path)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
path = resolve_bundled_variant (entry, effective_variant);
|
||||||
|
if (path)
|
||||||
|
return path;
|
||||||
|
|
||||||
|
return resolve_bundled_neutral (entry);
|
||||||
|
}
|
||||||
89
src/fe-gtk/icon-resolver.h
Normal file
89
src/fe-gtk/icon-resolver.h
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
#ifndef ZOITECHAT_ICON_RESOLVER_H
|
||||||
|
#define ZOITECHAT_ICON_RESOLVER_H
|
||||||
|
|
||||||
|
#include <gtk/gtk.h>
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICON_RESOLVER_ROLE_MENU_ACTION,
|
||||||
|
ICON_RESOLVER_ROLE_TRAY_STATE,
|
||||||
|
ICON_RESOLVER_ROLE_TREE_TYPE,
|
||||||
|
ICON_RESOLVER_ROLE_USERLIST_RANK
|
||||||
|
} IconResolverRole;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICON_RESOLVER_THEME_SYSTEM,
|
||||||
|
ICON_RESOLVER_THEME_LIGHT,
|
||||||
|
ICON_RESOLVER_THEME_DARK
|
||||||
|
} IconResolverThemeVariant;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICON_RESOLVER_MENU_ACTION_NEW,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_NETWORK_LIST,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_LOAD_PLUGIN,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_DETACH,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_CLOSE,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_QUIT,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_DISCONNECT,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_CONNECT,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_JOIN,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_PREFERENCES,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_CLEAR,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_COPY,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_DELETE,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_ADD,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_REMOVE,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_SPELL_CHECK,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_SAVE,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_SAVE_AS,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_REFRESH,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_SEARCH,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_FIND,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_PREVIOUS,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_NEXT,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_HELP,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_ABOUT,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_EMOJI,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_UPDATE,
|
||||||
|
ICON_RESOLVER_MENU_ACTION_CHANLIST
|
||||||
|
} IconResolverMenuAction;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICON_RESOLVER_TRAY_STATE_NORMAL,
|
||||||
|
ICON_RESOLVER_TRAY_STATE_FILEOFFER,
|
||||||
|
ICON_RESOLVER_TRAY_STATE_HIGHLIGHT,
|
||||||
|
ICON_RESOLVER_TRAY_STATE_MESSAGE
|
||||||
|
} IconResolverTrayState;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICON_RESOLVER_TREE_TYPE_CHANNEL,
|
||||||
|
ICON_RESOLVER_TREE_TYPE_DIALOG,
|
||||||
|
ICON_RESOLVER_TREE_TYPE_SERVER,
|
||||||
|
ICON_RESOLVER_TREE_TYPE_UTIL
|
||||||
|
} IconResolverTreeType;
|
||||||
|
|
||||||
|
typedef enum
|
||||||
|
{
|
||||||
|
ICON_RESOLVER_USERLIST_RANK_VOICE,
|
||||||
|
ICON_RESOLVER_USERLIST_RANK_HALFOP,
|
||||||
|
ICON_RESOLVER_USERLIST_RANK_OP,
|
||||||
|
ICON_RESOLVER_USERLIST_RANK_OWNER,
|
||||||
|
ICON_RESOLVER_USERLIST_RANK_FOUNDER,
|
||||||
|
ICON_RESOLVER_USERLIST_RANK_NETOP
|
||||||
|
} IconResolverUserlistRank;
|
||||||
|
|
||||||
|
const char *icon_resolver_icon_name_from_stock (const char *stock_name);
|
||||||
|
const char *icon_resolver_icon_name_for_menu_custom (const char *custom_icon_name);
|
||||||
|
gboolean icon_resolver_menu_action_from_custom (const char *custom_icon_name, int *action_out);
|
||||||
|
gboolean icon_resolver_menu_action_from_name (const char *name, int *action_out);
|
||||||
|
const char *icon_resolver_system_icon_name (IconResolverRole role, int item);
|
||||||
|
IconResolverThemeVariant icon_resolver_detect_theme_variant (void);
|
||||||
|
char *icon_resolver_resolve_path (IconResolverRole role, int item, GtkIconSize size,
|
||||||
|
const char *context, IconResolverThemeVariant variant,
|
||||||
|
const char **system_icon_name);
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -9,6 +9,7 @@ zoitechat_gtk_sources = [
|
|||||||
'fe-gtk.c',
|
'fe-gtk.c',
|
||||||
'fkeys.c',
|
'fkeys.c',
|
||||||
'gtkutil.c',
|
'gtkutil.c',
|
||||||
|
'icon-resolver.c',
|
||||||
'ignoregui.c',
|
'ignoregui.c',
|
||||||
'joind.c',
|
'joind.c',
|
||||||
'menu.c',
|
'menu.c',
|
||||||
|
|||||||
@@ -25,6 +25,7 @@
|
|||||||
#include "../common/zoitechat.h"
|
#include "../common/zoitechat.h"
|
||||||
#include "../common/fe.h"
|
#include "../common/fe.h"
|
||||||
#include "resources.h"
|
#include "resources.h"
|
||||||
|
#include "icon-resolver.h"
|
||||||
|
|
||||||
#include <gio/gio.h>
|
#include <gio/gio.h>
|
||||||
#include <gdk-pixbuf/gdk-pixbuf.h>
|
#include <gdk-pixbuf/gdk-pixbuf.h>
|
||||||
@@ -151,25 +152,36 @@ pixmap_load_from_file (char *filename)
|
|||||||
|
|
||||||
/* load custom icons from <config>/icons, don't mess in system folders */
|
/* load custom icons from <config>/icons, don't mess in system folders */
|
||||||
static GdkPixbuf *
|
static GdkPixbuf *
|
||||||
load_pixmap (const char *filename)
|
load_pixmap (IconResolverRole role, int item)
|
||||||
{
|
{
|
||||||
GdkPixbuf *pixbuf, *scaledpixbuf;
|
GdkPixbuf *pixbuf = NULL;
|
||||||
|
GdkPixbuf *scaledpixbuf;
|
||||||
const char *scale;
|
const char *scale;
|
||||||
int iscale;
|
int iscale;
|
||||||
|
char *path;
|
||||||
|
const char *system_icon_name = NULL;
|
||||||
|
|
||||||
gchar *path = g_strdup_printf ("%s" G_DIR_SEPARATOR_S "icons" G_DIR_SEPARATOR_S "%s.png", get_xdir (), filename);
|
path = icon_resolver_resolve_path (role, item, GTK_ICON_SIZE_MENU, "pixmap",
|
||||||
pixbuf = gdk_pixbuf_new_from_file (path, 0);
|
ICON_RESOLVER_THEME_SYSTEM, &system_icon_name);
|
||||||
g_free (path);
|
if (path)
|
||||||
|
|
||||||
if (!pixbuf)
|
|
||||||
{
|
{
|
||||||
path = g_strdup_printf ("/icons/%s.png", filename);
|
if (g_str_has_prefix (path, "/icons/"))
|
||||||
pixbuf = gdk_pixbuf_new_from_resource (path, NULL);
|
pixbuf = gdk_pixbuf_new_from_resource (path, NULL);
|
||||||
|
else
|
||||||
|
pixbuf = gdk_pixbuf_new_from_file (path, 0);
|
||||||
g_free (path);
|
g_free (path);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!pixbuf && system_icon_name)
|
||||||
|
{
|
||||||
|
GtkIconTheme *theme = gtk_icon_theme_get_default ();
|
||||||
|
if (theme)
|
||||||
|
pixbuf = gtk_icon_theme_load_icon (theme, system_icon_name, 16, GTK_ICON_LOOKUP_FORCE_SIZE, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
scale = g_getenv ("GDK_SCALE");
|
scale = g_getenv ("GDK_SCALE");
|
||||||
if (scale)
|
if (scale && pixbuf)
|
||||||
{
|
{
|
||||||
iscale = atoi (scale);
|
iscale = atoi (scale);
|
||||||
if (iscale > 0)
|
if (iscale > 0)
|
||||||
@@ -195,26 +207,26 @@ pixmaps_init (void)
|
|||||||
{
|
{
|
||||||
zoitechat_register_resource();
|
zoitechat_register_resource();
|
||||||
|
|
||||||
pix_ulist_voice = load_pixmap ("ulist_voice");
|
pix_ulist_voice = load_pixmap (ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_VOICE);
|
||||||
pix_ulist_halfop = load_pixmap ("ulist_halfop");
|
pix_ulist_halfop = load_pixmap (ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_HALFOP);
|
||||||
pix_ulist_op = load_pixmap ("ulist_op");
|
pix_ulist_op = load_pixmap (ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_OP);
|
||||||
pix_ulist_owner = load_pixmap ("ulist_owner");
|
pix_ulist_owner = load_pixmap (ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_OWNER);
|
||||||
pix_ulist_founder = load_pixmap ("ulist_founder");
|
pix_ulist_founder = load_pixmap (ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_FOUNDER);
|
||||||
pix_ulist_netop = load_pixmap ("ulist_netop");
|
pix_ulist_netop = load_pixmap (ICON_RESOLVER_ROLE_USERLIST_RANK, ICON_RESOLVER_USERLIST_RANK_NETOP);
|
||||||
|
|
||||||
pix_tray_normal = load_pixmap ("tray_normal");
|
pix_tray_normal = load_pixmap (ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_NORMAL);
|
||||||
pix_tray_fileoffer = load_pixmap ("tray_fileoffer");
|
pix_tray_fileoffer = load_pixmap (ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_FILEOFFER);
|
||||||
pix_tray_highlight = load_pixmap ("tray_highlight");
|
pix_tray_highlight = load_pixmap (ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_HIGHLIGHT);
|
||||||
pix_tray_message = load_pixmap ("tray_message");
|
pix_tray_message = load_pixmap (ICON_RESOLVER_ROLE_TRAY_STATE, ICON_RESOLVER_TRAY_STATE_MESSAGE);
|
||||||
|
|
||||||
pix_tree_channel = load_pixmap ("tree_channel");
|
pix_tree_channel = load_pixmap (ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_CHANNEL);
|
||||||
pix_tree_dialog = load_pixmap ("tree_dialog");
|
pix_tree_dialog = load_pixmap (ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_DIALOG);
|
||||||
pix_tree_server = load_pixmap ("tree_server");
|
pix_tree_server = load_pixmap (ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_SERVER);
|
||||||
pix_tree_util = load_pixmap ("tree_util");
|
pix_tree_util = load_pixmap (ICON_RESOLVER_ROLE_TREE_TYPE, ICON_RESOLVER_TREE_TYPE_UTIL);
|
||||||
|
|
||||||
/* non-replaceable book pixmap */
|
/* non-replaceable book pixmap */
|
||||||
pix_book = gdk_pixbuf_new_from_resource ("/icons/book.png", NULL);
|
pix_book = gdk_pixbuf_new_from_resource ("/icons/book.png", NULL);
|
||||||
|
|
||||||
/* used in About window, tray icon and WindowManager icon. */
|
/* used in About window, tray icon and WindowManager icon. */
|
||||||
pix_zoitechat = load_pixmap ("zoitechat");
|
pix_zoitechat = gdk_pixbuf_new_from_resource ("/icons/zoitechat.png", NULL);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -82,9 +82,10 @@
|
|||||||
|
|
||||||
<FontConfig Include="$(DepsRoot)\etc\fonts\*" />
|
<FontConfig Include="$(DepsRoot)\etc\fonts\*" />
|
||||||
<Share Include="share\**\*" />
|
<Share Include="share\**\*" />
|
||||||
<ZoiteChatMenuIcons Include="..\..\data\icons\menu\**\*" />
|
|
||||||
<Locale Include="$(ZoiteChatBin)locale\**\*;$(DepsRoot)\share\locale\**\*" />
|
<Locale Include="$(ZoiteChatBin)locale\**\*;$(DepsRoot)\share\locale\**\*" />
|
||||||
<MSWindowsTheme Include="$(DepsRoot)\share\themes\MS-Windows\**\*" />
|
<MSWindowsTheme Include="$(DepsRoot)\share\themes\MS-Windows\**\*" />
|
||||||
|
<HicolorIcons Include="$(DepsRoot)\share\icons\hicolor\index.theme" />
|
||||||
|
<HicolorIcons Include="$(DepsRoot)\share\icons\hicolor\**\*.*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<Copy SourceFiles="@(None)" DestinationFolder="$(ZoiteChatRel)" />
|
<Copy SourceFiles="@(None)" DestinationFolder="$(ZoiteChatRel)" />
|
||||||
@@ -95,12 +96,12 @@
|
|||||||
<Copy SourceFiles="@(GdkPixbufLoaderCache)" DestinationFiles="@(GdkPixbufLoaderCache->'$(ZoiteChatRel)\lib\gdk-pixbuf-2.0\%(RecursiveDir)%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(GdkPixbufLoaderCache)" DestinationFiles="@(GdkPixbufLoaderCache->'$(ZoiteChatRel)\lib\gdk-pixbuf-2.0\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||||
<Copy SourceFiles="@(GSettingsSchemas)" DestinationFiles="@(GSettingsSchemas->'$(ZoiteChatRel)\share\glib-2.0\schemas\%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(GSettingsSchemas)" DestinationFiles="@(GSettingsSchemas->'$(ZoiteChatRel)\share\glib-2.0\schemas\%(Filename)%(Extension)')" />
|
||||||
<Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(ZoiteChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(Share)" DestinationFiles="@(Share->'$(ZoiteChatRel)\share\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||||
<Copy SourceFiles="@(ZoiteChatMenuIcons)" DestinationFiles="@(ZoiteChatMenuIcons->'$(ZoiteChatRel)\share\icons\menu\%(RecursiveDir)%(Filename)%(Extension)')" />
|
|
||||||
<Copy SourceFiles="..\..\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat" />
|
<Copy SourceFiles="..\..\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\zoitechat" />
|
||||||
<Copy SourceFiles="$(WinSparklePath)\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\WinSparkle" />
|
<Copy SourceFiles="$(WinSparklePath)\COPYING" DestinationFolder="$(ZoiteChatRel)\share\doc\WinSparkle" />
|
||||||
<Copy SourceFiles="@(EnchantProviders)" DestinationFolder="$(ZoiteChatRel)\lib\enchant" />
|
<Copy SourceFiles="@(EnchantProviders)" DestinationFolder="$(ZoiteChatRel)\lib\enchant" />
|
||||||
<Copy SourceFiles="@(Locale)" DestinationFiles="@(Locale->'$(ZoiteChatRel)\share\locale\%(RecursiveDir)%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(Locale)" DestinationFiles="@(Locale->'$(ZoiteChatRel)\share\locale\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||||
<Copy SourceFiles="@(MSWindowsTheme)" DestinationFiles="@(MSWindowsTheme->'$(ZoiteChatRel)\share\themes\MS-Windows\%(RecursiveDir)%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(MSWindowsTheme)" DestinationFiles="@(MSWindowsTheme->'$(ZoiteChatRel)\share\themes\MS-Windows\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||||
|
<Copy SourceFiles="@(HicolorIcons)" DestinationFiles="@(HicolorIcons->'$(ZoiteChatRel)\share\icons\hicolor\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||||
<Copy SourceFiles="@(LuaShare)" DestinationFiles="@(LuaShare->'$(ZoiteChatRel)\share\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(LuaShare)" DestinationFiles="@(LuaShare->'$(ZoiteChatRel)\share\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||||
<Copy SourceFiles="@(LuaLib)" DestinationFiles="@(LuaLib->'$(ZoiteChatRel)\lib\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(LuaLib)" DestinationFiles="@(LuaLib->'$(ZoiteChatRel)\lib\lua\%(RecursiveDir)%(Filename)%(Extension)')" />
|
||||||
<Copy SourceFiles="@(Typelib)" DestinationFiles="@(Typelib->'$(ZoiteChatRel)\lib\girepository-1.0\%(Filename)%(Extension)')" />
|
<Copy SourceFiles="@(Typelib)" DestinationFiles="@(Typelib->'$(ZoiteChatRel)\lib\girepository-1.0\%(Filename)%(Extension)')" />
|
||||||
|
|||||||
@@ -101,9 +101,9 @@ Source: "cert.pem"; DestDir: "{app}"; Flags: ignoreversion; Components: libs
|
|||||||
Source: "share\xml\*"; DestDir: "{app}\share\xml"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
Source: "share\xml\*"; DestDir: "{app}\share\xml"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
||||||
Source: "share\doc\zoitechat\*"; DestDir: "{app}\share\doc\zoitechat"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
Source: "share\doc\zoitechat\*"; DestDir: "{app}\share\doc\zoitechat"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
||||||
Source: "share\doc\WinSparkle\*"; DestDir: "{app}\share\doc\WinSparkle"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
Source: "share\doc\WinSparkle\*"; DestDir: "{app}\share\doc\WinSparkle"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
||||||
Source: "share\icons\menu\*"; DestDir: "{app}\share\icons\menu"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
|
||||||
Source: "share\themes\MS-Windows\*"; DestDir: "{app}\share\themes\MS-Windows"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
|
Source: "share\themes\MS-Windows\*"; DestDir: "{app}\share\themes\MS-Windows"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
|
||||||
Source: "share\glib-2.0\schemas\*"; DestDir: "{app}\share\glib-2.0\schemas"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
|
Source: "share\glib-2.0\schemas\*"; DestDir: "{app}\share\glib-2.0\schemas"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
|
||||||
|
Source: "share\icons\hicolor\*"; DestDir: "{app}\share\icons\hicolor"; Flags: ignoreversion createallsubdirs recursesubdirs skipifsourcedoesntexist; Components: libs
|
||||||
Source: "share\locale\*"; DestDir: "{app}\share\locale"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: translations
|
Source: "share\locale\*"; DestDir: "{app}\share\locale"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: translations
|
||||||
Source: "etc\fonts\*"; DestDir: "{app}\etc\fonts"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
Source: "etc\fonts\*"; DestDir: "{app}\etc\fonts"; Flags: ignoreversion createallsubdirs recursesubdirs; Components: libs
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user