Question with selection



Attached is a patched version of the theme selector that also, if it
detects metacity running, also allows you to change the metacity
themes.  I realize the UI is not totally polished (there sizings/borders
look slightly different), but for the most part it is complete. 
However, in writing this, I have hit a snag that has stopped me from
finishing it, namely the selection from one treeview seems to be
slipping over into the other window (the problem reveals itself between
lines 130 and 142).  If anyone could point me towards what I am doing
wrong I would really apreciate it.

	Pete
/* This program was written with lots of love under the GPL by Jonathan
 * Blandford <jrb gnome org>
 */

#include <config.h>

#include <string.h>
#include <gtk/gtk.h>
#include <gconf/gconf-client.h>
#include <glade/glade.h>
#include <libgnomevfs/gnome-vfs.h>
#include <libgnomevfs/gnome-vfs-mime-utils.h>
#include "theme-common.h"
#include "capplet-util.h"
#include "activate-settings-daemon.h"
#include "gconf-property-editor.h"
#include "file-transfer-dialog.h"

#define GTK_THEME_KEY "/desktop/gnome/interface/gtk_theme"
#define METACITY_THEME_KEY "/apps/metacity/general/theme"

#define MAX_ELEMENTS_BEFORE_SCROLLING 8

#define GLADE_HOOKUP_OBJECT(component,widget,name) \
  gtk_object_set_data_full (GTK_OBJECT (component), name, \
    gtk_widget_ref (widget), (GtkDestroyNotify) gtk_widget_unref)

#ifdef PACKAGE_DATA_DIR
const gchar *package_data_dir = PACKAGE_DATA_DIR;
#else
const gchar *package_data_dir = "";
#endif
const gchar *theme_sub_dir = "/metacity/themes";

GtkWidget * temp_gtk_theme_notebook;

enum
{
	THEME_NAME_COLUMN,
	N_COLUMNS
};

enum
{
	TARGET_URI_LIST,
	TARGET_NS_URL
};

static GtkTargetEntry drop_types[] = {
	{"text/uri-list", 0, TARGET_URI_LIST},
	{"_NETSCAPE_URL", 0, TARGET_NS_URL}
};

static gint n_drop_types = sizeof (drop_types) / sizeof (GtkTargetEntry);
static gboolean setting_model = FALSE;
static gboolean initial_scroll = TRUE;

static GladeXML *
create_dialog (void)
{
	GladeXML *dialog;

	dialog = glade_xml_new (GLADEDIR "/theme-properties.glade", NULL,
				NULL);

	return dialog;
}

GtkWidget* 
lookup_widget (GtkWidget * widget, const gchar * widget_name)
{
	GtkWidget *parent, *found_widget;

	for (;;)
	{
		if (GTK_IS_MENU (widget))
			parent = gtk_menu_get_attach_widget (GTK_MENU
							     (widget));
		else
			parent = widget->parent;
		if (!parent)
			parent = gtk_object_get_data (GTK_OBJECT (widget),
						      "GladeParentKey");
		if (parent == NULL)
			break;
		widget = parent;
	}

	found_widget = (GtkWidget *) gtk_object_get_data (GTK_OBJECT (widget),
							  widget_name);
	if (!found_widget)
		g_warning ("Widget not found: %s", widget_name);
	return found_widget;
}


static void
theme_selection_changed (GtkTreeSelection * selection, gpointer data)
{
	GtkTreeModel *model;
	gchar *new_key;
	gchar *theme_key;
	GConfClient *client;
	GtkTreeIter iter;
	GladeXML *dialog = data;

	if (setting_model)
		return;
	
	client = gconf_client_get_default ();

//	if (gtk_notebook_get_current_page  (GTK_NOTEBOOK (temp_gtk_theme_notebook)) == 1)
	if (gtk_tree_selection_get_tree_view (selection) == lookup_widget (WID ("theme_dialog"), "metacity_treeview"))
		theme_key = METACITY_THEME_KEY;
	else
		theme_key = GTK_THEME_KEY;	

	if (gtk_tree_selection_get_selected (selection, &model, &iter))
	{
		gtk_tree_model_get (model, &iter,
				    THEME_NAME_COLUMN, &new_key, -1);
	}
	else
		/* This shouldn't happen */
	{
		new_key = NULL;
	}
		printf ("As of 1, it is %s \n", gconf_client_get_string (client, GTK_THEME_KEY, NULL));
		printf ("NEW KEY == %s \n", new_key);
		printf ("theme_key == %s \n", theme_key);
		printf ("Gnotebook page == %i \n", gtk_notebook_get_current_page  (GTK_NOTEBOOK (temp_gtk_theme_notebook)));
	if (new_key != NULL)
	{
		gchar *old_key;

		old_key =
			gconf_client_get_string (client, theme_key, NULL);
		if (old_key && strcmp (old_key, new_key))
		{
			gconf_client_set_string (client, theme_key,
						 new_key, NULL);
		}
		g_free (old_key);
	}
	else
	{
		gconf_client_unset (client, theme_key, NULL);
	}
		printf ("As of 2, it is %s \n", gconf_client_get_string (client, GTK_THEME_KEY, NULL));

	g_free (new_key);
	printf("---\n");
}

