implement theme saving
2007-06-24 Jens Granseuer <jensgr@gmx.net> * Makefile.am: * appearance-themes.c: (theme_selection_changed_cb), (theme_save_cb), (themes_init), (themes_shutdown): * appearance.glade: * appearance.h: * theme-save.c: * theme-save.h: * theme-util.h: implement theme saving svn path=/trunk/; revision=7771
This commit is contained in:
parent
4dd7379dbf
commit
122df3a8d0
8 changed files with 646 additions and 2 deletions
|
@ -1,3 +1,14 @@
|
|||
2007-06-24 Jens Granseuer <jensgr@gmx.net>
|
||||
|
||||
* Makefile.am:
|
||||
* appearance-themes.c: (theme_selection_changed_cb),
|
||||
(theme_save_cb), (themes_init), (themes_shutdown):
|
||||
* appearance.glade:
|
||||
* appearance.h:
|
||||
* theme-save.c:
|
||||
* theme-save.h:
|
||||
* theme-util.h: implement theme saving
|
||||
|
||||
2007-06-23 Jens Granseuer <jensgr@gmx.net>
|
||||
|
||||
* appearance-style.c: rearranged functions (no code changes)
|
||||
|
|
|
@ -26,6 +26,8 @@ gnome_appearance_properties_SOURCES = \
|
|||
gnome-wp-xml.h \
|
||||
theme-installer.c \
|
||||
theme-installer.h \
|
||||
theme-save.c \
|
||||
theme-save.h \
|
||||
theme-util.c \
|
||||
theme-util.h \
|
||||
wp-cellrenderer.c \
|
||||
|
|
|
@ -320,6 +320,7 @@ theme_selection_changed_cb (GtkWidget *icon_view, AppearanceData *data)
|
|||
{
|
||||
GList *selection;
|
||||
GnomeThemeMetaInfo *theme = NULL;
|
||||
gboolean is_custom = FALSE;
|
||||
|
||||
selection = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (icon_view));
|
||||
|
||||
|
@ -332,7 +333,9 @@ theme_selection_changed_cb (GtkWidget *icon_view, AppearanceData *data)
|
|||
gtk_tree_model_get_iter (model, &iter, selection->data);
|
||||
gtk_tree_model_get (model, &iter, COL_NAME, &name, -1);
|
||||
|
||||
if (!strcmp (name, CUSTOM_THEME_NAME))
|
||||
is_custom = !strcmp (name, CUSTOM_THEME_NAME);
|
||||
|
||||
if (is_custom)
|
||||
theme = data->theme_custom;
|
||||
else
|
||||
theme = gnome_theme_meta_info_find (name);
|
||||
|
@ -347,6 +350,7 @@ theme_selection_changed_cb (GtkWidget *icon_view, AppearanceData *data)
|
|||
|
||||
gtk_widget_set_sensitive (glade_xml_get_widget (data->xml, "theme_delete"),
|
||||
gnome_theme_is_writable (theme, GNOME_THEME_TYPE_METATHEME));
|
||||
gtk_widget_set_sensitive (glade_xml_get_widget (data->xml, "theme_save"), is_custom);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -364,6 +368,12 @@ theme_custom_cb (GtkWidget *button, AppearanceData *data)
|
|||
gtk_widget_show_all (w);
|
||||
}
|
||||
|
||||
static void
|
||||
theme_save_cb (GtkWidget *button, AppearanceData *data)
|
||||
{
|
||||
theme_save_dialog_run (data->theme_custom, data);
|
||||
}
|
||||
|
||||
static void
|
||||
theme_install_cb (GtkWidget *button, AppearanceData *data)
|
||||
{
|
||||
|
@ -494,6 +504,7 @@ themes_init (AppearanceData *data)
|
|||
gnome_wm_manager_init ();
|
||||
|
||||
data->theme_queue = NULL;
|
||||
data->theme_save_dialog = NULL;
|
||||
data->theme_custom = gnome_theme_meta_info_new ();
|
||||
data->theme_icon = gdk_pixbuf_new_from_file (GNOMECC_PIXMAP_DIR "/theme-thumbnailing.png", NULL);
|
||||
data->theme_store = theme_store =
|
||||
|
@ -553,6 +564,7 @@ themes_init (AppearanceData *data)
|
|||
|
||||
/* connect button signals */
|
||||
g_signal_connect (w, "clicked", (GCallback) theme_install_cb, data);
|
||||
g_signal_connect (glade_xml_get_widget (data->xml, "theme_save"), "clicked", (GCallback) theme_save_cb, data);
|
||||
g_signal_connect (glade_xml_get_widget (data->xml, "theme_custom"), "clicked", (GCallback) theme_custom_cb, data);
|
||||
g_signal_connect (del_button, "clicked", (GCallback) theme_delete_cb, data);
|
||||
|
||||
|
@ -571,4 +583,6 @@ themes_shutdown (AppearanceData *data)
|
|||
|
||||
if (data->theme_icon)
|
||||
g_object_unref (data->theme_icon);
|
||||
if (data->theme_save_dialog)
|
||||
gtk_widget_destroy (data->theme_save_dialog);
|
||||
}
|
||||
|
|
|
@ -679,6 +679,19 @@
|
|||
<property name="position">1</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="theme_save">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property>
|
||||
<property name="label">gtk-save-as</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="sensitive">False</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
<child>
|
||||
<widget class="GtkButton" id="theme_custom">
|
||||
<property name="visible">True</property>
|
||||
|
@ -688,7 +701,7 @@
|
|||
<property name="use_underline">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="position">2</property>
|
||||
<property name="position">3</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
|
@ -2369,4 +2382,223 @@ Text only</property>
|
|||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<widget class="GtkDialog" id="theme_save_dialog">
|
||||
<property name="border_width">6</property>
|
||||
<property name="title" translatable="yes">Save Theme As...</property>
|
||||
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||
<property name="modal">True</property>
|
||||
<property name="resizable">True</property>
|
||||
<property name="destroy_with_parent">False</property>
|
||||
<property name="decorated">True</property>
|
||||
<property name="skip_taskbar_hint">False</property>
|
||||
<property name="skip_pager_hint">False</property>
|
||||
<property name="type_hint">GDK_WINDOW_TYPE_HINT_DIALOG</property>
|
||||
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||
<property name="focus_on_map">True</property>
|
||||
<property name="urgency_hint">False</property>
|
||||
<property name="has_separator">False</property>
|
||||
|
||||
<child internal-child="vbox">
|
||||
<widget class="GtkVBox" id="dialog-vbox3">
|
||||
<property name="visible">True</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="spacing">2</property>
|
||||
|
||||
<child internal-child="action_area">
|
||||
<widget class="GtkHButtonBox" id="dialog-action_area3">
|
||||
<property name="visible">True</property>
|
||||
<property name="layout_style">GTK_BUTTONBOX_END</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="save_dialog_cancel_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-cancel</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-6</property>
|
||||
</widget>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkButton" id="save_dialog_save_button">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_default">True</property>
|
||||
<property name="has_default">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label">gtk-save</property>
|
||||
<property name="use_stock">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="response_id">-5</property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">False</property>
|
||||
<property name="fill">True</property>
|
||||
<property name="pack_type">GTK_PACK_END</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTable" id="table3">
|
||||
<property name="border_width">6</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="n_rows">3</property>
|
||||
<property name="n_columns">2</property>
|
||||
<property name="homogeneous">False</property>
|
||||
<property name="row_spacing">6</property>
|
||||
<property name="column_spacing">12</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkEntry" id="save_dialog_entry">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="visibility">True</property>
|
||||
<property name="max_length">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
<property name="has_frame">True</property>
|
||||
<property name="activates_default">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label49">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Name:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0.5</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="mnemonic_widget">save_dialog_entry</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">0</property>
|
||||
<property name="bottom_attach">1</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options">fill</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkScrolledWindow" id="scrolledwindow4">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="hscrollbar_policy">GTK_POLICY_NEVER</property>
|
||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||
<property name="shadow_type">GTK_SHADOW_IN</property>
|
||||
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||
|
||||
<child>
|
||||
<widget class="GtkTextView" id="save_dialog_textview">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="editable">True</property>
|
||||
<property name="overwrite">False</property>
|
||||
<property name="accepts_tab">False</property>
|
||||
<property name="justification">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap_mode">GTK_WRAP_WORD</property>
|
||||
<property name="cursor_visible">True</property>
|
||||
<property name="pixels_above_lines">0</property>
|
||||
<property name="pixels_below_lines">0</property>
|
||||
<property name="pixels_inside_wrap">0</property>
|
||||
<property name="left_margin">0</property>
|
||||
<property name="right_margin">0</property>
|
||||
<property name="indent">0</property>
|
||||
<property name="text" translatable="yes"></property>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkLabel" id="label50">
|
||||
<property name="visible">True</property>
|
||||
<property name="label" translatable="yes">_Description:</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="use_markup">False</property>
|
||||
<property name="justify">GTK_JUSTIFY_LEFT</property>
|
||||
<property name="wrap">False</property>
|
||||
<property name="selectable">False</property>
|
||||
<property name="xalign">0</property>
|
||||
<property name="yalign">0</property>
|
||||
<property name="xpad">0</property>
|
||||
<property name="ypad">0</property>
|
||||
<property name="mnemonic_widget">scrolledwindow4</property>
|
||||
<property name="ellipsize">PANGO_ELLIPSIZE_NONE</property>
|
||||
<property name="width_chars">-1</property>
|
||||
<property name="single_line_mode">False</property>
|
||||
<property name="angle">0</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">0</property>
|
||||
<property name="right_attach">1</property>
|
||||
<property name="top_attach">1</property>
|
||||
<property name="bottom_attach">2</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options">fill</property>
|
||||
</packing>
|
||||
</child>
|
||||
|
||||
<child>
|
||||
<widget class="GtkCheckButton" id="save_background_checkbutton">
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="label" translatable="yes">Save _Background Image</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="relief">GTK_RELIEF_NORMAL</property>
|
||||
<property name="focus_on_click">True</property>
|
||||
<property name="active">False</property>
|
||||
<property name="inconsistent">False</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="left_attach">1</property>
|
||||
<property name="right_attach">2</property>
|
||||
<property name="top_attach">2</property>
|
||||
<property name="bottom_attach">3</property>
|
||||
<property name="x_options">fill</property>
|
||||
<property name="y_options"></property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
<packing>
|
||||
<property name="padding">0</property>
|
||||
<property name="expand">True</property>
|
||||
<property name="fill">True</property>
|
||||
</packing>
|
||||
</child>
|
||||
</widget>
|
||||
</child>
|
||||
</widget>
|
||||
</glade-interface>
|
||||
|
|
|
@ -56,4 +56,5 @@ typedef struct {
|
|||
GSList *theme_queue;
|
||||
GnomeThemeMetaInfo *theme_custom;
|
||||
GdkPixbuf *theme_icon;
|
||||
GtkWidget *theme_save_dialog;
|
||||
} AppearanceData;
|
||||
|
|
361
capplets/appearance/theme-save.c
Normal file
361
capplets/appearance/theme-save.c
Normal file
|
@ -0,0 +1,361 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Thomas Wood <thos@gnome.org>
|
||||
* Jens Granseuer <jensgr@gmx.net>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#include "appearance.h"
|
||||
|
||||
#include <libgnomevfs/gnome-vfs-ops.h>
|
||||
|
||||
#include "theme-save.h"
|
||||
#include "theme-util.h"
|
||||
#include "capplet-util.h"
|
||||
|
||||
static GQuark error_quark;
|
||||
enum {
|
||||
INVALID_THEME_NAME
|
||||
};
|
||||
|
||||
/* taken from gnome-desktop-item.c */
|
||||
static gchar *
|
||||
escape_string_and_dup (const gchar *s)
|
||||
{
|
||||
gchar *return_value, *p;
|
||||
const gchar *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 = (gchar *) 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;
|
||||
gboolean retval = TRUE;
|
||||
|
||||
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);
|
||||
g_free (theme_name_dir);
|
||||
uri = gnome_vfs_uri_new (dir);
|
||||
g_free (dir);
|
||||
|
||||
if (gnome_vfs_uri_exists (uri)) {
|
||||
GtkDialog *dialog;
|
||||
GtkWidget *button;
|
||||
gint response;
|
||||
|
||||
dialog = (GtkDialog *) gtk_message_dialog_new (NULL,
|
||||
GTK_DIALOG_MODAL,
|
||||
GTK_MESSAGE_QUESTION,
|
||||
GTK_BUTTONS_CANCEL,
|
||||
_("The theme already exists. Would you like to replace it?"));
|
||||
button = gtk_dialog_add_button (dialog, _("_Overwrite"), GTK_RESPONSE_ACCEPT);
|
||||
gtk_button_set_image (GTK_BUTTON (button),
|
||||
gtk_image_new_from_stock (GTK_STOCK_SAVE, GTK_ICON_SIZE_BUTTON));
|
||||
response = gtk_dialog_run (dialog);
|
||||
gtk_widget_destroy (GTK_WIDGET (dialog));
|
||||
retval = (response != GTK_RESPONSE_CANCEL);
|
||||
}
|
||||
|
||||
gnome_vfs_uri_unref (uri);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
write_theme_to_disk (GnomeThemeMetaInfo *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;
|
||||
const gchar *theme_header =
|
||||
"[Desktop Entry]\n"
|
||||
"Name=%s\n"
|
||||
"Type=X-GNOME-Metatheme\n"
|
||||
"Comment=%s\n"
|
||||
"Encoding=UTF-8\n"
|
||||
"\n"
|
||||
"[X-GNOME-Metatheme]\n"
|
||||
"GtkTheme=%s\n"
|
||||
"MetacityTheme=%s\n"
|
||||
"IconTheme=%s\n";
|
||||
|
||||
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,
|
||||
theme_info->gtk_theme_name,
|
||||
theme_info->metacity_theme_name,
|
||||
theme_info->icon_theme_name);
|
||||
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
||||
g_free (str);
|
||||
|
||||
if (theme_info->gtk_color_scheme) {
|
||||
gchar *a, *tmp;
|
||||
tmp = g_strdup (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);
|
||||
}
|
||||
|
||||
if (save_background) {
|
||||
client = gconf_client_get_default ();
|
||||
current_background = gconf_client_get_string (client, BACKGROUND_KEY, NULL);
|
||||
|
||||
if (current_background != NULL) {
|
||||
str = g_strdup_printf ("BackgroundImage=%s\n", current_background);
|
||||
|
||||
gnome_vfs_write (handle, str, strlen (str), &bytes_written);
|
||||
|
||||
g_free (current_background);
|
||||
g_free (str);
|
||||
}
|
||||
g_object_unref (client);
|
||||
}
|
||||
|
||||
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 *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 (theme_info, theme_name, theme_description, save_background, error))
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
save_dialog_response (GtkWidget *save_dialog,
|
||||
gint response_id,
|
||||
AppearanceData *data)
|
||||
{
|
||||
if (response_id == GTK_RESPONSE_OK) {
|
||||
GtkWidget *entry;
|
||||
GtkWidget *text_view;
|
||||
GtkTextBuffer *buffer;
|
||||
GtkTextIter start_iter;
|
||||
GtkTextIter end_iter;
|
||||
gchar *buffer_text;
|
||||
GnomeThemeMetaInfo *theme_info;
|
||||
gchar *theme_description = NULL;
|
||||
gchar *theme_name = NULL;
|
||||
gboolean save_background;
|
||||
GError *error = NULL;
|
||||
|
||||
entry = glade_xml_get_widget (data->xml, "save_dialog_entry");
|
||||
theme_name = escape_string_and_dup (gtk_entry_get_text (GTK_ENTRY (entry)));
|
||||
|
||||
text_view = glade_xml_get_widget (data->xml, "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);
|
||||
theme_info = (GnomeThemeMetaInfo *) g_object_get_data (G_OBJECT (save_dialog), "meta-theme-info");
|
||||
save_background = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (
|
||||
glade_xml_get_widget (data->xml, "save_background_checkbutton")));
|
||||
|
||||
save_theme_to_disk (theme_info, theme_name, theme_description, save_background, &error);
|
||||
|
||||
g_free (theme_name);
|
||||
g_free (theme_description);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
gtk_widget_hide (save_dialog);
|
||||
}
|
||||
|
||||
static void
|
||||
entry_text_changed (GtkEditable *editable,
|
||||
GladeXML *dialog)
|
||||
{
|
||||
const gchar *text;
|
||||
|
||||
text = gtk_entry_get_text (GTK_ENTRY (editable));
|
||||
gtk_widget_set_sensitive (glade_xml_get_widget (dialog, "save_dialog_save_button"),
|
||||
text != NULL && text[0] != '\000');
|
||||
}
|
||||
|
||||
void
|
||||
theme_save_dialog_run (GnomeThemeMetaInfo *theme_info,
|
||||
AppearanceData *data)
|
||||
{
|
||||
GtkWidget *entry;
|
||||
GtkWidget *text_view;
|
||||
GtkTextBuffer *text_buffer;
|
||||
|
||||
entry = glade_xml_get_widget (data->xml, "save_dialog_entry");
|
||||
text_view = glade_xml_get_widget (data->xml, "save_dialog_textview");
|
||||
|
||||
if (data->theme_save_dialog == NULL) {
|
||||
data->theme_save_dialog = glade_xml_get_widget (data->xml, "theme_save_dialog");
|
||||
|
||||
g_signal_connect (data->theme_save_dialog, "response", (GCallback) save_dialog_response, data);
|
||||
g_signal_connect (data->theme_save_dialog, "delete-event", (GCallback) gtk_true, NULL);
|
||||
g_signal_connect (entry, "changed", (GCallback) entry_text_changed, data->xml);
|
||||
|
||||
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), data->xml);
|
||||
gtk_widget_grab_focus (entry);
|
||||
|
||||
text_buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (text_view));
|
||||
gtk_text_buffer_set_text (text_buffer, "", 0);
|
||||
g_object_set_data (G_OBJECT (data->theme_save_dialog), "meta-theme-info", theme_info);
|
||||
gtk_window_set_transient_for (GTK_WINDOW (data->theme_save_dialog),
|
||||
GTK_WINDOW (glade_xml_get_widget (data->xml, "appearance_window")));
|
||||
gtk_widget_show (data->theme_save_dialog);
|
||||
}
|
22
capplets/appearance/theme-save.h
Normal file
22
capplets/appearance/theme-save.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
/*
|
||||
* Copyright (C) 2007 The GNOME Foundation
|
||||
* Written by Jens Granseuer <jensgr@gmx.net>
|
||||
* All Rights Reserved
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
void theme_save_dialog_run (GnomeThemeMetaInfo *theme_info,
|
||||
AppearanceData *data);
|
|
@ -24,6 +24,7 @@
|
|||
#define COLOR_SCHEME_KEY "/desktop/gnome/interface/gtk_color_scheme"
|
||||
#define CURSOR_THEME_KEY "/desktop/gnome/peripherals/mouse/cursor_theme"
|
||||
#define LOCKDOWN_KEY "/desktop/gnome/lockdown/disable_theme_settings"
|
||||
#define BACKGROUND_KEY "/desktop/gnome/background/picture_filename"
|
||||
|
||||
enum {
|
||||
COL_THUMBNAIL,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue