changeset 4695:4bdd9a5fd026

[gaim-migrate @ 5006] This may very well have issues, but it's a slightly better core/ui split, removing global variables and fixing some GTK+ runtime errors and a couple segfaults. It's some progress. committer: Tailor Script <tailor@pidgin.im>
author Christian Hammond <chipx86@chipx86.com>
date Mon, 10 Mar 2003 18:16:29 +0000
parents 8f523dbb970e
children abec345c8c92
files src/buddy.c src/dialogs.c src/gtklist.h src/list.c src/list.h src/main.c src/multi.c src/prefs.c src/util.c
diffstat 9 files changed, 178 insertions(+), 47 deletions(-) [+]
line wrap: on
line diff
--- a/src/buddy.c	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/buddy.c	Mon Mar 10 18:16:29 2003 +0000
@@ -54,6 +54,8 @@
 #include "win32dep.h"
 #endif
 
+static struct gaim_gtk_buddy_list *gtkblist = NULL;
+
 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node);
 
 /***************************************************
@@ -482,6 +484,16 @@
 /**********************************************************************************
  * Public API Functions                                                           *
  **********************************************************************************/
+static void gaim_gtk_blist_new_list(struct gaim_buddy_list *blist)
+{
+	blist->ui_data = g_new0(struct gaim_gtk_buddy_list, 1);
+}
+
+static void gaim_gtk_blist_new_node(GaimBlistNode *node)
+{
+	node->ui_data = g_new0(struct gaim_gtk_blist_node, 1);
+}
+
 static void gaim_gtk_blist_show(struct gaim_buddy_list *list)
 {
 	GtkItemFactory *ift;
@@ -496,7 +508,8 @@
 		return;
 	}
 
-	gtkblist = g_new0(struct gaim_gtk_buddy_list , 1);
+	gtkblist = GAIM_GTK_BLIST(list);
+
 	gtkblist->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
 	gtk_window_set_title(GTK_WINDOW(gtkblist->window), _("Buddy List"));
 
@@ -608,17 +621,23 @@
 
 static void gaim_gtk_blist_update(struct gaim_buddy_list *list, GaimBlistNode *node)
 {
-	GtkTreeIter *iter = node->ui_data;
+	struct gaim_gtk_blist_node *gtknode;
+	GtkTreeIter *iter;
 	gboolean expand = FALSE;
 
 	if (!gtkblist)
 		return;
+	
+	gtknode = GAIM_GTK_BLIST_NODE(node);
+	iter = gtknode->iter;
+
 
 	if (!iter) { /* This is a newly added node */
 		if (GAIM_BLIST_NODE_IS_BUDDY(node)) {
 			if (((struct buddy*)node)->present) {
-				if(node->parent && node->parent && !node->parent->ui_data) {
-
+				if(node->parent && node->parent &&
+				   !GAIM_GTK_BLIST_NODE(node->parent)->iter) {
+					
 					/* This buddy's group has not yet been added.  We do that here */
 
 					char *mark = g_strdup_printf("<span weight='bold'>%s</span>",  ((struct group*)node->parent)->name);
@@ -627,36 +646,41 @@
 					GtkTreeIter *insertatiter = NULL;
 
 					/* We traverse backwards through the buddy list to find the node in the tree to insert it after */
-					while (insertat && !insertat->ui_data)
+					while (insertat && !GAIM_GTK_BLIST_NODE(insertat)->iter)
 						insertat = insertat->prev;
+
 					if (insertat)
-						insertatiter = insertat->ui_data;
+						insertatiter = GAIM_GTK_BLIST_NODE(insertat)->iter;
 
 					/* This is where we create the node and add it. */
 					gtk_tree_store_insert_after(gtkblist->treemodel, iter2, 
-								    node->parent->parent ? node->parent->parent->ui_data : NULL, insertatiter);
+								    node->parent->parent ?
+									GAIM_GTK_BLIST_NODE(node->parent->parent)->iter : NULL, insertatiter);
 					gtk_tree_store_set(gtkblist->treemodel, iter2, 
 							   STATUS_ICON_COLUMN, gtk_widget_render_icon
 							   (gtkblist->treeview,GTK_STOCK_OPEN,GTK_ICON_SIZE_SMALL_TOOLBAR,NULL),
 							   NAME_COLUMN, mark,
 							   NODE_COLUMN, node->parent,
 							   -1);
-					node->parent->ui_data = iter2;
+
+					GAIM_GTK_BLIST_NODE(node->parent)->iter = iter2;
 					expand = TRUE;
 				}
 				iter = g_new0(GtkTreeIter, 1);
-				node->ui_data = iter;
-				
-				gtk_tree_store_insert_after (gtkblist->treemodel, iter, node->parent  ? node->parent->ui_data : NULL,
-							     node->prev ? node->prev->ui_data : NULL);
+
+				GAIM_GTK_BLIST_NODE(node)->iter = iter;
+
+				gtk_tree_store_insert_after (gtkblist->treemodel, iter, node->parent  ? GAIM_GTK_BLIST_NODE(node->parent)->iter : NULL,
+							     node->prev ? GAIM_GTK_BLIST_NODE(node->prev)->iter : NULL);
 			
 							   
 				if (expand) {       /* expand was set to true if this is the first element added to a group.  In such case
 						     * we expand the group node */
-					GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), node->parent->ui_data);
+					GtkTreePath *path = gtk_tree_model_get_path(GTK_TREE_MODEL(gtkblist->treemodel), GAIM_GTK_BLIST_NODE(node->parent)->iter);
 					gtk_tree_view_expand_row(GTK_TREE_VIEW(gtkblist->treeview), path, TRUE);	
 				}
-				node->ui_data = iter;
+
+				GAIM_GTK_BLIST_NODE(node)->iter = iter;
 			}
 		} 
 	}