static void
read_themes (GladeXML * dialog)
{
	GConfClient *client;
	GList *gtk_theme_list;
	GList *list;
	GtkTreeModel *model;
	GtkTreeView *tree_view;
	gchar *current_theme;
	gint i = 0;
	gboolean current_theme_found = FALSE;
	gint theme_found_num = NULL;
	GtkTreeRowReference *row_ref = NULL;

	
	client = gconf_client_get_default ();

	gtk_theme_list = theme_common_get_list ();
	tree_view = GTK_TREE_VIEW (WID ("theme_treeview"));
	model = gtk_tree_view_get_model (tree_view);

	setting_model = TRUE;
	gtk_list_store_clear (GTK_LIST_STORE (model));

	current_theme = gconf_client_get_string (client, GTK_THEME_KEY, NULL);
	if (current_theme == NULL)
		current_theme = g_strdup ("Default");
	printf ("Current_theme == %s\n", current_theme);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
					(WID ("theme_swindow")),
					GTK_POLICY_NEVER, GTK_POLICY_NEVER);
	gtk_widget_set_usize (WID ("theme_swindow"), -1, -1);

	for (list = gtk_theme_list; list; list = list->next)
	{
		ThemeInfo *info = list->data;
		GtkTreeIter iter;

		if (!info->has_gtk)
			continue;

		gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
				    THEME_NAME_COLUMN, info->name, -1);

		if (strcmp (current_theme, info->name) == 0)
		{
			GtkTreeSelection *selection;

			selection = gtk_tree_view_get_selection (tree_view);
			gtk_tree_selection_select_iter (selection, &iter);
			if (initial_scroll)
			{
				GtkTreePath *path;

				path = gtk_tree_model_get_path (model, &iter);
				row_ref =
					gtk_tree_row_reference_new (model,
								    path);
				gtk_tree_path_free (path);
			}
			current_theme_found = TRUE;
			theme_found_num = i;
		}

		if (i == MAX_ELEMENTS_BEFORE_SCROLLING)
		{
			GtkRequisition rectangle;
			gtk_widget_size_request (GTK_WIDGET (tree_view),
						 &rectangle);
			gtk_widget_set_usize (WID ("theme_swindow"), -1,
					      rectangle.height);
			gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
							(WID
							 ("theme_swindow")),
							GTK_POLICY_NEVER,
							GTK_POLICY_AUTOMATIC);
		}
		i++;
	}

	if (!current_theme_found)
	{
		GtkTreeSelection *selection =
			gtk_tree_view_get_selection (tree_view);
		GtkTreeIter iter;

		gtk_list_store_prepend (GTK_LIST_STORE (model), &iter);
		gtk_list_store_set (GTK_LIST_STORE (model), &iter,
				    THEME_NAME_COLUMN, current_theme, -1);
		gtk_tree_selection_select_iter (selection, &iter);
		if (initial_scroll)
		{
			GtkTreePath *path;

			path = gtk_tree_model_get_path (model, &iter);
			row_ref = gtk_tree_row_reference_new (model, path);
			gtk_tree_path_free (path);
		}
	}

	if (row_ref && initial_scroll)
	{
		GtkTreePath *path;

		path = gtk_tree_row_reference_get_path (row_ref);

		gtk_tree_view_scroll_to_cell (tree_view, path, NULL, TRUE,
					      0.5, 0.0);

		gtk_tree_path_free (path);
		gtk_tree_row_reference_free (row_ref);
		initial_scroll = FALSE;
	}
	setting_model = FALSE;

	g_free (current_theme);
}


