* Finch is the legal property of its developers, whose names are too numerous * to list here. Please refer to the COPYRIGHT file distributed with this * 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 02111-1301 USA notify_msg_window_destroy_cb(GntWidget *window, PurpleNotifyType type) purple_notify_close(type, window); finch_notify_common(PurpleNotifyType ntype, PurpleNotifyMessageType msgtype, const char *title, const char *primary, const char *secondary, PurpleRequestCommonParameters *cpar) GntWidget *window, *button; GntTextFormatFlags pf = 0, sf = 0; case PURPLE_NOTIFY_MSG_ERROR: sf |= GNT_TEXT_FLAG_BOLD; case PURPLE_NOTIFY_MSG_WARNING: pf |= GNT_TEXT_FLAG_UNDERLINE; case PURPLE_NOTIFY_MSG_INFO: pf |= GNT_TEXT_FLAG_BOLD; window = gnt_window_box_new(FALSE, TRUE); gnt_box_set_title(GNT_BOX(window), title); gnt_box_set_fill(GNT_BOX(window), FALSE); gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); gnt_box_set_pad(GNT_BOX(window), 0); gnt_box_add_widget(GNT_BOX(window), gnt_label_new_with_format(primary, pf)); button = gnt_button_new(_("OK")); if (ntype == PURPLE_NOTIFY_FORMATTED) { int width = -1, height = -1; char *plain = (char*)secondary; msg = gnt_text_view_new(); gnt_text_view_set_flag(GNT_TEXT_VIEW(msg), GNT_TEXT_VIEW_TOP_ALIGN | GNT_TEXT_VIEW_NO_SCROLL); plain = purple_markup_strip_html(secondary); if (!gnt_util_parse_xhtml_to_textview(secondary, GNT_TEXT_VIEW(msg))) gnt_text_view_append_text_with_flags(GNT_TEXT_VIEW(msg), plain, sf); gnt_text_view_attach_scroll_widget(GNT_TEXT_VIEW(msg), button); gnt_util_get_text_bound(plain, &width, &height); gnt_widget_set_size(msg, width + 3, height + 1); msg = gnt_label_new_with_format(secondary, sf); gnt_box_add_widget(GNT_BOX(window), msg); g_object_set_data(G_OBJECT(window), "info-widget", msg); gnt_box_add_widget(GNT_BOX(window), button); g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), window); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(ntype)); /* handle is, in all/most occasions, a GntWidget * */ static void finch_close_notify(PurpleNotifyType type, void *handle) GntWidget *widget = handle; widget = gnt_widget_get_toplevel(widget); if (type == PURPLE_NOTIFY_SEARCHRESULTS) purple_notify_searchresults_free(g_object_get_data(handle, "notify-results")); /* This did not seem to be necessary */ g_signal_handlers_disconnect_by_func(G_OBJECT(widget), G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(type)); gnt_widget_destroy(widget); finch_notify_message(PurpleNotifyMessageType type, const char *title, const char *primary, const char *secondary, PurpleRequestCommonParameters *cpar) return finch_notify_common(PURPLE_NOTIFY_MESSAGE, type, title, primary, static void *finch_notify_formatted(const char *title, const char *primary, const char *secondary, const char *text) char *t = g_strdup_printf("<span>%s%s%s</span>", secondary ? secondary : "", purple_markup_html_to_xhtml(t, &xhtml, NULL); ret = finch_notify_common(PURPLE_NOTIFY_FORMATTED, PURPLE_NOTIFY_MSG_INFO, title, primary, xhtml, NULL); emaildialog.window = NULL; GntWidget *box, *tree, *button; emaildialog.window = box = gnt_vbox_new(FALSE); gnt_box_set_toplevel(GNT_BOX(box), TRUE); gnt_box_set_title(GNT_BOX(box), _("Emails")); gnt_box_set_fill(GNT_BOX(box), FALSE); gnt_box_set_alignment(GNT_BOX(box), GNT_ALIGN_MID); gnt_box_set_pad(GNT_BOX(box), 0); gnt_box_add_widget(GNT_BOX(box), gnt_label_new_with_format(_("You have mail!"), GNT_TEXT_FLAG_BOLD)); emaildialog.tree = tree = gnt_tree_new_with_columns(3); gnt_tree_set_column_titles(GNT_TREE(tree), _("Account"), _("Sender"), _("Subject")); gnt_tree_set_show_title(GNT_TREE(tree), TRUE); gnt_tree_set_col_width(GNT_TREE(tree), 0, 15); gnt_tree_set_col_width(GNT_TREE(tree), 1, 25); gnt_tree_set_col_width(GNT_TREE(tree), 2, 25); gnt_box_add_widget(GNT_BOX(box), tree); button = gnt_button_new(_("Close")); gnt_box_add_widget(GNT_BOX(box), button); g_signal_connect_swapped(G_OBJECT(button), "activate", G_CALLBACK(gnt_widget_destroy), box); g_signal_connect(G_OBJECT(box), "destroy", G_CALLBACK(reset_email_dialog), NULL); finch_notify_emails(PurpleConnection *gc, size_t count, gboolean detailed, const char **subjects, const char **froms, const char **tos, PurpleAccount *account = purple_connection_get_account(gc); message = g_strdup_printf( ngettext("%s (%s) has %d new message.", "%s (%s) has %d new messages.", (int)count), tos ? *tos : purple_account_get_username(account), purple_account_get_protocol_name(account), (int)count); ret = finch_notify_common(PURPLE_NOTIFY_EMAIL, PURPLE_NOTIFY_MSG_INFO, _("New Mail"), _("You have mail!"), message, gboolean newwin = (emaildialog.window == NULL); to = g_strdup_printf("%s (%s)", tos ? *tos : purple_account_get_username(account), purple_account_get_protocol_name(account)); gnt_tree_add_row_after(GNT_TREE(emaildialog.tree), GINT_TO_POINTER(++key), gnt_tree_create_row(GNT_TREE(emaildialog.tree), to, froms ? *froms : "[Unknown sender]", gnt_widget_show(emaildialog.window); gnt_window_present(emaildialog.window); finch_notify_email(PurpleConnection *gc, const char *subject, const char *from, const char *to, const char *url) return finch_notify_emails(gc, 1, subject != NULL, subject ? &subject : NULL, /** User information. **/ static GHashTable *userinfo; userinfo_hash(PurpleAccount *account, const char *who) g_snprintf(key, sizeof(key), "%s - %s", purple_account_get_username(account), purple_normalize(account, who)); return g_utf8_strup(key, -1); remove_userinfo(GntWidget *widget, gpointer key) g_hash_table_remove(userinfo, key); purple_notify_user_info_get_xhtml(PurpleNotifyUserInfo *user_info) text = g_string_new("<span>"); for (l = purple_notify_user_info_get_entries(user_info)->head; l != NULL; PurpleNotifyUserInfoEntry *user_info_entry = l->data; PurpleNotifyUserInfoEntryType type = purple_notify_user_info_entry_get_entry_type(user_info_entry); const char *label = purple_notify_user_info_entry_get_label(user_info_entry); const char *value = purple_notify_user_info_entry_get_value(user_info_entry); /* Handle the label/value pair itself */ if (type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER) g_string_append(text, "<u>"); g_string_append_printf(text, "<b>%s</b>", label); g_string_append(text, "<span>"); g_string_append(text, ": "); char *strip = purple_markup_strip_html(value); g_string_append(text, strip); g_string_append(text, "</span>"); if (type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_HEADER) g_string_append(text, "</u>"); else if (type == PURPLE_NOTIFY_USER_INFO_ENTRY_SECTION_BREAK) g_string_append(text, "<HR/>"); g_string_append(text, "<BR/>"); g_string_append(text, "</span>"); return g_string_free(text, FALSE); finch_notify_userinfo(PurpleConnection *gc, const char *who, PurpleNotifyUserInfo *user_info) char *key = userinfo_hash(purple_connection_get_account(gc), who); info = purple_notify_user_info_get_xhtml(user_info); ui_handle = g_hash_table_lookup(userinfo, key); GntTextView *msg = GNT_TEXT_VIEW(g_object_get_data(G_OBJECT(ui_handle), "info-widget")); char *strip = purple_markup_strip_html(info); int tvw, tvh, width, height, ntvw, ntvh; ui_handle = window = gnt_widget_get_toplevel(GNT_WIDGET(ui_handle)); gnt_widget_get_size(window, &width, &height); gnt_widget_get_size(GNT_WIDGET(msg), &tvw, &tvh); gnt_text_view_clear(msg); if (!gnt_util_parse_xhtml_to_textview(info, msg)) gnt_text_view_append_text_with_flags(msg, strip, GNT_TEXT_FLAG_NORMAL); gnt_text_view_scroll(msg, 0); gnt_util_get_text_bound(strip, &ntvw, &ntvh); gnt_screen_resize_widget(window, width + MAX(0, ntvw - tvw), height + MAX(0, ntvh - tvh)); primary = g_strdup_printf(_("Info for %s"), who); ui_handle = finch_notify_formatted(_("Buddy Information"), primary, NULL, info); g_hash_table_insert(userinfo, key, ui_handle); g_signal_connect(G_OBJECT(ui_handle), "destroy", G_CALLBACK(remove_userinfo), key); notify_button_activated(GntWidget *widget, PurpleNotifySearchButton *b) PurpleAccount *account = g_object_get_data(G_OBJECT(widget), "notify-account"); gpointer data = g_object_get_data(G_OBJECT(widget), "notify-data"); list = gnt_tree_get_selection_text_list(GNT_TREE(g_object_get_data(G_OBJECT(widget), "notify-tree"))); b->callback(purple_account_get_connection(account), list, data); g_list_free_full(list, g_free); finch_notify_sr_new_rows(PurpleConnection *gc, PurpleNotifySearchResults *results, void *data) GntWindow *window = GNT_WINDOW(data); GntTree *tree = GNT_TREE(g_object_get_data(G_OBJECT(window), "tree-widget")); gnt_tree_remove_all(GNT_TREE(tree)); for (o = results->rows; o; o = o->next) gnt_tree_add_row_after(GNT_TREE(tree), o->data, gnt_tree_create_row_from_list(GNT_TREE(tree), o->data), notify_sr_destroy_cb(GntWidget *window, void *data) purple_notify_close(PURPLE_NOTIFY_SEARCHRESULTS, window); finch_notify_searchresults(PurpleConnection *gc, const char *title, const char *primary, const char *secondary, PurpleNotifySearchResults *results, gpointer data) GntWidget *window, *tree, *box, *button; window = gnt_vbox_new(FALSE); gnt_box_set_toplevel(GNT_BOX(window), TRUE); gnt_box_set_title(GNT_BOX(window), title); gnt_box_set_fill(GNT_BOX(window), TRUE); gnt_box_set_pad(GNT_BOX(window), 0); gnt_box_set_alignment(GNT_BOX(window), GNT_ALIGN_MID); gnt_box_add_widget(GNT_BOX(window), gnt_label_new_with_format(primary, GNT_TEXT_FLAG_BOLD)); gnt_box_add_widget(GNT_BOX(window), gnt_label_new_with_format(secondary, GNT_TEXT_FLAG_NORMAL)); columns = g_list_length(results->columns); tree = gnt_tree_new_with_columns(columns); gnt_tree_set_show_title(GNT_TREE(tree), TRUE); gnt_box_add_widget(GNT_BOX(window), tree); for (iter = results->columns; iter; iter = iter->next) PurpleNotifySearchColumn *column = iter->data; gnt_tree_set_column_title(GNT_TREE(tree), i, purple_notify_searchresult_column_get_title(column)); if (!purple_notify_searchresult_column_is_visible(column)) gnt_tree_set_column_visible(GNT_TREE(tree), i, FALSE); box = gnt_hbox_new(TRUE); for (iter = results->buttons; iter; iter = iter->next) PurpleNotifySearchButton *b = iter->data; case PURPLE_NOTIFY_BUTTON_LABELED: case PURPLE_NOTIFY_BUTTON_CONTINUE: case PURPLE_NOTIFY_BUTTON_ADD: case PURPLE_NOTIFY_BUTTON_INFO: case PURPLE_NOTIFY_BUTTON_IM: case PURPLE_NOTIFY_BUTTON_JOIN: case PURPLE_NOTIFY_BUTTON_INVITE: button = gnt_button_new(text); g_object_set_data(G_OBJECT(button), "notify-account", purple_connection_get_account(gc)); g_object_set_data(G_OBJECT(button), "notify-data", data); g_object_set_data(G_OBJECT(button), "notify-tree", tree); g_signal_connect(G_OBJECT(button), "activate", G_CALLBACK(notify_button_activated), b); gnt_box_add_widget(GNT_BOX(box), button); gnt_box_add_widget(GNT_BOX(window), box); g_signal_connect(G_OBJECT(tree), "destroy", G_CALLBACK(notify_sr_destroy_cb), NULL); g_object_set_data(G_OBJECT(window), "tree-widget", tree); finch_notify_sr_new_rows(gc, results, window); g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(notify_msg_window_destroy_cb), GINT_TO_POINTER(PURPLE_NOTIFY_SEARCHRESULTS)); g_object_set_data(G_OBJECT(window), "notify-results", results); finch_notify_uri(const char *url) return finch_notify_common(PURPLE_NOTIFY_URI, PURPLE_NOTIFY_MSG_INFO, _("URI"), url, NULL, NULL); static PurpleNotifyUiOps ops = finch_notify_searchresults, finch_notify_sr_new_rows, finch_close_notify, /* The rest of the notify-uiops return a GntWidget. These widgets should be destroyed from here. */ PurpleNotifyUiOps *finch_notify_get_ui_ops() userinfo = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL); void finch_notify_uninit() g_hash_table_destroy(userinfo);