gnome-control-center/capplets/theme-switcher/gnome-theme-details.c
David Sedeño 0b8267577e New install procedure: See bug #102216. Remove
2005-02-01  David Sedeño <david@alderia.com>

	New install procedure: See bug #102216.
	* gnome-theme-details.c: Remove gnome_theme_installer_run_cb,
	gnome_icon_theme_installer_run_cb because gnome_theme_installer_run
	function now detects if it is a icon or theme.
	(gnome_theme_details_init): Remove install buttons in theme details
	window.
	* gnome-theme-installer.c (file_theme_type): Detects the type of the
	theme inspecting the content of the file.
	(transfer_done_targz_idle_cb, transfer_done_tarbz2_idle_cb): Install
	the theme in the correct temp dir.
	(transfer_done_cb): Detects if the file to install it is in the
	correct format and informs the user if it is not supported. Unpack the
	file (informs the user if there are not the correct utility in the
	system) and install the theme in the correct directory.
	(gnome_theme_installer_run): Remove parameter. Now we detect the file
	type.
	* gnome-theme-manager.c (gnome_meta_theme_installer_run_cb,
	gnome_theme_manager_drag_data_received_cb): Call
	gnome_theme_installer_run without the third parameter. Now we detect
	the file type.
	* theme-properties.glade: Removes install buttons in details window.
2005-02-01 22:33:47 +00:00

569 lines
16 KiB
C

#include <config.h>
#include <string.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 <libwindow-settings/gnome-wm-manager.h>
#include "capplet-util.h"
#include "gnome-theme-manager.h"
#include "gnome-theme-details.h"
#include "gnome-theme-installer.h"
#include "gnome-theme-info.h"
#define MAX_ELEMENTS_BEFORE_SCROLLING 12
static gboolean theme_details_initted = FALSE;
static gboolean setting_model = FALSE;
/* Function Prototypes */
static void cb_dialog_response (GtkDialog *dialog,
gint response_id);
static void setup_tree_view (GtkTreeView *tree_view,
GCallback changed_callback,
GladeXML *dialog);
static void gtk_theme_selection_changed (GtkTreeSelection *selection,
gpointer data);
static void window_theme_selection_changed (GtkTreeSelection *selection,
gpointer data);
static void icon_theme_selection_changed (GtkTreeSelection *selection,
gpointer data);
static void update_gconf_key_from_selection (GtkTreeSelection *selection,
const gchar *gconf_key);
static void load_theme_names (GtkTreeView *tree_view,
GList *theme_list,
const gchar *default_theme);
static char *path_to_theme_id (const char *path);
static char *
path_to_theme_id (const char *path)
{
char *dirname;
char *result;
dirname = g_path_get_dirname(path);
result = g_path_get_basename(dirname);
g_free(dirname);
return result;
}
static void
cb_dialog_response (GtkDialog *dialog, gint response_id)
{
if (response_id == GTK_RESPONSE_HELP)
capplet_help (GTK_WINDOW (dialog), "user-guide.xml", "goscustdesk-12");
else
gtk_widget_hide (GTK_WIDGET (dialog));
}
static gint
details_tree_sort_func (GtkTreeModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
gpointer user_data)
{
gchar *a_name = NULL;
gchar *b_name = NULL;
guint a_flag = FALSE;
guint b_flag = FALSE;
gint retval;
gtk_tree_model_get (model, a,
THEME_NAME_COLUMN, &a_name,
THEME_FLAG_COLUMN, &a_flag,
-1);
gtk_tree_model_get (model, b,
THEME_NAME_COLUMN, &b_name,
THEME_FLAG_COLUMN, &b_flag,
-1);
retval = gnome_theme_manager_sort_func (a_name, b_name, a_flag, b_flag);
g_free (a_name);
g_free (b_name);
return retval;
}
static void
setup_tree_view (GtkTreeView *tree_view,
GCallback changed_callback,
GladeXML *dialog)
{
GtkTreeModel *model;
GtkTreeSelection *selection;
GtkCellRenderer *renderer;
model = (GtkTreeModel *) gtk_list_store_new (N_COLUMNS, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_UINT);
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model), 0, details_tree_sort_func, NULL, NULL);
gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0, GTK_SORT_ASCENDING);
gtk_tree_view_set_model (tree_view, model);
selection = gtk_tree_view_get_selection (tree_view);
gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
g_signal_connect (G_OBJECT (selection), "changed", changed_callback, dialog);
renderer = gtk_cell_renderer_text_new ();
gtk_tree_view_insert_column_with_attributes (tree_view,
-1, NULL,
renderer,
"text", THEME_NAME_COLUMN,
NULL);
}
static void
gtk_theme_selection_changed (GtkTreeSelection *selection,
gpointer data)
{
update_gconf_key_from_selection (selection, GTK_THEME_KEY);
}
static void
window_theme_selection_changed (GtkTreeSelection *selection,
gpointer data)
{
GnomeWindowManager *window_manager;
GnomeWMSettings wm_settings;
GtkTreeIter iter;
gchar *window_theme_name;
GtkTreeModel *model;
if (setting_model)
return;
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
gtk_tree_model_get (model, &iter,
THEME_ID_COLUMN, &window_theme_name,
-1);
}
else
{
return;
}
window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ()));
if (window_manager != NULL) {
wm_settings.flags = GNOME_WM_SETTING_THEME;
wm_settings.theme = window_theme_name;
gnome_window_manager_change_settings (window_manager, &wm_settings);
}
g_free (window_theme_name);
}
static void
icon_theme_selection_changed (GtkTreeSelection *selection,
gpointer data)
{
update_gconf_key_from_selection (selection, ICON_THEME_KEY);
}
static void
load_theme_names (GtkTreeView *tree_view,
GList *theme_list,
const gchar *default_theme)
{
GList *list;
GtkTreeModel *model;
GtkWidget *swindow;
gint i = 0;
swindow = GTK_WIDGET (tree_view)->parent;
model = gtk_tree_view_get_model (tree_view);
g_assert (model);
setting_model = TRUE;
gtk_list_store_clear (GTK_LIST_STORE (model));
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
GTK_POLICY_NEVER, GTK_POLICY_NEVER);
gtk_widget_set_usize (swindow, -1, -1);
for (list = theme_list; list; list = list->next->next)
{
const char *name = list->data;
const char *id = list->next->data;
GtkTreeIter iter;
gboolean is_default;
gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
if (default_theme && strcmp (default_theme, name) == 0)
is_default = TRUE;
else
is_default = FALSE;
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
THEME_NAME_COLUMN, name,
THEME_ID_COLUMN, id,
THEME_FLAG_COLUMN, is_default,
-1);
if (i == MAX_ELEMENTS_BEFORE_SCROLLING)
{
GtkRequisition rectangle;
gtk_widget_size_request (GTK_WIDGET (tree_view), &rectangle);
gtk_widget_set_usize (swindow, -1, rectangle.height);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (swindow),
GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
}
i++;
}
setting_model = FALSE;
}
/* Shared by icons and gtk+ */
static void
update_gconf_key_from_selection (GtkTreeSelection *selection,
const gchar *gconf_key)
{
GtkTreeModel *model;
gchar *new_key;
GConfClient *client;
GtkTreeIter iter;
if (setting_model)
return;
client = gconf_client_get_default ();
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
gtk_tree_model_get (model, &iter,
THEME_ID_COLUMN, &new_key,
-1);
}
else
/* This shouldn't happen */
{
new_key = NULL;
}
if (new_key != NULL)
{
gchar *old_key;
old_key = gconf_client_get_string (client, gconf_key, NULL);
if (old_key && strcmp (old_key, new_key))
{
gconf_client_set_string (client, gconf_key, new_key, NULL);
}
g_free (old_key);
}
else
{
gconf_client_unset (client, gconf_key, NULL);
}
g_free (new_key);
g_object_unref (client);
}
void
gnome_theme_details_init (void)
{
GConfClient *client;
GtkWidget *parent, *widget;
GnomeWindowManager *window_manager;
GladeXML *dialog;
if (theme_details_initted)
return;
theme_details_initted = TRUE;
dialog = gnome_theme_manager_get_theme_dialog ();
client = gconf_client_get_default ();
window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ()));
parent = WID ("theme_details_dialog");
setup_tree_view (GTK_TREE_VIEW (WID ("control_theme_treeview")),
(GCallback) gtk_theme_selection_changed,
dialog);
setup_tree_view (GTK_TREE_VIEW (WID ("window_theme_treeview")),
(GCallback) window_theme_selection_changed,
dialog);
setup_tree_view (GTK_TREE_VIEW (WID ("icon_theme_treeview")),
(GCallback) icon_theme_selection_changed,
dialog);
/* gtk themes */
widget = WID ("control_manage_button");
g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (gnome_theme_manager_show_manage_themes), dialog);
/* window manager themes */
widget = WID ("window_manage_button");
g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (gnome_theme_manager_window_show_manage_themes), dialog);
/* icon themes */
widget = WID ("icon_manage_button");
g_signal_connect (G_OBJECT (widget), "clicked", G_CALLBACK (gnome_theme_manager_icon_show_manage_themes), dialog);
g_signal_connect (G_OBJECT (parent), "response", G_CALLBACK (cb_dialog_response), NULL);
g_signal_connect (G_OBJECT (parent), "delete-event", G_CALLBACK (gtk_true), NULL);
gtk_drag_dest_set (parent, GTK_DEST_DEFAULT_ALL,
drop_types, n_drop_types,
GDK_ACTION_COPY | GDK_ACTION_LINK | GDK_ACTION_MOVE);
g_signal_connect (G_OBJECT (parent), "drag-motion", G_CALLBACK (gnome_theme_manager_drag_motion_cb), NULL);
g_signal_connect (G_OBJECT (parent), "drag-leave", G_CALLBACK (gnome_theme_manager_drag_leave_cb), NULL);
g_signal_connect (G_OBJECT (parent), "drag-data-received", G_CALLBACK (gnome_theme_manager_drag_data_received_cb), NULL);
capplet_set_icon (parent, "gnome-settings-theme");
gnome_theme_details_reread_themes_from_disk ();
}
void
gnome_theme_details_show (void)
{
GladeXML *dialog;
GtkWidget *parent;
gnome_theme_details_init ();
dialog = gnome_theme_manager_get_theme_dialog ();
parent = WID ("theme_details_dialog");
gtk_widget_show (parent);
gtk_window_present (GTK_WINDOW (parent));
}
static void
warn_about_no_themes (void)
{
static GtkWidget *dialog;
if (dialog == NULL)
{
dialog = gtk_message_dialog_new (NULL,
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_OK,
_("No themes could be found on your system. This probably means that your \"Theme Preferences\" dialog was improperly installed, or you haven't installed the \"gnome-themes\" package."));
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
exit (0);
}
}
void
gnome_theme_details_reread_themes_from_disk (void)
{
GladeXML *dialog;
GList *theme_list;
GList *string_list;
GList *list;
GnomeWindowManager *window_manager;
GtkWidget *notebook;
gboolean have_gtk_theme;
gboolean have_window_theme;
gboolean have_icon_theme;
gnome_theme_details_init ();
dialog = gnome_theme_manager_get_theme_dialog ();
window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ()));
notebook = WID ("theme_notebook");
/* First, we update the GTK+ themes page */
theme_list = gnome_theme_info_find_by_type (GNOME_THEME_GTK_2);
string_list = NULL;
for (list = theme_list; list; list = list->next)
{
GnomeThemeInfo *info = list->data;
/* Use same string for ID as for name with GTK themes */
string_list = g_list_prepend (string_list, info->name);
string_list = g_list_prepend (string_list, info->name);
}
if (string_list == NULL)
{
have_gtk_theme = FALSE;
gtk_widget_hide (WID ("control_theme_vbox"));
}
else
{
have_gtk_theme = TRUE;
gtk_widget_show (WID ("control_theme_vbox"));
load_theme_names (GTK_TREE_VIEW (WID ("control_theme_treeview")), string_list, gtk_theme_default_name);
g_list_free (string_list);
}
g_list_free (theme_list);
/* Next, we do the window managers */
theme_list = window_manager ? gnome_window_manager_get_theme_list (window_manager) : NULL;
string_list = NULL;
for (list = theme_list; list; list = list->next)
{
/* Use same string for ID as for name with Window themes */
string_list = g_list_prepend (string_list, list->data);
string_list = g_list_prepend (string_list, list->data);
}
if (string_list == NULL)
{
have_window_theme = FALSE;
gtk_widget_hide (WID ("window_theme_vbox"));
}
else
{
have_window_theme = TRUE;
gtk_widget_show (WID ("window_theme_vbox"));
load_theme_names (GTK_TREE_VIEW (WID ("window_theme_treeview")), string_list, window_theme_default_name);
g_list_free (string_list);
}
g_list_free (theme_list);
/* Third, we do the icon theme */
theme_list = gnome_theme_icon_info_find_all ();
string_list = NULL;
for (list = theme_list; list; list = list->next)
{
GnomeThemeIconInfo *info = list->data;
string_list = g_list_prepend (string_list, path_to_theme_id(info->path));
string_list = g_list_prepend (string_list, info->name);
}
if (string_list == NULL)
{
have_icon_theme = FALSE;
gtk_widget_hide (WID ("icon_theme_vbox"));
}
else
{
have_icon_theme = TRUE;
gtk_widget_show (WID ("icon_theme_vbox"));
load_theme_names (GTK_TREE_VIEW (WID ("icon_theme_treeview")), string_list, icon_theme_default_name);
g_list_free (string_list);
}
g_list_free (theme_list);
if (! have_gtk_theme && ! have_window_theme && ! have_icon_theme)
warn_about_no_themes ();
gnome_theme_details_update_from_gconf ();
}
static void
update_list_something (GtkWidget *tree_view, const gchar *theme)
{
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreeIter next_iter;
gboolean valid;
gboolean theme_found;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (tree_view));
g_assert (model);
valid = gtk_tree_model_get_iter_first (model, &iter);
theme_found = FALSE;
while (valid)
{
gchar *theme_id;
guint flags = 0;
next_iter = iter;
valid = gtk_tree_model_iter_next (model, &next_iter);
gtk_tree_model_get (model, &iter,
THEME_ID_COLUMN, &theme_id,
THEME_FLAG_COLUMN, &flags,
-1);
if (! strcmp (theme, theme_id))
{
GtkTreePath *path;
GtkTreePath *cursor_path;
gboolean cursor_same = FALSE;
gtk_tree_view_get_cursor (GTK_TREE_VIEW (tree_view), &cursor_path, NULL);
path = gtk_tree_model_get_path (model, &iter);
if (cursor_path && gtk_tree_path_compare (path, cursor_path) == 0)
cursor_same = TRUE;
gtk_tree_path_free (cursor_path);
if (!cursor_same)
{
gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree_view), path, NULL, FALSE);
}
gtk_tree_path_free (path);
theme_found = TRUE;
}
else
{
if (flags & THEME_FLAG_CUSTOM)
{
gtk_list_store_remove (GTK_LIST_STORE (model), &iter);
}
}
g_free (theme_id);
iter = next_iter;
if (theme_found)
break;
}
if (theme_found == FALSE)
/* Never found the theme. */
{
GtkTreePath *path;
gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
gtk_list_store_set (GTK_LIST_STORE (model), &iter,
THEME_NAME_COLUMN, theme,
THEME_ID_COLUMN, theme,
THEME_FLAG_COLUMN, THEME_FLAG_CUSTOM,
-1);
path = gtk_tree_model_get_path (model, &iter);
gtk_tree_view_set_cursor (GTK_TREE_VIEW (tree_view), path, NULL, FALSE);
gtk_tree_path_free (path);
}
}
void
gnome_theme_details_update_from_gconf (void)
{
GConfClient *client;
GladeXML *dialog;
GtkWidget *tree_view;
gchar *theme;
GnomeWindowManager *window_manager;
GnomeWMSettings wm_settings;
gnome_theme_details_init ();
window_manager = gnome_wm_manager_get_current (gdk_display_get_default_screen (gdk_display_get_default ()));
client = gconf_client_get_default ();
dialog = gnome_theme_manager_get_theme_dialog ();
/* FIXME: What do we really do when there is no theme? Ask Havoc here. */
tree_view = WID ("control_theme_treeview");
theme = gconf_client_get_string (client, GTK_THEME_KEY, NULL);
update_list_something (tree_view, theme);
g_free (theme);
tree_view = WID ("window_theme_treeview");
wm_settings.flags = GNOME_WM_SETTING_THEME;
if (window_manager) {
gnome_window_manager_get_settings (window_manager, &wm_settings);
update_list_something (tree_view, wm_settings.theme);
}
tree_view = WID ("icon_theme_treeview");
theme = gconf_client_get_string (client, ICON_THEME_KEY, NULL);
update_list_something (tree_view, theme);
g_free (theme);
}