mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-14 01:30:19 +00:00
feat: centralize theming in theme-manager (palette/tokens, CSS, dark-mode, setup UI), add tests + win32/meson wiring
This commit is contained in:
@@ -258,12 +258,13 @@ int
|
||||
cfg_get_color (char *cfg, char *var, guint16 *r, guint16 *g, guint16 *b)
|
||||
{
|
||||
char str[128];
|
||||
int matched;
|
||||
|
||||
if (!cfg_get_str (cfg, var, str, sizeof (str)))
|
||||
return 0;
|
||||
|
||||
sscanf (str, "%04hx %04hx %04hx", r, g, b);
|
||||
return 1;
|
||||
matched = sscanf (str, "%04hx %04hx %04hx", r, g, b);
|
||||
return matched == 3;
|
||||
}
|
||||
|
||||
int
|
||||
|
||||
@@ -45,6 +45,7 @@
|
||||
<ClInclude Include="zoitechat-plugin.h" />
|
||||
<ClInclude Include="zoitechat.h" />
|
||||
<ClInclude Include="zoitechatc.h" />
|
||||
<ClInclude Include="theme-service.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="cfgfiles.c" />
|
||||
@@ -75,6 +76,7 @@
|
||||
<ClCompile Include="userlist.c" />
|
||||
<ClCompile Include="util.c" />
|
||||
<ClCompile Include="zoitechat.c" />
|
||||
<ClCompile Include="theme-service.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\win32\config.h.tt" />
|
||||
|
||||
@@ -119,6 +119,9 @@
|
||||
<ClInclude Include="sysinfo\sysinfo.h">
|
||||
<Filter>Source Files\sysinfo</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="theme-service.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="cfgfiles.c">
|
||||
@@ -202,6 +205,9 @@
|
||||
<ClCompile Include="sysinfo\win32\backend.c">
|
||||
<Filter>Source Files\sysinfo\win32</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="theme-service.c">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\..\win32\config.h.tt" />
|
||||
|
||||
@@ -3,6 +3,7 @@ common_sources = [
|
||||
'chanopt.c',
|
||||
'ctcp.c',
|
||||
'dcc.c',
|
||||
'theme-service.c',
|
||||
'zoitechat.c',
|
||||
'history.c',
|
||||
'ignore.c',
|
||||
|
||||
176
src/common/theme-service.c
Normal file
176
src/common/theme-service.c
Normal file
@@ -0,0 +1,176 @@
|
||||
#include <errno.h>
|
||||
|
||||
#include <gio/gio.h>
|
||||
#include <glib/gstdio.h>
|
||||
|
||||
#include "cfgfiles.h"
|
||||
#include "zoitechat.h"
|
||||
#include "theme-service.h"
|
||||
|
||||
static zoitechat_theme_post_apply_callback zoitechat_theme_post_apply_cb;
|
||||
|
||||
static gboolean
|
||||
zoitechat_theme_service_copy_file (const char *src, const char *dest, GError **error)
|
||||
{
|
||||
char *data = NULL;
|
||||
gsize len = 0;
|
||||
|
||||
if (!g_file_get_contents (src, &data, &len, error))
|
||||
return FALSE;
|
||||
|
||||
if (!g_file_set_contents (dest, data, len, error))
|
||||
{
|
||||
g_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *
|
||||
zoitechat_theme_service_get_themes_dir (void)
|
||||
{
|
||||
return g_build_filename (get_xdir (), "themes", NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
zoitechat_theme_service_validate (const char *theme_name,
|
||||
char **colors_src,
|
||||
char **events_src,
|
||||
GError **error)
|
||||
{
|
||||
char *themes_dir;
|
||||
char *theme_dir;
|
||||
|
||||
if (!theme_name || !*theme_name)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
||||
_("No theme name specified."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
themes_dir = zoitechat_theme_service_get_themes_dir ();
|
||||
theme_dir = g_build_filename (themes_dir, theme_name, NULL);
|
||||
g_free (themes_dir);
|
||||
|
||||
*colors_src = g_build_filename (theme_dir, "colors.conf", NULL);
|
||||
*events_src = g_build_filename (theme_dir, "pevents.conf", NULL);
|
||||
|
||||
if (!g_file_test (*colors_src, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
_("This theme is missing a colors.conf file."));
|
||||
g_free (*events_src);
|
||||
g_free (*colors_src);
|
||||
*events_src = NULL;
|
||||
*colors_src = NULL;
|
||||
g_free (theme_dir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (theme_dir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
gboolean
|
||||
zoitechat_theme_service_apply (const char *theme_name, GError **error)
|
||||
{
|
||||
char *colors_src = NULL;
|
||||
char *colors_dest = NULL;
|
||||
char *events_src = NULL;
|
||||
char *events_dest = NULL;
|
||||
gboolean ok = FALSE;
|
||||
|
||||
if (!zoitechat_theme_service_validate (theme_name, &colors_src, &events_src, error))
|
||||
return FALSE;
|
||||
|
||||
colors_dest = g_build_filename (get_xdir (), "colors.conf", NULL);
|
||||
events_dest = g_build_filename (get_xdir (), "pevents.conf", NULL);
|
||||
|
||||
if (!zoitechat_theme_service_copy_file (colors_src, colors_dest, error))
|
||||
goto cleanup;
|
||||
|
||||
if (g_file_test (events_src, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
if (!zoitechat_theme_service_copy_file (events_src, events_dest, error))
|
||||
goto cleanup;
|
||||
}
|
||||
else if (g_file_test (events_dest, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
if (g_unlink (events_dest) != 0)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
|
||||
_("Failed to remove existing event settings."));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
zoitechat_theme_service_run_post_apply_callback ();
|
||||
ok = TRUE;
|
||||
|
||||
cleanup:
|
||||
g_free (events_dest);
|
||||
g_free (events_src);
|
||||
g_free (colors_dest);
|
||||
g_free (colors_src);
|
||||
return ok;
|
||||
}
|
||||
|
||||
GStrv
|
||||
zoitechat_theme_service_discover_themes (void)
|
||||
{
|
||||
char *themes_dir;
|
||||
GDir *dir;
|
||||
const char *name;
|
||||
GPtrArray *themes;
|
||||
GStrv result;
|
||||
|
||||
themes_dir = zoitechat_theme_service_get_themes_dir ();
|
||||
if (!g_file_test (themes_dir, G_FILE_TEST_IS_DIR))
|
||||
g_mkdir_with_parents (themes_dir, 0700);
|
||||
|
||||
themes = g_ptr_array_new_with_free_func (g_free);
|
||||
dir = g_dir_open (themes_dir, 0, NULL);
|
||||
if (dir)
|
||||
{
|
||||
while ((name = g_dir_read_name (dir)))
|
||||
{
|
||||
char *theme_dir = g_build_filename (themes_dir, name, NULL);
|
||||
char *colors_path;
|
||||
|
||||
if (!g_file_test (theme_dir, G_FILE_TEST_IS_DIR))
|
||||
{
|
||||
g_free (theme_dir);
|
||||
continue;
|
||||
}
|
||||
|
||||
colors_path = g_build_filename (theme_dir, "colors.conf", NULL);
|
||||
if (g_file_test (colors_path, G_FILE_TEST_IS_REGULAR))
|
||||
g_ptr_array_add (themes, g_strdup (name));
|
||||
|
||||
g_free (colors_path);
|
||||
g_free (theme_dir);
|
||||
}
|
||||
g_dir_close (dir);
|
||||
}
|
||||
|
||||
g_ptr_array_sort (themes, (GCompareFunc) g_strcmp0);
|
||||
g_ptr_array_add (themes, NULL);
|
||||
result = (GStrv) g_ptr_array_free (themes, FALSE);
|
||||
g_free (themes_dir);
|
||||
return result;
|
||||
}
|
||||
|
||||
void
|
||||
zoitechat_theme_service_set_post_apply_callback (zoitechat_theme_post_apply_callback callback)
|
||||
{
|
||||
zoitechat_theme_post_apply_cb = callback;
|
||||
}
|
||||
|
||||
void
|
||||
zoitechat_theme_service_run_post_apply_callback (void)
|
||||
{
|
||||
if (zoitechat_theme_post_apply_cb)
|
||||
zoitechat_theme_post_apply_cb ();
|
||||
}
|
||||
12
src/common/theme-service.h
Normal file
12
src/common/theme-service.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef ZOITECHAT_THEME_SERVICE_H
|
||||
#define ZOITECHAT_THEME_SERVICE_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
char *zoitechat_theme_service_get_themes_dir (void);
|
||||
GStrv zoitechat_theme_service_discover_themes (void);
|
||||
gboolean zoitechat_theme_service_apply (const char *theme_name, GError **error);
|
||||
void zoitechat_theme_service_set_post_apply_callback (void (*callback) (void));
|
||||
void zoitechat_theme_service_run_post_apply_callback (void);
|
||||
|
||||
#endif
|
||||
@@ -54,6 +54,7 @@
|
||||
#include "text.h"
|
||||
#include "url.h"
|
||||
#include "zoitechatc.h"
|
||||
#include "theme-service.h"
|
||||
|
||||
#if ! GLIB_CHECK_VERSION (2, 36, 0)
|
||||
#include <glib-object.h> /* for g_type_init() */
|
||||
@@ -251,83 +252,22 @@ zoitechat_remote_win32 (void)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static gboolean
|
||||
zoitechat_copy_theme_file (const char *src, const char *dest, GError **error)
|
||||
void
|
||||
zoitechat_set_theme_post_apply_callback (zoitechat_theme_post_apply_callback callback)
|
||||
{
|
||||
char *data = NULL;
|
||||
gsize len = 0;
|
||||
zoitechat_theme_service_set_post_apply_callback (callback);
|
||||
}
|
||||
|
||||
if (!g_file_get_contents (src, &data, &len, error))
|
||||
return FALSE;
|
||||
|
||||
if (!g_file_set_contents (dest, data, len, error))
|
||||
{
|
||||
g_free (data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
g_free (data);
|
||||
return TRUE;
|
||||
void
|
||||
zoitechat_run_theme_post_apply_callback (void)
|
||||
{
|
||||
zoitechat_theme_service_run_post_apply_callback ();
|
||||
}
|
||||
|
||||
gboolean
|
||||
zoitechat_apply_theme (const char *theme_name, GError **error)
|
||||
{
|
||||
char *theme_dir;
|
||||
char *colors_src;
|
||||
char *colors_dest;
|
||||
char *events_src;
|
||||
char *events_dest;
|
||||
gboolean ok = FALSE;
|
||||
|
||||
if (!theme_name || !*theme_name)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
||||
_("No theme name specified."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
theme_dir = g_build_filename (get_xdir (), "themes", theme_name, NULL);
|
||||
colors_src = g_build_filename (theme_dir, "colors.conf", NULL);
|
||||
colors_dest = g_build_filename (get_xdir (), "colors.conf", NULL);
|
||||
events_src = g_build_filename (theme_dir, "pevents.conf", NULL);
|
||||
events_dest = g_build_filename (get_xdir (), "pevents.conf", NULL);
|
||||
|
||||
if (!g_file_test (colors_src, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_FOUND,
|
||||
_("This theme is missing a colors.conf file."));
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (!zoitechat_copy_theme_file (colors_src, colors_dest, error))
|
||||
goto cleanup;
|
||||
|
||||
if (g_file_test (events_src, G_FILE_TEST_IS_REGULAR))
|
||||
{
|
||||
if (!zoitechat_copy_theme_file (events_src, events_dest, error))
|
||||
goto cleanup;
|
||||
}
|
||||
else if (g_file_test (events_dest, G_FILE_TEST_EXISTS))
|
||||
{
|
||||
if (g_unlink (events_dest) != 0)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
|
||||
_("Failed to remove existing event settings."));
|
||||
goto cleanup;
|
||||
}
|
||||
}
|
||||
|
||||
ok = TRUE;
|
||||
|
||||
cleanup:
|
||||
g_free (events_dest);
|
||||
g_free (events_src);
|
||||
g_free (colors_dest);
|
||||
g_free (colors_src);
|
||||
g_free (theme_dir);
|
||||
return ok;
|
||||
return zoitechat_theme_service_apply (theme_name, error);
|
||||
}
|
||||
|
||||
gboolean
|
||||
@@ -352,7 +292,7 @@ zoitechat_import_theme (const char *path, GError **error)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
themes_dir = g_build_filename (get_xdir (), "themes", NULL);
|
||||
themes_dir = zoitechat_theme_service_get_themes_dir ();
|
||||
basename = g_path_get_basename (path);
|
||||
if (!basename || basename[0] == '\0')
|
||||
{
|
||||
@@ -825,7 +765,6 @@ irc_init (session *sess)
|
||||
{
|
||||
message = g_strdup_printf (_("Theme \"%s\" imported and applied."), basename);
|
||||
fe_message (message, FE_MSG_INFO);
|
||||
handle_command (sess, "gui apply", FALSE);
|
||||
g_free (message);
|
||||
}
|
||||
else
|
||||
@@ -877,8 +816,7 @@ irc_init (session *sess)
|
||||
{
|
||||
message = g_strdup_printf (_("Theme \"%s\" imported and applied."), basename);
|
||||
fe_message (message, FE_MSG_INFO);
|
||||
handle_command (sess, "gui apply", FALSE);
|
||||
g_free (message);
|
||||
g_free (message);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -32,6 +32,9 @@
|
||||
gboolean zoitechat_theme_path_from_arg (const char *arg, char **path_out);
|
||||
gboolean zoitechat_import_theme (const char *path, GError **error);
|
||||
gboolean zoitechat_apply_theme (const char *theme_name, GError **error);
|
||||
typedef void (*zoitechat_theme_post_apply_callback) (void);
|
||||
void zoitechat_set_theme_post_apply_callback (zoitechat_theme_post_apply_callback callback);
|
||||
void zoitechat_run_theme_post_apply_callback (void);
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef __APPLE__
|
||||
|
||||
Reference in New Issue
Block a user