[prev in list] [next in list] [prev in thread] [next in thread] 

List:       sylpheed
Subject:    [sylpheed:23860] GTK 2-ize foldersel.c
From:       Alfons Hoogervorst <alfons () proteus ! demon ! nl>
Date:       2005-01-19 22:30:25
Message-ID: 20050119233025.33830015.alfons () proteus ! demon ! nl
[Download RAW message or body]

Lo Hiro,

Over the last four weeks, for claws, I moved 90% of the dialogs to GTK 2 
(missing are the news group list dialog and the address book dialogs), so good
 idea to feed them to you too.

You can pull the patches from my darcs tree, or just track the tree here:

http://hoogervorst.dyndns.org/cgi-bin/darcs.cgi/sylpheed/?c=patches

Here's a description of the attached patches:

* add_gtkut_stock_button_set_create.gtkutils.patch

	Adds a gtkut_stock_button_set_create() function to create
	sets of stock buttons. Needed for foldersel.c.

* add_stock_pixbuf_gdk.stockpixmap.patch
	
	Adds a stock_pixbuf_gdk() function to create / cache 
	a pixbuf structure from pixmap data. This is different
	from the Claws version (which has "theming")

* to-gtk2-foldersel.patch

	Moves foldersel.c to use GTK 2 widgets. This is also 
	based on my Claws work, with a sort fix contribution
	by Stephan Sachse

Bye.

-- 
Ecuación algebraico sin solución posible,
a menos de poseer profundos conocimientos
en matemática - Revueltas (Ocho Por Radio)


["add_gtkut_stock_button_set_create.gtkutils.patch" (text/plain)]

Wed Jan 19 23:14:18 CET 2005  alfons_hoogervorst@gmail_com
  * foldersel move to GTK 2
Wed Jan 19 23:13:03 CET 2005  alfons_hoogervorst@gmail_com
  * stock_pixmap add stock_pixbuf_gdk
Wed Jan 19 23:11:49 CET 2005  alfons_hoogervorst@gmail_com
  * gtkutils add gtkut_stock_button_create()
--- sylpheed-old/trunk/src/gtkutils.c	2005-01-19 23:18:52.000000000 +0100
+++ sylpheed-new/trunk/src/gtkutils.c	2005-01-19 22:14:34.000000000 +0100
@@ -106,6 +106,38 @@
 	}
 }
 
+void gtkut_stock_button_set_create(GtkWidget **bbox,
+				   GtkWidget **button1, const gchar *label1,
+				   GtkWidget **button2, const gchar *label2,
+				   GtkWidget **button3, const gchar *label3)
+{
+	g_return_if_fail(bbox != NULL);
+	g_return_if_fail(button1 != NULL);
+
+	*bbox = gtk_hbutton_box_new();
+	gtk_button_box_set_layout(GTK_BUTTON_BOX(*bbox), GTK_BUTTONBOX_END);
+	gtk_box_set_spacing(GTK_BOX(*bbox), 5);
+
+	*button1 = gtk_button_new_from_stock(label1);
+	GTK_WIDGET_SET_FLAGS(*button1, GTK_CAN_DEFAULT);
+	gtk_box_pack_start(GTK_BOX(*bbox), *button1, TRUE, TRUE, 0);
+	gtk_widget_show(*button1);
+
+	if (button2) {
+		*button2 = gtk_button_new_from_stock(label2);
+		GTK_WIDGET_SET_FLAGS(*button2, GTK_CAN_DEFAULT);
+		gtk_box_pack_start(GTK_BOX(*bbox), *button2, TRUE, TRUE, 0);
+		gtk_widget_show(*button2);
+	}
+
+	if (button3) {
+		*button3 = gtk_button_new_from_stock(label3);
+		GTK_WIDGET_SET_FLAGS(*button3, GTK_CAN_DEFAULT);
+		gtk_box_pack_start(GTK_BOX(*bbox), *button3, TRUE, TRUE, 0);
+		gtk_widget_show(*button3);
+	}
+}
+
 static void combo_button_size_request(GtkWidget *widget,
 				      GtkRequisition *requisition,
 				      gpointer data)

--- sylpheed-old/trunk/src/gtkutils.h	2005-01-19 23:18:52.000000000 +0100
+++ sylpheed-new/trunk/src/gtkutils.h	2005-01-19 22:15:02.000000000 +0100
@@ -96,6 +96,14 @@
 					 const gchar	 *label2,
 					 GtkWidget	**button3,
 					 const gchar	 *label3);
