Logo Search packages:      
Sourcecode: control-center version File versions  Download package

theme-installer.c

/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*-
 *
 * 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 <string.h>
#include <glib.h>
#include <glib/gi18n.h>
#include <gio/gio.h>
#include <glib/gstdio.h>
#include <unistd.h>

#include "capplet-util.h"
#include "file-transfer-dialog.h"
#include "theme-installer.h"
#include "theme-util.h"

enum {
      THEME_INVALID,
      THEME_ICON,
      THEME_GNOME,
      THEME_GTK,
      THEME_ENGINE,
      THEME_METACITY,
      THEME_CURSOR,
      THEME_ICON_CURSOR
};

enum {
      TARGZ,
      TARBZ,
      DIRECTORY
};

static gboolean
cleanup_tmp_dir (GIOSchedulerJob *job,
             GCancellable *cancellable,
             const gchar *tmp_dir)
{
      GFile *directory;

      directory = g_file_new_for_path (tmp_dir);
      capplet_file_delete_recursive (directory, NULL);
      g_object_unref (directory);

      return FALSE;
}

static int
file_theme_type (const gchar *dir)
{
      gchar *filename = NULL;
      gboolean exists;

      if (!dir)
            return THEME_INVALID;

      filename = g_build_filename (dir, "index.theme", NULL);
      exists = g_file_test (filename, G_FILE_TEST_IS_REGULAR);

      if (exists) {
            GPatternSpec *pattern;
            gchar *file_contents = NULL;
            gsize file_size;
            gboolean match;

            g_file_get_contents (filename, &file_contents, &file_size, NULL);
            g_free (filename);

            pattern = g_pattern_spec_new ("*[Icon Theme]*");
            match = g_pattern_match_string (pattern, file_contents);
            g_pattern_spec_free (pattern);

            if (match) {
                  pattern = g_pattern_spec_new ("*Directories=*");
                  match = g_pattern_match_string (pattern, file_contents);
                  g_pattern_spec_free (pattern);
                  g_free (file_contents);

                  if (match) {
                        /* check if we have a cursor, too */
                        filename = g_build_filename (dir, "cursors", NULL);
                        exists = g_file_test (filename, G_FILE_TEST_IS_DIR);
                        g_free (filename);

                        if (exists)
                              return THEME_ICON_CURSOR;
                        else
                              return THEME_ICON;
                  }
                  return THEME_CURSOR;
            }

            pattern = g_pattern_spec_new ("*[X-GNOME-Metatheme]*");
            match = g_pattern_match_string (pattern, file_contents);
            g_pattern_spec_free (pattern);
            g_free (file_contents);

            if (match)
                  return THEME_GNOME;
      } else {
            g_free (filename);
      }

      filename = g_build_filename (dir, "gtk-2.0", "gtkrc", NULL);
      exists = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
      g_free (filename);

      if (exists)
            return THEME_GTK;

      filename = g_build_filename (dir, "metacity-1", "metacity-theme-1.xml", NULL);
      exists = g_file_test (filename, G_FILE_TEST_IS_REGULAR);
      g_free (filename);

      if (exists)
            return THEME_METACITY;

      /* cursor themes don't necessarily have an index.theme */
      filename = g_build_filename (dir, "cursors", NULL);
      exists = g_file_test (filename, G_FILE_TEST_IS_DIR);
      g_free (filename);

      if (exists)
            return THEME_CURSOR;

      filename = g_build_filename (dir, "configure", NULL);
      exists = g_file_test (filename, G_FILE_TEST_IS_EXECUTABLE);
      g_free (filename);

      if (exists)
            return THEME_ENGINE;

      return THEME_INVALID;
}

static void
transfer_cancel_cb (GtkWidget *dialog,
                gchar *path)
{
      GFile *todelete;

      todelete = g_file_new_for_path (path);
      capplet_file_delete_recursive (todelete, NULL);

      g_object_unref (todelete);
      g_free (path);
      gtk_widget_destroy (dialog);
}

