mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-10 07:50:19 +00:00
theme import fixes.
This commit is contained in:
@@ -53,6 +53,33 @@ new_param_variant (const char *arg)
|
||||
return g_variant_new_tuple (args, 1);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
has_theme_argument (void)
|
||||
{
|
||||
char *theme_path = NULL;
|
||||
guint i;
|
||||
|
||||
if (arg_url && zoitechat_theme_path_from_arg (arg_url, &theme_path))
|
||||
{
|
||||
g_free (theme_path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (arg_urls)
|
||||
{
|
||||
for (i = 0; i < g_strv_length (arg_urls); i++)
|
||||
{
|
||||
if (zoitechat_theme_path_from_arg (arg_urls[i], &theme_path))
|
||||
{
|
||||
g_free (theme_path);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
void
|
||||
zoitechat_remote (void)
|
||||
/* TODO: dbus_g_connection_unref (connection) are commented because it makes
|
||||
@@ -68,12 +95,17 @@ zoitechat_remote (void)
|
||||
GError *error = NULL;
|
||||
char *command = NULL;
|
||||
guint i;
|
||||
gboolean allow_remote;
|
||||
|
||||
/* if there is nothing to do, return now. */
|
||||
if (!arg_existing || !(arg_url || arg_urls || arg_command)) {
|
||||
if (!(arg_url || arg_urls || arg_command)) {
|
||||
return;
|
||||
}
|
||||
|
||||
allow_remote = arg_existing || has_theme_argument ();
|
||||
if (!allow_remote)
|
||||
return;
|
||||
|
||||
arg_dont_autoconnect = TRUE;
|
||||
|
||||
connection = g_bus_get_sync (G_BUS_TYPE_SESSION, NULL, &error);
|
||||
|
||||
@@ -3770,6 +3770,35 @@ cmd_url (struct session *sess, char *tbuf, char *word[], char *word_eol[])
|
||||
{
|
||||
if (word[2][0])
|
||||
{
|
||||
char *theme_path = NULL;
|
||||
if (zoitechat_theme_path_from_arg (word[2], &theme_path))
|
||||
{
|
||||
GError *error = NULL;
|
||||
char *basename = g_path_get_basename (theme_path);
|
||||
char *dot = strrchr (basename, '.');
|
||||
char *message;
|
||||
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
|
||||
if (zoitechat_import_theme (theme_path, &error))
|
||||
{
|
||||
message = g_strdup_printf (_("Theme \"%s\" imported."), basename);
|
||||
fe_message (message, FE_MSG_INFO);
|
||||
g_free (message);
|
||||
}
|
||||
else
|
||||
{
|
||||
fe_message (error ? error->message : _("Failed to import theme."),
|
||||
FE_MSG_ERROR);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_free (basename);
|
||||
g_free (theme_path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
char *server_name = NULL;
|
||||
char *port = NULL;
|
||||
char *channel = NULL;
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <errno.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
@@ -107,6 +108,293 @@ struct session *current_tab;
|
||||
struct session *current_sess = 0;
|
||||
struct zoitechatprefs prefs;
|
||||
|
||||
gboolean
|
||||
zoitechat_theme_path_from_arg (const char *arg, char **path_out)
|
||||
{
|
||||
char *path = NULL;
|
||||
const char *ext;
|
||||
|
||||
if (!arg)
|
||||
return FALSE;
|
||||
|
||||
if (g_str_has_prefix (arg, "file://"))
|
||||
path = g_filename_from_uri (arg, NULL, NULL);
|
||||
else
|
||||
path = g_strdup (arg);
|
||||
|
||||
if (!path)
|
||||
return FALSE;
|
||||
|
||||
ext = strrchr (path, '.');
|
||||
if (!g_file_test (path, G_FILE_TEST_IS_REGULAR) ||
|
||||
!ext ||
|
||||
(g_ascii_strcasecmp (ext, ".zct") != 0 &&
|
||||
g_ascii_strcasecmp (ext, ".hct") != 0))
|
||||
{
|
||||
g_free (path);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (path_out)
|
||||
*path_out = path;
|
||||
else
|
||||
g_free (path);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
static gboolean
|
||||
zoitechat_has_theme_argument (void)
|
||||
{
|
||||
char *theme_path = NULL;
|
||||
guint i;
|
||||
|
||||
if (arg_url && zoitechat_theme_path_from_arg (arg_url, &theme_path))
|
||||
{
|
||||
g_free (theme_path);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
if (arg_urls)
|
||||
{
|
||||
for (i = 0; i < g_strv_length (arg_urls); i++)
|
||||
{
|
||||
if (zoitechat_theme_path_from_arg (arg_urls[i], &theme_path))
|
||||
{
|
||||
g_free (theme_path);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static HWND
|
||||
zoitechat_find_running_window (void)
|
||||
{
|
||||
HWND hwnd = FindWindowA ("ZoiteChat", NULL);
|
||||
|
||||
if (!hwnd)
|
||||
hwnd = FindWindowA ("zoitechat", NULL);
|
||||
if (!hwnd)
|
||||
hwnd = FindWindowA (NULL, "ZoiteChat");
|
||||
|
||||
return hwnd;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
zoitechat_send_command_to_existing (HWND hwnd, const char *command)
|
||||
{
|
||||
COPYDATASTRUCT copy_data;
|
||||
DWORD_PTR send_result = 0;
|
||||
|
||||
if (!hwnd || !command || !*command)
|
||||
return FALSE;
|
||||
|
||||
copy_data.dwData = 0;
|
||||
copy_data.cbData = (DWORD)strlen (command) + 1;
|
||||
copy_data.lpData = (void *)command;
|
||||
|
||||
return SendMessageTimeoutA (hwnd, WM_COPYDATA, (WPARAM)NULL,
|
||||
(LPARAM)©_data,
|
||||
SMTO_ABORTIFHUNG | SMTO_BLOCK,
|
||||
5000, &send_result) != 0;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
zoitechat_remote_win32 (void)
|
||||
{
|
||||
HWND hwnd;
|
||||
gboolean allow_remote;
|
||||
gboolean sent = FALSE;
|
||||
|
||||
allow_remote = arg_existing || zoitechat_has_theme_argument ();
|
||||
if (!allow_remote)
|
||||
return FALSE;
|
||||
|
||||
hwnd = zoitechat_find_running_window ();
|
||||
if (!hwnd)
|
||||
return FALSE;
|
||||
|
||||
if (arg_url)
|
||||
{
|
||||
char *command = g_strdup_printf ("url %s", arg_url);
|
||||
sent = zoitechat_send_command_to_existing (hwnd, command) || sent;
|
||||
g_free (command);
|
||||
}
|
||||
else if (arg_command)
|
||||
{
|
||||
sent = zoitechat_send_command_to_existing (hwnd, arg_command) || sent;
|
||||
}
|
||||
|
||||
if (arg_urls)
|
||||
{
|
||||
guint i;
|
||||
for (i = 0; i < g_strv_length (arg_urls); i++)
|
||||
{
|
||||
char *command = g_strdup_printf ("url %s", arg_urls[i]);
|
||||
sent = zoitechat_send_command_to_existing (hwnd, command) || sent;
|
||||
g_free (command);
|
||||
}
|
||||
g_strfreev (arg_urls);
|
||||
arg_urls = NULL;
|
||||
}
|
||||
|
||||
return sent;
|
||||
}
|
||||
#endif
|
||||
|
||||
gboolean
|
||||
zoitechat_import_theme (const char *path, GError **error)
|
||||
{
|
||||
char *themes_dir;
|
||||
char *basename;
|
||||
char *dot;
|
||||
char *theme_dir;
|
||||
char *argv[] = {"unzip", "-o", (char *)path, "-d", NULL, NULL};
|
||||
int status = 0;
|
||||
gboolean ok;
|
||||
#ifdef WIN32
|
||||
char *command = NULL;
|
||||
char *powershell = NULL;
|
||||
char *extractor = NULL;
|
||||
#endif
|
||||
|
||||
if (!path)
|
||||
{
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
||||
_("No theme file specified."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
themes_dir = g_build_filename (get_xdir (), "themes", NULL);
|
||||
basename = g_path_get_basename (path);
|
||||
if (!basename || basename[0] == '\0')
|
||||
{
|
||||
g_free (themes_dir);
|
||||
g_free (basename);
|
||||
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
|
||||
_("Failed to determine theme name."));
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
dot = strrchr (basename, '.');
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
|
||||
theme_dir = g_build_filename (themes_dir, basename, NULL);
|
||||
if (g_mkdir_with_parents (theme_dir, 0700) != 0)
|
||||
{
|
||||
g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
|
||||
_("Failed to create theme directory."));
|
||||
g_free (theme_dir);
|
||||
g_free (basename);
|
||||
g_free (themes_dir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
argv[4] = theme_dir;
|
||||
#ifdef WIN32
|
||||
extractor = g_find_program_in_path ("unzip");
|
||||
if (extractor)
|
||||
{
|
||||
argv[0] = extractor;
|
||||
ok = g_spawn_sync (NULL, argv, NULL, 0, NULL, NULL,
|
||||
NULL, NULL, &status, error);
|
||||
}
|
||||
else
|
||||
{
|
||||
powershell = g_find_program_in_path ("powershell.exe");
|
||||
if (!powershell)
|
||||
powershell = g_find_program_in_path ("powershell");
|
||||
|
||||
if (!powershell)
|
||||
{
|
||||
g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_NOENT,
|
||||
_("No archive extractor was found."));
|
||||
ok = FALSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
GString *escaped_path = g_string_new ("'");
|
||||
GString *escaped_dir = g_string_new ("'");
|
||||
const char *cursor;
|
||||
|
||||
for (cursor = path; *cursor != '\0'; cursor++)
|
||||
{
|
||||
if (*cursor == '\'')
|
||||
g_string_append (escaped_path, "''");
|
||||
else
|
||||
g_string_append_c (escaped_path, *cursor);
|
||||
}
|
||||
g_string_append_c (escaped_path, '\'');
|
||||
|
||||
for (cursor = theme_dir; *cursor != '\0'; cursor++)
|
||||
{
|
||||
if (*cursor == '\'')
|
||||
g_string_append (escaped_dir, "''");
|
||||
else
|
||||
g_string_append_c (escaped_dir, *cursor);
|
||||
}
|
||||
g_string_append_c (escaped_dir, '\'');
|
||||
|
||||
command = g_strdup_printf ("Expand-Archive -LiteralPath %s -DestinationPath %s -Force",
|
||||
escaped_path->str,
|
||||
escaped_dir->str);
|
||||
g_string_free (escaped_path, TRUE);
|
||||
g_string_free (escaped_dir, TRUE);
|
||||
|
||||
{
|
||||
char *ps_argv[] = {powershell, "-NoProfile", "-NonInteractive", "-Command", command, NULL};
|
||||
ok = g_spawn_sync (NULL, ps_argv, NULL, 0, NULL, NULL,
|
||||
NULL, NULL, &status, error);
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
ok = g_spawn_sync (NULL, argv, NULL, G_SPAWN_SEARCH_PATH, NULL, NULL,
|
||||
NULL, NULL, &status, error);
|
||||
#endif
|
||||
if (!ok)
|
||||
{
|
||||
#ifdef WIN32
|
||||
g_free (command);
|
||||
g_free (powershell);
|
||||
g_free (extractor);
|
||||
#endif
|
||||
g_free (theme_dir);
|
||||
g_free (basename);
|
||||
g_free (themes_dir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!g_spawn_check_exit_status (status, error))
|
||||
{
|
||||
#ifdef WIN32
|
||||
g_free (command);
|
||||
g_free (powershell);
|
||||
g_free (extractor);
|
||||
#endif
|
||||
g_free (theme_dir);
|
||||
g_free (basename);
|
||||
g_free (themes_dir);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#ifdef WIN32
|
||||
g_free (command);
|
||||
g_free (powershell);
|
||||
g_free (extractor);
|
||||
#endif
|
||||
|
||||
g_free (theme_dir);
|
||||
g_free (basename);
|
||||
g_free (themes_dir);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the priority queue of the "interesting sessions"
|
||||
* (sess_list_by_lastact).
|
||||
@@ -448,41 +736,36 @@ irc_init (session *sess)
|
||||
if (arg_url != NULL)
|
||||
{
|
||||
theme_path = NULL;
|
||||
if (g_str_has_prefix (arg_url, "file://"))
|
||||
theme_path = g_filename_from_uri (arg_url, NULL, NULL);
|
||||
else
|
||||
theme_path = g_strdup (arg_url);
|
||||
|
||||
if (theme_path != NULL)
|
||||
if (zoitechat_theme_path_from_arg (arg_url, &theme_path))
|
||||
{
|
||||
const char *ext = strrchr (theme_path, '.');
|
||||
GError *error = NULL;
|
||||
char *basename = g_path_get_basename (theme_path);
|
||||
char *dot = strrchr (basename, '.');
|
||||
char *message;
|
||||
|
||||
if (g_file_test (theme_path, G_FILE_TEST_IS_REGULAR) &&
|
||||
ext != NULL &&
|
||||
(g_ascii_strcasecmp (ext, ".zct") == 0 ||
|
||||
g_ascii_strcasecmp (ext, ".hct") == 0))
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
|
||||
if (zoitechat_import_theme (theme_path, &error))
|
||||
{
|
||||
char *themes_dir = g_build_filename (get_xdir (), "themes", NULL);
|
||||
char *basename = g_path_get_basename (theme_path);
|
||||
char *message = g_strdup_printf (_("Theme file \"%s\" opened.\n"
|
||||
"To install it, move it into:\n%s\n"
|
||||
"Then apply it from Settings → Themes."),
|
||||
basename, themes_dir);
|
||||
|
||||
g_mkdir_with_parents (themes_dir, 0700);
|
||||
message = g_strdup_printf (_("Theme \"%s\" imported."), basename);
|
||||
fe_message (message, FE_MSG_INFO);
|
||||
fe_open_url (themes_dir);
|
||||
|
||||
g_free (message);
|
||||
g_free (basename);
|
||||
g_free (themes_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = g_strdup_printf ("server %s", arg_url);
|
||||
handle_command (sess, buf, FALSE);
|
||||
g_free (buf);
|
||||
fe_message (error ? error->message : _("Failed to import theme."),
|
||||
FE_MSG_ERROR);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_free (basename);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = g_strdup_printf ("server %s", arg_url);
|
||||
handle_command (sess, buf, FALSE);
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
g_free (theme_path);
|
||||
@@ -495,41 +778,36 @@ irc_init (session *sess)
|
||||
for (i = 0; i < g_strv_length (arg_urls); i++)
|
||||
{
|
||||
theme_path = NULL;
|
||||
if (g_str_has_prefix (arg_urls[i], "file://"))
|
||||
theme_path = g_filename_from_uri (arg_urls[i], NULL, NULL);
|
||||
else
|
||||
theme_path = g_strdup (arg_urls[i]);
|
||||
|
||||
if (theme_path != NULL)
|
||||
if (zoitechat_theme_path_from_arg (arg_urls[i], &theme_path))
|
||||
{
|
||||
const char *ext = strrchr (theme_path, '.');
|
||||
GError *error = NULL;
|
||||
char *basename = g_path_get_basename (theme_path);
|
||||
char *dot = strrchr (basename, '.');
|
||||
char *message;
|
||||
|
||||
if (g_file_test (theme_path, G_FILE_TEST_IS_REGULAR) &&
|
||||
ext != NULL &&
|
||||
(g_ascii_strcasecmp (ext, ".zct") == 0 ||
|
||||
g_ascii_strcasecmp (ext, ".hct") == 0))
|
||||
if (dot)
|
||||
*dot = '\0';
|
||||
|
||||
if (zoitechat_import_theme (theme_path, &error))
|
||||
{
|
||||
char *themes_dir = g_build_filename (get_xdir (), "themes", NULL);
|
||||
char *basename = g_path_get_basename (theme_path);
|
||||
char *message = g_strdup_printf (_("Theme file \"%s\" opened.\n"
|
||||
"To install it, move it into:\n%s\n"
|
||||
"Then apply it from Settings → Themes."),
|
||||
basename, themes_dir);
|
||||
|
||||
g_mkdir_with_parents (themes_dir, 0700);
|
||||
message = g_strdup_printf (_("Theme \"%s\" imported."), basename);
|
||||
fe_message (message, FE_MSG_INFO);
|
||||
fe_open_url (themes_dir);
|
||||
|
||||
g_free (message);
|
||||
g_free (basename);
|
||||
g_free (themes_dir);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = g_strdup_printf ("%s %s", i==0? "server" : "newserver", arg_urls[i]);
|
||||
handle_command (sess, buf, FALSE);
|
||||
g_free (buf);
|
||||
fe_message (error ? error->message : _("Failed to import theme."),
|
||||
FE_MSG_ERROR);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
g_free (basename);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf = g_strdup_printf ("%s %s", i==0? "server" : "newserver", arg_urls[i]);
|
||||
handle_command (sess, buf, FALSE);
|
||||
g_free (buf);
|
||||
}
|
||||
|
||||
g_free (theme_path);
|
||||
@@ -1163,6 +1441,11 @@ main (int argc, char *argv[])
|
||||
if (ret != -1)
|
||||
return ret;
|
||||
|
||||
#ifdef WIN32
|
||||
if (zoitechat_remote_win32 ())
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
#ifdef USE_DBUS
|
||||
zoitechat_remote ();
|
||||
#endif
|
||||
|
||||
@@ -29,6 +29,9 @@
|
||||
#ifndef HEXCHAT_H
|
||||
#define HEXCHAT_H
|
||||
|
||||
gboolean zoitechat_theme_path_from_arg (const char *arg, char **path_out);
|
||||
gboolean zoitechat_import_theme (const char *path, GError **error);
|
||||
|
||||
#ifdef USE_OPENSSL
|
||||
#ifdef __APPLE__
|
||||
#define __AVAILABILITYMACROS__
|
||||
|
||||
@@ -78,6 +78,9 @@ enum
|
||||
|
||||
static void mg_create_entry (session *sess, GtkWidget *box);
|
||||
static void mg_create_search (session *sess, GtkWidget *box);
|
||||
#ifdef G_OS_WIN32
|
||||
static GdkFilterReturn mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data);
|
||||
#endif
|
||||
static void mg_link_irctab (session *sess, int focus);
|
||||
|
||||
static session_gui static_mg_gui;
|
||||
@@ -3143,6 +3146,9 @@ mg_create_topwindow (session *sess)
|
||||
{
|
||||
GtkWidget *win;
|
||||
GtkWidget *table;
|
||||
#ifdef G_OS_WIN32
|
||||
GdkWindow *parent_win;
|
||||
#endif
|
||||
|
||||
if (sess->type == SESS_DIALOG)
|
||||
win = gtkutil_window_new ("ZoiteChat", NULL,
|
||||
@@ -3218,6 +3224,11 @@ mg_create_topwindow (session *sess)
|
||||
mg_place_userlist_and_chanview (sess->gui);
|
||||
|
||||
gtk_widget_show (win);
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
parent_win = gtk_widget_get_window (win);
|
||||
gdk_window_add_filter (parent_win, mg_win32_filter, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@@ -3246,13 +3257,34 @@ mg_tabwindow_de_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data)
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
static GdkFilterReturn
|
||||
mg_time_change (GdkXEvent *xevent, GdkEvent *event, gpointer data)
|
||||
mg_win32_filter (GdkXEvent *xevent, GdkEvent *event, gpointer data)
|
||||
{
|
||||
MSG *msg = (MSG*)xevent;
|
||||
|
||||
if (!msg)
|
||||
return GDK_FILTER_CONTINUE;
|
||||
|
||||
if (msg->message == WM_TIMECHANGE)
|
||||
{
|
||||
_tzset();
|
||||
return GDK_FILTER_CONTINUE;
|
||||
}
|
||||
|
||||
if (msg->message == WM_COPYDATA)
|
||||
{
|
||||
COPYDATASTRUCT *copy_data = (COPYDATASTRUCT *)msg->lParam;
|
||||
|
||||
if (copy_data && copy_data->lpData && copy_data->cbData > 0 && current_sess)
|
||||
{
|
||||
char *command = g_strndup ((const char *)copy_data->lpData, copy_data->cbData);
|
||||
|
||||
if (command)
|
||||
{
|
||||
handle_command (current_sess, command, FALSE);
|
||||
g_free (command);
|
||||
return GDK_FILTER_REMOVE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return GDK_FILTER_CONTINUE;
|
||||
@@ -3334,7 +3366,7 @@ mg_create_tabwindow (session *sess)
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
parent_win = gtk_widget_get_window (win);
|
||||
gdk_window_add_filter (parent_win, mg_time_change, NULL);
|
||||
gdk_window_add_filter (parent_win, mg_win32_filter, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user