+					 
+void gtkut_stock_button_set_create	(GtkWidget	**bbox,
+					 GtkWidget	**button1,
+					 const gchar	 *label1,
+					 GtkWidget	**button2,
+					 const gchar	 *label2,
+					 GtkWidget	**button3,
+					 const gchar	 *label3);
 
 ComboButton *gtkut_combo_button_create	(GtkWidget		*button,
 					 GtkItemFactoryEntry	*entries,



["add_stock_pixbuf_gdk.stockpixmap.patch" (text/plain)]

Wed Jan 19 23:14:18 CET 2005  alfons_hoogervorst@gmail_com
  * foldersel move to GTK 2
Wed Jan 19 23:13:03 CET 2005  alfons_hoogervorst@gmail_com
  * stock_pixmap add stock_pixbuf_gdk
--- sylpheed-old/trunk/src/stock_pixmap.c	2005-01-19 23:17:57.000000000 +0100
+++ sylpheed-new/trunk/src/stock_pixmap.c	2005-01-19 22:06:06.000000000 +0100
@@ -86,6 +86,7 @@
 	gchar **data;
 	GdkPixmap *pixmap;
 	GdkBitmap *mask;
+	GdkPixbuf *pixbuf;
 };
 
 static StockPixmapData pixmaps[] =
@@ -159,6 +160,29 @@
 	return gtk_pixmap_new(pixmap, mask);
 }
 
+gint stock_pixbuf_gdk(GtkWidget *window, StockPixmap icon, GdkPixbuf **pixbuf)
+{
+	StockPixmapData *pix_d;
+
+	if (pixbuf)
+		*pixbuf = NULL;
+	
+	g_return_val_if_fail(window != NULL, -1);
+	g_return_val_if_fail(icon >= 0 && icon < N_STOCK_PIXMAPS, -1);
+
+	pix_d = &pixmaps[icon];
+	if (!pix_d->pixbuf)
+		pix_d->pixbuf = gdk_pixbuf_new_from_xpm_data((const gchar **) pix_d->data);
+	
+	if (!pix_d->pixbuf)
+		return -1;
+
+	if (pixbuf) 
+		*pixbuf = pix_d->pixbuf;
+	
+	return 0;
+}
+
 /* create GdkPixmap if it has not created yet */
 gint stock_pixmap_gdk(GtkWidget *window, StockPixmap icon,
 		      GdkPixmap **pixmap, GdkBitmap **mask)

--- sylpheed-old/trunk/src/stock_pixmap.h	2005-01-19 23:17:57.000000000 +0100
+++ sylpheed-new/trunk/src/stock_pixmap.h	2005-01-19 22:04:51.000000000 +0100
@@ -85,6 +85,9 @@
 
 GtkWidget *stock_pixmap_widget	(GtkWidget	 *window,
 				 StockPixmap	  icon);