static void
missing_utility_message_dialog (GtkWindow *parent,
                        const gchar *utility)
{
      GtkWidget *dialog = gtk_message_dialog_new (parent,
                                        GTK_DIALOG_MODAL,
                                        GTK_MESSAGE_ERROR,
                                        GTK_BUTTONS_OK,
                                        _("Cannot install theme"));
      gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                      _("The %s utility is not installed."), utility);
      gtk_dialog_run (GTK_DIALOG (dialog));
      gtk_widget_destroy (dialog);
}

/* 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
process_local_theme_tgz_tbz (GtkWindow *parent,
                       const gchar *util,
                       const gchar *tmp_dir,
                       const gchar *archive)
{
      gboolean rc;
      int status;
      gchar *command, *filename, *zip, *tar;

      if (!(zip = g_find_program_in_path (util))) {
            missing_utility_message_dialog (parent, util);
            return FALSE;
      }
      if (!(tar = g_find_program_in_path ("tar"))) {
            missing_utility_message_dialog (parent, "tar");
            g_free (zip);
            return FALSE;
      }

      filename = g_shell_quote (archive);

      /* this should be something more clever and nonblocking */
      command = g_strdup_printf ("sh -c 'cd \"%s\"; %s -d -c < \"%s\" | %s xf - '",
                           tmp_dir, zip, filename, tar);
      g_free (zip);
      g_free (tar);
      g_free (filename);

      rc = (g_spawn_command_line_sync (command, NULL, NULL, &status, NULL) && status == 0);
      g_free (command);

      if (rc == FALSE) {
            GtkWidget *dialog;

            dialog = gtk_message_dialog_new (parent,
                                     GTK_DIALOG_MODAL,
                                     GTK_MESSAGE_ERROR,
                                     GTK_BUTTONS_OK,
                                     _("Cannot install theme"));
            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                            _("There was a problem while extracting the theme."));
            gtk_dialog_run (GTK_DIALOG (dialog));
            gtk_widget_destroy (dialog);
      }

      return rc;
}

static gboolean
process_local_theme_archive (GtkWindow *parent,
                       gint filetype,
                       const gchar *tmp_dir,
                       const gchar *archive)
{
      if (filetype == TARGZ)
            return process_local_theme_tgz_tbz (parent, "gzip", tmp_dir, archive);
      else if (filetype == TARBZ)
            return process_local_theme_tgz_tbz (parent, "bzip2", tmp_dir, archive);
      else
            return FALSE;
}

static void
invalid_theme_dialog (GtkWindow *parent,
                  const gchar *filename,
                  gboolean maybe_theme_engine)
{
      GtkWidget *dialog;
      const gchar *primary = _("There was an error installing the selected file");
      const gchar *secondary = _("\"%s\" does not appear to be a valid theme.");
      const gchar *engine = _("\"%s\" does not appear to be a valid theme. It may be a theme engine which you need to compile.");

      dialog = gtk_message_dialog_new (parent,
                               GTK_DIALOG_MODAL,
                               GTK_MESSAGE_ERROR,
                               GTK_BUTTONS_OK,
                               "%s", primary);
      if (maybe_theme_engine)
            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), engine, filename);
      else
            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog), secondary, filename);
      gtk_dialog_run (GTK_DIALOG (dialog));
      gtk_widget_destroy (dialog);
}

