Added context menu

This commit is contained in:
Jesse van den Kieboom 2006-01-08 16:32:51 +00:00
parent 9a843265cf
commit de90a39120
3 changed files with 531 additions and 71 deletions

View File

@ -5,6 +5,7 @@
#include <errno.h>
#include "gm-mcp-icecrew-userlist.h"
#include "gm-iuserlist.h"
#include "gm-mcp-userlist-view.h"
#include "gm-mcp-icecrew-playerdb.h"
#include "gm-mcp-session.h"
@ -50,6 +51,8 @@ struct _GmMcpIcecrewUserlistPrivate {
gchar *rank_dir;
gchar *state_dir;
GList *menu;
gboolean initializing;
};
@ -73,9 +76,12 @@ enum {
NUM_SIGNALS
};
static void gm_mcp_icecrew_userlist_iface_init(GmIUserlistInterface *iface);
static guint gm_mcp_icecrew_userlist_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmMcpIcecrewUserlist, gm_mcp_icecrew_userlist, GM_TYPE_MCP_PACKAGE)
G_DEFINE_TYPE_EXTENDED(GmMcpIcecrewUserlist, gm_mcp_icecrew_userlist, \
GM_TYPE_MCP_PACKAGE, 0, G_IMPLEMENT_INTERFACE(GM_TYPE_IUSERLIST, \
gm_mcp_icecrew_userlist_iface_init))
void on_gm_mcp_icecrew_userlist_add(GmMcpIcecrewPlayerdb *playerdb,
GmPlayerdbPlayerInfo *ppi, GmMcpIcecrewUserlist *userlist);
@ -100,6 +106,14 @@ void gm_mcp_icecrew_userlist_create_view(GmMcpPackage *package,
void gm_mcp_icecrew_userlist_fetch_progress(GmFetchHandle *g,
GmMcpIcecrewUserlist *package);
GList *gm_mcp_icecrew_userlist_get_menu(GmIUserlist *userlist, gint id);
static void
gm_mcp_icecrew_userlist_iface_init(
GmIUserlistInterface *iface) {
iface->get_menu = gm_mcp_icecrew_userlist_get_menu;
}
void
gm_mcp_icecrew_userlist_pair_free(GmKeyValuePair *pair) {
g_free(pair->key);
@ -118,6 +132,12 @@ gm_mcp_icecrew_userlist_free_list(GList *rs) {
g_list_free(rs);
}
static void
gm_mcp_icecrew_userlist_free_menu(GmMcpIcecrewUserlist *obj) {
gm_mcp_icecrew_userlist_free_list(obj->priv->menu);
obj->priv->menu = NULL;
}
static void
gm_mcp_icecrew_userlist_finalize(GObject *object) {
GmMcpIcecrewUserlist *obj = GM_MCP_ICECREW_USERLIST(object);
@ -132,14 +152,7 @@ gm_mcp_icecrew_userlist_finalize(GObject *object) {
g_signal_handlers_disconnect_by_func(playerdb,
on_gm_mcp_icecrew_userlist_delete, obj);
}
gm_mcp_icecrew_userlist_free_list(obj->priv->state_icons);
gm_mcp_icecrew_userlist_free_list(obj->priv->rank_icons);
gm_mcp_icecrew_userlist_free_list(obj->priv->key_datatags);
g_free(obj->priv->rank_dir);
g_free(obj->priv->state_dir);
if (obj->priv->rank_fetch) {
obj->priv->rank_fetch->aborted = TRUE;
}
@ -147,6 +160,16 @@ gm_mcp_icecrew_userlist_finalize(GObject *object) {
if (obj->priv->state_fetch) {
obj->priv->state_fetch->aborted = TRUE;
}
gm_mcp_icecrew_userlist_free_list(obj->priv->state_icons);
gm_mcp_icecrew_userlist_free_list(obj->priv->rank_icons);
gm_mcp_icecrew_userlist_free_list(obj->priv->key_datatags);
gm_mcp_icecrew_userlist_free_menu(obj);
gm_mcp_icecrew_userlist_free_list(obj->priv->rank_alternatives);
gm_mcp_icecrew_userlist_free_list(obj->priv->state_alternatives);
g_free(obj->priv->rank_dir);
g_free(obj->priv->state_dir);
G_OBJECT_CLASS(gm_mcp_icecrew_userlist_parent_class)->finalize(object);
}
@ -682,28 +705,18 @@ void
gm_mcp_icecrew_userlist_fetch_progress(GmFetchHandle *g,
GmMcpIcecrewUserlist *package) {
gchar *path;
gboolean rank = (package->priv->rank_fetch == g);
gboolean rank;
GdkPixbuf *pixtest;
GError *err = NULL;
if (g->aborted) {
if (rank) {
package->priv->rank_fetch = NULL;
gm_mcp_icecrew_userlist_free_list(
package->priv->rank_alternatives);
package->priv->rank_alternatives = NULL;
} else {
package->priv->state_fetch = NULL;
gm_mcp_icecrew_userlist_free_list(
package->priv->state_alternatives);
package->priv->state_alternatives = NULL;
}
if (g->aborted) {
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchProgress: "
"fetch aborted!");
return;
}
rank = (package->priv->rank_fetch == g);
if (g->done) {
gm_debug_msg(DEBUG_MCP, "GmMcpIcecrewUserlist.FetchProgress: "
"fetch done!");
@ -791,13 +804,156 @@ gm_mcp_icecrew_userlist_process_triggers(GmMcpIcecrewUserlist *package,
}
gchar *
gm_mcp_icecrew_userlist_menu_item_subst(GmMcpIcecrewUserlist *package,
gchar *str, GmPlayerdbPlayerInfo *info) {
GString *result;
gchar *ptr = str, *subst, *tmp, *prop;
gchar const *value;
gunichar ch, cnum;
gboolean substituted;
if (str == NULL) {
return NULL;
}
result = g_string_sized_new(strlen(str));
while ((ch = g_utf8_get_char(ptr)) != '\0') {
substituted = FALSE;
if (ch == '$') {
tmp = subst = g_utf8_next_char(ptr);
while ((cnum = g_utf8_get_char(subst)) && (cnum == '_' ||
g_unichar_isalpha(cnum))) {
subst = g_utf8_next_char(subst);
}
prop = g_strndup(tmp, subst - tmp);
if (strcmp(prop, "ID") == 0) {
tmp = g_strdup_printf("#%d", info->id);
result = g_string_append(result, tmp);
g_free(tmp);
substituted = TRUE;
} else {
value = gm_playerdb_player_info_get_prop(info, prop);
if (value) {
for (; *value != '\0'; value = g_utf8_next_char(value)) {
ch = g_utf8_get_char(value);
if (ch == '_') {
result = g_string_append_c(result, '_');
}
result = g_string_append_unichar(result, ch);
}
substituted = TRUE;
}
}
if (substituted) {
ptr = subst;
}
}
if (!substituted) {
result = g_string_append_unichar(result, ch);
}
if (*ptr == '\0') {
break;
}
ptr = g_utf8_next_char(ptr);
}
ptr = result->str;
g_string_free(result, FALSE);
return ptr;
}
GmKeyValuePair *
gm_mcp_icecrew_userlist_get_menu_item(GmMcpIcecrewUserlist *package,
GmKeyValuePair *menuitem, GmPlayerdbPlayerInfo *info) {
GmKeyValuePair *result = g_new0(GmKeyValuePair, 1);
if (!menuitem) {
return result;
}
result->key = gm_mcp_icecrew_userlist_menu_item_subst(package,
menuitem->key, info);
result->value = gm_mcp_icecrew_userlist_menu_item_subst(package,
menuitem->value, info);
return result;
}
GList *
gm_mcp_icecrew_userlist_get_menu(GmIUserlist *userlist, gint id) {
GmMcpIcecrewUserlist *object = GM_MCP_ICECREW_USERLIST(userlist);
GmMcpIcecrewPlayerdb *playerdb = GM_MCP_ICECREW_PLAYERDB(
gm_mcp_session_find_package(GM_MCP_PACKAGE_SESSION(userlist),
"dns-nl-icecrew-playerdb"));
GmPlayerdbPlayerInfo *info = gm_mcp_icecrew_playerdb_find(playerdb, id);
GList *item, *result = NULL;
for (item = object->priv->menu; item; item = item->next) {
result = g_list_append(result, gm_mcp_icecrew_userlist_get_menu_item(
object, (GmKeyValuePair *)(item->data), info));
}
return result;
}
void
gm_mcp_icecrew_userlist_handle_menu(GmMcpIcecrewUserlist *package,
GList *values) {
GmKeyValuePair *pair;
GList *item, *data;
gm_mcp_icecrew_userlist_free_menu(package);
for (item = values; item; item = item->next) {
data = (GList *)(item->data);
pair = g_new0(GmKeyValuePair, 1);
if (g_list_length(data) == 2) {
pair->key = g_strdup(data->data);
pair->value = g_strdup(data->next->data);
}
package->priv->menu = g_list_append(package->priv->menu,
pair);
}
}
void
gm_mcp_icecrew_userlist_handle_ranks_states(GmMcpIcecrewUserlist *package,
GList *values, gboolean rank) {
GList *tmp, *data, *new_list = NULL;
gchar *name, **alternatives, *path, **ptr;
gchar const *cpath;
/* Abort a previous fetch if needed */
if (rank && package->priv->rank_fetch) {
package->priv->rank_fetch = NULL;
gm_mcp_icecrew_userlist_free_list(package->priv->rank_alternatives);
package->priv->rank_alternatives = NULL;
package->priv->rank_fetch->aborted = TRUE;
} else if (!rank && package->priv->state_fetch) {
package->priv->state_fetch = NULL;
gm_mcp_icecrew_userlist_free_list(package->priv->state_alternatives);
package->priv->state_alternatives = NULL;
package->priv->state_fetch->aborted = TRUE;
}
for (tmp = values; tmp; tmp = tmp->next) {
data = (GList *)(tmp->data);
@ -873,19 +1029,6 @@ gm_mcp_icecrew_userlist_handle_ranks_states(GmMcpIcecrewUserlist *package,
package->priv->state_icons = new_list;
}
/* Abort a previous fetch if needed */
if (rank && package->priv->rank_fetch) {
package->priv->rank_fetch->aborted = TRUE;
} else if (!rank && package->priv->state_fetch) {
package->priv->state_fetch->aborted = TRUE;
}
/* Wait for vfs async to be aborted */
while ((rank && package->priv->rank_fetch != NULL) ||
(!rank && package->priv->state_fetch != NULL)) {
gm_do_events();
}
if (rank && package->priv->rank_alternatives) {
gm_mcp_icecrew_userlist_fetch_next_alternatives(package, rank);
} else if (!rank && package->priv->state_alternatives) {
@ -921,6 +1064,8 @@ gm_mcp_icecrew_userlist_handle_multi(GmMcpPackage *package,
gm_mcp_icecrew_userlist_handle_ranks_states(userlist, vals, TRUE);
} else if (strcmp(key, "state") == 0) {
gm_mcp_icecrew_userlist_handle_ranks_states(userlist, vals, FALSE);
} else if (strcmp(key, "menu") == 0) {
gm_mcp_icecrew_userlist_handle_menu(userlist, vals);
}
gm_mcp_icecrew_userlist_remove_datatag(userlist, data_tag);

View File

@ -2,6 +2,7 @@
#include "gm-mcp-package.h"
#include "gm-mcp-userlist-view.h"
#include "gm-iuserlist.h"
#include "../widgets/gm-world-view.h"
#include "../gm-pixbuf.h"
#include "../gm-debug.h"
@ -23,25 +24,28 @@ typedef struct _GmMcpUserlistView {
GtkListStore *store;
GtkTreeView *tree_view;
GtkScrolledWindow *scrolled_window;
GtkWidget *popup_menu;
gboolean initializing;
} GmMcpUserlistView;
void on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj);
static void on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj);
void on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id,
static void on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id,
gchar const *name, gchar const *icon, gchar const *sort,
GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id,
static void on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id,
GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id,
static void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id,
gchar const *name, gchar const *sort, GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id,
static void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id,
static void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view);
void on_gm_mcp_userlist_view_initializing(GmMcpPackage *package,
gboolean initializing, GmMcpUserlistView *view);
static gboolean on_gm_mcp_userlist_view_popup_menu(GtkWidget *widget,
GmMcpUserlistView *view);
static gboolean on_gm_mcp_userlist_view_button_press(GtkWidget *widget,
GdkEventButton *event, GmMcpUserlistView *view);
GtkTreeModel *
gm_mcp_userlist_view_model_create(GmMcpUserlistView *view) {
@ -88,7 +92,13 @@ gm_mcp_userlist_view_create_userlist(GmMcpUserlistView *view) {
gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(model),
GM_USERLIST_SORT, GTK_SORT_ASCENDING);
GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(tree_view), GTK_CAN_FOCUS);
GTK_WIDGET_UNSET_FLAGS(GTK_WIDGET(tree_view), GTK_CAN_FOCUS);
gtk_widget_modify_base(GTK_WIDGET(tree_view), GTK_STATE_ACTIVE,
&(GTK_WIDGET(tree_view)->style->base[GTK_STATE_SELECTED]));
gtk_widget_modify_text(GTK_WIDGET(tree_view), GTK_STATE_ACTIVE,
&(GTK_WIDGET(tree_view)->style->text[GTK_STATE_SELECTED]));
gtk_tree_view_columns_autosize(GTK_TREE_VIEW(tree_view));
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(tree_view), FALSE);
@ -108,7 +118,7 @@ gm_mcp_userlist_view_new(GmMcpPackage *package, GObject *parent) {
return;
}
view = g_new(GmMcpUserlistView, 1);
view = g_new0(GmMcpUserlistView, 1);
view->view = GM_WORLD_VIEW(parent);
view->package = package;
@ -125,6 +135,11 @@ gm_mcp_userlist_view_new(GmMcpPackage *package, GObject *parent) {
gtk_box_pack_end(GTK_BOX(vbox), child, TRUE, TRUE, 0);
gtk_widget_show_all(vbox);
g_signal_connect(view->tree_view, "popup-menu",
G_CALLBACK(on_gm_mcp_userlist_view_popup_menu), view);
g_signal_connect(view->tree_view, "button-press-event",
G_CALLBACK(on_gm_mcp_userlist_view_button_press), view);
g_signal_connect(package, "player_added",
G_CALLBACK(on_gm_mcp_userlist_view_player_added), view);
g_signal_connect(package, "player_removed",
@ -141,7 +156,7 @@ gm_mcp_userlist_view_new(GmMcpPackage *package, GObject *parent) {
}
/* Callbacks */
void
static void
on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj) {
GmMcpUserlistView *view = (GmMcpUserlistView *)(data);
GtkWidget *vbox;
@ -162,11 +177,11 @@ on_gm_mcp_userlist_view_weak_notify(gpointer data, GObject *obj) {
g_list_free(children);
}
}
g_free(data);
}
gboolean
static gboolean
gm_mcp_userlist_view_find(GmMcpUserlistView *view, gint id, GtkTreeIter *iter) {
GtkTreeModel *model = GTK_TREE_MODEL(view->store);
gint iterid;
@ -184,7 +199,7 @@ gm_mcp_userlist_view_find(GmMcpUserlistView *view, gint id, GtkTreeIter *iter) {
return FALSE;
}
void
static void
on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id,
gchar const *name, gchar const *icon, gchar const *sort,
GmMcpUserlistView *view) {
@ -203,7 +218,7 @@ on_gm_mcp_userlist_view_player_added(GmMcpPackage *package, gint id,
sort, -1);
}
void
static void
on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id,
GmMcpUserlistView *view) {
GtkTreeIter iter;
@ -217,7 +232,8 @@ on_gm_mcp_userlist_view_player_removed(GmMcpPackage *package, gint id,
gtk_list_store_remove(view->store, &iter);
}
void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id,
static void
on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id,
gchar const *name, gchar const *sort, GmMcpUserlistView *view) {
GtkTreeIter iter;
@ -234,7 +250,8 @@ void on_gm_mcp_userlist_view_name_changed(GmMcpPackage *package, gint id,
}
}
void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id,
static void
on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view) {
GtkTreeIter iter;
@ -253,7 +270,8 @@ void on_gm_mcp_userlist_view_rank_changed(GmMcpPackage *package, gint id,
}
}
void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id,
static void
on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id,
gchar const *icon, gchar const *sort, GmMcpUserlistView *view) {
GtkTreeIter iter;
@ -271,3 +289,121 @@ void on_gm_mcp_userlist_view_state_changed(GmMcpPackage *package, gint id,
gtk_list_store_set(view->store, &iter, GM_USERLIST_SORT, sort, -1);
}
}
static void
popup_menu_detach(GtkWidget *attach_widget, GtkMenu *menu) {
GmMcpUserlistView *view = (GmMcpUserlistView *)g_object_get_data(
G_OBJECT(menu), "McpUserlistView");
view->popup_menu = NULL;
}
static void
on_gm_mcp_userlist_view_menuitem_activate(GtkMenuItem *item,
GmMcpUserlistView *view) {
gchar *action = (gchar *)g_object_get_data(G_OBJECT(item),
"UserlistAction");
if (action) {
gm_world_sendln(GM_MCP_SESSION_WORLD(GM_MCP_PACKAGE_SESSION(
view->package)), action);
}
}
static gboolean
gm_mcp_userlist_view_do_popup(GmMcpUserlistView *view, GdkEventButton *event) {
GList *menu;
GList *item;
GmKeyValuePair *pair;
GtkWidget *menuitem;
GtkTreeSelection *selection = gtk_tree_view_get_selection(view->tree_view);
gint id;
GtkTreeModel *model;
GtkTreeIter iter;
GtkTreePath *path;
if (!event) {
if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
return FALSE;
}
gtk_tree_model_get(model, &iter, GM_USERLIST_ID, &id, -1);
} else {
if (!gtk_tree_view_get_path_at_pos(view->tree_view, event->x, event->y,
&path, NULL, NULL, NULL)) {
return FALSE;
} else {
gtk_tree_model_get_iter(view->model, &iter, path);
gtk_tree_path_free(path);
gtk_tree_model_get(view->model, &iter, GM_USERLIST_ID, &id, -1);
}
}
menu = gm_iuserlist_get_menu(GM_IUSERLIST(view->package), id);
if (view->popup_menu) {
gtk_widget_destroy(view->popup_menu);
}
if (!menu) {
return FALSE;
}
view->popup_menu = gtk_menu_new();
g_object_set_data(G_OBJECT(view->popup_menu), "McpUserlistView", view);
gtk_menu_attach_to_widget(GTK_MENU(view->popup_menu),
GTK_WIDGET(view->tree_view), popup_menu_detach);
for (item = menu; item; item = item->next) {
pair = (GmKeyValuePair *)(item->data);
if (pair->key == NULL) {
menuitem = gtk_separator_menu_item_new();
g_free(pair->value);
} else {
menuitem = gtk_menu_item_new_with_mnemonic(pair->key);
g_object_set_data_full(G_OBJECT(menuitem), "UserlistAction",
pair->value, g_free);
g_signal_connect(menuitem, "activate",
G_CALLBACK(on_gm_mcp_userlist_view_menuitem_activate),
view);
}
gtk_widget_show(menuitem);
gtk_menu_shell_append(GTK_MENU_SHELL(view->popup_menu), menuitem);
g_free(pair->key);
g_free(pair);
}
g_list_free(menu);
if (!event) {
gtk_menu_popup(GTK_MENU(view->popup_menu), NULL, NULL, NULL, NULL, 0,
gtk_get_current_event_time());
} else {
gtk_menu_popup(GTK_MENU(view->popup_menu), NULL, NULL, NULL, NULL,
event->button, event->time);
}
return TRUE;
}
static gboolean
on_gm_mcp_userlist_view_popup_menu(GtkWidget *widget,
GmMcpUserlistView *view) {
return gm_mcp_userlist_view_do_popup(view, NULL);
}
static gboolean
on_gm_mcp_userlist_view_button_press(GtkWidget *widget, GdkEventButton *event,
GmMcpUserlistView *view) {
if (event->button == 3 && event->type == GDK_BUTTON_PRESS) {
gm_mcp_userlist_view_do_popup(view, event);
}
return FALSE;
}