static void
pre_read_themes (GtkWidget * button, gpointer data)
{
	GladeXML *dialog = data;
	read_themes (dialog);
}

static void
theme_key_changed (GConfClient * client,
		   guint cnxn_id, GConfEntry * entry, gpointer user_data)
{
	if (strcmp (entry->key, GTK_THEME_KEY))
		return;

	read_themes ((GladeXML *) user_data);
}


static void
theme_changed_func (gpointer uri, gpointer user_data)
{
	read_themes ((GladeXML *) user_data);
}

static gint
sort_func (GtkTreeModel * model,
	   GtkTreeIter * a, GtkTreeIter * b, gpointer user_data)
{
	gchar *a_str = NULL;
	gchar *b_str = NULL;

	gtk_tree_model_get (model, a, 0, &a_str, -1);
	gtk_tree_model_get (model, b, 0, &b_str, -1);

	if (a_str == NULL)
		a_str = g_strdup ("");
	if (b_str == NULL)
		b_str = g_strdup ("");

	if (!strcmp (a_str, "Default"))
		return -1;
	if (!strcmp (b_str, "Default"))
		return 1;

	return g_utf8_collate (a_str, b_str);
}

/* Callback issued during drag movements */

static gboolean
drag_motion_cb (GtkWidget * widget, GdkDragContext * context,
		gint x, gint y, guint time, gpointer data)
{
	return FALSE;
}

/* Callback issued during drag leaves */

static void
drag_leave_cb (GtkWidget * widget, GdkDragContext * context,
	       guint time, gpointer data)
{
	gtk_widget_queue_draw (widget);
}

/* Callback issued on actual drops. Attempts to load the file dropped. */
static void
drag_data_received_cb (GtkWidget * widget, GdkDragContext * context,
		       gint x, gint y,
		       GtkSelectionData * selection_data,
		       guint info, guint time, gpointer data)
{
	GList *uris;
	GladeXML *dialog = data;
	gchar *filename;

	if (!(info == TARGET_URI_LIST || info == TARGET_NS_URL))
		return;

	uris = gnome_vfs_uri_list_parse ((gchar *) selection_data->data);

	filename =
		gnome_vfs_uri_to_string (uris->data, GNOME_VFS_URI_HIDE_NONE);
	if (strncmp (filename, "http://";, 7)
	    && strncmp (filename, "ftp://";, 6))
	{
		g_free (filename);
		filename =
			gnome_vfs_uri_to_string (uris->data,
						 GNOME_VFS_URI_HIDE_TOPLEVEL_METHOD);
	}
	gnome_file_entry_set_filename (GNOME_FILE_ENTRY
				       (WID ("install_theme_picker")),
				       filename);
	g_free (filename);
	gnome_vfs_uri_list_unref (uris);
	gtk_widget_show (WID ("install_dialog"));
}

static void
show_install_dialog (GtkWidget * button, gpointer data)
{
	GladeXML *dialog = data;
	gtk_widget_show (WID ("install_dialog"));
}

static void
show_manage_themes (GtkWidget * button, gpointer data)
{
	gchar *path, *command;
	GnomeVFSURI *uri;

	if (gtk_notebook_get_current_page  (GTK_NOTEBOOK (temp_gtk_theme_notebook)) == 1)
		path = g_strdup_printf ("%s/.metacity/themes",
					g_get_home_dir ());
	else
		path = g_strdup_printf ("%s/.themes", g_get_home_dir ());
	uri = gnome_vfs_uri_new (path);

	if (!gnome_vfs_uri_exists (uri))
	{
		/* Create the directory */
		gnome_vfs_make_directory_for_uri (uri, 0775);
	}
	gnome_vfs_uri_unref (uri);

	command = g_strdup_printf ("nautilus --no-desktop %s", path);
	g_free (path);

	g_spawn_command_line_async (command, NULL);
	g_free (command);
}