static gboolean
gnome_theme_install_real (GtkWindow *parent,
                    gint filetype,
                    const gchar *tmp_dir,
                    const gchar *theme_name,
                    gboolean ask_user)
{
      gboolean success = TRUE;
      GtkWidget *dialog, *apply_button;
      GFile *theme_source_dir, *theme_dest_dir;
      GError *error = NULL;
      gint theme_type;
      gchar *target_dir = NULL;

      /* What type of theme is it? */
      theme_type = file_theme_type (tmp_dir);
      switch (theme_type) {
      case THEME_ICON:
      case THEME_CURSOR:
      case THEME_ICON_CURSOR:
            target_dir = g_build_path (G_DIR_SEPARATOR_S,
                                 g_get_home_dir (), ".icons",
                                 theme_name, NULL);
            break;
      case THEME_GNOME:
            target_dir = g_build_path (G_DIR_SEPARATOR_S,
                                 g_get_home_dir (), ".themes",
                                 theme_name, NULL);
            break;
      case THEME_METACITY:
      case THEME_GTK:
            target_dir = g_build_path (G_DIR_SEPARATOR_S,
                                 g_get_home_dir (), ".themes",
                                 theme_name, NULL);
            break;
      case THEME_ENGINE:
            invalid_theme_dialog (parent, theme_name, TRUE);
            return FALSE;
      default:
            invalid_theme_dialog (parent, theme_name, FALSE);
            return FALSE;
      }

      /* see if there is an icon theme lurking in this package */
      if (theme_type == THEME_GNOME) {
            gchar *path;

            path = g_build_path (G_DIR_SEPARATOR_S,
                             tmp_dir, "icons", NULL);
            if (g_file_test (path, G_FILE_TEST_IS_DIR)
                && (file_theme_type (path) == THEME_ICON)) {
                  gchar *new_path, *update_icon_cache;
                  GFile *new_file;
                  GFile *src_file;

                  src_file = g_file_new_for_path (path);
                  new_path = g_build_path (G_DIR_SEPARATOR_S,
                                     g_get_home_dir (),
                                     ".icons",
                                     theme_name, NULL);
                  new_file = g_file_new_for_path (new_path);

                  if (!g_file_move (src_file, new_file, G_FILE_COPY_NONE,
                                NULL, NULL, NULL, &error)) {
                        g_warning ("Error while moving from `%s' to `%s': %s",
                                 path, new_path, error->message);
                        g_error_free (error);
                        error = NULL;
                  }
                  g_object_unref (new_file);
                  g_object_unref (src_file);

                  /* update icon cache - shouldn't really matter if this fails */
                  update_icon_cache = g_strdup_printf ("gtk-update-icon-cache %s", new_path);
                  g_spawn_command_line_async (update_icon_cache, NULL);
                  g_free (update_icon_cache);

                  g_free (new_path);
            }
            g_free (path);
      }

      /* Move the dir to the target dir */
      theme_source_dir = g_file_new_for_path (tmp_dir);
      theme_dest_dir = g_file_new_for_path (target_dir);

      if (!g_file_move (theme_source_dir, theme_dest_dir,
                    G_FILE_COPY_OVERWRITE, NULL, NULL,
                    NULL, &error)) {
            gchar *str;

            str = g_strdup_printf (_("Installation for theme \"%s\" failed."), theme_name);
            dialog = gtk_message_dialog_new (parent,
                                     GTK_DIALOG_MODAL,
                                     GTK_MESSAGE_ERROR,
                                     GTK_BUTTONS_OK,
                                     "%s",
                                     str);
            gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                            "%s", error->message);

            g_free (str);
            g_error_free (error);
            error = NULL;

            gtk_dialog_run (GTK_DIALOG (dialog));
            gtk_widget_destroy (dialog);
            success = FALSE;
      } else {
            if (theme_type == THEME_ICON || theme_type == THEME_ICON_CURSOR)
            {
                  gchar *update_icon_cache;

                  /* update icon cache - shouldn't really matter if this fails */
                  update_icon_cache = g_strdup_printf ("gtk-update-icon-cache %s", target_dir);
                  g_spawn_command_line_async (update_icon_cache, NULL);

                  g_free (update_icon_cache);
            }

            if (ask_user) {
                  /* Ask to apply theme (if we can) */
                  if (theme_type == THEME_GTK
                      || theme_type == THEME_METACITY
                      || theme_type == THEME_ICON
                      || theme_type == THEME_CURSOR
                      || theme_type == THEME_ICON_CURSOR) {
                        /* TODO: currently cannot apply "gnome themes" */
                        gchar *str;

                        str = g_strdup_printf (_("The theme \"%s\" has been installed."), theme_name);
                        dialog = gtk_message_dialog_new_with_markup (parent,
                                                           GTK_DIALOG_MODAL,
                                                           GTK_MESSAGE_INFO,
                                                           GTK_BUTTONS_NONE,
                                                           "<span weight=\"bold\" size=\"larger\">%s</span>",
                                                           str);
                        g_free (str);

                        gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (dialog),
                                                        _("Would you like to apply it now, or keep your current theme?"));

                        gtk_dialog_add_button (GTK_DIALOG (dialog),
                                           _("Keep Current Theme"),
                                           GTK_RESPONSE_CLOSE);

                        apply_button = gtk_button_new_with_label (_("Apply New Theme"));
                        gtk_button_set_image (GTK_BUTTON (apply_button),
                                          gtk_image_new_from_stock (GTK_STOCK_APPLY,
                                                            GTK_ICON_SIZE_BUTTON));
                        gtk_dialog_add_action_widget (GTK_DIALOG (dialog), apply_button, GTK_RESPONSE_APPLY);
                        GTK_WIDGET_SET_FLAGS (apply_button, GTK_CAN_DEFAULT);
                        gtk_widget_show (apply_button);

                        gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_APPLY);

                        if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_APPLY) {
                              /* apply theme here! */
                              GConfClient *gconf_client;

                              gconf_client = gconf_client_get_default ();

                              switch (theme_type) {
                              case THEME_GTK:
                                    gconf_client_set_string (gconf_client, GTK_THEME_KEY, theme_name, NULL);
                                    break;
                              case THEME_METACITY:
                                    gconf_client_set_string (gconf_client, METACITY_THEME_KEY, theme_name, NULL);
                                    break;
                              case THEME_ICON:
                                    gconf_client_set_string (gconf_client, ICON_THEME_KEY, theme_name, NULL);
                                    break;
                              case THEME_CURSOR:
                                    gconf_client_set_string (gconf_client, CURSOR_THEME_KEY, theme_name, NULL);
                                    break;
                              case THEME_ICON_CURSOR:
                                    gconf_client_set_string (gconf_client, ICON_THEME_KEY, theme_name, NULL);
                                    gconf_client_set_string (gconf_client, CURSOR_THEME_KEY, theme_name, NULL);
                                    break;
                              default:
                                    break;
                              }

                              g_object_unref (gconf_client);
                        }
                  } else {
                        dialog = gtk_message_dialog_new (parent,
                                                 GTK_DIALOG_MODAL,
                                                 GTK_MESSAGE_INFO,
                                                 GTK_BUTTONS_OK,
                                                 _("GNOME Theme %s correctly installed"),
                                                 theme_name);
                        gtk_dialog_run (GTK_DIALOG (dialog));
                  }
                  gtk_widget_destroy (dialog);
            }
      }

      g_free (target_dir);

      return success;
}