View File

@ -2,6 +2,7 @@
#include <string.h>
#include "gm-mcp-vmoo-userlist.h"
#include "gm-mcp-userlist-view.h"
#include "gm-iuserlist.h"
#include "gm-mcp-session.h"
#include "gm-mcp.h"
#include "../gm-support.h"
@ -44,7 +45,7 @@ struct _GmMcpVmooUserlistPrivate {
GList *fields;
GList *icons;
GList *users;
GList *menu;
gboolean initializing;
};
@ -59,9 +60,12 @@ enum {
NUM_SIGNALS
};
static void gm_mcp_vmoo_userlist_iface_init(GmIUserlistInterface *iface);
static guint gm_mcp_vmoo_userlist_signals[NUM_SIGNALS] = {0};
G_DEFINE_TYPE(GmMcpVmooUserlist, gm_mcp_vmoo_userlist, GM_TYPE_MCP_PACKAGE)
G_DEFINE_TYPE_EXTENDED(GmMcpVmooUserlist, gm_mcp_vmoo_userlist, \
GM_TYPE_MCP_PACKAGE, 0, G_IMPLEMENT_INTERFACE(GM_TYPE_IUSERLIST, \
gm_mcp_vmoo_userlist_iface_init))
void gm_mcp_vmoo_userlist_handle_simple(GmMcpPackage *package,
gchar *suffix, GList *fields);
@ -71,6 +75,13 @@ gboolean gm_mcp_vmoo_userlist_handle_multi(GmMcpPackage *package,
void gm_mcp_vmoo_userlist_create_view(GmMcpPackage *package,
GObject *parent);
GList *gm_mcp_vmoo_userlist_get_menu(GmIUserlist *userlist, gint id);
static void
gm_mcp_vmoo_userlist_iface_init(
GmIUserlistInterface *iface) {
iface->get_menu = gm_mcp_vmoo_userlist_get_menu;
}
void
gm_mcp_vmoo_userlist_remove_users(GmMcpVmooUserlist *package) {
@ -89,6 +100,22 @@ gm_mcp_vmoo_userlist_remove_users(GmMcpVmooUserlist *package) {
g_list_free(users);
}
static void
gm_mcp_vmoo_userlist_free_menu(GmMcpVmooUserlist *obj) {
GList *field;
GmKeyValuePair *pair;
for (field = obj->priv->menu; field; field = field->next) {
pair = (GmKeyValuePair *)(field->data);
g_free(pair->key);
g_free(pair->value);
g_free(pair);
}
obj->priv->menu = NULL;
}
static void
gm_mcp_vmoo_userlist_finalize(GObject *object) {
GmMcpVmooUserlist *obj = GM_MCP_VMOO_USERLIST(object);
@ -105,6 +132,8 @@ gm_mcp_vmoo_userlist_finalize(GObject *object) {
}
g_list_free(obj->priv->icons);
gm_mcp_vmoo_userlist_free_menu(obj);
gm_mcp_vmoo_userlist_remove_users(obj);
g_list_free(obj->priv->users);
@ -303,6 +332,27 @@ gm_mcp_vmoo_userlist_handle_icons(GmMcpVmooUserlist *package, MOOVar *list) {
}
}
void
gm_mcp_vmoo_userlist_handle_menu(GmMcpVmooUserlist *package, MOOVar *list) {
MOOVar *field;
GmKeyValuePair *pair;
for (field = list->list; field; field = field->next) {
pair = g_new0(GmKeyValuePair, 1);
if (field->type == LIST && field->i == 2) {
pair->key = g_strdup(field->list->s);
pair->value = g_strdup(field->list->next->s);
package->priv->menu = g_list_append(package->priv->menu,
pair);
} else if (field->type != LIST) {
package->priv->menu = g_list_append(package->priv->menu, pair);
} else {
g_free(pair);
}
}
}
gchar *
gm_mcp_vmoo_userlist_get_string(GmMcpVmooUserlist *package, MOOVar *v,
MOOType type, gchar *cmp) {
@ -359,6 +409,118 @@ gm_mcp_vmoo_userlist_find_user(GmMcpVmooUserlist *package, gint nr) {
return NULL;
}
gchar *
gm_mcp_vmoo_userlist_menu_item_subst(GmMcpVmooUserlist *package,
gchar *str, UserInfo *info) {
GString *result;
gchar *ptr = str, *subst, *tmp;
gunichar ch, cnum;
gint num;
gboolean substituted;
if (str == NULL) {
return NULL;
}
result = g_string_sized_new(strlen(str));
while ((ch = g_utf8_get_char(ptr)) != '\0') {
substituted = FALSE;
if (ch == '&') {
result = g_string_append_c(result, '_');
substituted = TRUE;
} else if (ch == '$') {
subst = g_utf8_next_char(ptr);
if (g_utf8_get_char(subst) == '(') {
subst = g_utf8_next_char(subst);
num = 0;
while (g_unichar_isdigit((cnum = g_utf8_get_char(subst)))) {
num = (num * 10) + g_unichar_digit_value(cnum);
subst = g_utf8_next_char(subst);
}
if (g_utf8_get_char(subst) == ')') {
switch (num) {
case 1:
tmp = g_strdup_printf("#%d", info->nr);
result = g_string_append(result, tmp);
g_free(tmp);
break;
case 2:
for (tmp = info->name; *tmp != '\0';
tmp = g_utf8_next_char(tmp)) {
ch = g_utf8_get_char(tmp);
if (ch == '_') {
result = g_string_append_c(result, '_');
}
result = g_string_append_unichar(result, ch);
}
break;
default:
break;
}
ptr = subst;
substituted = TRUE;
}
}
}
if (!substituted) {
result = g_string_append_unichar(result, ch);
}
ptr = g_utf8_next_char(ptr);
}
ptr = result->str;
g_string_free(result, FALSE);
return ptr;
}
GmKeyValuePair *
gm_mcp_vmoo_userlist_get_menu_item(GmMcpVmooUserlist *package,
GmKeyValuePair *menuitem, UserInfo *info) {
GmKeyValuePair *result = g_new0(GmKeyValuePair, 1);
if (!menuitem) {
return result;
}
result->key = gm_mcp_vmoo_userlist_menu_item_subst(package,
menuitem->key, info);
result->value = gm_mcp_vmoo_userlist_menu_item_subst(package,
menuitem->value, info);
return result;
}
GList *
gm_mcp_vmoo_userlist_get_menu(GmIUserlist *userlist, gint id) {
GmMcpVmooUserlist *package = (GmMcpVmooUserlist *)(userlist);
UserInfo *info = gm_mcp_vmoo_userlist_find_user(package, id);
GList *item, *menu = NULL;
GmKeyValuePair *pair;
if (!info) {
return NULL;
}
for (item = package->priv->menu; item; item = item->next) {
pair = (GmKeyValuePair *)(item->data);
menu = g_list_append(menu, gm_mcp_vmoo_userlist_get_menu_item(package,
pair, info));
}
return menu;
}
void
gm_mcp_vmoo_userlist_remove_user(GmMcpVmooUserlist *package, gint nr) {
GList *elem;
@ -573,10 +735,10 @@ gm_mcp_vmoo_userlist_handle_state(GmMcpVmooUserlist *package, MOOVar *v,
g_free(sort);
} else {
GM_DEBUG("User %d does not exist!", nr->i);
gm_debug_msg(DEBUG_MCP, "User %d does not exist!", nr->i);
}
} else {
GM_DEBUG("Nr is not an object: %d", nr->type);
gm_debug_msg(DEBUG_MCP, "Nr is not an object: %d", nr->type);
}
}
}
@ -584,20 +746,37 @@ gm_mcp_vmoo_userlist_handle_state(GmMcpVmooUserlist *package, MOOVar *v,
void
gm_mcp_vmoo_userlist_handle_simple(GmMcpPackage *package, gchar *suffix,
GList *fields) {
MOOVar *you;
MOOVar *v = NULL;
GmMcpVmooUserlist *userlist = GM_MCP_VMOO_USERLIST(package);
gchar const *value;
if (suffix && strcmp(suffix, "you") == 0) {
you = MOOVar_parse(gm_mcp_find_value(fields, "nr"));
if (you->type == OBJECT) {
userlist->priv->you = you->i;
MOOVar_free(you);
} else {
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleSimple: "
"you is not an object!");
if (suffix) {
if (strcmp(suffix, "you") == 0) {
v = MOOVar_parse(gm_mcp_find_value(fields, "nr"));
if (v->type == OBJECT) {
userlist->priv->you = v->i;
} else {
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleSimple: "
"you is not an object!");
}
} else if (strcmp(suffix, "menu") == 0) {
value = gm_mcp_find_value(fields, "menu");
v = MOOVar_parse(value);
if (!v || v->type != LIST) {
gm_debug_msg(DEBUG_MCP, "GmMcpVmooUserlist.HandleMulti: "
"invalid value: %s", value);
} else {
gm_mcp_vmoo_userlist_free_menu(userlist);
gm_mcp_vmoo_userlist_handle_menu(userlist, v);
}
}
}
if (v) {
MOOVar_free(v);
}
}
gboolean