static void unnotify(PurpleConversation *conv, gboolean reset) { PurpleConversation *active_conv = NULL; PidginWindow *purplewin = NULL; g_return_if_fail(conv != NULL); if (PIDGIN_CONVERSATION(conv) == NULL) return; purplewin = PIDGIN_CONVERSATION(conv)->win; active_conv = pidgin_conv_window_get_active_conversation(purplewin); /* reset the conversation window title */ purple_conversation_autoset_title(active_conv); if (reset) { /* Only need to actually remove the urgent hinting here, since * removing it just to have it readded in re-notify is an * unnecessary couple extra RTs to the server */ handle_urgent(purplewin, FALSE); purple_conversation_set_data(conv, "notify-message-count", GINT_TO_POINTER(0)); /* Same logic as for the urgent hint, xprops are also a RT. * This needs to go here so that it gets the updated message * count. */ handle_count_xprop(purplewin); } return; }
static void message_source_activated(MessagingMenuApp *app, const gchar *id, gpointer user_data) { gchar **sections = g_strsplit(id, ":", 0); PurpleConversation *conv = NULL; PurpleAccount *account; PidginConvWindow *purplewin = NULL; char *type = sections[0]; char *cname = sections[1]; char *aname = sections[2]; char *protocol = sections[3]; account = purple_accounts_find(aname, protocol); if (g_strcmp0(type, "im") == 0) conv = PURPLE_CONVERSATION(purple_conversations_find_im_with_account(cname, account)); else if (g_strcmp0(type, "chat") == 0) conv = PURPLE_CONVERSATION(purple_conversations_find_chat_with_account(cname, account)); else conv = purple_conversations_find_with_account(cname, account); if (conv) { unalert(conv); purplewin = PIDGIN_CONVERSATION(conv)->win; pidgin_conv_window_switch_gtkconv(purplewin, PIDGIN_CONVERSATION(conv)); gdk_window_focus(gtk_widget_get_window(purplewin->window), time(NULL)); } g_strfreev (sections); }
static int alert(PurpleConversation *conv) { gint count; PidginConvWindow *purplewin = NULL; if (conv == NULL || PIDGIN_CONVERSATION(conv) == NULL) return 0; purplewin = PIDGIN_CONVERSATION(conv)->win; if (!pidgin_conv_window_has_focus(purplewin) || !pidgin_conv_window_is_active_conversation(conv)) { count = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(conv), "unity-message-count")); if (!count++) ++n_sources; g_object_set_data(G_OBJECT(conv), "unity-message-count", GINT_TO_POINTER(count)); messaging_menu_add_conversation(conv, count); update_launcher(); } return 0; }
static void add_button (MMConversation *mmconv) { PurpleConversation *conv = mmconv->conv; GtkWidget *button, *image, *sep; gchar *file_path; button = gtk_toggle_button_new(); gtk_button_set_relief(GTK_BUTTON(button), GTK_RELIEF_NONE); g_signal_connect(G_OBJECT(button), "toggled", G_CALLBACK(music_button_toggled), mmconv); file_path = g_build_filename(DATADIR, "pixmaps", "purple", "buttons", "music.png", NULL); image = gtk_image_new_from_file(file_path); g_free(file_path); gtk_container_add((GtkContainer *)button, image); sep = gtk_vseparator_new(); mmconv->seperator = sep; mmconv->button = button; gtk_widget_show(sep); gtk_widget_show(image); gtk_widget_show(button); gtk_box_pack_start(GTK_BOX(PIDGIN_CONVERSATION(conv)->toolbar), sep, FALSE, FALSE, 0); gtk_box_pack_start(GTK_BOX(PIDGIN_CONVERSATION(conv)->toolbar), button, FALSE, FALSE, 0); }
static gboolean plugin_load(PurplePlugin *plugin, GError **error) { GList *convs = purple_conversations_get_all(); void *gtk_conv_handle = pidgin_conversations_get_handle(); purple_signal_connect(gtk_conv_handle, "conversation-displayed", plugin, PURPLE_CALLBACK(conversation_displayed_cb), NULL); /* purple_signal_connect(gtk_conv_handle, "conversation-hiding", plugin, PURPLE_CALLBACK(conversation_hiding_cb), NULL); */ while (convs) { PurpleConversation *conv = (PurpleConversation *)convs->data; /* Setup Send button */ if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) { create_send_button_pidgin(PIDGIN_CONVERSATION(conv)); } convs = convs->next; } return TRUE; }
/** * \fn add_message_iter * \brief Stores the current position in the chat window */ void add_message_iter(PurpleConnection *gc, const char* to, const gchar* messageid, int newlines) { #ifdef DEBUG printf("to: %s \n", to); #endif PurpleAccount *acct = purple_connection_get_account (gc); if(!acct) return; PurpleConversation *conv = purple_find_conversation_with_account(PURPLE_CONV_TYPE_ANY, to, acct); if(!conv) return; PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); GtkIMHtml *imhtml = GTK_IMHTML(gtkconv->imhtml); message_info *info = g_new(message_info, 1); info->textbuffer = imhtml->text_buffer; GtkTextIter location; gtk_text_buffer_get_end_iter(imhtml->text_buffer, &location); info->offset = gtk_text_iter_get_offset (&location); info->lines = newlines; //Insert the location to the table, use messageid as key g_hash_table_insert(ht_locations, strdup(messageid), info); #ifdef DEBUG printf("attached key: %s, table size now %d \n", messageid, g_hash_table_size(ht_locations)); #endif }
static gboolean twitter_conv_icon_displaying_chat_cb(PurpleAccount * account, const char *who, char **message, PurpleConversation * conv, PurpleMessageFlags flags, void *account_signal) { GtkIMHtml *imhtml; GtkTextBuffer *text_buffer; gint linenumber = 0; if (account != account_signal) return FALSE; purple_debug_info(PLUGIN_ID, "called %s\n", G_STRFUNC); /* get text buffer */ imhtml = GTK_IMHTML(PIDGIN_CONVERSATION(conv)->imhtml); text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml)); /* store number of lines */ linenumber = gtk_text_buffer_get_line_count(text_buffer); //this is just used to pass the current line number (before the insertion of the new text) //to the _displayed_chat_cb func. //Since pidgin is (mostly) single threaded, this is probably overkill and we could just use //a single global int. //On another note, we don't insert the icon here because the message may not end up being displayed //based on what other plugins do purple_conversation_set_data(conv, PLUGIN_ID "-icon-ln", GINT_TO_POINTER(linenumber)); return FALSE; }
/************************************************************************************************** Load plugin **************************************************************************************************/ static gboolean plugin_load(PurplePlugin *plugin) { PidginBuddyList *gtkblist = pidgin_blist_get_default_gtk_blist(); GList *convs = purple_get_conversations(); if (purple_prefs_get_bool("/plugins/core/hidemenu/default_state")) { hmb_is_menu_visible = FALSE; } else { hmb_is_menu_visible = TRUE; } // set callback for 'blist created' signal purple_signal_connect(pidgin_blist_get_handle(), "gtkblist-created", plugin, PURPLE_CALLBACK(hmb_blist_created_cb), NULL); // set callback for 'conversation displayed' signal purple_signal_connect(pidgin_conversations_get_handle(), "conversation-displayed", plugin, PURPLE_CALLBACK(hmb_conversation_displayed_cb), NULL); // hide blist menubar hmb_toggle_menubar(gtkblist, NULL); // hide conversations menubar while (convs) { PurpleConversation *conv = (PurpleConversation *)convs->data; if (PIDGIN_IS_PIDGIN_CONVERSATION(conv)) { hmb_toggle_menubar(NULL, PIDGIN_CONVERSATION(conv)); } convs = convs->next; } return TRUE; }
static void timestamp_display(PurpleConversation *conv, time_t then, time_t now) { PidginConversation *gtk_conv = PIDGIN_CONVERSATION(conv); GtkWidget *imhtml = gtk_conv->imhtml; GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml)); GtkTextIter iter; const char *mdate; int y, height; GdkRectangle rect; /* display timestamp */ mdate = purple_utf8_strftime(then == 0 ? "%H:%M" : "\n%H:%M", localtime(&now)); gtk_text_buffer_get_end_iter(buffer, &iter); if (gtk_text_tag_table_lookup(gtk_text_buffer_get_tag_table(buffer), "TIMESTAMP") == NULL) gtk_text_buffer_create_tag(buffer, "TIMESTAMP", "foreground", "#888888", "justification", GTK_JUSTIFY_CENTER, "weight", PANGO_WEIGHT_BOLD, NULL); gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, mdate, strlen(mdate), "TIMESTAMP", NULL); /* scroll view if necessary */ gtk_text_view_get_visible_rect(GTK_TEXT_VIEW(imhtml), &rect); gtk_text_view_get_line_yrange( GTK_TEXT_VIEW(imhtml), &iter, &y, &height); if (((y + height) - (rect.y + rect.height)) > height && gtk_text_buffer_get_char_count(buffer)) { gboolean smooth = purple_prefs_get_bool( PIDGIN_PREFS_ROOT "/conversations/use_smooth_scrolling"); gtk_imhtml_scroll_to_end(GTK_IMHTML(imhtml), smooth); } }
static void detach_signals(PurpleConversation *conv) { PidginConversation *gtkconv = NULL; GSList *ids = NULL, *l; gtkconv = PIDGIN_CONVERSATION(conv); if (!gtkconv) return; ids = g_object_get_data(G_OBJECT(conv), "notify-webview-signals"); for (l = ids; l != NULL; l = l->next) g_signal_handler_disconnect(gtkconv->webview, GPOINTER_TO_INT(l->data)); g_slist_free(ids); ids = g_object_get_data(G_OBJECT(conv), "notify-entry-signals"); for (l = ids; l != NULL; l = l->next) g_signal_handler_disconnect(gtkconv->entry, GPOINTER_TO_INT(l->data)); g_slist_free(ids); g_object_set_data(G_OBJECT(conv), "notify-message-count", GINT_TO_POINTER(0)); g_object_set_data(G_OBJECT(conv), "notify-webview-signals", NULL); g_object_set_data(G_OBJECT(conv), "notify-entry-signals", NULL); }
/** * A callback for when a conversation is opened * * This will simply remove the instructions tab when a conversation is opened * in a notebook that is displaying it. * * @param[in] conv The new conversation **/ static void conversation_created_cb(PurpleConversation *conv) { PidginConversation *gtkconv; /*< The new Pidgin conversation */ PidginBuddyList *gtkblist; /*< The Buddy List associated with conv */ PidginWindow *gtkconvwin; /*< The conversation window that owns conv */ if (conv == NULL) return; gtkconv = PIDGIN_CONVERSATION(conv); gtkconvwin = pidgin_conv_get_window(gtkconv); gtkblist = pwm_convs_get_blist(gtkconvwin); /* Sanity check: This callback should only continue for merged windows. */ if (gtkblist == NULL) return; /* If there is a tab in addition to the instructions tab, remove it. */ if (pidgin_conv_window_get_gtkconv_count(gtkconvwin) > 1) { pwm_hide_dummy_conversation(gtkblist); pwm_set_conv_menus_visible(gtkblist, TRUE); /* Process queued focus events, and focus the conversation entry * field. */ while (gtk_events_pending()) gtk_main_iteration(); gtk_widget_grab_focus(gtkconv->entry); } }
static gboolean displaying_im_cb(PurpleAccount *account, const char *who, char **message, PurpleConversation *conv, PurpleMessageFlags flags, void *unused) { GtkIMHtml *imhtml; GtkTextBuffer *text_buffer; gint service = get_service_type(conv); gint linenumber = 0; twitter_debug("called\n"); if(service == unknown_service) { twitter_debug("neither twitter nor wassr conv\n"); return FALSE; } /* get text buffer */ imhtml = GTK_IMHTML(PIDGIN_CONVERSATION(conv)->imhtml); text_buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(imhtml)); /* store number of lines */ linenumber = gtk_text_buffer_get_line_count(text_buffer); g_hash_table_insert(conv_hash, conv, GINT_TO_POINTER(linenumber)); twitter_debug("conv = %p linenumber = %d\n", conv, linenumber); return FALSE; }
static void detach_from_conversation(PurpleConversation *conv) { PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); GtkTextView *view = GTK_TEXT_VIEW(gtkconv->entry); g_signal_handlers_disconnect_matched(G_OBJECT(view), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(right_click_popup), NULL); }
static void conv_updated_cb(PurpleConversation *conv, PurpleConvUpdateType type) { PidginConversation *pconv = PIDGIN_CONVERSATION(conv); PidginWindow *win = pidgin_conv_get_window(pconv); if (type == PURPLE_CONV_UPDATE_UNSEEN && !pidgin_conv_is_hidden(pconv) && pconv->unseen_state == PIDGIN_UNSEEN_NONE && pidgin_conv_window_get_gtkconv_count(win) == 1) { GtkWidget *window = win->window; gboolean has_focus; g_object_get(G_OBJECT(window), "has-toplevel-focus", &has_focus, NULL); if (!has_focus || !purple_prefs_get_bool(OPT_WINTRANS_IM_ONFOCUS)) set_conv_window_trans(NULL, win); if (g_signal_handler_find(G_OBJECT(window), G_SIGNAL_MATCH_FUNC, 0, 0, NULL, G_CALLBACK(focus_conv_win_cb), NULL) == 0) { g_signal_connect(G_OBJECT(window), "focus_in_event", G_CALLBACK(focus_conv_win_cb), window); g_signal_connect(G_OBJECT(window), "focus_out_event", G_CALLBACK(focus_conv_win_cb), window); } } }
static void send_as_link (PidginWindow * win, PidginConversation * _gtkconv) { PurplePlugin *plugin; plugin = purple_plugins_find_with_id (PLUGIN_ID); if (PLUGIN (locked)) return; /* Just return, don't fail. */ else { PidginConversation *gtkconv; PLUGIN (locked) = TRUE; PLUGIN (send_as) = SEND_AS_HTTP_LINK; if (win != NULL) gtkconv = PIDGIN_CONVERSATION (pidgin_conv_window_get_active_conversation (win)); else gtkconv = _gtkconv; if (!strcmp (purple_prefs_get_string (PREF_UPLOAD_TO), HOST_DISABLED)) { purple_notify_error (plugin, PLUGIN_NAME, PLUGIN_ERROR, PLUGIN_HOST_DISABLED_ERROR); plugin_stop (plugin); return; } REMEMBER_ACCOUNT (gtkconv); PLUGIN (conv_features) = gtkconv->active_conv->features; freeze_desktop (plugin, FALSE); } }
static void conversation_delete_cb(PurpleConversation *conv) { PidginWindow *win = pidgin_conv_get_window(PIDGIN_CONVERSATION(conv)); /* If it is the last conversation in the window, cleanup */ if (win != NULL && pidgin_conv_window_get_gtkconv_count(win) == 1) cleanup_conv_window(win); }
static void detach_signals(PurpleConversation *conv) { PidginConversation *gtkconv = NULL; PidginWindow *gtkwin = NULL; GSList *ids = NULL, *l; gtkconv = PIDGIN_CONVERSATION(conv); if (!gtkconv) return; gtkwin = gtkconv->win; ids = purple_conversation_get_data(conv, "notify-imhtml-signals"); for (l = ids; l != NULL; l = l->next) g_signal_handler_disconnect(gtkconv->imhtml, GPOINTER_TO_INT(l->data)); g_slist_free(ids); ids = purple_conversation_get_data(conv, "notify-entry-signals"); for (l = ids; l != NULL; l = l->next) g_signal_handler_disconnect(gtkconv->entry, GPOINTER_TO_INT(l->data)); g_slist_free(ids); purple_conversation_set_data(conv, "notify-message-count", GINT_TO_POINTER(0)); purple_conversation_set_data(conv, "notify-imhtml-signals", NULL); purple_conversation_set_data(conv, "notify-entry-signals", NULL); }
static void conv_created_cb(PurpleConversation *conv, gpointer null) { PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); twitter_debug("called\n"); g_return_if_fail(gtkconv != NULL); gint service = get_service_type(conv); /* only attach to twitter conversation window */ switch(service) { case twitter_service: get_status_with_api((gpointer)conv); source.id = g_timeout_add_seconds( purple_prefs_get_int(OPT_API_BASE_GET_INTERVAL), get_status_with_api, (gpointer)conv); source.conv = conv; attach_to_conv(conv, NULL); break; case wassr_service: case identica_service: case jisko_service: case ffeed_service: attach_to_conv(conv, NULL); break; default: twitter_debug("unknown service\n"); break; } }
static void send_as_image (PidginWindow * win, PidginConversation * _gtkconv) { PurplePlugin *plugin = purple_plugins_find_with_id (PLUGIN_ID); if (PLUGIN (locked)) return; /* Just return, don't fail. */ else { PidginConversation *gtkconv; PLUGIN (locked) = TRUE; PLUGIN (send_as) = SEND_AS_IMAGE; if (win != NULL) gtkconv = PIDGIN_CONVERSATION (pidgin_conv_window_get_active_conversation (win)); else gtkconv = _gtkconv; REMEMBER_ACCOUNT (gtkconv); PLUGIN (conv_features) = gtkconv->active_conv->features; freeze_desktop (plugin, FALSE); } }
static void detach_from_conv(PurpleConversation *conv, gpointer null) { PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); GtkWidget *box, *counter = NULL, *sep = NULL; g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry_buffer), (GFunc) insert_text_cb, conv); g_signal_handlers_disconnect_by_func(G_OBJECT(gtkconv->entry_buffer), (GFunc) delete_text_cb, conv); box = gtkconv->toolbar; /* remove counter */ counter = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-counter"); if(counter) { gtk_container_remove(GTK_CONTAINER(box), counter); g_object_unref(counter); g_object_set_data(G_OBJECT(box), PLUGIN_ID "-counter", NULL); } /* remove separator */ sep = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-sep"); if(sep) { gtk_container_remove(GTK_CONTAINER(box), sep); g_object_unref(sep); g_object_set_data(G_OBJECT(box), PLUGIN_ID "-sep", NULL); } gtk_widget_queue_draw(pidgin_conv_get_window(gtkconv)->window); }
/** * A callback for when a conversation is being closed * * This is only used to display help, hide conversation menu items, and reset * the window title when the last conversation in the Buddy List window is * being closed. * * @param[in] conv The conversation on its way out the door **/ static void deleting_conversation_cb(PurpleConversation *conv) { PidginBuddyList *gtkblist; /*< The Buddy List associated with conv */ PidginWindow *gtkconvwin; /*< The conversation window that owns conv */ if (conv == NULL) return; gtkconvwin = pidgin_conv_get_window(PIDGIN_CONVERSATION(conv)); gtkblist = pwm_convs_get_blist(gtkconvwin); /* Sanity check: This callback should only continue for merged windows. */ if (gtkblist == NULL) return; /* If the last conv is being deleted, reset help, icons, title, and * menu. */ if (pidgin_conv_window_get_gtkconv_count(gtkconvwin) <= 1) { pwm_show_dummy_conversation(gtkblist); gtk_window_set_icon_list(GTK_WINDOW(gtkblist->window), NULL); gtk_window_set_title(GTK_WINDOW(gtkblist->window), pwm_fetch(gtkblist, "title")); pwm_set_conv_menus_visible(gtkblist, FALSE); } }
static void attach_to_conversation(PurpleConversation *conv) { PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); GtkTextView *view = GTK_TEXT_VIEW(gtkconv->entry); g_signal_connect(G_OBJECT(view), "populate-popup", G_CALLBACK(right_click_popup), gtkconv); }
static void reorder_tabs(PurpleConversation *purpleConv) { PidginConversation *pidginConv; PidginWindow *win; if (!purpleConv) { return; } pidginConv = PIDGIN_CONVERSATION(purpleConv); if (!pidginConv || !pidginConv->tab_cont) { return; } win = pidgin_conv_get_window(pidginConv); if (!win || !win->notebook) { return; } int count_tabs = gtk_notebook_get_n_pages(GTK_NOTEBOOK(win->notebook)); const char* tablist[count_tabs]; for (int i = 0; i < count_tabs; i++) { tablist[i] = get_tab_title(i, win); } qsort(tablist, sizeof(tablist)/sizeof(char *), sizeof(char *), compare); for (int i = 0; i < count_tabs; i++) { //printf("Sorted: %s\n", tablist[i]); gtk_notebook_reorder_child(GTK_NOTEBOOK(win->notebook), get_tab_by_title(tablist[i], win), i); } }
static void attach_to_conv(PurpleConversation *conv, gpointer null) { PidginConversation *gtkconv = PIDGIN_CONVERSATION(conv); GtkWidget *box, *sep, *counter, *menus; GtkIMHtml *imhtml; box = gtkconv->toolbar; imhtml = GTK_IMHTML(gtkconv->imhtml); /* Disable widgets that decorate or add link to composing text * because Twitter cannot receive marked up string. For lean-view * and wide-view, see pidgin/gtkimhtmltoolbar.c. */ menus = g_object_get_data(G_OBJECT(box), "lean-view"); if(menus) { gtk_widget_set_sensitive(GTK_WIDGET(menus), FALSE); } menus = g_object_get_data(G_OBJECT(box), "wide-view"); if(menus) { gtk_widget_set_sensitive(GTK_WIDGET(menus), FALSE); } purple_conversation_set_features( gtkconv->active_conv, purple_conversation_get_features(gtkconv->active_conv) & ~PURPLE_CONNECTION_HTML); /* check if the counter is enabled */ if(!purple_prefs_get_bool(OPT_COUNTER)) return; /* get counter object */ counter = g_object_get_data(G_OBJECT(box), PLUGIN_ID "-counter"); g_return_if_fail(counter == NULL); /* make counter object */ counter = gtk_label_new(NULL); gtk_widget_set_name(counter, "counter_label"); gtk_label_set_text(GTK_LABEL(counter), "0"); gtk_box_pack_end(GTK_BOX(box), counter, FALSE, FALSE, 0); gtk_widget_show_all(counter); g_object_set_data(G_OBJECT(box), PLUGIN_ID "-counter", counter); /* make separator object */ sep = gtk_vseparator_new(); gtk_box_pack_end(GTK_BOX(box), sep, FALSE, FALSE, 0); gtk_widget_show_all(sep); g_object_set_data(G_OBJECT(box), PLUGIN_ID "-sep", sep); /* connect to signals */ g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "insert_text", G_CALLBACK(insert_text_cb), conv); g_signal_connect(G_OBJECT(gtkconv->entry_buffer), "delete_range", G_CALLBACK(delete_text_cb), conv); /* redraw window */ gtk_widget_queue_draw(pidgin_conv_get_window(gtkconv)->window); }
static void new_conversation_cb(PurpleConversation *conv) { PidginWindow *win = pidgin_conv_get_window(PIDGIN_CONVERSATION(conv)); /* If it is the first conversation in the window, * add the sliders, and set transparency */ if (!pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv)) && pidgin_conv_window_get_gtkconv_count(win) == 1) { GtkWidget *window = win->window; set_conv_window_trans(NULL, win); g_signal_connect(G_OBJECT(window), "focus_in_event", G_CALLBACK(focus_conv_win_cb), window); g_signal_connect(G_OBJECT(window), "focus_out_event", G_CALLBACK(focus_conv_win_cb), window); } }
static void handle_present(PurpleConversation *conv) { if (pidgin_conv_is_hidden(PIDGIN_CONVERSATION(conv))) return; purple_conversation_present(conv); }
static void stroke_new_win(GtkWidget *widget, void *data) { PidginWindow *new_win, *old_win; PurpleConversation *conv; conv = (PurpleConversation *)data; old_win = PIDGIN_CONVERSATION(conv)->win; if (pidgin_conv_window_get_gtkconv_count(old_win) <= 1) return; new_win = pidgin_conv_window_new(); pidgin_conv_window_remove_gtkconv(old_win, PIDGIN_CONVERSATION(conv)); pidgin_conv_window_add_gtkconv(new_win, PIDGIN_CONVERSATION(conv)); pidgin_conv_window_show(new_win); }
static int attach_signals(PurpleConversation *conv) { PidginConversation *gtkconv = NULL; PidginWindow *gtkwin = NULL; GSList *imhtml_ids = NULL, *entry_ids = NULL; guint id; gtkconv = PIDGIN_CONVERSATION(conv); if (!gtkconv) { purple_debug_misc("notify", "Failed to find gtkconv\n"); return 0; } gtkwin = gtkconv->win; if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_focus")) { /* TODO should really find a way to make this work no matter * where the focus is inside the conv window, without having * to bind to focus-in-event on the g(d|t)kwindow */ /* try setting the signal on the focus-in-event for * gtkwin->notebook->container? */ id = g_signal_connect(G_OBJECT(gtkconv->entry), "focus-in-event", G_CALLBACK(unnotify_cb), conv); entry_ids = g_slist_append(entry_ids, GUINT_TO_POINTER(id)); id = g_signal_connect(G_OBJECT(gtkconv->imhtml), "focus-in-event", G_CALLBACK(unnotify_cb), conv); imhtml_ids = g_slist_append(imhtml_ids, GUINT_TO_POINTER(id)); } if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_click")) { /* TODO similarly should really find a way to allow for * clicking in other places of the window */ id = g_signal_connect(G_OBJECT(gtkconv->entry), "button-press-event", G_CALLBACK(unnotify_cb), conv); entry_ids = g_slist_append(entry_ids, GUINT_TO_POINTER(id)); id = g_signal_connect(G_OBJECT(gtkconv->imhtml), "button-press-event", G_CALLBACK(unnotify_cb), conv); imhtml_ids = g_slist_append(imhtml_ids, GUINT_TO_POINTER(id)); } if (purple_prefs_get_bool("/plugins/gtk/X11/notify/notify_type")) { id = g_signal_connect(G_OBJECT(gtkconv->entry), "key-press-event", G_CALLBACK(unnotify_cb), conv); entry_ids = g_slist_append(entry_ids, GUINT_TO_POINTER(id)); } purple_conversation_set_data(conv, "notify-imhtml-signals", imhtml_ids); purple_conversation_set_data(conv, "notify-entry-signals", entry_ids); return 0; }
/** * \fn deleting_conversation_cb * \brief Deletes all references to this conversation from the hashtable */ static void deleting_conversation_cb(PurpleConversation *conv) { g_hash_table_foreach_remove(ht_locations, deleting_conversation_remove_items, GTK_IMHTML(PIDGIN_CONVERSATION(conv)->imhtml)->text_buffer); #ifdef DEBUG printf("conversation closed, table size now %d \n", g_hash_table_size(ht_locations)); #endif }
static void stroke_next_tab(GtkWidget *widget, void *data) { PurpleConversation *conv; PidginWindow *win; conv = (PurpleConversation *)data; win = PIDGIN_CONVERSATION(conv)->win; switch_page(win, GTK_DIR_RIGHT); }