@@ -679,23 +703,36 @@
 				   -1);
 			
 		g_free(mark);
-		g_object_unref(status);
-		if (avatar) {
-				g_object_unref(avatar);
-		}
-	} else if (GAIM_BLIST_NODE_IS_BUDDY(node) && node->ui_data){
-		gtk_tree_store_remove(GTK_TREE_STORE(gtkblist->treemodel), (GtkTreeIter*)(node->ui_data));
-		g_free(node->ui_data);
-		node->ui_data = NULL;
+
+		if (status != NULL)
+			g_object_unref(status);
+
+		if (avatar != NULL)
+			g_object_unref(avatar);
+
+	} else if (GAIM_BLIST_NODE_IS_BUDDY(node) && GAIM_GTK_BLIST_NODE(node)->iter){
+		gtk_tree_store_remove(GTK_TREE_STORE(gtkblist->treemodel), GAIM_GTK_BLIST_NODE(node)->iter);
+
+		g_free(GAIM_GTK_BLIST_NODE(node)->iter);
+		GAIM_GTK_BLIST_NODE(node)->iter = NULL;
 	}
 	
 }
 
 static void gaim_gtk_blist_remove(struct gaim_buddy_list *list, GaimBlistNode *node)
 {
+	struct gaim_gtk_blist_node *gtknode;
+
 	if (!node->ui_data)
 		return;
-	gtk_tree_store_remove(gtkblist->treemodel, (GtkTreeIter*)(node->ui_data));
+
+	gtknode = (struct gaim_gtk_blist_node *)node->ui_data;
+
+	if (gtknode->timer > 0)
+		g_source_remove(gtknode->timer);
+
+	if (gtknode->iter != NULL)
+		gtk_tree_store_remove(gtkblist->treemodel, gtknode->iter);
 }
 
 static void gaim_gtk_blist_destroy(struct gaim_buddy_list *list)
