2007-01-19 Thomas Wood <thos@gnome.org> * gnome-theme-details.c: (update_color_scheme_tab), (color_select), (toggle_color_scheme_key): * gnome-theme-manager.c: (free_all), (load_meta_themes), (meta_theme_setup_info), (meta_theme_selection_changed), (update_themes_from_disk), (add_custom_row_to_meta_theme), (themes_equal), (update_settings_from_gconf_idle), (update_settings_from_gconf), (gtk_theme_key_changed), (setup_dialog): * gnome-theme-save.c: (write_theme_to_disk): * theme-properties.glade: - Remove seperate color scheme saving UI - Add support for gtk-color-scheme key in metatheme info 2007-01-19 Thomas Wood <thos@gnome.org> * gnome-theme-apply.c: (gnome_meta_theme_set): * gnome-theme-info.c: (gnome_theme_read_meta_theme), (gnome_theme_meta_info_new), (gnome_theme_meta_info_free), (gnome_theme_meta_info_print), (gnome_theme_meta_info_compare): * gnome-theme-info.h: Add support for saving and applying the gtk-color-scheme key svn path=/trunk/; revision=7152
361 lines
9.2 KiB
C
361 lines
9.2 KiB
C
#include "gnome-theme-info.h"
|
|
#include "gnome-theme-save.h"
|
|
#include "gnome-theme-manager.h"
|
|
#include "capplet-util.h"
|
|
#include <libgnomevfs/gnome-vfs-ops.h>
|
|
#include <gconf/gconf-client.h>
|
|
|
|
#include "gnome-theme-save-data.c"
|
|
|
|
static GQuark error_quark;
|
|
enum
|
|
{
|
|
INVALID_THEME_NAME
|
|
};
|
|
|
|
/* taken from gnome-desktop-item.c */
|
|
static char *
|
|
escape_string_and_dup (const char *s)
|
|
{
|
|
char *return_value, *p;
|
|
const char *q;
|
|
int len = 0;
|
|
|
|
if (s == NULL)
|
|
return g_strdup("");
|
|
|
|
q = s;
|
|
while (*q)
|
|
{
|
|
len++;
|
|
if (strchr ("\n\r\t\\", *q) != NULL)
|
|
len++;
|
|
q++;
|
|
}
|
|
return_value = p = (char *) g_malloc (len + 1);
|
|
do
|
|
{
|
|
switch (*s)
|
|
{
|
|
case '\t':
|
|
*p++ = '\\';
|
|
*p++ = 't';
|
|
break;
|
|
case '\n':
|
|
*p++ = '\\';
|
|
*p++ = 'n';
|
|
break;
|
|
case '\r':
|
|
*p++ = '\\';
|
|
*p++ = 'r';
|
|
break;
|
|
case '\\':
|
|
*p++ = '\\';
|
|
*p++ = '\\';
|
|
break;
|
|
default:
|
|
*p++ = *s;
|
|
}
|
|
}
|
|
while (*s++);
|
|
return return_value;
|
|
}
|
|
|
|
static gboolean
|
|
check_theme_name (const gchar *theme_name,
|
|
GError **error)
|
|
{
|
|
if (theme_name == NULL)
|
|
{
|
|
g_set_error (error,
|
|
error_quark,
|
|
INVALID_THEME_NAME,
|
|
_("Theme name must be present"));
|
|
return FALSE;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
static gchar*
|
|
str_remove_slash (const gchar *src)
|
|
{
|
|
const gchar *i;
|
|
gchar *rtn;
|
|
gint len = 0;
|
|
i = src;
|
|
|
|
while (*i)
|
|
{
|
|
if (*i != '/')
|
|
len++;
|
|
i++;
|
|
}
|
|
|
|
rtn = (gchar *) g_malloc (len + 1);
|
|
while (*src)
|
|
{
|
|
if (*src != '/')
|
|
{
|
|
*rtn = *src;
|
|
rtn++;
|
|
}
|
|
src++;
|
|
}
|
|
*rtn = '\0';
|
|
return rtn - len;
|
|
}
|
|
|
|
|
|
static gboolean
|
|
setup_directory_structure (const gchar *theme_name,
|
|
GError **error)
|
|
{
|
|
gchar *dir, *theme_name_dir;
|
|
GnomeVFSURI *uri;
|
|
|
|
theme_name_dir = str_remove_slash (theme_name);
|
|
|
|
dir = g_build_filename (g_get_home_dir (), ".themes", NULL);
|
|
uri = gnome_vfs_uri_new (dir);
|
|
if (!gnome_vfs_uri_exists (uri))
|
|
gnome_vfs_make_directory_for_uri (uri, 0775);
|
|
gnome_vfs_uri_unref (uri);
|
|
g_free (dir);
|
|
|
|
dir = g_build_filename (g_get_home_dir (), ".themes", theme_name_dir, NULL);
|
|
uri = gnome_vfs_uri_new (dir);
|
|
if (!gnome_vfs_uri_exists (uri))
|
|
gnome_vfs_make_directory_for_uri (uri, 0775);
|
|
gnome_vfs_uri_unref (uri);
|
|
g_free (dir);
|
|
|
|
dir = g_build_filename (g_get_home_dir (), ".themes", theme_name_dir, "index.theme", NULL);
|
|
uri = gnome_vfs_uri_new (dir);
|
|
|
|
if (gnome_vfs_uri_exists (uri))
|
|
{
|
|
GtkWidget *dialog;
|
|
gint response;
|
|
|
|
dialog = gtk_message_dialog_new (NULL,
|
|
GTK_DIALOG_MODAL,
|
|
GTK_MESSAGE_QUESTION,
|
|
GTK_BUTTONS_OK_CANCEL,
|
|
_("The theme already exists. Would you like to replace it?"));
|
|
response = gtk_dialog_run(GTK_DIALOG(dialog));
|
|
gtk_widget_destroy(dialog);
|
|
if (response == GTK_RESPONSE_CANCEL)
|
|
{
|
|
gnome_vfs_uri_unref (uri);
|
|
g_free (dir);
|
|
g_free (theme_name_dir);
|
|
return FALSE;
|
|
}
|
|
}
|
|
|
|
gnome_vfs_uri_unref (uri);
|
|
g_free (dir);
|
|
g_free (theme_name_dir);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
write_theme_to_disk (GnomeThemeMetaInfo *meta_theme_info,
|
|
const gchar *theme_name,
|
|
const gchar *theme_description,
|
|
gboolean save_background,
|
|
GError **error)
|
|
{
|
|
gchar *dir, *theme_name_dir;
|
|
GnomeVFSURI *uri;
|
|
GnomeVFSURI *target_uri;
|
|
GnomeVFSHandle *handle = NULL;
|
|
GnomeVFSFileSize bytes_written;
|
|
gchar *str, *current_background;
|
|
GConfClient *client;
|
|
|
|
theme_name_dir = str_remove_slash (theme_name);
|
|
dir = g_build_filename (g_get_home_dir (), ".themes", theme_name_dir, "index.theme~", NULL);
|
|
g_free (theme_name_dir);
|
|
|
|
uri = gnome_vfs_uri_new (dir);
|
|
dir [strlen (dir) - 1] = '\000';
|
|
target_uri = gnome_vfs_uri_new (dir);
|
|
g_free (dir);
|
|
gnome_vfs_create_uri (&handle, uri, GNOME_VFS_OPEN_READ | GNOME_VFS_OPEN_WRITE, FALSE, 0644);
|
|
|
|
gnome_vfs_truncate_handle (handle, 0);
|
|
|
|
/* start making the theme file */
|
|
str = g_strdup_printf (theme_header, theme_name, theme_description);
|
|
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
|
g_free (str);
|
|
|
|
str = g_strdup_printf ("GtkTheme=%s\n", meta_theme_info->gtk_theme_name);
|
|
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
|
g_free (str);
|
|
|
|
if (meta_theme_info->gtk_color_scheme)
|
|
{
|
|
gchar *a, *tmp;
|
|
tmp = g_strdup (meta_theme_info->gtk_color_scheme);
|
|
for (a = tmp; *a != '\0'; a++)
|
|
if (*a == '\n')
|
|
*a = ',';
|
|
str = g_strdup_printf ("GtkColorScheme=%s\n", tmp);
|
|
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
|
g_free (str);
|
|
g_free (tmp);
|
|
}
|
|
|
|
str = g_strdup_printf ("MetacityTheme=%s\n", meta_theme_info->metacity_theme_name);
|
|
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
|
g_free (str);
|
|
|
|
str = g_strdup_printf ("IconTheme=%s\n", meta_theme_info->icon_theme_name);
|
|
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
|
g_free (str);
|
|
|
|
if (save_background)
|
|
{
|
|
client = gconf_client_get_default ();
|
|
current_background = gconf_client_get_string (client, BACKGROUND_KEY, NULL);
|
|
str = g_strdup_printf ("BackgroundImage=%s\n", current_background);
|
|
|
|
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
|
|
|
g_object_unref (client);
|
|
g_free (current_background);
|
|
g_free (str);
|
|
}
|
|
|
|
gnome_vfs_close (handle);
|
|
|
|
|
|
gnome_vfs_move_uri (uri, target_uri, TRUE);
|
|
gnome_vfs_uri_unref (uri);
|
|
gnome_vfs_uri_unref (target_uri);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static gboolean
|
|
save_theme_to_disk (GnomeThemeMetaInfo *meta_theme_info,
|
|
const gchar *theme_name,
|
|
const gchar *theme_description,
|
|
gboolean save_background,
|
|
GError **error)
|
|
{
|
|
if (! check_theme_name (theme_name, error))
|
|
return FALSE;
|
|
|
|
if (! setup_directory_structure (theme_name, error))
|
|
return FALSE;
|
|
|
|
if (! write_theme_to_disk (meta_theme_info, theme_name, theme_description, save_background, error))
|
|
return FALSE;
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
static void
|
|
save_dialog_response (GtkWidget *save_dialog,
|
|
gint response_id,
|
|
gpointer data)
|
|
{
|
|
GnomeThemeMetaInfo *meta_theme_info;
|
|
char *theme_description = NULL;
|
|
char *theme_name = NULL;
|
|
GError *error = NULL;
|
|
|
|
if (response_id == GTK_RESPONSE_OK)
|
|
{
|
|
GladeXML *dialog;
|
|
GtkWidget *entry;
|
|
GtkWidget *text_view;
|
|
GtkTextBuffer *buffer;
|
|
GtkTextIter start_iter;
|
|
GtkTextIter end_iter;
|
|
gchar *buffer_text;
|
|
gboolean save_background;
|
|
|
|
dialog = gnome_theme_manager_get_theme_dialog ();
|
|
entry = WID ("save_dialog_entry");
|
|
theme_name = escape_string_and_dup (gtk_entry_get_text (GTK_ENTRY (entry)));
|
|
|
|
text_view = WID ("save_dialog_textview");
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
|
gtk_text_buffer_get_start_iter (buffer, &start_iter);
|
|
gtk_text_buffer_get_end_iter (buffer, &end_iter);
|
|
buffer_text = gtk_text_buffer_get_text (buffer, &start_iter, &end_iter, FALSE);
|
|
theme_description = escape_string_and_dup (buffer_text);
|
|
g_free (buffer_text);
|
|
meta_theme_info = (GnomeThemeMetaInfo *) g_object_get_data (G_OBJECT (save_dialog), "meta-theme-info");
|
|
save_background = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (WID ("save_background_checkbutton")));
|
|
if (! save_theme_to_disk (meta_theme_info, theme_name, theme_description, save_background, &error))
|
|
{
|
|
goto out;
|
|
}
|
|
}
|
|
|
|
out:
|
|
g_clear_error (&error);
|
|
gtk_widget_hide (save_dialog);
|
|
g_free (theme_name);
|
|
g_free (theme_description);
|
|
}
|
|
|
|
|
|
static void
|
|
entry_text_changed (GtkEditable *editable,
|
|
gpointer data)
|
|
{
|
|
GladeXML *dialog = (GladeXML *) data;
|
|
const gchar *text;
|
|
|
|
text = gtk_entry_get_text (GTK_ENTRY (editable));
|
|
if (text != NULL && text[0] != '\000')
|
|
gtk_widget_set_sensitive (WID ("save_dialog_save_button"), TRUE);
|
|
else
|
|
gtk_widget_set_sensitive (WID ("save_dialog_save_button"), FALSE);
|
|
}
|
|
|
|
|
|
void
|
|
gnome_theme_save_show_dialog (GtkWidget *parent,
|
|
GnomeThemeMetaInfo *meta_theme_info)
|
|
{
|
|
static GtkWidget *save_dialog = NULL;
|
|
GladeXML *dialog;
|
|
GtkWidget *entry;
|
|
GtkWidget *text_view;
|
|
GtkTextBuffer *text_buffer;
|
|
|
|
dialog = gnome_theme_manager_get_theme_dialog ();
|
|
entry = WID ("save_dialog_entry");
|
|
text_view = WID ("save_dialog_textview");
|
|
|
|
if (save_dialog == NULL)
|
|
{
|
|
save_dialog = WID ("save_dialog");
|
|
g_assert (save_dialog);
|
|
|
|
g_signal_connect (G_OBJECT (save_dialog), "response", G_CALLBACK (save_dialog_response), NULL);
|
|
g_signal_connect (G_OBJECT (save_dialog), "delete-event", G_CALLBACK (gtk_true), NULL);
|
|
g_signal_connect (G_OBJECT (entry), "changed", G_CALLBACK (entry_text_changed), dialog);
|
|
|
|
error_quark = g_quark_from_string ("gnome-theme-save");
|
|
gtk_widget_set_size_request (text_view, 300, 100);
|
|
}
|
|
|
|
gtk_entry_set_text (GTK_ENTRY (entry), "");
|
|
entry_text_changed (GTK_EDITABLE (entry), dialog);
|
|
gtk_widget_grab_focus (entry);
|
|
|
|
text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
|
gtk_text_buffer_set_text (text_buffer, "", strlen (""));
|
|
g_object_set_data (G_OBJECT (save_dialog), "meta-theme-info", meta_theme_info);
|
|
gtk_window_set_transient_for (GTK_WINDOW (save_dialog), GTK_WINDOW (parent));
|
|
gtk_widget_show (save_dialog);
|
|
}
|