Thu Jan 16 02:32:39 2003 Jonathan Blandford <jrb@gnome.org> * gnome-theme-details.c (gnome_theme_details_update_from_gconf): make sure we're initted, as this function can be run asynchronously. * gnome-theme-manager.c (gnome_meta_theme_installer_run_cb): hook up the installer. * gnome-theme-installer.c: Try to handle icon themes.
186 lines
5.5 KiB
C
186 lines
5.5 KiB
C
|
|
#include <config.h>
|
|
|
|
#include <string.h>
|
|
#include <libwindow-settings/gnome-wm-manager.h>
|
|
#include "gnome-theme-installer.h"
|
|
#include <gtk/gtk.h>
|
|
#include <gconf/gconf-client.h>
|
|
#include <glade/glade.h>
|
|
#include <libgnomevfs/gnome-vfs-async-ops.h>
|
|
#include <libgnomevfs/gnome-vfs-ops.h>
|
|
#include <libgnomevfs/gnome-vfs-utils.h>
|
|
|
|
#include "gnome-theme-info.h"
|
|
#include "capplet-util.h"
|
|
#include "activate-settings-daemon.h"
|
|
#include "gconf-property-editor.h"
|
|
#include "file-transfer-dialog.h"
|
|
#include "gnome-theme-installer.h"
|
|
|
|
|
|
static void
|
|
transfer_cancel_cb (GtkWidget *dlg, gchar *path)
|
|
{
|
|
gnome_vfs_unlink (path);
|
|
g_free (path);
|
|
gtk_widget_destroy (dlg);
|
|
}
|
|
|
|
/* this works around problems when doing fork/exec in a threaded app
|
|
* with some locks being held/waited on in different threads.
|
|
*
|
|
* we do the idle callback so that the async xfer has finished and
|
|
* cleaned up its vfs job. otherwise it seems the slave thread gets
|
|
* woken up and it removes itself from the job queue before it is
|
|
* supposed to. very strange.
|
|
*
|
|
* see bugzilla.gnome.org #86141 for details
|
|
*/
|
|
static gboolean
|
|
transfer_done_targz_idle_cb (gpointer data)
|
|
{
|
|
int status;
|
|
gchar *command;
|
|
gchar *path = data;
|
|
|
|
/* this should be something more clever and nonblocking */
|
|
command = g_strdup_printf ("sh -c 'gzip -d -c < \"%s\" | tar xf - -C \"%s/.themes\"'",
|
|
path, g_get_home_dir ());
|
|
if (g_spawn_command_line_sync (command, NULL, NULL, &status, NULL) && status == 0)
|
|
gnome_vfs_unlink (path);
|
|
g_free (command);
|
|
g_free (path);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/* this works around problems when doing fork/exec in a threaded app
|
|
* with some locks being held/waited on in different threads.
|
|
*
|
|
* we do the idle callback so that the async xfer has finished and
|
|
* cleaned up its vfs job. otherwise it seems the slave thread gets
|
|
* woken up and it removes itself from the job queue before it is
|
|
* supposed to. very strange.
|
|
*
|
|
* see bugzilla.gnome.org #86141 for details
|
|
*/
|
|
static gboolean
|
|
transfer_done_tarbz2_idle_cb (gpointer data)
|
|
{
|
|
int status;
|
|
gchar *command;
|
|
gchar *path = data;
|
|
|
|
/* this should be something more clever and nonblocking */
|
|
command = g_strdup_printf ("sh -c 'bzip2 -d -c < \"%s\" | tar xf - -C \"%s/.themes\"'",
|
|
path, g_get_home_dir ());
|
|
if (g_spawn_command_line_sync (command, NULL, NULL, &status, NULL) && status == 0)
|
|
gnome_vfs_unlink (path);
|
|
g_free (command);
|
|
g_free (path);
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
static void
|
|
transfer_done_cb (GtkWidget *dlg, gchar *path)
|
|
{
|
|
int len = strlen (path);
|
|
if (path && len > 7 && !strcmp (path + len - 7, ".tar.gz"))
|
|
g_idle_add (transfer_done_targz_idle_cb, path);
|
|
if (path && len > 8 && !strcmp (path + len - 8, ".tar.bz2"))
|
|
g_idle_add (transfer_done_tarbz2_idle_cb, path);
|
|
gtk_widget_destroy (dlg);
|
|
}
|
|
|
|
static void
|
|
install_dialog_response (GtkWidget *widget, int response_id, gpointer data)
|
|
{
|
|
GladeXML *dialog = data;
|
|
GtkWidget *dlg;
|
|
gchar *filename, *path, *base;
|
|
GList *src, *target;
|
|
GnomeVFSURI *src_uri;
|
|
const gchar *raw;
|
|
gboolean icon_theme;
|
|
|
|
if (response_id == GTK_RESPONSE_HELP) {
|
|
capplet_help (GTK_WINDOW (widget),
|
|
"wgoscustdesk.xml",
|
|
"goscustdesk-12");
|
|
return;
|
|
}
|
|
|
|
if (response_id == 0) {
|
|
icon_theme = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (widget), "icon_theme"));
|
|
raw = gtk_entry_get_text (GTK_ENTRY (gnome_file_entry_gtk_entry (GNOME_FILE_ENTRY (WID ("install_theme_picker")))));
|
|
if (raw == NULL || strlen (raw) <= 0)
|
|
return;
|
|
|
|
if (strncmp (raw, "http://", 7) && strncmp (raw, "ftp://", 6) && *raw != '/')
|
|
filename = gnome_file_entry_get_full_path (GNOME_FILE_ENTRY (WID ("install_theme_picker")), TRUE);
|
|
else
|
|
filename = g_strdup (raw);
|
|
if (filename == NULL)
|
|
return;
|
|
|
|
src_uri = gnome_vfs_uri_new (filename);
|
|
base = gnome_vfs_uri_extract_short_name (src_uri);
|
|
src = g_list_append (NULL, src_uri);
|
|
if (icon_theme)
|
|
path = g_build_filename (g_get_home_dir (), ".icons", base, NULL);
|
|
else
|
|
path = g_build_filename (g_get_home_dir (), ".themes", base, NULL);
|
|
target = g_list_append (NULL, gnome_vfs_uri_new (path));
|
|
|
|
dlg = file_transfer_dialog_new ();
|
|
file_transfer_dialog_wrap_async_xfer (FILE_TRANSFER_DIALOG (dlg),
|
|
src, target,
|
|
GNOME_VFS_XFER_RECURSIVE,
|
|
GNOME_VFS_XFER_ERROR_MODE_QUERY,
|
|
GNOME_VFS_XFER_OVERWRITE_MODE_QUERY,
|
|
GNOME_VFS_PRIORITY_DEFAULT);
|
|
gnome_vfs_uri_list_unref (src);
|
|
gnome_vfs_uri_list_unref (target);
|
|
g_free (base);
|
|
g_free (filename);
|
|
g_signal_connect (G_OBJECT (dlg), "cancel",
|
|
G_CALLBACK (transfer_cancel_cb), path);
|
|
g_signal_connect (G_OBJECT (dlg), "done",
|
|
G_CALLBACK (transfer_done_cb), path);
|
|
gtk_widget_show (dlg);
|
|
}
|
|
}
|
|
|
|
void
|
|
gnome_theme_installer_run (GtkWidget *parent, gchar *filename, gboolean icon_theme)
|
|
{
|
|
static gboolean running_theme_install = FALSE;
|
|
GladeXML *dialog;
|
|
GtkWidget *widget;
|
|
|
|
if (running_theme_install)
|
|
return;
|
|
|
|
running_theme_install = TRUE;
|
|
|
|
dialog = glade_xml_new (GLADEDIR "/theme-install.glade", NULL, NULL);
|
|
widget = WID ("install_dialog");
|
|
|
|
g_object_set_data (G_OBJECT (widget), "icon_theme", GINT_TO_POINTER (icon_theme));
|
|
g_signal_connect (G_OBJECT (widget), "response", G_CALLBACK (install_dialog_response), dialog);
|
|
gtk_window_set_transient_for (GTK_WINDOW (widget), GTK_WINDOW (parent));
|
|
gtk_window_set_position (GTK_WINDOW (widget), GTK_WIN_POS_CENTER_ON_PARENT);
|
|
if (filename)
|
|
gnome_file_entry_set_filename (GNOME_FILE_ENTRY (WID ("install_theme_picker")), filename);
|
|
|
|
while (gtk_dialog_run (GTK_DIALOG (widget)) == GTK_RESPONSE_HELP)
|
|
;
|
|
|
|
gtk_widget_destroy (widget);
|
|
g_object_unref (G_OBJECT (dialog));
|
|
|
|
running_theme_install = FALSE;
|
|
}
|