@@ -713,6 +750,8 @@
 
 static struct gaim_blist_ui_ops blist_ui_ops =
 {
+	gaim_gtk_blist_new_list,
+	gaim_gtk_blist_new_node,
 	gaim_gtk_blist_show,
 	gaim_gtk_blist_update,
 	gaim_gtk_blist_remove,
--- a/src/dialogs.c	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/dialogs.c	Mon Mar 10 18:16:29 2003 +0000
@@ -585,10 +585,12 @@
 	GtkWidget *window;
 	GtkWidget *hbox;
 	GtkWidget *label;
-	
+	struct gaim_gtk_buddy_list *gtkblist;
 	char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_cool.png", NULL);
 	GtkWidget *img = gtk_image_new_from_file(filename);
-	
+
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+
 	label = gtk_label_new(NULL);
 	if (ee == 0)
 		gtk_label_set_markup(GTK_LABEL(label), 
@@ -658,11 +660,14 @@
 	GtkWidget *table, *menu, *opt;
 	GSList *g = connections;
 	struct gaim_connection *c;
+	struct gaim_gtk_buddy_list *gtkblist;
 	char buf[256];
 	char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL);
 	GtkWidget *img = gtk_image_new_from_file(filename);
 	struct getuserinfo *info = NULL;
 
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+
 	g_free(filename);
 
 	if (!imdialog) {
@@ -764,8 +769,11 @@
 	GSList *g = connections;
 	struct gaim_connection *c;
 	struct getuserinfo *info = g_new0(struct getuserinfo, 1);
+	struct gaim_gtk_buddy_list *gtkblist;
 	char buf[256];
 
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+
 	g_free(filename);
 	info->gc = connections->data;
 
@@ -941,10 +949,13 @@
 
 	GtkWidget *hbox, *vbox;
 	GtkWidget *label;
+	struct gaim_gtk_buddy_list *gtkblist;
 	char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL);
 	GtkWidget *img = gtk_image_new_from_file(filename);
 	struct addbuddy *a = g_new0(struct addbuddy, 1);
 
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+
 	g_free(filename);
 	a->gc = gc;
 
@@ -1051,13 +1062,14 @@
 	GtkWidget *label;
 	GtkWidget *hbox;
 	GtkWidget *vbox;
-
+	struct gaim_gtk_buddy_list *gtkblist;
 	char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL);
 	GtkWidget *img = gtk_image_new_from_file(filename);
-
 	struct addbuddy *a = g_new0(struct addbuddy, 1);
 	a->gc = gc ? gc : connections->data;
 
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+
 	g_free(filename);
 
 	GAIM_DIALOG(a->window);
@@ -3911,12 +3923,15 @@
 
 	GtkWidget *hbox, *vbox;
 	GtkWidget *label;
