grim/purple-plugin-pack
--leaks
org.guifications.plugins
2009-04-15, darkrain42
* irssi - Implements several irssi features for Purple * Copyright (C) 2005-2008 Gary Kramlich <grim@reaperworld.com> * Copyright (C) 2006-2008 John Bailey <rekkanoryo@rekkanoryo.org> * Copyright (C) 2006-2008 Sadrul Habib Chowdhury <sadrul@users.sourceforge.net> * 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., 51 Franklin Street, Fifth Floor, Boston, MA /* If you can't figure out what this line is for, DON'T TOUCH IT. */ #include "../common/pp_internal.h" #define IRSSI_LAYOUT_SETTING "irssi::layout" #define SETTING_TO_INTS(s, i1, i2) { \ #define SETTING_FROM_INTS(i1, i2) (((i1) << 10 ) + (i2)) /****************************************************************************** *****************************************************************************/ static PurpleCmdId irssi_layout_cmd_id = 0; /****************************************************************************** *****************************************************************************/ irssi_layout_get_node_from_conv(PurpleConversation *conv) { PurpleBlistNode *node = NULL; /* this is overkill for now, but who knows, we _may_ need it later */ case PURPLE_CONV_TYPE_CHAT: node = (PurpleBlistNode *)purple_blist_find_chat(conv->account, case PURPLE_CONV_TYPE_IM: node = (PurpleBlistNode *)purple_find_buddy(conv->account, conv->name); static PurpleConversation * irssi_layout_get_conv_from_node(PurpleBlistNode *node, gboolean create) { PurpleAccount *account = NULL; PurpleConversation *conv = NULL; PurpleConversationType ctype = PURPLE_CONV_TYPE_UNKNOWN; const gchar *name = NULL; case PURPLE_BLIST_CHAT_NODE: { PurpleChat *chat = (PurpleChat *)node; ctype = PURPLE_CONV_TYPE_CHAT; name = purple_chat_get_name(chat); case PURPLE_BLIST_BUDDY_NODE: { PurpleBuddy *buddy = (PurpleBuddy *)node; ctype = PURPLE_CONV_TYPE_IM; account = buddy->account; conv = purple_find_conversation_with_account(ctype, name, account); conv = purple_conversation_new(ctype, account, name); if(ctype == PURPLE_BLIST_CHAT_NODE) { PurpleChat *chat = (PurpleChat *)node; PURPLE_CONV_CHAT(conv)->left = TRUE; serv_join_chat(account->gc, chat->components); irssi_layout_get_setting(PidginConversation *gtkconv) { PurpleConversation *conv = gtkconv->active_conv; PurpleBlistNode *node = NULL; node = irssi_layout_get_node_from_conv(conv); ret = purple_blist_node_get_int(node, IRSSI_LAYOUT_SETTING); irssi_layout_reset(void) { PurpleBlistNode *node = purple_blist_get_root(); for(; node; node = purple_blist_node_next(node, TRUE)) purple_blist_node_remove_setting(node, IRSSI_LAYOUT_SETTING); irssi_layout_save(void) { PurpleBlistNode *node = NULL; /* reset the previous layouts if any exist */ /* now save the layout... */ wins = pidgin_conv_windows_get_list(); for(i = 1; wins; wins = wins->next, i++) { PidginWindow *win = wins->data; GList *convs = pidgin_conv_window_get_gtkconvs(win); for(j = 1; convs; convs = convs->next, j++) { PidginConversation *gtkconv = convs->data; PurpleConversation *conv = gtkconv->active_conv; node = irssi_layout_get_node_from_conv(conv); purple_blist_node_set_int(node, IRSSI_LAYOUT_SETTING, SETTING_FROM_INTS(i, j)); irssi_layout_load(void) { PurpleConversation *conv = NULL; PidginConversation *gtkconv = NULL; PidginWindow *window = NULL; GList *convs = NULL, *settings = NULL, *wins = NULL; node = purple_blist_get_root(); /* build our GList's with the conversation and the setting */ for(; node; node = purple_blist_node_next(node, FALSE)) { gint setting = purple_blist_node_get_int(node, IRSSI_LAYOUT_SETTING); conv = irssi_layout_get_conv_from_node(node, FALSE); convs = g_list_prepend(convs, conv); settings = g_list_prepend(settings, GINT_TO_POINTER(setting)); /* now restore the layout */ /* we start by looping until all of our settings are handled */ GList *l1 = NULL, *l2 = NULL; /* now go through the list and make sure we put the conversations in for(l1 = convs, l2 = settings; l1; ) { setting = GPOINTER_TO_INT(l2->data); SETTING_TO_INTS(setting, pos, win); /* pop of the nodes we just handled but hold our places and update convs = g_list_delete_link(convs, s); settings = g_list_delete_link(settings, s); /* now find the actual window this should go into */ wins = pidgin_conv_windows_get_list(); window = g_list_nth_data(wins, win - 1); /* make dat der dun winda */ window = pidgin_conv_window_new(); /* add the conversation to the window */ if(gtkconv->win != window) { pidgin_conv_window_remove_gtkconv(gtkconv->win, gtkconv); pidgin_conv_window_add_gtkconv(window, gtkconv); /* All the conversations are in the correct windows. Now we make sure * they're in their right positions. for(wins = pidgin_conv_windows_get_list(); wins; wins = wins->next) { gint count, i, pos, position; count = pidgin_conv_window_get_gtkconv_count(window); for(position = 1; position < count; position++) { gtkconv = pidgin_conv_window_get_gtkconv_at_index(window, position); pos = irssi_layout_get_setting(gtkconv); SETTING_TO_INTS(pos, pos, w); /* this could probably use tweaking, but it _should_ work */ for(i = pos; i < position; i++) { PidginConversation *gtkconv2 = NULL; pidgin_conv_window_get_gtkconv_at_index(window, i); p = irssi_layout_get_setting(gtkconv2); gtk_notebook_reorder_child(GTK_NOTEBOOK(window->notebook), irssi_layout_cmd_cb(PurpleConversation *conv, const gchar *cmd, gchar **args, gchar **error, void *data) const gchar *sub_cmd = args[0]; if(!g_ascii_strcasecmp(sub_cmd, "load")) { } else if(!g_ascii_strcasecmp(sub_cmd, "save")) { } else if(!g_ascii_strcasecmp(sub_cmd, "reset")) { return PURPLE_CMD_RET_OK; /****************************************************************************** *****************************************************************************/ irssi_layout_init(PurplePlugin *plugin) { if(irssi_layout_cmd_id != 0) * XXX: Translators: DO NOT TRANSLATE the first "layout" or the "\nsave" * or "reset" at the beginning of the last line below, or the HTML tags. help = _("<pre>layout <save|reset>: Remember the layout of the " "current conversations to reopen them when Purple is restarted.\n" "save - saves the current layout\n" "reset - clears the current saved layout\n" purple_cmd_register("layout", "w", PURPLE_CMD_P_PLUGIN, PURPLE_CMD_FLAG_IM | PURPLE_CMD_FLAG_CHAT, NULL, PURPLE_CMD_FUNC(irssi_layout_cmd_cb), help, NULL); irssi_layout_uninit(PurplePlugin *plugin) { if(irssi_layout_cmd_id == 0) purple_cmd_unregister(irssi_layout_cmd_id);