# HG changeset patch # User Sadrul Habib Chowdhury # Date 1197957043 0 # Node ID a3f0c30eb0bfc293fd3704cea0c123377ec7d252 # Parent c117352a6088df3a9249153ac74cd759c5e771ff# Parent c88a3f2dbb529b6f907c801bba23898b6a90485d propagate from branch 'im.pidgin.pidgin' (head 1716154a473ab645c7477f4285579df56d955fde) to branch 'im.pidgin.pidgin.next.minor' (head 457a3a60abf75010d7855c1f25254e8118d38466) diff -r c117352a6088 -r a3f0c30eb0bf ChangeLog.API --- a/ChangeLog.API Tue Dec 18 03:35:20 2007 +0000 +++ b/ChangeLog.API Tue Dec 18 05:50:43 2007 +0000 @@ -1,5 +1,23 @@ Pidgin and Finch: The Pimpin' Penguin IM Clients That're Good for the Soul +version 2.4.0 (??/??/????): + libpurple: + Added: + * purple_certificate_add_ca_search_path. (Florian Quèze) + + Pidgin: + Added: + * pidgin_create_dialog to create a window that closes on escape. Also + added utility functions pidgin_dialog_get_vbox_with_properties, + pidgin_dialog_get_vbox, pidgin_dialog_get_action_area to access the + contents in the created dialog. (Peter 'fmoo' Ruibal) + * pidgin_dialog_add_button to add buttons to a dialog created by + pidgin_create_dialog. + * GTK_IMHTML_NO_SMILEY for GtkIMHtmlOptions means not to look for + smileys in the text. (Florian 'goutnet' Delizy) + * pidgin_auto_parent_window to make a window transient for a suitable + parent window. + version 2.3.2 (??/??/????): Finch: libgnt: diff -r c117352a6088 -r a3f0c30eb0bf libpurple/certificate.c --- a/libpurple/certificate.c Tue Dec 18 03:35:20 2007 +0000 +++ b/libpurple/certificate.c Tue Dec 18 05:50:43 2007 +0000 @@ -627,7 +627,7 @@ /** System directory to probe for CA certificates */ /* This is set in the lazy_init function */ -static const gchar *x509_ca_syspath = NULL; +static GList *x509_ca_paths = NULL; /** A list of loaded CAs, populated from the above path whenever the lazy_init happens. Contains pointers to x509_ca_elements */ @@ -674,6 +674,7 @@ GDir *certdir; const gchar *entry; GPatternSpec *pempat; + GList *iter = NULL; if (x509_ca_initialized) return TRUE; @@ -687,54 +688,48 @@ return FALSE; } - /* Attempt to point at the appropriate system path */ - if (NULL == x509_ca_syspath) { -#ifdef _WIN32 - x509_ca_syspath = g_build_filename(DATADIR, - "ca-certs", NULL); -#else - x509_ca_syspath = g_build_filename(DATADIR, - "purple", "ca-certs", NULL); -#endif - } - - /* Populate the certificates pool from the system path */ - certdir = g_dir_open(x509_ca_syspath, 0, NULL); - g_return_val_if_fail(certdir, FALSE); - /* Use a glob to only read .pem files */ pempat = g_pattern_spec_new("*.pem"); - - while ( (entry = g_dir_read_name(certdir)) ) { - gchar *fullpath; - PurpleCertificate *crt; - if ( !g_pattern_match_string(pempat, entry) ) { + /* Populate the certificates pool from the search path(s) */ + for (iter = x509_ca_paths; iter; iter = iter->next) { + certdir = g_dir_open(iter->data, 0, NULL); + if (!certdir) { + purple_debug_error("certificate/x509/ca", "Couldn't open location '%s'\n", iter->data); continue; } - fullpath = g_build_filename(x509_ca_syspath, entry, NULL); - - /* TODO: Respond to a failure in the following? */ - crt = purple_certificate_import(x509, fullpath); + while ( (entry = g_dir_read_name(certdir)) ) { + gchar *fullpath; + PurpleCertificate *crt; + + if ( !g_pattern_match_string(pempat, entry) ) { + continue; + } + + fullpath = g_build_filename(iter->data, entry, NULL); + + /* TODO: Respond to a failure in the following? */ + crt = purple_certificate_import(x509, fullpath); - if (x509_ca_quiet_put_cert(crt)) { - purple_debug_info("certificate/x509/ca", - "Loaded %s\n", - fullpath); - } else { - purple_debug_error("certificate/x509/ca", - "Failed to load %s\n", - fullpath); + if (x509_ca_quiet_put_cert(crt)) { + purple_debug_info("certificate/x509/ca", + "Loaded %s\n", + fullpath); + } else { + purple_debug_error("certificate/x509/ca", + "Failed to load %s\n", + fullpath); + } + + purple_certificate_destroy(crt); + g_free(fullpath); } - - purple_certificate_destroy(crt); - g_free(fullpath); + g_dir_close(certdir); } g_pattern_spec_free(pempat); - g_dir_close(certdir); - + purple_debug_info("certificate/x509/ca", "Lazy init completed.\n"); x509_ca_initialized = TRUE; @@ -744,6 +739,17 @@ static gboolean x509_ca_init(void) { + /* Attempt to point at the appropriate system path */ + if (NULL == x509_ca_paths) { +#ifdef _WIN32 + x509_ca_paths = g_list_append(NULL, g_build_filename(DATADIR, + "ca-certs", NULL)); +#else + x509_ca_paths = g_list_append(NULL, g_build_filename(DATADIR, + "purple", "ca-certs", NULL)); +#endif + } + /* Attempt to initialize now, but if it doesn't work, that's OK; it will get done later */ if ( ! x509_ca_lazy_init()) { @@ -752,7 +758,7 @@ "dependency is not yet registered. " "It has been deferred to later.\n"); } - + return TRUE; } @@ -768,6 +774,9 @@ g_list_free(x509_ca_certs); x509_ca_certs = NULL; x509_ca_initialized = FALSE; + g_list_foreach(x509_ca_paths, (GFunc)g_free, NULL); + g_list_free(x509_ca_paths); + x509_ca_paths = NULL; } /** Look up a ca_element by dn */ @@ -1901,3 +1910,10 @@ g_byte_array_free(sha_bin, TRUE); } +void purple_certificate_add_ca_search_path(const char *path) +{ + if (g_list_find_custom(x509_ca_paths, path, (GCompareFunc)strcmp)) + return; + x509_ca_paths = g_list_append(x509_ca_paths, g_strdup(path)); +} + diff -r c117352a6088 -r a3f0c30eb0bf libpurple/certificate.h --- a/libpurple/certificate.h Tue Dec 18 03:35:20 2007 +0000 +++ b/libpurple/certificate.h Tue Dec 18 05:50:43 2007 +0000 @@ -786,6 +786,12 @@ void purple_certificate_display_x509(PurpleCertificate *crt); +/** + * Add a search path for certificates. + * + * @param path Path to search for certificates. + */ +void purple_certificate_add_ca_search_path(const char *path); #ifdef __cplusplus } diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkaccount.c --- a/pidgin/gtkaccount.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkaccount.c Tue Dec 18 05:50:43 2007 +0000 @@ -1437,7 +1437,6 @@ GtkWidget *win; GtkWidget *main_vbox; GtkWidget *vbox; - GtkWidget *bbox; GtkWidget *dbox; GtkWidget *notebook; GtkWidget *button; @@ -1475,16 +1474,14 @@ if ((dialog->plugin = purple_find_prpl(dialog->protocol_id)) != NULL) dialog->prpl_info = PURPLE_PLUGIN_PROTOCOL_INFO(dialog->plugin); - dialog->window = win = pidgin_create_window((type == PIDGIN_ADD_ACCOUNT_DIALOG) ? _("Add Account") : _("Modify Account"), + dialog->window = win = pidgin_create_dialog((type == PIDGIN_ADD_ACCOUNT_DIALOG) ? _("Add Account") : _("Modify Account"), PIDGIN_HIG_BORDER, "account", FALSE); g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(account_win_destroy_cb), dialog); /* Setup the vbox */ - main_vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(win), main_vbox); - gtk_widget_show(main_vbox); + main_vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); notebook = gtk_notebook_new(); gtk_box_pack_start(GTK_BOX(main_vbox), notebook, FALSE, FALSE, 0); @@ -1511,8 +1508,6 @@ if (!dialog->prpl_info || !dialog->prpl_info->register_user) gtk_widget_hide(button); - - /* Setup the page with 'Advanced'. */ dialog->bottom_vbox = dbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_set_border_width(GTK_CONTAINER(dbox), PIDGIN_HIG_BORDER); @@ -1524,30 +1519,13 @@ add_protocol_options(dialog, dbox); add_proxy_options(dialog, dbox); - /* Setup the button box */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(main_vbox), bbox, FALSE, TRUE, 0); - gtk_widget_show(bbox); - /* Cancel button */ - button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(cancel_account_prefs_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CANCEL, G_CALLBACK(cancel_account_prefs_cb), dialog); /* Save button */ - button = gtk_button_new_from_stock(GTK_STOCK_SAVE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - + button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_SAVE, G_CALLBACK(ok_account_prefs_cb), dialog); if (dialog->account == NULL) gtk_widget_set_sensitive(button, FALSE); - - gtk_widget_show(button); - dialog->ok_button = button; /* Set up DND */ @@ -1561,9 +1539,6 @@ g_signal_connect(G_OBJECT(dialog->window), "drag_data_received", G_CALLBACK(account_dnd_recv), dialog); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(ok_account_prefs_cb), dialog); - /* Show the window. */ gtk_widget_show(win); } @@ -2313,7 +2288,6 @@ AccountsWindow *dialog; GtkWidget *win; GtkWidget *vbox; - GtkWidget *bbox; GtkWidget *sw; GtkWidget *button; int width, height; @@ -2328,7 +2302,7 @@ width = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/accounts/dialog/width"); height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/accounts/dialog/height"); - dialog->window = win = pidgin_create_window(_("Accounts"), PIDGIN_HIG_BORDER, "accounts", TRUE); + dialog->window = win = pidgin_create_dialog(_("Accounts"), PIDGIN_HIG_BORDER, "accounts", TRUE); gtk_window_set_default_size(GTK_WINDOW(win), width, height); g_signal_connect(G_OBJECT(win), "delete_event", @@ -2337,57 +2311,28 @@ G_CALLBACK(configure_cb), accounts_window); /* Setup the vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(win), vbox); - gtk_widget_show(vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); /* Setup the scrolled window that will contain the list of accounts. */ sw = create_accounts_list(dialog); gtk_box_pack_start(GTK_BOX(vbox), sw, TRUE, TRUE, 0); gtk_widget_show(sw); - /* Button box. */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); - gtk_widget_show(bbox); - /* Add button */ - button = gtk_button_new_from_stock(GTK_STOCK_ADD); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(add_account_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_ADD, G_CALLBACK(add_account_cb), dialog); /* Modify button */ - button = gtk_button_new_from_stock(PIDGIN_STOCK_MODIFY); + button = pidgin_dialog_add_button(GTK_DIALOG(win), PIDGIN_STOCK_MODIFY, G_CALLBACK(modify_account_cb), dialog); dialog->modify_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(modify_account_cb), dialog); /* Delete button */ - button = gtk_button_new_from_stock(GTK_STOCK_DELETE); + button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_DELETE, G_CALLBACK(ask_delete_account_cb), dialog); dialog->delete_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(ask_delete_account_cb), dialog); /* Close button */ - button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(close_accounts_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE, G_CALLBACK(close_accounts_cb), dialog); purple_signal_connect(pidgin_account_get_handle(), "account-modified", accounts_window, diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkcertmgr.c --- a/pidgin/gtkcertmgr.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkcertmgr.c Tue Dec 18 05:50:43 2007 +0000 @@ -559,7 +559,6 @@ CertMgrDialog *dlg; GtkWidget *win; GtkWidget *vbox; - GtkWidget *bbox; /* Enumerate all the certificates on file */ { @@ -599,7 +598,7 @@ dlg = certmgr_dialog = g_new0(CertMgrDialog, 1); win = dlg->window = - pidgin_create_window(_("Certificate Manager"),/* Title */ + pidgin_create_dialog(_("Certificate Manager"),/* Title */ PIDGIN_HIG_BORDER, /*Window border*/ "certmgr", /* Role */ TRUE); /* Allow resizing */ @@ -611,9 +610,7 @@ gtk_window_set_default_size(GTK_WINDOW(win), 400, 400); /* Main vbox */ - vbox = gtk_vbox_new( FALSE, PIDGIN_HIG_BORDER ); - gtk_container_add(GTK_CONTAINER(win), vbox); - gtk_widget_show(vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); /* Notebook of various certificate managers */ dlg->notebook = gtk_notebook_new(); @@ -622,19 +619,9 @@ 0); gtk_widget_show(dlg->notebook); - /* Box for the close button */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); - gtk_widget_show(bbox); - /* Close button */ - dlg->closebutton = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), dlg->closebutton, FALSE, FALSE, 0); - gtk_widget_show(dlg->closebutton); - g_signal_connect(G_OBJECT(dlg->closebutton), "clicked", - G_CALLBACK(certmgr_close_cb), dlg); + dlg->closebutton = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE, + G_CALLBACK(certmgr_close_cb), dlg); /* Add the defined certificate managers */ /* TODO: Find a way of determining whether each is shown or not */ diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkconv.c --- a/pidgin/gtkconv.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkconv.c Tue Dec 18 05:50:43 2007 +0000 @@ -8318,7 +8318,7 @@ } if (e->button == 3) { - /* Right click was pressed. Popup the Send To menu. */ + /* Right click was pressed. Popup the context menu. */ GtkWidget *menu = gtk_menu_new(), *sub; gboolean populated = populate_menu_with_options(menu, gtkconv, TRUE); sub = gtk_menu_item_get_submenu(GTK_MENU_ITEM(gtkconv->win->menu.send_to)); diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkft.c --- a/pidgin/gtkft.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkft.c Tue Dec 18 05:50:43 2007 +0000 @@ -745,7 +745,6 @@ PidginXferDialog *dialog; GtkWidget *window; GtkWidget *vbox1, *vbox2; - GtkWidget *bbox; GtkWidget *sw; GtkWidget *button; GtkWidget *expander; @@ -759,15 +758,13 @@ purple_prefs_get_bool(PIDGIN_PREFS_ROOT "/filetransfer/clear_finished"); /* Create the window. */ - dialog->window = window = pidgin_create_window(_("File Transfers"), PIDGIN_HIG_BORDER, "file transfer", TRUE); + dialog->window = window = pidgin_create_dialog(_("File Transfers"), PIDGIN_HIG_BORDER, "file transfer", TRUE); g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_win_cb), dialog); /* Create the parent vbox for everything. */ - vbox1 = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(window), vbox1); - gtk_widget_show(vbox1); + vbox1 = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(window), FALSE, PIDGIN_HIG_BORDER); /* Create the main vbox for top half of the window. */ vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE); @@ -812,71 +809,35 @@ gtk_container_add(GTK_CONTAINER(expander), table); gtk_widget_show(table); - /* Now the button box for the buttons */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox1), bbox, FALSE, TRUE, 0); - gtk_widget_show(bbox); - /* Open button */ - button = gtk_button_new_from_stock(GTK_STOCK_OPEN); + button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_OPEN, G_CALLBACK(open_button_cb), dialog); gtk_widget_set_sensitive(button, FALSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); dialog->open_button = button; - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(open_button_cb), dialog); - /* Pause button */ - button = gtk_button_new_with_mnemonic(_("_Pause")); + button = pidgin_dialog_add_button(GTK_DIALOG(window), _("_Pause"), G_CALLBACK(pause_button_cb), dialog); gtk_widget_set_sensitive(button, FALSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); dialog->pause_button = button; - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(pause_button_cb), dialog); - /* Resume button */ - button = gtk_button_new_with_mnemonic(_("_Resume")); + button = pidgin_dialog_add_button(GTK_DIALOG(window), _("_Resume"), G_CALLBACK(resume_button_cb), dialog); gtk_widget_set_sensitive(button, FALSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); dialog->resume_button = button; - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(resume_button_cb), dialog); - /* Remove button */ - button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_REMOVE, G_CALLBACK(remove_button_cb), dialog); gtk_widget_hide(button); dialog->remove_button = button; - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(remove_button_cb), dialog); - /* Stop button */ - button = gtk_button_new_from_stock(GTK_STOCK_STOP); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); + button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_STOP, G_CALLBACK(stop_button_cb), dialog); gtk_widget_set_sensitive(button, FALSE); dialog->stop_button = button; - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(stop_button_cb), dialog); - /* Close button */ - button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); + button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_CLOSE, G_CALLBACK(close_button_cb), dialog); dialog->close_button = button; - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(close_button_cb), dialog); - #ifdef _WIN32 g_signal_connect(G_OBJECT(dialog->window), "show", G_CALLBACK(winpidgin_ensure_onscreen), dialog->window); diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkimhtml.c --- a/pidgin/gtkimhtml.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkimhtml.c Tue Dec 18 05:50:43 2007 +0000 @@ -1012,7 +1012,7 @@ static void imhtml_paste_insert(GtkIMHtml *imhtml, const char *text, gboolean plaintext) { GtkTextIter iter; - GtkIMHtmlOptions flags = plaintext ? 0 : (GTK_IMHTML_NO_NEWLINE | GTK_IMHTML_NO_COMMENTS); + GtkIMHtmlOptions flags = plaintext ? GTK_IMHTML_NO_SMILEY : (GTK_IMHTML_NO_NEWLINE | GTK_IMHTML_NO_COMMENTS); if (gtk_text_buffer_get_selection_bounds(imhtml->text_buffer, NULL, NULL)) gtk_text_buffer_delete_selection(imhtml->text_buffer, TRUE, TRUE); @@ -2998,6 +2998,7 @@ pos += tlen; g_free(tag); /* This was allocated back in VALID_TAG() */ } else if (imhtml->edit.link == NULL && + !(options & GTK_IMHTML_NO_SMILEY) && gtk_imhtml_is_smiley(imhtml, fonts, c, &smilelen)) { GtkIMHtmlFontDetail *fd; gchar *sml = NULL; diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkimhtml.h --- a/pidgin/gtkimhtml.h Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkimhtml.h Tue Dec 18 05:50:43 2007 +0000 @@ -225,7 +225,8 @@ GTK_IMHTML_RETURN_LOG = 1 << 7, GTK_IMHTML_USE_POINTSIZE = 1 << 8, GTK_IMHTML_NO_FORMATTING = 1 << 9, - GTK_IMHTML_USE_SMOOTHSCROLLING = 1 << 10 + GTK_IMHTML_USE_SMOOTHSCROLLING = 1 << 10, + GTK_IMHTML_NO_SMILEY = 1 << 11, } GtkIMHtmlOptions; enum { diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtknotify.c --- a/pidgin/gtknotify.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtknotify.c Tue Dec 18 05:50:43 2007 +0000 @@ -284,6 +284,8 @@ gtk_misc_set_alignment(GTK_MISC(label), 0, 0); gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0); + pidgin_auto_parent_window(dialog); + gtk_widget_show_all(dialog); return dialog; @@ -684,6 +686,8 @@ g_object_set_data(G_OBJECT(window), "info-widget", imhtml); /* Show the window */ + pidgin_auto_parent_window(window); + gtk_widget_show(window); return window; @@ -894,6 +898,8 @@ pidgin_notify_searchresults_new_rows(gc, results, data); /* Show the window */ + pidgin_auto_parent_window(window); + gtk_widget_show(window); return data; } diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkpounce.c --- a/pidgin/gtkpounce.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkpounce.c Tue Dec 18 05:50:43 2007 +0000 @@ -1317,7 +1317,6 @@ pidgin_pounces_manager_show(void) { PouncesManager *dialog; - GtkWidget *bbox; GtkWidget *button; GtkWidget *list; GtkWidget *vbox; @@ -1334,7 +1333,7 @@ width = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/pounces/dialog/width"); height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/pounces/dialog/height"); - dialog->window = win = pidgin_create_window(_("Buddy Pounces"), PIDGIN_HIG_BORDER, "pounces", TRUE); + dialog->window = win = pidgin_create_dialog(_("Buddy Pounces"), PIDGIN_HIG_BORDER, "pounces", TRUE); gtk_window_set_default_size(GTK_WINDOW(win), width, height); g_signal_connect(G_OBJECT(win), "delete_event", @@ -1343,61 +1342,33 @@ G_CALLBACK(pounces_manager_configure_cb), dialog); /* Setup the vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(win), vbox); - gtk_widget_show(vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); /* List of saved buddy pounces */ list = create_pounces_list(dialog); gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); - /* Button box. */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); - gtk_widget_show(bbox); + /* Add button */ + button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_ADD, G_CALLBACK(pounces_manager_add_cb), dialog); + gtk_widget_set_sensitive(button, (purple_accounts_get_all() != NULL)); - /* Add button */ - button = gtk_button_new_from_stock(GTK_STOCK_ADD); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_set_sensitive(button, (purple_accounts_get_all() != NULL)); purple_signal_connect(purple_connections_get_handle(), "signed-on", pounces_manager, PURPLE_CALLBACK(pounces_manager_connection_cb), button); purple_signal_connect(purple_connections_get_handle(), "signed-off", pounces_manager, PURPLE_CALLBACK(pounces_manager_connection_cb), button); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(pounces_manager_add_cb), dialog); /* Modify button */ - button = gtk_button_new_from_stock(PIDGIN_STOCK_MODIFY); - dialog->modify_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + button = pidgin_dialog_add_button(GTK_DIALOG(win), PIDGIN_STOCK_MODIFY, G_CALLBACK(pounces_manager_modify_cb), dialog); gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(pounces_manager_modify_cb), dialog); + dialog->modify_button = button; /* Delete button */ - button = gtk_button_new_from_stock(GTK_STOCK_DELETE); - dialog->delete_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_DELETE, G_CALLBACK(pounces_manager_delete_cb), dialog); gtk_widget_set_sensitive(button, FALSE); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(pounces_manager_delete_cb), dialog); + dialog->delete_button = button; /* Close button */ - button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(pounces_manager_close_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE, G_CALLBACK(pounces_manager_close_cb), dialog); gtk_widget_show(win); } diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkprefs.c --- a/pidgin/gtkprefs.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkprefs.c Tue Dec 18 05:50:43 2007 +0000 @@ -2150,7 +2150,6 @@ void pidgin_prefs_show(void) { GtkWidget *vbox; - GtkWidget *bbox; GtkWidget *notebook; GtkWidget *button; @@ -2166,31 +2165,20 @@ /* Back to instant-apply! I win! BU-HAHAHA! */ /* Create the window */ - prefs = pidgin_create_window(_("Preferences"), PIDGIN_HIG_BORDER, "preferences", FALSE); + prefs = pidgin_create_dialog(_("Preferences"), PIDGIN_HIG_BORDER, "preferences", FALSE); g_signal_connect(G_OBJECT(prefs), "destroy", G_CALLBACK(delete_prefs), NULL); - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(prefs), vbox); - gtk_widget_show(vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(prefs), FALSE, PIDGIN_HIG_BORDER); /* The notebook */ prefsnotebook = notebook = gtk_notebook_new (); gtk_box_pack_start (GTK_BOX (vbox), notebook, FALSE, FALSE, 0); gtk_widget_show(prefsnotebook); - /* The buttons to press! */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show (bbox); - - button = gtk_button_new_from_stock (GTK_STOCK_CLOSE); + button = pidgin_dialog_add_button(GTK_DIALOG(prefs), GTK_STOCK_CLOSE, NULL, NULL); g_signal_connect_swapped(G_OBJECT(button), "clicked", G_CALLBACK(gtk_widget_destroy), prefs); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); prefs_notebook_init(); diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkprivacy.c --- a/pidgin/gtkprivacy.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkprivacy.c Tue Dec 18 05:50:43 2007 +0000 @@ -45,6 +45,7 @@ GtkWidget *add_button; GtkWidget *remove_button; GtkWidget *clear_button; + GtkWidget *close_button; GtkWidget *button_box; GtkWidget *allow_widget; @@ -259,19 +260,22 @@ gtk_widget_hide(dialog->allow_widget); gtk_widget_hide(dialog->block_widget); - gtk_widget_hide(dialog->button_box); + gtk_widget_hide_all(dialog->button_box); if (new_type == PURPLE_PRIVACY_ALLOW_USERS) { gtk_widget_show(dialog->allow_widget); - gtk_widget_show(dialog->button_box); + gtk_widget_show_all(dialog->button_box); dialog->in_allow_list = TRUE; } else if (new_type == PURPLE_PRIVACY_DENY_USERS) { gtk_widget_show(dialog->block_widget); - gtk_widget_show(dialog->button_box); + gtk_widget_show_all(dialog->button_box); dialog->in_allow_list = FALSE; } + gtk_widget_show_all(dialog->close_button); + gtk_widget_show(dialog->button_box); + purple_blist_schedule_save(); pidgin_blist_refresh(purple_get_blist()); } @@ -355,7 +359,6 @@ privacy_dialog_new(void) { PidginPrivacyDialog *dialog; - GtkWidget *bbox; GtkWidget *hbox; GtkWidget *vbox; GtkWidget *button; @@ -367,15 +370,13 @@ dialog = g_new0(PidginPrivacyDialog, 1); - dialog->win = pidgin_create_window(_("Privacy"), PIDGIN_HIG_BORDER, "privacy", TRUE); + dialog->win = pidgin_create_dialog(_("Privacy"), PIDGIN_HIG_BORDER, "privacy", TRUE); g_signal_connect(G_OBJECT(dialog->win), "delete_event", G_CALLBACK(destroy_cb), dialog); /* Main vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(dialog->win), vbox); - gtk_widget_show(vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(dialog->win), FALSE, PIDGIN_HIG_BORDER); /* Description label */ label = gtk_label_new( @@ -433,52 +434,27 @@ gtk_box_pack_start(GTK_BOX(vbox), dialog->block_widget, TRUE, TRUE, 0); /* Add the button box for Add, Remove, Clear */ - dialog->button_box = bbox = gtk_hbutton_box_new(); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_SPREAD); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); + dialog->button_box = pidgin_dialog_get_action_area(GTK_DIALOG(dialog->win)); /* Add button */ - button = gtk_button_new_from_stock(GTK_STOCK_ADD); + button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), GTK_STOCK_ADD, G_CALLBACK(add_cb), dialog); dialog->add_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(add_cb), dialog); /* Remove button */ - button = gtk_button_new_from_stock(GTK_STOCK_REMOVE); + button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), GTK_STOCK_REMOVE, G_CALLBACK(remove_cb), dialog); dialog->remove_button = button; gtk_widget_set_sensitive(button, FALSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(remove_cb), dialog); /* Clear button */ - button = gtk_button_new_from_stock(GTK_STOCK_CLEAR); + button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), GTK_STOCK_CLEAR, G_CALLBACK(clear_cb), dialog); dialog->clear_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(clear_cb), dialog); - - /* Another button box. */ - bbox = gtk_hbutton_box_new(); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, FALSE, 0); - gtk_widget_show(bbox); /* Close button */ - button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); + button = pidgin_dialog_add_button(GTK_DIALOG(dialog->win), GTK_STOCK_CLOSE, G_CALLBACK(close_cb), dialog); + dialog->close_button = button; - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(close_cb), dialog); - + type_changed_cb(GTK_OPTION_MENU(dialog->type_menu), dialog); +#if 0 if (dialog->account->perm_deny == PURPLE_PRIVACY_ALLOW_USERS) { gtk_widget_show(dialog->allow_widget); gtk_widget_show(dialog->button_box); @@ -489,7 +465,7 @@ gtk_widget_show(dialog->button_box); dialog->in_allow_list = FALSE; } - +#endif return dialog; } diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkrequest.c Tue Dec 18 05:50:43 2007 +0000 @@ -439,6 +439,8 @@ pidgin_set_accessible_label (entry, label); data->u.input.entry = entry; + pidgin_auto_parent_window(dialog); + /* Show everything. */ gtk_widget_show(dialog); @@ -546,6 +548,8 @@ g_object_set_data(G_OBJECT(dialog), "radio", radio); /* Show everything. */ + pidgin_auto_parent_window(dialog); + gtk_widget_show_all(dialog); return data; @@ -661,6 +665,8 @@ gtk_dialog_set_default_response(GTK_DIALOG(dialog), default_action); /* Show everything. */ + pidgin_auto_parent_window(dialog); + gtk_widget_show_all(dialog); return data; @@ -1059,7 +1065,6 @@ GtkWidget *vbox; GtkWidget *vbox2; GtkWidget *hbox; - GtkWidget *bbox; GtkWidget *frame; GtkWidget *label; GtkWidget *table; @@ -1089,9 +1094,9 @@ #ifdef _WIN32 - data->dialog = win = pidgin_create_window(PIDGIN_ALERT_TITLE, PIDGIN_HIG_BORDER, "multifield", TRUE) ; + data->dialog = win = pidgin_create_dialog(PIDGIN_ALERT_TITLE, PIDGIN_HIG_BORDER, "multifield", TRUE) ; #else /* !_WIN32 */ - data->dialog = win = pidgin_create_window(title, PIDGIN_HIG_BORDER, "multifield", TRUE) ; + data->dialog = win = pidgin_create_dialog(title, PIDGIN_HIG_BORDER, "multifield", TRUE) ; #endif /* _WIN32 */ g_signal_connect(G_OBJECT(win), "delete_event", @@ -1099,7 +1104,7 @@ /* Setup the main horizontal box */ hbox = gtk_hbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(win), hbox); + gtk_container_add(GTK_CONTAINER(pidgin_dialog_get_vbox(GTK_DIALOG(win))), hbox); gtk_widget_show(hbox); /* Dialog icon. */ @@ -1382,39 +1387,21 @@ g_object_unref(sg); - /* Button box. */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); - gtk_widget_show(bbox); - /* Cancel button */ - button = gtk_button_new_from_stock(text_to_stock(cancel_text)); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(multifield_cancel_cb), data); - + button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(cancel_text), G_CALLBACK(multifield_cancel_cb), data); GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); /* OK button */ - button = gtk_button_new_from_stock(text_to_stock(ok_text)); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_show(button); - + button = pidgin_dialog_add_button(GTK_DIALOG(win), text_to_stock(ok_text), G_CALLBACK(multifield_ok_cb), data); data->ok_button = button; - GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); gtk_window_set_default(GTK_WINDOW(win), button); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(multifield_ok_cb), data); - if (!purple_request_fields_all_required_filled(fields)) gtk_widget_set_sensitive(button, FALSE); + pidgin_auto_parent_window(win); + gtk_widget_show(win); return data; @@ -1622,6 +1609,8 @@ G_CALLBACK(file_ok_check_if_exists_cb), data); #endif /* FILECHOOSER */ + pidgin_auto_parent_window(filesel); + data->dialog = filesel; gtk_widget_show(filesel); @@ -1673,6 +1662,8 @@ #endif data->dialog = dirsel; + pidgin_auto_parent_window(dirsel); + gtk_widget_show(dirsel); return (void *)data; diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkroomlist.c --- a/pidgin/gtkroomlist.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkroomlist.c Tue Dec 18 05:50:43 2007 +0000 @@ -685,15 +685,13 @@ dialog->account = account; /* Create the window. */ - dialog->window = window = pidgin_create_window(_("Room List"), PIDGIN_HIG_BORDER, "room list", TRUE); + dialog->window = window = pidgin_create_dialog(_("Room List"), PIDGIN_HIG_BORDER, "room list", TRUE); g_signal_connect(G_OBJECT(window), "delete_event", G_CALLBACK(delete_win_cb), dialog); /* Create the parent vbox for everything. */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(window), vbox); - gtk_widget_show(vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(window), FALSE, PIDGIN_HIG_BORDER); vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); gtk_container_add(GTK_CONTAINER(vbox), vbox2); @@ -738,19 +736,14 @@ gtk_widget_show(dialog->progress); /* button box */ - bbox = gtk_hbutton_box_new(); + bbox = pidgin_dialog_get_action_area(GTK_DIALOG(window)); gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_start(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); - gtk_widget_show(bbox); /* stop button */ - dialog->stop_button = gtk_button_new_from_stock(GTK_STOCK_STOP); - gtk_box_pack_start(GTK_BOX(bbox), dialog->stop_button, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(dialog->stop_button), "clicked", + dialog->stop_button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_STOP, G_CALLBACK(stop_button_cb), dialog); gtk_widget_set_sensitive(dialog->stop_button, FALSE); - gtk_widget_show(dialog->stop_button); /* list button */ dialog->list_button = pidgin_pixbuf_button_from_stock(_("_Get List"), GTK_STOCK_REFRESH, @@ -779,11 +772,8 @@ gtk_widget_show(dialog->join_button); /* close button */ - dialog->close_button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), dialog->close_button, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(dialog->close_button), "clicked", + dialog->close_button = pidgin_dialog_add_button(GTK_DIALOG(window), GTK_STOCK_CLOSE, G_CALLBACK(close_button_cb), dialog); - gtk_widget_show(dialog->close_button); /* show the dialog window and return the dialog */ gtk_widget_show(dialog->window); diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtksavedstatuses.c --- a/pidgin/gtksavedstatuses.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtksavedstatuses.c Tue Dec 18 05:50:43 2007 +0000 @@ -594,7 +594,7 @@ width = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/status/dialog/width"); height = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/status/dialog/height"); - dialog->window = win = pidgin_create_window(_("Saved Statuses"), PIDGIN_HIG_BORDER, "statuses", TRUE); + dialog->window = win = pidgin_create_dialog(_("Saved Statuses"), PIDGIN_HIG_BORDER, "statuses", TRUE); gtk_window_set_default_size(GTK_WINDOW(win), width, height); g_signal_connect(G_OBJECT(win), "delete_event", @@ -603,18 +603,14 @@ G_CALLBACK(configure_cb), dialog); /* Setup the vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(win), vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); /* List of saved status states */ list = create_saved_status_list(dialog); gtk_box_pack_start(GTK_BOX(vbox), list, TRUE, TRUE, 0); /* Button box. */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); + bbox = pidgin_dialog_get_action_area(GTK_DIALOG(win)); /* Use button */ button = pidgin_pixbuf_button_from_stock(_("_Use"), GTK_STOCK_EXECUTE, @@ -627,36 +623,23 @@ G_CALLBACK(status_window_use_cb), dialog); /* Add button */ - button = gtk_button_new_from_stock(GTK_STOCK_ADD); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(status_window_add_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_ADD, + G_CALLBACK(status_window_add_cb), dialog); /* Modify button */ - button = gtk_button_new_from_stock(PIDGIN_STOCK_MODIFY); + button = pidgin_dialog_add_button(GTK_DIALOG(win), PIDGIN_STOCK_MODIFY, + G_CALLBACK(status_window_modify_cb), dialog); dialog->modify_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + + /* Delete button */ + button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_DELETE, + G_CALLBACK(status_window_delete_cb), dialog); + dialog->delete_button = button; gtk_widget_set_sensitive(button, FALSE); - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(status_window_modify_cb), dialog); - - /* Delete button */ - button = gtk_button_new_from_stock(GTK_STOCK_DELETE); - dialog->delete_button = button; - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - gtk_widget_set_sensitive(button, FALSE); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(status_window_delete_cb), dialog); - /* Close button */ - button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(status_window_close_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CLOSE, + G_CALLBACK(status_window_close_cb), dialog); purple_signal_connect(purple_savedstatuses_get_handle(), "savedstatus-changed", status_window, @@ -1147,14 +1130,13 @@ if (edit) dialog->original_title = g_strdup(purple_savedstatus_get_title(saved_status)); - dialog->window = win = pidgin_create_window(_("Status"), PIDGIN_HIG_BORDER, "status", TRUE); + dialog->window = win = pidgin_create_dialog(_("Status"), PIDGIN_HIG_BORDER, "status", TRUE); g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(status_editor_destroy_cb), dialog); /* Setup the vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(win), vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); @@ -1257,23 +1239,18 @@ (saved_status != NULL) && purple_savedstatus_has_substatuses(saved_status)); /* Button box */ - bbox = gtk_hbutton_box_new(); + bbox = pidgin_dialog_get_action_area(GTK_DIALOG(win)); gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); /* Cancel button */ - button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(status_editor_cancel_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CANCEL, + G_CALLBACK(status_editor_cancel_cb), dialog); /* Use button */ button = pidgin_pixbuf_button_from_stock(_("_Use"), GTK_STOCK_EXECUTE, PIDGIN_BUTTON_HORIZONTAL); gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(status_editor_ok_cb), dialog); @@ -1284,19 +1261,15 @@ gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); if (dialog->original_title == NULL) gtk_widget_set_sensitive(button, FALSE); - g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(status_editor_ok_cb), dialog); /* Save button */ - button = gtk_button_new_from_stock(GTK_STOCK_SAVE); - dialog->save_button = GTK_BUTTON(button); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + button = pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_SAVE, + G_CALLBACK(status_editor_ok_cb), dialog); if (dialog->original_title == NULL) gtk_widget_set_sensitive(button, FALSE); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(status_editor_ok_cb), dialog); + dialog->save_button = GTK_BUTTON(button); gtk_widget_show_all(win); g_object_unref(sg); @@ -1447,8 +1420,6 @@ char *tmp; SubStatusEditor *dialog; GtkSizeGroup *sg; - GtkWidget *bbox; - GtkWidget *button; GtkWidget *combo; GtkWidget *hbox; GtkWidget *frame; @@ -1486,15 +1457,14 @@ dialog->account = account; tmp = g_strdup_printf(_("Status for %s"), purple_account_get_username(account)); - dialog->window = win = pidgin_create_window(tmp, PIDGIN_HIG_BORDER, "substatus", TRUE); + dialog->window = win = pidgin_create_dialog(tmp, PIDGIN_HIG_BORDER, "substatus", TRUE); g_free(tmp); g_signal_connect(G_OBJECT(win), "delete_event", G_CALLBACK(substatus_editor_destroy_cb), dialog); /* Setup the vbox */ - vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER); - gtk_container_add(GTK_CONTAINER(win), vbox); + vbox = pidgin_dialog_get_vbox_with_properties(GTK_DIALOG(win), FALSE, PIDGIN_HIG_BORDER); sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL); @@ -1543,25 +1513,13 @@ dialog->toolbar = GTK_IMHTMLTOOLBAR(toolbar); gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, TRUE, 0); - /* Button box */ - bbox = gtk_hbutton_box_new(); - gtk_box_set_spacing(GTK_BOX(bbox), PIDGIN_HIG_BOX_SPACE); - gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_END); - gtk_box_pack_end(GTK_BOX(vbox), bbox, FALSE, TRUE, 0); - /* Cancel button */ - button = gtk_button_new_from_stock(GTK_STOCK_CANCEL); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(substatus_editor_cancel_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_CANCEL, + G_CALLBACK(substatus_editor_cancel_cb), dialog); /* OK button */ - button = gtk_button_new_from_stock(GTK_STOCK_OK); - gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); - - g_signal_connect(G_OBJECT(button), "clicked", - G_CALLBACK(substatus_editor_ok_cb), dialog); + pidgin_dialog_add_button(GTK_DIALOG(win), GTK_STOCK_OK, + G_CALLBACK(substatus_editor_ok_cb), dialog); /* Seed the input widgets with the current values */ diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkutils.c --- a/pidgin/gtkutils.c Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkutils.c Tue Dec 18 05:50:43 2007 +0000 @@ -132,12 +132,9 @@ } } -GtkWidget * -pidgin_create_window(const char *title, guint border_width, const char *role, gboolean resizable) +static +void pidgin_window_init(GtkWindow *wnd, const char *title, guint border_width, const char *role, gboolean resizable) { - GtkWindow *wnd = NULL; - - wnd = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); if (title) gtk_window_set_title(wnd, title); #ifdef _WIN32 @@ -148,11 +145,63 @@ if (role) gtk_window_set_role(wnd, role); gtk_window_set_resizable(wnd, resizable); +} + +GtkWidget * +pidgin_create_window(const char *title, guint border_width, const char *role, gboolean resizable) +{ + GtkWindow *wnd = NULL; + + wnd = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL)); + pidgin_window_init(wnd, title, border_width, role, resizable); + + return GTK_WIDGET(wnd); +} + +GtkWidget * +pidgin_create_dialog(const char *title, guint border_width, const char *role, gboolean resizable) +{ + GtkWindow *wnd = NULL; + + wnd = GTK_WINDOW(gtk_dialog_new()); + pidgin_window_init(wnd, title, border_width, role, resizable); + g_object_set(G_OBJECT(wnd), "has-separator", FALSE, NULL); return GTK_WIDGET(wnd); } GtkWidget * +pidgin_dialog_get_vbox_with_properties(GtkDialog *dialog, gboolean homogeneous, gint spacing) +{ + GtkBox *vbox = GTK_BOX(GTK_DIALOG(dialog)->vbox); + gtk_box_set_homogeneous(vbox, homogeneous); + gtk_box_set_spacing(vbox, spacing); + return GTK_WIDGET(vbox); +} + +GtkWidget *pidgin_dialog_get_vbox(GtkDialog *dialog) +{ + return GTK_DIALOG(dialog)->vbox; +} + +GtkWidget *pidgin_dialog_get_action_area(GtkDialog *dialog) +{ + return GTK_DIALOG(dialog)->action_area; +} + +GtkWidget *pidgin_dialog_add_button(GtkDialog *dialog, const char *label, + GCallback callback, gpointer callbackdata) +{ + GtkWidget *button = gtk_button_new_from_stock(label); + GtkWidget *bbox = pidgin_dialog_get_action_area(dialog); + gtk_box_pack_start(GTK_BOX(bbox), button, FALSE, FALSE, 0); + if (callback) + g_signal_connect(G_OBJECT(button), "clicked", callback, callbackdata); + gtk_widget_show(button); + return button; +} + +GtkWidget * pidgin_create_imhtml(gboolean editable, GtkWidget **imhtml_ret, GtkWidget **toolbar_ret, GtkWidget **sw_ret) { GtkWidget *frame; @@ -3269,3 +3318,107 @@ gtk_entry_set_text(GTK_ENTRY(GTK_BIN((widget))->child), (text)); } +gboolean pidgin_auto_parent_window(GtkWidget *widget) +{ +#if 0 + /* This looks at the most recent window that received focus, and makes + * that the parent window. */ +#ifndef _WIN32 + static GdkAtom _WindowTime = GDK_NONE; + static GdkAtom _Cardinal = GDK_NONE; + GList *windows = NULL; + GtkWidget *parent = NULL; + time_t window_time = 0; + + windows = gtk_window_list_toplevels(); + + if (_WindowTime == GDK_NONE) { + _WindowTime = gdk_x11_xatom_to_atom(gdk_x11_get_xatom_by_name("_NET_WM_USER_TIME")); + } + if (_Cardinal == GDK_NONE) { + _Cardinal = gdk_atom_intern("CARDINAL", FALSE); + } + + while (windows) { + GtkWidget *window = windows->data; + guchar *data = NULL; + int al = 0; + time_t value; + + windows = g_list_delete_link(windows, windows); + + if (window == widget || + !GTK_WIDGET_VISIBLE(window)) + continue; + + if (!gdk_property_get(window->window, _WindowTime, _Cardinal, 0, sizeof(time_t), FALSE, + NULL, NULL, &al, &data)) + continue; + value = *(time_t *)data; + if (window_time < value) { + window_time = value; + parent = window; + } + g_free(data); + } + if (windows) + g_list_free(windows); + if (parent) { + if (!gtk_get_current_event() && gtk_window_has_toplevel_focus(GTK_WINDOW(parent))) { + /* The window is in focus, and the new window was not triggered by a keypress/click + * event. So do not set it transient, to avoid focus stealing and all that. + */ + return FALSE; + } + gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(parent)); + return TRUE; + } + return FALSE; +#endif +#else + /* This finds the currently active window and makes that the parent window. */ + GList *windows = NULL; + GtkWidget *parent = NULL; + GdkEvent *event = gtk_get_current_event(); + GdkWindow *menu = NULL; + + if (event == NULL) + /* The window was not triggered by a user action. */ + return FALSE; + + /* We need to special case events from a popup menu. */ + if (event->type == GDK_BUTTON_RELEASE) { + /* XXX: Neither of the following works: + menu = event->button.window; + menu = gdk_window_get_parent(event->button.window); + menu = gdk_window_get_toplevel(event->button.window); + */ + } else if (event->type == GDK_KEY_PRESS) + menu = event->key.window; + + windows = gtk_window_list_toplevels(); + while (windows) { + GtkWidget *window = windows->data; + windows = g_list_delete_link(windows, windows); + + if (window == widget || + !GTK_WIDGET_VISIBLE(window)) { + continue; + } + + if (gtk_window_has_toplevel_focus(GTK_WINDOW(window)) || + (menu && menu == window->window)) { + parent = window; + break; + } + } + if (windows) + g_list_free(windows); + if (parent) { + gtk_window_set_transient_for(GTK_WINDOW(widget), GTK_WINDOW(parent)); + return TRUE; + } + return FALSE; +#endif +} + diff -r c117352a6088 -r a3f0c30eb0bf pidgin/gtkutils.h --- a/pidgin/gtkutils.h Tue Dec 18 03:35:20 2007 +0000 +++ b/pidgin/gtkutils.h Tue Dec 18 05:50:43 2007 +0000 @@ -121,6 +121,61 @@ GtkWidget *pidgin_create_window(const char *title, guint border_width, const char *role, gboolean resizable); /** + * Creates a new dialog window + * + * @param title The window title, or @c NULL + * @param border_width The window's desired border width + * @param role A string indicating what the window is responsible for doing, or @c NULL + * @param resizable Whether the window should be resizable (@c TRUE) or not (@c FALSE) + * + * @since 2.4.0 + */ +GtkWidget *pidgin_create_dialog(const char *title, guint border_width, const char *role, gboolean resizable); + +/** + * Retrieves the main content box (vbox) from a pidgin dialog window + * + * @param dialog The dialog window + * @param homogeneous TRUE if all children are to be given equal space allotments. + * @param spacing the number of pixels to place by default between children + * + * @since 2.4.0 + */ +GtkWidget *pidgin_dialog_get_vbox_with_properties(GtkDialog *dialog, gboolean homogeneous, gint spacing); + +/** + * Retrieves the main content box (vbox) from a pidgin dialog window + * + * @param dialog The dialog window + * + * @since 2.4.0 + */ +GtkWidget *pidgin_dialog_get_vbox(GtkDialog *dialog); + +/** + * Add a button to a dialog created by #pidgin_create_dialog. + * + * @param dialog The dialog window + * @param label The stock-id or the label for the button + * @param callback The callback function for the button + * @param callbackdata The user data for the callback function + * + * @return The created button. + * @since 2.4.0 + */ +GtkWidget *pidgin_dialog_add_button(GtkDialog *dialog, const char *label, + GCallback callback, gpointer callbackdata); + +/** + * Retrieves the action area (button box) from a pidgin dialog window + * + * @param dialog The dialog window + * + * @since 2.4.0 + */ +GtkWidget *pidgin_dialog_get_action_area(GtkDialog *dialog); + +/** * Toggles the sensitivity of a widget. * * @param widget @c NULL. Used for signal handlers. @@ -725,5 +780,15 @@ */ void pidgin_text_combo_box_entry_set_text(GtkWidget *widget, const char *text); +/** + * Automatically make a window transient to a suitable parent window. + * + * @param window The window to make transient. + * + * @return Whether the window was made transient or not. + * @since 2.4.0 + */ +gboolean pidgin_auto_parent_window(GtkWidget *window); + #endif /* _PIDGINUTILS_H_ */