static void
transfer_cancel_cb (GtkWidget * dlg, gchar * path)
{
	gnome_vfs_unlink (path);
	g_free (path);
	gtk_widget_destroy (dlg);
}
static void
transfer_done_cb (GtkWidget * dlg, gchar * path)
{
	gchar *answer;
	answer = gnome_vfs_get_mime_type (path);
	if (g_ascii_strcasecmp (answer, "application/x-bzip-compressed-tar") == 0)
	{
		int status;
		gchar *command;
		/* this should be something more clever and nonblocking */
		if (gtk_notebook_get_current_page  (GTK_NOTEBOOK (temp_gtk_theme_notebook)) == 1)
			command =
				g_strdup_printf
				("sh -c 'bzip2 -d -c < \"%s\" | tar xf - -C \"%s/.metacity/themes\"'",
				 path, g_get_home_dir ());
		else 
			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);
	}
	
	if (g_ascii_strcasecmp (answer, "application/x-compressed-tar") == 0)
	{
		int status;
		gchar *command;

		/* this should be something more clever and nonblocking */
		if (gtk_notebook_get_current_page   (GTK_NOTEBOOK (temp_gtk_theme_notebook)) == 1)
			command =
				g_strdup_printf
				("sh -c 'gzip -d -c < \"%s\" | tar xf - -C \"%s/.metacity/themes\"'",
				 path, g_get_home_dir ());
		else
			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);
	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;

	if (response_id == GTK_RESPONSE_HELP)
	{
		capplet_help (GTK_WINDOW (widget),
			      "wgoscustdesk.xml", "goscustdesk-12");
		return;
	}

	if (response_id == 0)
	{
		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;

		gtk_widget_hide (widget);

		src_uri = gnome_vfs_uri_new (filename);
		base = gnome_vfs_uri_extract_short_name (src_uri);
		src = g_list_append (NULL, src_uri);
		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);
	}
	else
		gtk_widget_hide (widget);
}

static void
cb_dialog_response (GtkDialog * dialog, gint response_id)
{
	if (response_id == GTK_RESPONSE_HELP)
		capplet_help (GTK_WINDOW (dialog),
			      "wgoscustdesk.xml", "goscustdesk-12");
	else
		gtk_main_quit ();
}

static void
check_metacity_themes (GtkWidget * widget)
{
	enum
	{ NAME_COL };

	
	
	GtkListStore *themeList = gtk_list_store_new (1, G_TYPE_STRING);
	GtkCellRenderer *renderer;
	GtkTreeViewColumn *column;
	GtkTreeIter iter;
	GtkTreePath *path;
	GConfClient *client;
	gint i;
	gint good_num = -1;
	gchar *test_string;
	gchar *meta_city_theme_dir =
		(gchar *) malloc (strlen (package_data_dir) +
				  strlen (theme_sub_dir) + 1);
	const gchar *filename;
	GPtrArray *themeNameHolder = g_ptr_array_new ();
	gchar *possibleThemeDirs[5] =
		{ g_build_filename (g_get_home_dir (), ".metacity", "themes",
				    NULL),
		meta_city_theme_dir,
		"/usr/share/metacity/themes/",
		"/usr/local/share/metacity/themes/"
		};

	client = gconf_client_get_default ();

	test_string = gconf_client_get_string (client,
					       "/apps/metacity/general/theme",
					       NULL);

	sprintf (meta_city_theme_dir, "%s%s", package_data_dir,
		 theme_sub_dir);

/* Search the paths that metacity-setup will search for themes in for directories 
	and place all found themes in a single pointer array */

	for (i = 0; i < 3; i++)
	{
		if (g_file_test (possibleThemeDirs[i], G_FILE_TEST_IS_DIR))
		{
			GDir *themeDirectory =
				g_dir_open (possibleThemeDirs[i], 0, NULL);

			while ((filename =
				g_dir_read_name (themeDirectory)) != NULL)
				if (g_file_test
				    (g_build_filename
				     (possibleThemeDirs[i], filename, NULL),
				     G_FILE_TEST_IS_DIR))
					g_ptr_array_add (themeNameHolder,
							 g_strdup (filename));
			g_dir_close (themeDirectory);
		}
	}

	/*  Now place all of the found theme dirs from and fill a gtk_list_store with them */


	for (i = 0; i < themeNameHolder->len; i++)
	{
		gtk_list_store_append (themeList, &iter);
		gtk_list_store_set (GTK_LIST_STORE (themeList), &iter,
				    NAME_COL,
				    g_ptr_array_index (themeNameHolder, i),
				    -1);

		/* Here we are trying to find the current theme so that, when metacity-setup starts,
		 * it doesn't default back to Atlanta, but keeps the current appearence.  This is done
		 * by checking each found dir and checking it against the current one (gotten from gconf)
		 * If the current theme is found, it's index is placed in good_num, which is used later to
		 * actuallly select the item that is already being displayed */

		if (g_ascii_strcasecmp
		    (test_string,
		     g_ptr_array_index (themeNameHolder, i)) == 0)
		{
			good_num = i;
		}
	}
	gtk_tree_view_set_model (GTK_TREE_VIEW (widget),
				 GTK_TREE_MODEL (themeList));
	
	renderer = gtk_cell_renderer_text_new ();
	column = gtk_tree_view_column_new_with_attributes ("Installed Themes",
							   renderer,
							   "text", NAME_COL,
							   NULL);

	/*      This checks to see if columns are already defined, and removes them if they are.  This is done
	 * so that, when the list is refreshed, multiple columns are not created */
	if (gtk_tree_view_get_column (GTK_TREE_VIEW (widget), 0))
		gtk_tree_view_remove_column (GTK_TREE_VIEW (widget),
					     gtk_tree_view_get_column
					     (GTK_TREE_VIEW (widget), 0));

	gtk_tree_view_append_column (GTK_TREE_VIEW (widget), column);

	/*      This here actually selects the currently defined theme to maintain a smooth appearence,
	 * assuming that the current theme was found in the list of themes, which would make i == something
	 * other than -1 */

	path = gtk_tree_path_new ();
	
	if (good_num != -1)
	{
		gtk_tree_path_append_index (path, good_num);

		gtk_tree_view_set_cursor (GTK_TREE_VIEW (widget),
					  path, NULL, FALSE);
	}

}