static void
process_local_theme (GtkWindow  *parent,
                 const char *path)
{
      GtkWidget *dialog;
      gint filetype;

      if (g_str_has_suffix (path, ".tar.gz")
          || g_str_has_suffix (path, ".tgz")
          || g_str_has_suffix(path, ".gtp")) {
            filetype = TARGZ;
      } else if (g_str_has_suffix (path, ".tar.bz2")) {
            filetype = TARBZ;
      } else if (g_file_test (path, G_FILE_TEST_IS_DIR)) {
            filetype = DIRECTORY;
      } else {
            gchar *filename;
            filename = g_path_get_basename (path);
            invalid_theme_dialog (parent, filename, FALSE);
            g_free (filename);
            return;
      }

      if (filetype == DIRECTORY) {
            gchar *name = g_path_get_basename (path);
            gnome_theme_install_real (parent,
                                filetype,
                                path,
                                name,
                                TRUE);
            g_free (name);
      } else {
            /* Create a temp directory and uncompress file there */
            GDir *dir;
            const gchar *name;
            gchar *tmp_dir;
            gboolean ok;
            gint n_themes;
            GFile *todelete;

            tmp_dir = g_strdup_printf ("%s/.themes/.theme-%u",
                                 g_get_home_dir (),
                                 g_random_int ());

            if ((g_mkdir (tmp_dir, 0700)) != 0) {
                  dialog = gtk_message_dialog_new (parent,
                                           GTK_DIALOG_MODAL,
                                           GTK_MESSAGE_ERROR,
                                           GTK_BUTTONS_OK,
                                           _("Failed to create temporary directory"));
                  gtk_dialog_run (GTK_DIALOG (dialog));
                  gtk_widget_destroy (dialog);
                  g_free (tmp_dir);
                  return;
            }

            if (!process_local_theme_archive (parent, filetype, tmp_dir, path)
                || ((dir = g_dir_open (tmp_dir, 0, NULL)) == NULL)) {
                  g_io_scheduler_push_job ((GIOSchedulerJobFunc) cleanup_tmp_dir,
                                     g_strdup (tmp_dir),
                                     g_free,
                                     G_PRIORITY_DEFAULT,
                                     NULL);
                  g_free (tmp_dir);
                  return;
            }

            todelete = g_file_new_for_path (path);
            g_file_delete (todelete, NULL, NULL);
            g_object_unref (todelete);

            /* See whether we have multiple themes to install. If so,
             * we won't ask the user whether to apply the new theme
             * after installation. */
            n_themes = 0;
            for (name = g_dir_read_name (dir);
                 name && n_themes <= 1;
                 name = g_dir_read_name (dir)) {
                  gchar *theme_dir;

                  theme_dir = g_build_filename (tmp_dir, name, NULL);

                  if (g_file_test (theme_dir, G_FILE_TEST_IS_DIR))
                        ++n_themes;

                  g_free (theme_dir);
            }
            g_dir_rewind (dir);

            ok = TRUE;
            for (name = g_dir_read_name (dir); name && ok;
                 name = g_dir_read_name (dir)) {
                  gchar *theme_dir;

                  theme_dir = g_build_filename (tmp_dir, name, NULL);

                  if (g_file_test (theme_dir, G_FILE_TEST_IS_DIR))
                        ok = gnome_theme_install_real (parent,
                                                 filetype,
                                                 theme_dir,
                                                 name,
                                                 n_themes == 1);

                  g_free (theme_dir);
            }
            g_dir_close (dir);

            if (ok && n_themes > 1) {
                  dialog = gtk_message_dialog_new (parent,
                                           GTK_DIALOG_MODAL,
                                           GTK_MESSAGE_INFO,
                                           GTK_BUTTONS_OK,
                                           _("New themes have been successfully installed."));
                  gtk_dialog_run (GTK_DIALOG (dialog));
                  gtk_widget_destroy (dialog);
            }
            g_io_scheduler_push_job ((GIOSchedulerJobFunc) cleanup_tmp_dir,
                               tmp_dir, g_free,
                               G_PRIORITY_DEFAULT, NULL);
      }
}