+gint stock_pixbuf_gdk		(GtkWidget	 *window, 
+				 StockPixmap	  icon, 
+				 GdkPixbuf	**pixbuf);
 gint stock_pixmap_gdk		(GtkWidget	 *window,
 				 StockPixmap	  icon,
 				 GdkPixmap	**pixmap,



["to-gtk2.foldersel.patch" (text/plain)]

Wed Jan 19 23:14:18 CET 2005  alfons_hoogervorst@gmail_com
  * foldersel move to GTK 2
Wed Jan 19 23:13:03 CET 2005  alfons_hoogervorst@gmail_com
  * stock_pixmap add stock_pixbuf_gdk
Wed Jan 19 23:11:49 CET 2005  alfons_hoogervorst@gmail_com
  * gtkutils add gtkut_stock_button_create()
Wed Jan 19 19:56:27 CET 2005  alfons_hoogervorst@gmail_com
  * compose.c: make compile with gcc 2.95.x
--- sylpheed-old/trunk/src/foldersel.c	2005-01-19 23:19:29.000000000 +0100
+++ sylpheed-new/trunk/src/foldersel.c	2005-01-19 23:09:43.000000000 +0100
@@ -23,13 +23,16 @@
 #include <gdk/gdkkeysyms.h>
 #include <gtk/gtkmain.h>
 #include <gtk/gtkwidget.h>
-#include <gtk/gtkctree.h>
 #include <gtk/gtkwindow.h>
 #include <gtk/gtkvbox.h>
 #include <gtk/gtkscrolledwindow.h>
 #include <gtk/gtkentry.h>
 #include <gtk/gtkhbbox.h>
 #include <gtk/gtksignal.h>
+
+#include <gtk/gtktreestore.h>
+#include <gtk/gtktreeview.h>
+
 #include <stdio.h>
 #include <unistd.h>
 #include <string.h>
@@ -50,15 +53,19 @@
 #include "inputdialog.h"
 #include "folder.h"
 
-static GdkPixmap *folderxpm;
-static GdkBitmap *folderxpmmask;
-static GdkPixmap *folderopenxpm;
-static GdkBitmap *folderopenxpmmask;
-static GdkPixmap *foldernoselectxpm;
-static GdkBitmap *foldernoselectxpmmask;
+enum {
+	FOLDERSEL_FOLDERNAME,
+	FOLDERSEL_FOLDERITEM,
+	FOLDERSEL_FOLDERPIXBUF,
+	FOLDERSEL_FOLDEREXPANDER,
+	N_FOLDERSEL_COLUMNS
+};
+
+static GdkPixbuf *folder_pixbuf;
+static GdkPixbuf *folderopen_pixbuf;
 
 static GtkWidget *window;
-static GtkWidget *ctree;
+static GtkTreeView *tree_view;
 static GtkWidget *entry;
 static GtkWidget *ok_button;
 static GtkWidget *cancel_button;
@@ -70,16 +77,17 @@
 static gboolean cancelled;
 static gboolean finished;
 
-static void foldersel_create	(void);
-static void foldersel_init	(void);
-static void foldersel_set_tree	(Folder			*cur_folder,
-				 FolderSelectionType	 type);
-
-static void foldersel_selected	(GtkCList	*clist,
-				 gint		 row,
-				 gint		 column,
-				 GdkEvent	*event,
-				 gpointer	 data);
+static GtkTreeStore *tree_store;
+
+static void foldersel_update_tree_store		(Folder * folder, FolderSelectionType type);
+static void foldersel_create			(void);
+static void foldersel_init_tree_view_images	(void);
+
+static gboolean foldersel_selected(GtkTreeSelection *selection,
+				   GtkTreeModel *model, 
+				   GtkTreePath *path,
+				   gboolean already_selected,
+				   gpointer data);
 
 static void foldersel_ok	(GtkButton	*button,
 				 gpointer	 data);
@@ -94,44 +102,134 @@
 static gboolean key_pressed	(GtkWidget	*widget,
 				 GdkEventKey	*event,
 				 gpointer	 data);
+				 
+static void foldersel_double_click (GtkTreeView		*tree_view, 
+				    GtkTreePath		*path,
+				    GtkTreeViewColumn	*column, 
+				    gpointer		 data);
+
+static gint foldersel_folder_name_compare(GtkTreeModel *model, 
+					  GtkTreeIter *a, 
+					  GtkTreeIter *b, 
+					  gpointer context)
+{
+	gchar *str_a = NULL, *str_b = NULL;
+	gint res = 0;
+	FolderItem *fld_a = NULL, *fld_b = NULL;
+	GtkTreeIter parent;
+
+	gtk_tree_model_get(model, a, 
+			   FOLDERSEL_FOLDERITEM, &fld_a,
+			   -1);
+	gtk_tree_model_get(model, b, 
+			   FOLDERSEL_FOLDERITEM, &fld_b,
+			   -1);
+
+	/* no sort for root folder */
+	if (!gtk_tree_model_iter_parent(GTK_TREE_MODEL(model), &parent, a))
+		return 0;
+
+	/* if both a and b are special folders, sort them according to 
+	 * their types (which is in-order). Note that this assumes that
+	 * there are no multiple folders of a special type. */
+	if (fld_a->stype != F_NORMAL  && fld_b->stype != F_NORMAL)
+		return fld_a->stype < fld_b->stype ? -1 : 1;
+
+	/* if b is normal folder, and a is not, b is smaller (ends up 
+	 * lower in the list) */ 
+	if (fld_a->stype != F_NORMAL && fld_b->stype == F_NORMAL)
+		return -1;
 
-static gint foldersel_clist_compare	(GtkCList	*clist,
-					 gconstpointer	 ptr1,
-					 gconstpointer	 ptr2);
+	/* if b is special folder, and a is not, b is larger (ends up
+	 * higher in the list) */
+	if (fld_a->stype == F_NORMAL && fld_b->stype != F_NORMAL)	 
+		return 1;
+	
+	/* XXX g_utf8_collate_key() comparisons may speed things
+	 * up when having large lists of folders */
+	gtk_tree_model_get(model, a, 
+			   FOLDERSEL_FOLDERNAME, &str_a, 
+			   -1);
+	gtk_tree_model_get(model, b, 
+			   FOLDERSEL_FOLDERNAME, &str_b, 
+			   -1);
+
+	/* otherwise just compare the folder names */		
+	res = g_utf8_collate(str_a, str_b);
+
+	g_free(str_a);
+	g_free(str_b);
+
+	return res;
+}
+
+typedef struct FolderItemSearch {
+	FolderItem  *item;
+	GtkTreePath *path;
+	GtkTreeIter  iter;
+} FolderItemSearch;
+
+static gboolean tree_view_folder_item_func(GtkTreeModel		*model,
+					   GtkTreePath		*path,
+					   GtkTreeIter		*iter,
+					   FolderItemSearch	*data)
+{
+	FolderItem *item = NULL;
+
+	gtk_tree_model_get(model, iter, FOLDERSEL_FOLDERITEM, &item, -1);
+	
+	if (data->item == item) {
+		data->path = gtk_tree_path_copy(path);
+		data->iter = *iter;
+		return TRUE;
+	}
+	
+	return FALSE;
+}
 
-FolderItem *foldersel_folder_sel(Folder *cur_folder,
-				 FolderSelectionType type,
+FolderItem *foldersel_folder_sel(Folder *cur_folder, FolderSelectionType type,
 				 const gchar *default_folder)
 {
-	GtkCTreeNode *node;
-
 	selected_item = NULL;
 
-	if (!window) {
+	if (!window)
 		foldersel_create();
-		foldersel_init();
-	} else
+	else
 		gtk_widget_show(window);
-	manage_window_set_transient(GTK_WINDOW(window));
 
-	foldersel_set_tree(cur_folder, type);
+	/* update the tree */		
+	foldersel_update_tree_store(cur_folder, type);
+
+	gtk_tree_view_expand_all(tree_view); 
+	
+	manage_window_set_transient(GTK_WINDOW(window));
+	
+	gtk_widget_grab_focus(ok_button);
+	gtk_widget_grab_focus(GTK_WIDGET(tree_view));
 
+	/* select current */
 	if (folder_item) {
-		node = gtk_ctree_find_by_row_data
-			(GTK_CTREE(ctree), NULL, folder_item);
-		if (node) {
-			gint row;
-
-			row = gtkut_ctree_get_nth_from_node
-				(GTK_CTREE(ctree), node);
-			gtk_clist_select_row(GTK_CLIST(ctree), row, -1);
-			gtkut_clist_set_focus_row(GTK_CLIST(ctree), row);
-			gtk_ctree_node_moveto(GTK_CTREE(ctree), node, -1,
-					      0.5, 0);
+		FolderItemSearch fis;
+
+		fis.item = folder_item;
+		fis.path = NULL;
+
+		/* find matching model entry */
+		gtk_tree_model_foreach
+			(GTK_TREE_MODEL(tree_store), 
+			 (GtkTreeModelForeachFunc)tree_view_folder_item_func,
+ 		         &fis);
+		
+		if (fis.path) {
+			GtkTreeSelection *selection;
+		
+			selection = gtk_tree_view_get_selection(tree_view);
+			gtk_tree_selection_select_iter(selection, &fis.iter);
+			gtk_tree_view_set_cursor(tree_view, fis.path,
+						 NULL, FALSE);
+			gtk_tree_path_free(fis.path);						 
 		}
 	}
-	gtk_widget_grab_focus(ok_button);
-	gtk_widget_grab_focus(ctree);
 
 	cancelled = finished = FALSE;
 
@@ -140,7 +238,6 @@
 
 	gtk_widget_hide(window);
 	gtk_entry_set_text(GTK_ENTRY(entry), "");
-	gtk_clist_clear(GTK_CLIST(ctree));
 
 	if (!cancelled &&
 	    selected_item && selected_item->path && !selected_item->no_select) {
@@ -150,17 +247,88 @@
 		return NULL;
 }
 
+static void foldersel_insert_gnode_in_store(GtkTreeStore *store, GNode *node, 
+					    GtkTreeIter *parent)
+{
+	FolderItem *item;
+	GtkTreeIter child;
+	GNode *iter;
+
+	g_return_if_fail(node);
+	g_return_if_fail(node->data);
+	g_return_if_fail(store);
+
+	item = FOLDER_ITEM(node->data);
+
+	/* if parent == NULL, top level */
+	gtk_tree_store_append(store, &child, parent);
+
+	/* insert this node */
+	gtk_tree_store_set(store, &child,
+			   FOLDERSEL_FOLDERNAME, item->name,
+			   FOLDERSEL_FOLDERITEM, item,
+			   FOLDERSEL_FOLDERPIXBUF, folder_pixbuf,
+			   FOLDERSEL_FOLDEREXPANDER, node->children ? TRUE : FALSE,
+			   -1);
+	
+	/* insert its children (this node as parent) */
+	for (iter = node->children; iter != NULL; iter = iter->next)
+		foldersel_insert_gnode_in_store(store, iter, &child);
+	
+}
+
+static void foldersel_update_tree_store(Folder *cur_folder, FolderSelectionType type)
+{
+	GList *list;
+
+	gtk_tree_store_clear(tree_store);		
+
+	/* insert folder data */
+	for (list = folder_get_list(); list != NULL; list = list->next) {
+		Folder *folder;
+
+		folder = FOLDER(list->data);
+		g_return_if_fail(folder);
+		if (type != FOLDER_SEL_ALL) {
+			if (FOLDER_TYPE(folder) == F_NEWS)
+				continue;
+		}
+
+		foldersel_insert_gnode_in_store(tree_store, folder->node, NULL);
+	}
+
+	/* sort */
+	gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(tree_store), 
+					     FOLDERSEL_FOLDERNAME,
+					     GTK_SORT_ASCENDING);
+}
+
 static void foldersel_create(void)
 {
 	GtkWidget *vbox;
 	GtkWidget *scrolledwin;
 	GtkWidget *confirm_area;
+	GtkTreeViewColumn *column;
+	GtkCellRenderer *renderer;
+	GtkTreeSelection *selection;
+
+	/* create and initialize tree store */
+	tree_store = gtk_tree_store_new(N_FOLDERSEL_COLUMNS,
+					G_TYPE_STRING,
+					G_TYPE_POINTER,
+					GDK_TYPE_PIXBUF,
+					G_TYPE_BOOLEAN); 
+	gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(tree_store),
+					FOLDERSEL_FOLDERNAME,	
+					foldersel_folder_name_compare, 
+					NULL, NULL);
 
 	window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 	gtk_window_set_title(GTK_WINDOW(window), _("Select folder"));
 	gtk_container_set_border_width(GTK_CONTAINER(window), 4);
 	gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
 	gtk_window_set_modal(GTK_WINDOW(window), TRUE);
+	gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
 	gtk_window_set_policy(GTK_WINDOW(window), FALSE, TRUE, FALSE);
 	gtk_window_set_wmclass
 		(GTK_WINDOW(window), "folder_selection", "Sylpheed");
@@ -179,33 +347,69 @@
 				       GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
 	gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
 
-	ctree = gtk_ctree_new(1, 0);
-	gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(scrolledwin),
-					    GTK_CLIST(ctree)->vadjustment);
-	gtk_container_add(GTK_CONTAINER(scrolledwin), ctree);
-	gtk_clist_set_selection_mode(GTK_CLIST(ctree), GTK_SELECTION_BROWSE);
-	gtk_ctree_set_line_style(GTK_CTREE(ctree), GTK_CTREE_LINES_DOTTED);
-	gtk_ctree_set_expander_style(GTK_CTREE(ctree),
-				     GTK_CTREE_EXPANDER_SQUARE);
-	gtk_ctree_set_indent(GTK_CTREE(ctree), CTREE_INDENT);
-	gtk_clist_set_compare_func(GTK_CLIST(ctree), foldersel_clist_compare);
-	GTK_WIDGET_UNSET_FLAGS(GTK_CLIST(ctree)->column[0].button,
-			       GTK_CAN_FOCUS);
-	/* g_signal_connect(G_OBJECT(ctree), "tree_select_row",
-			    G_CALLBACK(foldersel_selected), NULL); */
-	g_signal_connect(G_OBJECT(ctree), "select_row",
-			 G_CALLBACK(foldersel_selected), NULL);
+	/* create tree view */
+	tree_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model
+		(GTK_TREE_MODEL(tree_store)));
+	g_object_unref(G_OBJECT(tree_store));
 
+	gtk_scrolled_window_set_vadjustment(GTK_SCROLLED_WINDOW(scrolledwin),
+					    gtk_tree_view_get_vadjustment
+						(tree_view));
+	gtk_tree_view_set_headers_visible(tree_view, FALSE);
+	gtk_tree_view_set_rules_hint(tree_view, TRUE);
+	gtk_tree_view_set_search_column(tree_view, FOLDERSEL_FOLDERNAME); 
+	
+	selection = gtk_tree_view_get_selection(tree_view);
+	gtk_tree_selection_set_mode(selection, GTK_SELECTION_BROWSE);
+	gtk_tree_selection_set_select_function(selection, foldersel_selected,
+					       NULL, NULL);
+
+	g_signal_connect(G_OBJECT(tree_view), "row-activated", 
+			 G_CALLBACK(foldersel_double_click), NULL);
+
+	gtk_widget_show(GTK_WIDGET(tree_view));
+
+	/* now safe to initialize images for tree view */
+	foldersel_init_tree_view_images();
+	
+	gtk_container_add(GTK_CONTAINER(scrolledwin), GTK_WIDGET(tree_view));
+	
+	column = gtk_tree_view_column_new();
+
+	renderer = gtk_cell_renderer_pixbuf_new();
+	gtk_tree_view_column_pack_start(column, renderer, FALSE);
+
+	/* tell renderer to act as an expander and use the
+	 * appropriate image if it's not an expander (i.e.
+	 * a folder without children) */
+	g_object_set(renderer,
+		     "pixbuf-expander-open", folderopen_pixbuf,
+		     "pixbuf-expander-closed", folder_pixbuf,
+		     NULL);
+	gtk_tree_view_column_set_attributes(column, renderer,
+                   "is-expander", FOLDERSEL_FOLDEREXPANDER,
+		   "pixbuf",      FOLDERSEL_FOLDERPIXBUF,
+		   NULL);
+			     
+	/* create text renderer */
+	renderer = gtk_cell_renderer_text_new();
+	gtk_tree_view_column_pack_start(column, renderer, TRUE);
+	gtk_tree_view_column_set_attributes(column, renderer,
+					    "text", FOLDERSEL_FOLDERNAME,
+					    NULL);
+	
+	gtk_tree_view_append_column(tree_view, column);
+					    
 	entry = gtk_entry_new();
 	gtk_entry_set_editable(GTK_ENTRY(entry), FALSE);
 	gtk_box_pack_start(GTK_BOX(vbox), entry, FALSE, FALSE, 0);
 	g_signal_connect(G_OBJECT(entry), "activate",
 			 G_CALLBACK(foldersel_activated), NULL);
 
-	gtkut_button_set_create(&confirm_area,
-				&ok_button,	_("OK"),
-				&cancel_button,	_("Cancel"),
-				&new_button,    _("New folder"));
+	gtkut_stock_button_set_create(&confirm_area,
+				      &ok_button,	GTK_STOCK_OK,
+				      &cancel_button,	GTK_STOCK_CANCEL,
+				      &new_button,	GTK_STOCK_NEW);
 
 	gtk_box_pack_end(GTK_BOX(vbox), confirm_area, FALSE, FALSE, 0);
 	gtk_widget_grab_default(ok_button);
@@ -220,165 +424,43 @@
 	gtk_widget_show_all(window);
 }
 