static void
pre_check_metacity_themes (GtkButton * button, gpointer user_data)
{
	check_metacity_themes (lookup_widget
			       (GTK_WIDGET (button), "metacity_treeview"));
}

/* NEW */
static void
add_metacity_dialog (gpointer data)
{
	GladeXML *dialog = data;
	GtkWidget *metacity_tab_label;
	GtkWidget *metacity_vbox;
	GtkWidget *metacity_vbox_frame;
	GtkWidget *metacity_vbox_frame_vbox;
	GtkWidget *metacity_vbox_frame_vbox_hbox;
	GtkWidget *metacity_vbox_frame_vbox_hbox_vbox;
	GtkWidget *metacity_vbox_frame_vbox_hbox2;
	GtkWidget *metacity_install_new_button;
	GtkWidget *metacity_theme_folder_button;
	GtkWidget *metacity_refresh_button;
	GtkWidget *metacity_theme_window;
	GtkWidget *metacity_treeview;
	GtkWidget *metacity_help_label;
	GtkWidget *metacity_image;
	GtkTreeSelection *metacity_selection;
	
	metacity_vbox = gtk_vbox_new (FALSE, 8);
	gtk_widget_show (metacity_vbox);

	metacity_vbox_frame = gtk_frame_new ("Installed Themes");
	gtk_widget_show (metacity_vbox_frame);
	gtk_box_pack_start (GTK_BOX (metacity_vbox), metacity_vbox_frame,
			    TRUE, TRUE, 0);
	gtk_container_set_border_width (GTK_CONTAINER (metacity_vbox), 8);

	metacity_vbox_frame_vbox = gtk_vbox_new (FALSE, 0);
	gtk_widget_show (metacity_vbox_frame_vbox);
	gtk_container_add (GTK_CONTAINER (metacity_vbox_frame),
			   metacity_vbox_frame_vbox);

	metacity_vbox_frame_vbox_hbox = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (metacity_vbox_frame_vbox_hbox);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox),
			    metacity_vbox_frame_vbox_hbox, TRUE, TRUE, 0);
	gtk_container_set_border_width (GTK_CONTAINER
					(metacity_vbox_frame_vbox_hbox), 5);

	metacity_vbox_frame_vbox_hbox_vbox = gtk_vbox_new (FALSE, 8);
	gtk_widget_show (metacity_vbox_frame_vbox_hbox_vbox);
	gtk_box_pack_end (GTK_BOX (metacity_vbox_frame_vbox_hbox),
			  metacity_vbox_frame_vbox_hbox_vbox, FALSE, FALSE,
			  0);
	gtk_container_set_border_width (GTK_CONTAINER
					(metacity_vbox_frame_vbox_hbox_vbox),
					5);

	metacity_install_new_button =
		gtk_button_new_with_mnemonic (_("_Install new theme..."));
	gtk_widget_show (metacity_install_new_button);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox_hbox_vbox),
			    metacity_install_new_button, FALSE, FALSE, 0);

	g_signal_connect (G_OBJECT (metacity_install_new_button), "clicked",
			  G_CALLBACK (show_install_dialog), dialog);

	GLADE_HOOKUP_OBJECT (WID ("theme_dialog"),
			     metacity_install_new_button,
			     "metacity_install_new_button");

	metacity_theme_folder_button =
		gtk_button_new_with_mnemonic (_("_Go to theme folder"));
	gtk_widget_show (metacity_theme_folder_button);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox_hbox_vbox),
			    metacity_theme_folder_button, FALSE, FALSE, 0);

	g_signal_connect (G_OBJECT (metacity_theme_folder_button), "clicked",
			  G_CALLBACK (show_manage_themes), dialog);

	GLADE_HOOKUP_OBJECT (WID ("theme_dialog"),
			     metacity_theme_folder_button,
			     "metacity_theme_folder_button");

	metacity_refresh_button =
		gtk_button_new_with_mnemonic (_("_Refresh theme list"));
	gtk_widget_show (metacity_refresh_button);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox_hbox_vbox),
			    metacity_refresh_button, FALSE, FALSE, 0);

	g_signal_connect (G_OBJECT (metacity_refresh_button), "clicked",
			  G_CALLBACK (pre_check_metacity_themes), dialog);

	GLADE_HOOKUP_OBJECT (WID ("theme_dialog"),
			     metacity_refresh_button,
			     "metacity_refresh_button");

	metacity_theme_window = gtk_scrolled_window_new (NULL, NULL);

	gtk_widget_show (metacity_theme_window);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox_hbox),
			    metacity_theme_window, TRUE, TRUE, 0);
	gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW
					(metacity_theme_window),
					GTK_POLICY_AUTOMATIC,
					GTK_POLICY_AUTOMATIC);
	gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW
					     (metacity_theme_window),
					     GTK_SHADOW_IN);

	metacity_treeview = gtk_tree_view_new ();
	gtk_widget_show (metacity_treeview);
	gtk_container_add (GTK_CONTAINER (metacity_theme_window),
			   metacity_treeview);
	gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (metacity_treeview),
					   FALSE);
	gtk_tree_view_set_enable_search (GTK_TREE_VIEW (metacity_treeview),
					 FALSE);

	GLADE_HOOKUP_OBJECT (WID ("theme_dialog"), metacity_treeview,
			     "metacity_treeview");

	metacity_selection =
		gtk_tree_view_get_selection (GTK_TREE_VIEW (metacity_treeview));
	gtk_tree_selection_set_mode (metacity_selection, GTK_SELECTION_BROWSE);
	g_signal_connect (G_OBJECT (metacity_selection), "changed",
			  (GCallback) theme_selection_changed, NULL);

	metacity_vbox_frame_vbox_hbox2 = gtk_hbox_new (FALSE, 0);
	gtk_widget_show (metacity_vbox_frame_vbox_hbox2);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox),
			    metacity_vbox_frame_vbox_hbox2, FALSE, FALSE, 0);
	gtk_container_set_border_width (GTK_CONTAINER
					(metacity_vbox_frame_vbox_hbox2), 5);

	metacity_image = gtk_image_new_from_stock ("gtk-dialog-info",
						   GTK_ICON_SIZE_DIALOG);
	gtk_widget_show (metacity_image);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox_hbox2),
			    metacity_image, FALSE, FALSE, 5);

	metacity_help_label =
		gtk_label_new (_
			       ("New themes can also be installed by dragging\nthem into the window"));
	gtk_widget_show (metacity_help_label);
	gtk_box_pack_start (GTK_BOX (metacity_vbox_frame_vbox_hbox2),
			    metacity_help_label, FALSE, FALSE, 0);
	metacity_tab_label = gtk_label_new ("Window Themes");
	gtk_notebook_append_page (GTK_NOTEBOOK
				  (WID ("gtk_theme_notebook")),
				  metacity_vbox, metacity_tab_label);

	check_metacity_themes (metacity_treeview);
}

/* END NEW */

static void
setup_dialog (GladeXML * dialog)
{
	GConfClient *client;
	GtkWidget *widget;
	GtkTreeModel *model;
	GtkTreeSelection *selection;

	client = gconf_client_get_default ();
	
	/* NEW */
	temp_gtk_theme_notebook = WID ("gtk_theme_notebook");
	
	if ((g_ascii_strcasecmp (gconf_client_get_string (client,
							"/desktop/gnome/applications/window_manager/current",
							  NULL), "metacity") == 0) ||
	    (g_strrstr ((gconf_client_get_string
	       (client, "/desktop/gnome/applications/window_manager/default",
			NULL), "metacity"), "metacity") != NULL))
	{
		if (g_file_test (g_build_filename (g_get_home_dir (), ".metacity", NULL), G_FILE_TEST_IS_DIR))
		{
			if (!g_file_test (g_build_filename (g_get_home_dir (), ".metacity", "themes", NULL), G_FILE_TEST_IS_DIR))
				mkdir ( g_build_filename (g_get_home_dir (), ".metacity", "themes", NULL), 0744);
		}
		else
		{
			mkdir ( g_build_filename (g_get_home_dir (), ".metacity", NULL), 0744);
			mkdir ( g_build_filename (g_get_home_dir (), ".metacity", "themes", NULL), 0744);
		}
		add_metacity_dialog (dialog);
	}
	/* END NEW */
	
	gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW
						     (WID ("theme_treeview")),
						     -1, NULL,
						     gtk_cell_renderer_text_new
						     (), "text",
						     THEME_NAME_COLUMN, NULL);
	gconf_client_add_dir (client, "/desktop/gnome/interface",
			      GCONF_CLIENT_PRELOAD_ONELEVEL, NULL);
	gconf_client_notify_add (client, GTK_THEME_KEY,
				 (GConfClientNotifyFunc) & theme_key_changed,
				 dialog, NULL, NULL);
	model = (GtkTreeModel *) gtk_list_store_new (N_COLUMNS,
						     G_TYPE_STRING);
	gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (model), 0,
					 sort_func, NULL, NULL);
	gtk_tree_sortable_set_sort_column_id (GTK_TREE_SORTABLE (model), 0,
					      GTK_SORT_ASCENDING);
	gtk_tree_view_set_model (GTK_TREE_VIEW (WID ("theme_treeview")),
				 model);
	selection =
		gtk_tree_view_get_selection (GTK_TREE_VIEW
					     (WID ("theme_treeview")));
	gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
	g_signal_connect (G_OBJECT (selection), "changed",
			  (GCallback) theme_selection_changed, NULL);
	read_themes (dialog);
	theme_common_register_theme_change (theme_changed_func, dialog);

	widget = WID ("install_button");
	g_signal_connect (G_OBJECT (widget), "clicked",
			  G_CALLBACK (show_install_dialog), dialog);
	widget = WID ("manage_button");
	g_signal_connect (G_OBJECT (widget), "clicked",
			  G_CALLBACK (show_manage_themes), dialog);
	widget = WID ("refresh_button");
	g_signal_connect (G_OBJECT (widget), "clicked",
			  G_CALLBACK (pre_read_themes), dialog);

	widget = WID ("install_dialog");
	g_signal_connect (G_OBJECT (widget), "response",
			  G_CALLBACK (install_dialog_response), dialog);

	widget = WID ("theme_dialog");

	g_signal_connect (G_OBJECT (widget),
			  "response", G_CALLBACK (cb_dialog_response), NULL);

	gtk_drag_dest_set (widget, GTK_DEST_DEFAULT_ALL,
			   drop_types, n_drop_types,
			   GDK_ACTION_COPY | GDK_ACTION_LINK |
			   GDK_ACTION_MOVE);

	g_signal_connect (G_OBJECT (widget), "drag-motion",
			  G_CALLBACK (drag_motion_cb), NULL);
	g_signal_connect (G_OBJECT (widget), "drag-leave",
			  G_CALLBACK (drag_leave_cb), NULL);
	g_signal_connect (G_OBJECT (widget), "drag-data-received",
			  G_CALLBACK (drag_data_received_cb), dialog);

	gtk_widget_show (widget);
}

int
main (int argc, char *argv[])
{
	GladeXML *dialog;

	bindtextdomain (GETTEXT_PACKAGE, GNOMELOCALEDIR);
	bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
	textdomain (GETTEXT_PACKAGE);

	gnome_program_init ("gnome-theme-properties", VERSION,
			    LIBGNOMEUI_MODULE, argc, argv,
			    GNOME_PARAM_APP_DATADIR, GNOMECC_DATA_DIR, NULL);

	activate_settings_daemon ();

	dialog = create_dialog ();
	setup_dialog (dialog);

	gtk_main ();

	return 0;
}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]