00606 typedef struct
{
      GtkWindow *parent;
      char      *path;
} TransferData;

static void
transfer_done_cb (GtkWidget *dialog,
              TransferData *tdata)
{
      gdk_threads_enter ();
      /* XXX: path should be on the local filesystem by now? */

      if (dialog != NULL) {
            gtk_widget_destroy (dialog);
      }

      process_local_theme (tdata->parent, tdata->path);

      g_free (tdata->path);
      g_free (tdata);

      gdk_threads_leave ();
}

void
gnome_theme_install (GFile *file,
                 GtkWindow *parent)
{
      GtkWidget *dialog;
      gchar *path, *base;
      GList *src, *target;
      const gchar *template;
      TransferData *tdata;

      if (file == NULL) {
            dialog = gtk_message_dialog_new (parent,
                                     GTK_DIALOG_MODAL,
                                     GTK_MESSAGE_ERROR,
                                     GTK_BUTTONS_OK,
                                     _("No theme file location specified to install"));
            gtk_dialog_run (GTK_DIALOG (dialog));
            gtk_widget_destroy (dialog);
            return;
      }

      /* see if someone dropped a local directory */
      if (g_file_is_native (file)
          && g_file_query_file_type (file, G_FILE_QUERY_INFO_NONE, NULL) == G_FILE_TYPE_DIRECTORY) {
            path = g_file_get_path (file);
            process_local_theme (parent, path);
            g_free (path);
            return;
      }

      /* we can't tell if this is an icon theme yet, so just make a
       * temporary copy in .themes */
      path = g_build_filename (g_get_home_dir (), ".themes", NULL);

      if (access (path, X_OK | W_OK) != 0) {
            dialog = gtk_message_dialog_new (parent,
                                     GTK_DIALOG_MODAL,
                                     GTK_MESSAGE_ERROR,
                                     GTK_BUTTONS_OK,
                                     _("Insufficient permissions to install the theme in:\n%s"), path);
            gtk_dialog_run (GTK_DIALOG (dialog));
            gtk_widget_destroy (dialog);
            g_free (path);
            return;
      }

      base = g_file_get_basename (file);

      if (g_str_has_suffix (base, ".tar.gz")
          || g_str_has_suffix (base, ".tgz")
          || g_str_has_suffix (base, ".gtp"))
            template = "gnome-theme-%d.gtp";
      else if (g_str_has_suffix (base, ".tar.bz2"))
            template = "gnome-theme-%d.tar.bz2";
      else {
            invalid_theme_dialog (parent, base, FALSE);
            g_free (base);
            return;
      }
      g_free (base);

      src = g_list_append (NULL, g_object_ref (file));

      path = NULL;
      do {
            gchar *file_tmp;

            g_free (path);
            file_tmp = g_strdup_printf (template, g_random_int ());
            path = g_build_filename (g_get_home_dir (), ".themes", file_tmp, NULL);
            g_free (file_tmp);
      } while (g_file_test (path, G_FILE_TEST_EXISTS));

      tdata = g_new0 (TransferData, 1);
      tdata->parent = parent;
      tdata->path = path;

      dialog = file_transfer_dialog_new_with_parent (parent);
      g_signal_connect (dialog,
                    "cancel",
                    (GCallback) transfer_cancel_cb, path);
      g_signal_connect (dialog,
                    "done",
                    (GCallback) transfer_done_cb, tdata);

      target = g_list_append (NULL, g_file_new_for_path (path));
      file_transfer_dialog_copy_async (FILE_TRANSFER_DIALOG (dialog),
                               src,
                               target,
                               FILE_TRANSFER_DIALOG_DEFAULT,
                               G_PRIORITY_DEFAULT);
      gtk_widget_show (dialog);

      /* don't free the path since we're using that for the signals */
      g_list_foreach (src, (GFunc) g_object_unref, NULL);
      g_list_free (src);
      g_list_foreach (target, (GFunc) g_object_unref, NULL);
      g_list_free (target);
}