+	struct gaim_gtk_buddy_list *gtkblist;
 	char *filename = g_build_filename(DATADIR, "pixmaps", "gaim", "dialogs", "gaim_question.png", NULL);
 	GtkWidget *img = gtk_image_new_from_file(filename);
 	GtkWidget *name_entry = NULL;
 
 	g_free(filename);
 
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+
 	if (!rename_dialog) {
 		rename_dialog =  gtk_dialog_new_with_buttons(_("Rename Group"), GTK_WINDOW(gtkblist->window), GTK_DIALOG_MODAL, 
 						 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_OK, GTK_RESPONSE_OK, NULL);
--- a/src/gtklist.h	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/gtklist.h	Mon Mar 10 18:16:29 2003 +0000
@@ -23,7 +23,6 @@
 
 #ifndef _GAIM_GTK_LIST_H_
 #define _GAIM_GTK_LIST_H_
-extern GtkWidget *blist;
 
 enum {
 	STATUS_ICON_COLUMN,
@@ -51,8 +50,18 @@
 			
 	GtkWidget *bbox;                /**< A Button Box. */
 };
-struct gaim_gtk_buddy_list *gtkblist;
 
+/**
+ * A GTK+ buddy list node.
+ */
+struct gaim_gtk_blist_node
+{
+	GtkTreeIter *iter;               /**< The tree iterator. */
+	uint timer;                      /**< The timer handle.  */
+};
+
+#define GAIM_GTK_BLIST_NODE(node) ((struct gaim_gtk_blist_node *)(node)->ui_data)
+#define GAIM_GTK_BLIST(list) ((struct gaim_gtk_buddy_list *)(list)->ui_data)
 
 /**************************************************************************
  * @name GTK+ Conversation API
--- a/src/list.c	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/list.c	Mon Mar 10 18:16:29 2003 +0000
@@ -89,10 +89,27 @@
 struct gaim_buddy_list *gaim_blist_new()
 {
 	struct gaim_buddy_list *gbl = g_new0(struct gaim_buddy_list, 1);
-	gbl->ui_ops = blist_ui_ops;
+
+	gbl->ui_ops = gaim_get_blist_ui_ops();
+
+	if (gbl->ui_ops != NULL && gbl->ui_ops->new_list != NULL)
+		gbl->ui_ops->new_list(gbl);
+
 	return gbl;
 }
 
+void
+gaim_set_blist(struct gaim_buddy_list *list)
+{
+	gaimbuddylist = list;
+}
+
+struct gaim_buddy_list *
+gaim_get_blist(void)
+{
+	return gaimbuddylist;
+}
+
 void  gaim_blist_show () 
 {
 	struct gaim_blist_ui_ops *ops = gaimbuddylist->ui_ops;
@@ -173,13 +190,21 @@
 }
 struct buddy *gaim_buddy_new(struct gaim_account *account, const char *screenname, const char *alias)
 {
-	struct buddy *b = g_new0(struct buddy, 1);
+	struct buddy *b;
+	struct gaim_blist_ui_ops *ops;
+
+	b = g_new0(struct buddy, 1);
 	b->account = account;
 	b->name  = g_strdup(screenname);
 	b->alias = g_strdup(alias);
 	b->settings = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
 	((GaimBlistNode*)b)->type = GAIM_BLIST_BUDDY_NODE;
 
+	ops = gaim_get_blist_ui_ops();
+
+	if (ops != NULL && ops->new_node != NULL)
+		ops->new_node((GaimBlistNode *)b);
+
 	return b;
 }
 void  gaim_blist_add_buddy (struct buddy *buddy, struct group *group, GaimBlistNode *node)
@@ -224,11 +249,18 @@
 struct group *gaim_group_new(const char *name)
 {
 	struct group *g = gaim_find_group(name);
+
 	if (!g) {
+		struct gaim_blist_ui_ops *ops;
 		g= g_new0(struct group, 1);
 		g->name = g_strdup(name);
 		((GaimBlistNode*)g)->type = GAIM_BLIST_GROUP_NODE;
 
+		ops = gaim_get_blist_ui_ops();
+
+		if (ops != NULL && ops->new_node != NULL)
+			ops->new_node((GaimBlistNode *)g);
+
 	}
 	return g;
 }
@@ -1243,5 +1275,11 @@
 
 void gaim_set_blist_ui_ops(struct gaim_blist_ui_ops *ops)
 {
-	gaimbuddylist->ui_ops = blist_ui_ops = ops;
+	blist_ui_ops = ops;
 }
+
+struct gaim_blist_ui_ops *
+gaim_get_blist_ui_ops(void)
+{
+	return blist_ui_ops;
+}
--- a/src/list.h	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/list.h	Mon Mar 10 18:16:29 2003 +0000
@@ -37,8 +37,8 @@
 	GAIM_BLIST_OTHER_NODE,
 };
 
-#define GAIM_BLIST_NODE_IS_BUDDY(n) (n->type == GAIM_BLIST_BUDDY_NODE)
-#define GAIM_BLIST_NODE_IS_GROUP(n) (n->type == GAIM_BLIST_GROUP_NODE)
+#define GAIM_BLIST_NODE_IS_BUDDY(n) ((n)->type == GAIM_BLIST_BUDDY_NODE)
+#define GAIM_BLIST_NODE_IS_GROUP(n) ((n)->type == GAIM_BLIST_GROUP_NODE)
 
 /**************************************************************************/
 /* Data Structures                                                        */
@@ -93,6 +93,8 @@
 struct gaim_buddy_list {
 	GaimBlistNode *root;                    /**< The first node in the buddy list */
 	struct gaim_blist_ui_ops *ui_ops;       /**< The UI operations for the buddy list */
+
+	void *ui_data;                          /**< UI-specific data. */
 };
 
 /**
@@ -103,6 +105,8 @@
  */
 struct gaim_blist_ui_ops
 {
+	void (*new_list)(struct gaim_buddy_list *list); /**< Sets UI-specific data on a buddy list. */
+	void (*new_node)(GaimBlistNode *node);      /**< Sets UI-specific data on a node. */
 	void (*show)(struct gaim_buddy_list *list);     /**< The core will call this when its finished doing it's core stuff */
 	void (*update)(struct gaim_buddy_list *list, 
 		       GaimBlistNode *node);            /**< This will update a node in the buddy list. */
@@ -115,12 +119,6 @@
 }; 
 
 /**************************************************************************/
-/* Globals                                                                */
-/**************************************************************************/
-extern struct gaim_buddy_list *gaimbuddylist;      /**< A global for the core buddy list. */
-
-
-/**************************************************************************/
 /** @name Buddy List API                                                  */
 /**************************************************************************/
 /*@{*/
@@ -130,6 +128,19 @@
  */
 struct gaim_buddy_list *gaim_blist_new();
 
+/**
+ * Sets the main buddy list.
+ *
+ * @return The main buddy list.
+ */
+void gaim_set_blist(struct gaim_buddy_list *blist);
+
+/**
+ * Returns the main buddy list.
+ *
+ * @return The main buddy list.
+ */
+struct gaim_buddy_list *gaim_get_blist(void);
 
 /**
  * Shows the buddy list, creating a new one if necessary.
@@ -402,6 +413,13 @@
  */
 void gaim_set_blist_ui_ops(struct gaim_blist_ui_ops *ops);
 
+/**
+ * Returns the UI operations structure to be used for the buddy list.
+ *
+ * @return The UI operations structure.
+ */
+struct gaim_blist_ui_ops *gaim_get_blist_ui_ops(void);
+
 /*@}*/
 
 #endif /* _LIST_H_ */
--- a/src/main.c	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/main.c	Mon Mar 10 18:16:29 2003 +0000
@@ -526,11 +526,6 @@
 		}
 	}
 