-static void foldersel_init(void)
-{
-	stock_pixmap_gdk(ctree, STOCK_PIXMAP_DIR_CLOSE,
-			 &folderxpm, &folderxpmmask);
-	stock_pixmap_gdk(ctree, STOCK_PIXMAP_DIR_OPEN,
-			 &folderopenxpm, &folderopenxpmmask);
-	stock_pixmap_gdk(ctree, STOCK_PIXMAP_DIR_NOSELECT,
-			 &foldernoselectxpm, &foldernoselectxpmmask);
-}
-
-static gboolean foldersel_gnode_func(GtkCTree *ctree, guint depth,
-				     GNode *gnode, GtkCTreeNode *cnode,
-				     gpointer data)
-{
-	FolderItem *item = FOLDER_ITEM(gnode->data);
-	gchar *name;
-	GdkPixmap *xpm, *openxpm;
-	GdkBitmap *mask, *openmask;
-
-	switch (item->stype) {
-	case F_INBOX:
-		name = _("Inbox");
-		break;
-	case F_OUTBOX:
-		name = _("Sent");
-		break;
-	case F_QUEUE:
-		name = _("Queue");
-		break;
-	case F_TRASH:
-		name = _("Trash");
-		break;
-	case F_DRAFT:
-		name = _("Drafts");
-		break;
-	default:
-		name = item->name;
-
-		if (!item->parent) {
-			switch (FOLDER_TYPE(item->folder)) {
-			case F_MH:
-				Xstrcat_a(name, name, " (MH)", ); break;
-			case F_IMAP:
-				Xstrcat_a(name, name, " (IMAP4)", ); break;
-			case F_NEWS:
-				Xstrcat_a(name, name, " (News)", ); break;
-			default:
-				break;
-			}
-		}
-	}
-
-	if (item->no_select) {
-		GdkColor color_noselect = {0, COLOR_DIM, COLOR_DIM, COLOR_DIM};
-		xpm = openxpm = foldernoselectxpm;
-		mask = openmask = foldernoselectxpmmask;
-		gtk_ctree_node_set_foreground(ctree, cnode, &color_noselect);
-	} else {
-		xpm = folderxpm;
-		mask = folderxpmmask;
-		openxpm = folderopenxpm;
-		openmask = folderopenxpmmask;
-	}
-
-	gtk_ctree_node_set_row_data(ctree, cnode, item);
-	gtk_ctree_set_node_info(ctree, cnode, name,
-				FOLDER_SPACING,
-				xpm, mask, openxpm, openmask,
-				FALSE, FALSE);
-
-	return TRUE;
-}
-
-static void foldersel_expand_func(GtkCTree *ctree, GtkCTreeNode *node,
-				  gpointer data)
-{
-	if (GTK_CTREE_ROW(node)->children)
-		gtk_ctree_expand(ctree, node);
-}
-
-#define SET_SPECIAL_FOLDER(item)					   \
-{									   \
-	if (item) {							   \
-		GtkCTreeNode *node_, *parent, *sibling;			   \
-									   \
-		node_ = gtk_ctree_find_by_row_data			   \
-			(GTK_CTREE(ctree), node, item);			   \
-		if (!node_)						   \
-			g_warning("%s not found.\n", item->path);	   \
-		else {							   \
-			parent = GTK_CTREE_ROW(node_)->parent;		   \
-			if (prev && parent == GTK_CTREE_ROW(prev)->parent) \
-				sibling = GTK_CTREE_ROW(prev)->sibling;	   \
-			else						   \
-				sibling = GTK_CTREE_ROW(parent)->children; \
-			if (node_ != sibling)				   \
-				gtk_ctree_move(GTK_CTREE(ctree),	   \
-					       node_, parent, sibling);	   \
-		}							   \
-									   \
-		prev = node_;						   \
-	}								   \
-}
-
-static void foldersel_set_tree(Folder *cur_folder, FolderSelectionType type)
+static void foldersel_init_tree_view_images(void)
 {
-	Folder *folder;
-	GtkCTreeNode *node;
-	GList *list;
-
-	list = folder_get_list();
-
-	gtk_clist_freeze(GTK_CLIST(ctree));
-
-	for (; list != NULL; list = list->next) {
-		GtkCTreeNode *prev = NULL;
-
-		folder = FOLDER(list->data);
-		g_return_if_fail(folder != NULL);
-
-		if (type != FOLDER_SEL_ALL) {
-			if (FOLDER_TYPE(folder) == F_NEWS)
-				continue;
-		}
-
-		node = gtk_ctree_insert_gnode(GTK_CTREE(ctree), NULL, NULL,
-					      folder->node,
-					      foldersel_gnode_func,
-					      NULL);
-		gtk_ctree_sort_recursive(GTK_CTREE(ctree), node);
-		SET_SPECIAL_FOLDER(folder->inbox);
-		SET_SPECIAL_FOLDER(folder->outbox);
-		SET_SPECIAL_FOLDER(folder->draft);
-		SET_SPECIAL_FOLDER(folder->queue);
-		SET_SPECIAL_FOLDER(folder->trash);
-		gtk_ctree_pre_recursive(GTK_CTREE(ctree), node,
-					foldersel_expand_func,
-					NULL);
-	}
-
-	gtk_clist_thaw(GTK_CLIST(ctree));
-}
-
-static void foldersel_selected(GtkCList *clist, gint row, gint column,
-			       GdkEvent *event, gpointer data)
-{
-	GdkEventButton *ev = (GdkEventButton *)event;
-
-	selected_item = gtk_clist_get_row_data(clist, row);
-	if (selected_item && selected_item->path && !selected_item->no_select) {
+	stock_pixbuf_gdk(GTK_WIDGET(tree_view), STOCK_PIXMAP_DIR_CLOSE,
+			 &folder_pixbuf);
+	stock_pixbuf_gdk(GTK_WIDGET(tree_view), STOCK_PIXMAP_DIR_OPEN,
+			 &folderopen_pixbuf);
+}
+
+static gboolean foldersel_selected(GtkTreeSelection *selection,
+				   GtkTreeModel *model, 
+				   GtkTreePath *path,
+				   gboolean currently_selected,
+				   gpointer data)
+{
+	GtkTreeIter iter;
+	FolderItem *item = NULL;
+
+	if (currently_selected)
+		return TRUE;
+	
+	if (!gtk_tree_model_get_iter(GTK_TREE_MODEL(model), &iter, path))
+		return TRUE;
+
+	gtk_tree_model_get(GTK_TREE_MODEL(tree_store), &iter, 
+			   FOLDERSEL_FOLDERITEM, &item,
+			   -1);
+	
+	selected_item = item;
+	if (selected_item && selected_item->path) {
 		gchar *id;
 		id = folder_item_get_identifier(selected_item);
 		gtk_entry_set_text(GTK_ENTRY(entry), id);
 		g_free(id);
 	} else
 		gtk_entry_set_text(GTK_ENTRY(entry), "");
-
-	if (ev && GDK_2BUTTON_PRESS == ev->type)
-		gtk_button_clicked(GTK_BUTTON(ok_button));
+	
+	return TRUE;
 }
 
 static void foldersel_ok(GtkButton *button, gpointer data)
@@ -398,17 +480,21 @@
 	gchar *new_folder;
 	gchar *disp_name;
 	gchar *p;
-	gchar *text[1] = {NULL};
-	GtkCTreeNode *selected_node;
-	GtkCTreeNode *node;
-	gint row;
+	GtkTreeIter selected, new_child;
+	GtkTreePath *new_child_p;
+	GtkTreeStore *store;
+	GtkTreeSelection *selection;
 
 	if (!selected_item || FOLDER_TYPE(selected_item->folder) == F_NEWS)
 		return;
-	selected_node = gtk_ctree_find_by_row_data(GTK_CTREE(ctree), NULL,
-						   selected_item);
-	if (!selected_node) return;
 
+	selection = gtk_tree_view_get_selection(tree_view);		
+
+	if (!gtk_tree_selection_get_selected
+			(selection, (GtkTreeModel **) &store, &selected)) 
+		return;			 
+	
+		
 	new_folder = input_dialog(_("New folder"),
 				  _("Input the name of new folder:"),
 				  _("NewFolder"));
@@ -441,20 +527,27 @@
 		return;
 	}
 
