* Guifications - The end all, be all, toaster popup plugin * Copyright (C) 2003-2005 Gary Kramlich * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # include "../gf_config.h" #include "gf_notification.h" #include "gf_theme_info.h" #define GF_NODE_SETTING "guifications-theme" /****************************************************************************** *****************************************************************************/ typedef struct _GfBlistDialog { PurpleRequestField *theme_field; /****************************************************************************** *****************************************************************************/ typedef enum _GfBlistThemeType { GF_BLIST_THEME_UNASSIGNED = 0, /****************************************************************************** *****************************************************************************/ static GList *dialogs = NULL; /****************************************************************************** *****************************************************************************/ gf_blist_dialog_ok_cb(gpointer data, PurpleRequestFields *fields) { GfBlistDialog *diag = (GfBlistDialog *)data; const gchar *name = NULL; value = purple_request_field_choice_get_value(diag->theme_field); l = purple_request_field_choice_get_labels(diag->theme_field); name = g_list_nth_data(l, value); case GF_BLIST_THEME_UNASSIGNED: purple_blist_node_remove_setting(diag->node, GF_NODE_SETTING); case GF_BLIST_THEME_RANDOM: purple_blist_node_set_string(diag->node, GF_NODE_SETTING, case GF_BLIST_THEME_NONE: purple_blist_node_set_string(diag->node, GF_NODE_SETTING, purple_blist_node_set_string(diag->node, GF_NODE_SETTING, name); dialogs = g_list_remove(dialogs, diag); gf_blist_dialog_cancel_cb(gpointer data, PurpleRequestFields *fields) { GfBlistDialog *diag = (GfBlistDialog *)data; dialogs = g_list_remove(dialogs, diag); /****************************************************************************** *****************************************************************************/ gf_blist_dialog_new(PurpleBlistNode *node) { GfBlistDialog *dialog = NULL; PurpleRequestFields *fields; PurpleRequestFieldGroup *group; PurpleAccount *account = NULL; const gchar *name = NULL, *format = NULL, *current = NULL; dialog = g_new0(GfBlistDialog, 1); /* wow this should really be in blist.[ch] someone remind me to * write a patch at some point. if(PURPLE_BLIST_NODE_IS_BUDDY(node)) { PurpleBuddy *buddy = (PurpleBuddy *)node; account = purple_buddy_get_account(buddy); format = N_("Please select a theme for the buddy %s"); } else if(PURPLE_BLIST_NODE_IS_CONTACT(node)) { PurpleContact *contact = (PurpleContact *)node; if(contact->priority->alias) name = contact->priority->alias; name = contact->priority->name; format = N_("Please select a theme for the contact %s"); } else if(PURPLE_BLIST_NODE_IS_GROUP(node)) { PurpleGroup *group = (PurpleGroup *)node; format = N_("Please select a theme for the group %s"); current = purple_blist_node_get_string(node, GF_NODE_SETTING); fields = purple_request_fields_new(); group = purple_request_field_group_new(NULL); purple_request_fields_add_group(fields, group); dialog->theme_field = purple_request_field_choice_new("theme", purple_request_field_group_add_field(group, dialog->theme_field); purple_request_field_choice_add(dialog->theme_field, _("Clear setting")); purple_request_field_choice_add(dialog->theme_field, _("Random")); if(!gf_utils_strcmp("(RANDOM)", current)) history = GF_BLIST_THEME_RANDOM; purple_request_field_choice_add(dialog->theme_field, _("None")); if(!gf_utils_strcmp("(NONE)", current)) history = GF_BLIST_THEME_NONE; for(l = gf_themes_get_loaded(); l; l = l->next) { GfTheme *theme = GF_THEME(l->data); GfThemeInfo *info = gf_theme_get_theme_info(theme); theme_name = gf_theme_info_get_name(info); purple_request_field_choice_add(dialog->theme_field, theme_name); if(!gf_utils_strcmp(theme_name, current)) history = i + GF_BLIST_THEME_SPECIFIC; purple_request_field_choice_set_default_value(dialog->theme_field, history); purple_request_field_choice_set_value(dialog->theme_field, history); info = g_strdup_printf(_(format), name); purple_request_fields(NULL, _("Select Guifications theme"), _("OK"), G_CALLBACK(gf_blist_dialog_ok_cb), _("Cancel"), G_CALLBACK(gf_blist_dialog_cancel_cb), account, NULL, NULL, dialog); dialogs = g_list_append(dialogs, dialog); /****************************************************************************** *****************************************************************************/ gf_blist_menu_cb(PurpleBlistNode *node, gpointer data) { /* Fix this up when we actually have a way to know if a request window * is still visible, ie: remind me to write a patch for that and to * "show" that window for the next gaim release.. gf_blist_dialog_new(node); gf_blist_drawing_menu_cb(PurpleBlistNode *node, GList **menu) { PurpleMenuAction *action; /* theres no way to get the name of a chat yet so we don't support if(PURPLE_BLIST_NODE_IS_CHAT(node)) (*menu) = g_list_append(*menu, NULL); action = purple_menu_action_new(_("Guifications Theme"), PURPLE_CALLBACK(gf_blist_menu_cb), NULL, NULL); (*menu) = g_list_append(*menu, action); /****************************************************************************** *****************************************************************************/ gf_blist_init(PurplePlugin *plugin) { purple_signal_connect(purple_blist_get_handle(), "blist-node-extended-menu", PURPLE_CALLBACK(gf_blist_drawing_menu_cb), for(l = dialogs; l; l = ll) { diag = (GfBlistDialog *)l->data; purple_request_close(PURPLE_REQUEST_FIELDS, diag->handle); dialogs = g_list_remove(dialogs, diag); /* The pointer to a GfTheme is only used if gf_blist_get_theme_type returns * GF_BLIST_THEME_SPECIFIC. If it returns random we handle that in the gf_blist_get_theme_type(PurpleBlistNode *node, GfTheme **theme) { const gchar *node_theme = NULL; g_return_val_if_fail(node, GF_BLIST_THEME_NONE); g_return_val_if_fail(theme, GF_BLIST_THEME_NONE); node_theme = purple_blist_node_get_string(node, GF_NODE_SETTING); return GF_BLIST_THEME_UNASSIGNED; if(!gf_utils_strcmp(node_theme, "(RANDOM)")) { return GF_BLIST_THEME_RANDOM; } else if(!gf_utils_strcmp(node_theme, "(NONE)")) { return GF_BLIST_THEME_NONE; *theme = gf_theme_find_theme_by_name(node_theme); /* if the specific theme is not loaded we fallback to a random theme * and do not touch the setting in the event that the user reloads * said specific theme. In our words, lets not muck everything up if * the user unloads a theme they don't mean to :) return GF_BLIST_THEME_RANDOM; return GF_BLIST_THEME_SPECIFIC; gf_blist_get_notification_for_buddy(PurpleBuddy *buddy, const gchar *n_type) { PurpleBlistNode *node = NULL; g_return_val_if_fail(buddy, NULL); g_return_val_if_fail(n_type, NULL); node = (PurpleBlistNode *)buddy; g_return_val_if_fail(node, NULL); /* i don't really like the way this is setup.. but I also don't liek the * idea of typing this out three times... GfBlistThemeType theme_type; /* grab the theme type right away */ theme_type = gf_blist_get_theme_type(node, &theme); /* then update the parent so we avoid excessive checking */ /* no theme set, check the parent */ if(theme_type == GF_BLIST_THEME_UNASSIGNED) if(theme_type == GF_BLIST_THEME_RANDOM) return gf_notification_find_for_event(n_type); if(theme_type == GF_BLIST_THEME_NONE) if(theme_type == GF_BLIST_THEME_SPECIFIC) return gf_notification_find_for_theme(theme, n_type); return gf_notification_find_for_event(n_type);