void
gnome_theme_installer_run (GtkWindow *parent,
                     const gchar *filename)
{
      static gboolean running_theme_install = FALSE;
      static gchar old_folder[512] = "";
      GtkWidget *dialog;
      GtkFileFilter *filter;

      if (running_theme_install)
            return;

      running_theme_install = TRUE;

      if (filename == NULL)
            filename = old_folder;

      dialog = gtk_file_chooser_dialog_new (_("Select Theme"),
                                    parent,
                                    GTK_FILE_CHOOSER_ACTION_OPEN,
                                    GTK_STOCK_CANCEL,
                                    GTK_RESPONSE_REJECT,
                                    GTK_STOCK_OPEN,
                                    GTK_RESPONSE_ACCEPT,
                                    NULL);
      gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);

      filter = gtk_file_filter_new ();
      gtk_file_filter_set_name (filter, _("Theme Packages"));
      gtk_file_filter_add_mime_type (filter, "application/x-bzip-compressed-tar");
      gtk_file_filter_add_mime_type (filter, "application/x-compressed-tar");
      gtk_file_filter_add_mime_type (filter, "application/x-gnome-theme-package");
      gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);

      filter = gtk_file_filter_new ();
      gtk_file_filter_set_name (filter, _("All Files"));
      gtk_file_filter_add_pattern(filter, "*");
      gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dialog), filter);

      if (strcmp (old_folder, ""))
            gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), old_folder);

      if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) {
            gchar *uri_selected, *folder;

            uri_selected = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));

            folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
            g_strlcpy (old_folder, folder, 255);
            g_free (folder);

            gtk_widget_destroy (dialog);

            if (uri_selected != NULL) {
                  GFile *file = g_file_new_for_uri (uri_selected);
                  g_free (uri_selected);

                  gnome_theme_install (file, parent);
                  g_object_unref (file);
            }
      } else {
            gtk_widget_destroy (dialog);
      }

      /*
       * we're relying on the gnome theme info module to pick up changes
       * to the themes so we don't need to update the model here
       */

      running_theme_install = FALSE;
}

Generated by  Doxygen 1.6.0   Back to index