-	/* Set the UI operation structures. */
-	gaim_set_win_ui_ops(gaim_get_gtk_window_ui_ops());
-	gaim_set_xfer_ui_ops(gaim_get_gtk_xfer_ui_ops());
-	gaim_set_blist_ui_ops(gaim_get_gtk_blist_ui_ops());
-
 	setup_stock();
 
 #ifndef _WIN32
@@ -863,6 +858,11 @@
 	wgaim_init();
 #endif
 
+	/* Set the UI operation structures. */
+	gaim_set_win_ui_ops(gaim_get_gtk_window_ui_ops());
+	gaim_set_xfer_ui_ops(gaim_get_gtk_xfer_ui_ops());
+	gaim_set_blist_ui_ops(gaim_get_gtk_blist_ui_ops());
+
 	load_prefs();
 	core_main();
 	ui_main();
--- a/src/multi.c	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/multi.c	Mon Mar 10 18:16:29 2003 +0000
@@ -185,9 +185,14 @@
 		gtk_widget_destroy(acctedit);
 		acctedit = NULL;
 	}
+
 	treeview = NULL;
-	if (!d && !gtkblist->window && !mainwindow && !connections)
+
+	if (!d && !GAIM_GTK_BLIST(gaim_get_blist())->window &&
+		!mainwindow && !connections) {
+
 		do_quit();
+	}
 }
 
 static void on_delete_acctedit(GtkWidget *w, GdkEvent *ev, gpointer d)
--- a/src/prefs.c	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/prefs.c	Mon Mar 10 18:16:29 2003 +0000
@@ -1966,12 +1966,16 @@
 
 static void set_blist_option(GtkWidget *w, int option)
 {
+	struct gaim_gtk_buddy_list *gtkblist;
+
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
+
 	blist_options ^= option;
 	
 	if (!gtkblist)
 		return;
 	
-	gaim_gtk_blist_refresh(gaimbuddylist);
+	gaim_gtk_blist_refresh(gaim_get_blist());
 
 }
 
--- a/src/util.c	Mon Mar 10 16:39:46 2003 +0000
+++ b/src/util.c	Mon Mar 10 18:16:29 2003 +0000
@@ -815,6 +815,9 @@
 {
 	GSList *awy = away_messages;
 	struct away_message *a, *message = NULL;
+	struct gaim_gtk_buddy_list *gtkblist;
+
+	gtkblist = GAIM_GTK_BLIST(gaim_get_blist());
 
 	if (!gtkblist->window) {
 		return;