gnome-control-center/capplets/theme-switcher/gnome-theme-save.c
Thomas Wood 13c68a2e1e - Remove seperate color scheme saving UI - Add support for
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
2007-01-19 01:33:26 +00:00

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);
}