-	text[0] = new_item->name;
-	node = gtk_ctree_insert_node(GTK_CTREE(ctree), selected_node,
-				     NULL, text, FOLDER_SPACING,
-				     folderxpm, folderxpmmask,
-				     folderopenxpm, folderopenxpmmask,
-				     FALSE, FALSE);
-	gtk_ctree_expand(GTK_CTREE(ctree), selected_node);
-	gtk_ctree_node_set_row_data(GTK_CTREE(ctree), node, new_item);
-	gtk_ctree_sort_recursive(GTK_CTREE(ctree), selected_node);
-
-	row = gtkut_ctree_get_nth_from_node(GTK_CTREE(ctree), node);
-	gtk_clist_select_row(GTK_CLIST(ctree), row, -1);
-	gtkut_clist_set_focus_row(GTK_CLIST(ctree), row);
-	gtk_ctree_node_moveto(GTK_CTREE(ctree), node, -1, 0.5, 0);
+	/* parent can expand */
+	gtk_tree_store_set(store, &selected,
+			   FOLDERSEL_FOLDEREXPANDER, TRUE,
+			   -1);
+
+	/* add new child */
+	gtk_tree_store_append(store, &new_child, &selected);
+	new_child_p = gtk_tree_model_get_path(GTK_TREE_MODEL(store),
+					      &new_child);
+	gtk_tree_store_set(store, &new_child, 
+			   FOLDERSEL_FOLDERNAME, new_item->name,
+			   FOLDERSEL_FOLDERITEM, new_item,
+			   FOLDERSEL_FOLDERPIXBUF, folder_pixbuf,
+			   FOLDERSEL_FOLDEREXPANDER, FALSE,
+			   -1);
+
+	gtk_tree_view_expand_all(tree_view);			   
+	gtk_tree_selection_select_path(selection, new_child_p);	
+	gtk_tree_view_scroll_to_cell(tree_view, new_child_p, 
+				     NULL, TRUE, 0.5f, 0.0f);
+	gtk_tree_path_free(new_child_p);				     
 
 	folderview_append_item(new_item);
 	folder_write_list();
@@ -478,16 +571,10 @@
 	return FALSE;
 }
 
-static gint foldersel_clist_compare(GtkCList *clist,
-				    gconstpointer ptr1, gconstpointer ptr2)
+static void foldersel_double_click(GtkTreeView *tree_view, GtkTreePath *path,
+				   GtkTreeViewColumn *column, gpointer data)
 {
-	FolderItem *item1 = ((GtkCListRow *)ptr1)->data;
-	FolderItem *item2 = ((GtkCListRow *)ptr2)->data;
+	gtk_button_clicked(GTK_BUTTON(ok_button));
+}
 
-	if (!item1->name)
-		return (item2->name != NULL);
-	if (!item2->name)
-		return -1;
 
-	return g_strcasecmp(item1->name, item2->name);
-}




[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic