diff -r e093c956c5e5 -r c0aef3b64c56 pidgin/gtkrequest.c
--- a/pidgin/gtkrequest.c Sat Sep 07 02:30:39 2013 +0530
+++ b/pidgin/gtkrequest.c Thu Sep 12 19:08:48 2013 +0530
@@ -187,7 +187,7 @@
if (id >= 0 && (gsize)id < data->cb_count && data->cbs[id] != NULL)
while (group) {
if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(group->data))) {
- ((PurpleRequestChoiceCb)data->cbs[id])(data->user_data, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(group->data), "choice_id")));
+ ((PurpleRequestChoiceCb)data->cbs[id])(data->user_data, g_object_get_data(G_OBJECT(group->data), "choice_value"));
break;
}
group = group->next;
@@ -232,17 +232,32 @@
static void
field_choice_menu_cb(GtkComboBox *menu, PurpleRequestField *field)
{
- purple_request_field_choice_set_value(field,
- gtk_combo_box_get_active(menu));
+ int active = gtk_combo_box_get_active(menu);
+ gpointer *values = g_object_get_data(G_OBJECT(menu), "values");
+
+ g_return_if_fail(values != NULL);
+ g_return_if_fail(active >= 0);
+
+ purple_request_field_choice_set_value(field, values[active]);
}
static void
field_choice_option_cb(GtkRadioButton *button, PurpleRequestField *field)
{
- if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
- purple_request_field_choice_set_value(field,
- (g_slist_length(gtk_radio_button_get_group(button)) -
- g_slist_index(gtk_radio_button_get_group(button), button)) - 1);
+ int active;
+ gpointer *values = g_object_get_data(G_OBJECT(g_object_get_data(
+ G_OBJECT(button), "box")), "values");
+
+ if (!gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button)))
+ return;
+
+ active = (g_slist_length(gtk_radio_button_get_group(button)) -
+ g_slist_index(gtk_radio_button_get_group(button), button)) - 1;
+
+ g_return_if_fail(values != NULL);
+ g_return_if_fail(active >= 0);
+
+ purple_request_field_choice_set_value(field, values[active]);
}
static void
@@ -309,13 +324,112 @@
return text;
}
+static gchar *
+pidgin_request_escape(PurpleRequestCommonParameters *cpar, const gchar *text)
+{
+ if (text == NULL)
+ return NULL;
+
+ if (purple_request_cpar_is_html(cpar)) {
+ gboolean valid;
+
+ valid = pango_parse_markup(text, -1, 0, NULL, NULL, NULL, NULL);
+
+ if (valid)
+ return g_strdup(text);
+ else {
+ purple_debug_error("pidgin", "Passed label text is not "
+ "a valid markup. Falling back to plain text.");
+ }
+ }
+
+ return g_markup_escape_text(text, -1);
+}
+
+static GtkWidget *
+pidgin_request_dialog_icon(PurpleRequestCommonParameters *cpar)
+{
+ GtkWidget *img = NULL;
+ PurpleRequestIconType icon_type;
+ gconstpointer icon_data;
+ gsize icon_size;
+ const gchar *icon_stock = PIDGIN_STOCK_DIALOG_QUESTION;
+
+ /* Dialog icon. */
+ icon_data = purple_request_cpar_get_custom_icon(cpar, &icon_size);
+ if (icon_data) {
+ GdkPixbuf *pixbuf;
+
+ pixbuf = pidgin_pixbuf_from_data(icon_data, icon_size);
+ if (pixbuf) {
+ /* scale the image if it is too large */
+ int width = gdk_pixbuf_get_width(pixbuf);
+ int height = gdk_pixbuf_get_height(pixbuf);
+ if (width > 128 || height > 128) {
+ int scaled_width = width > height ?
+ 128 : (128 * width) / height;
+ int scaled_height = height > width ?
+ 128 : (128 * height) / width;
+ GdkPixbuf *scaled;
+
+ purple_debug_info("pidgin", "dialog icon was "
+ "too large, scaling it down");
+
+ scaled = gdk_pixbuf_scale_simple(pixbuf,
+ scaled_width, scaled_height,
+ GDK_INTERP_BILINEAR);
+ if (scaled) {
+ g_object_unref(pixbuf);
+ pixbuf = scaled;
+ }
+ }
+ img = gtk_image_new_from_pixbuf(pixbuf);
+ g_object_unref(pixbuf);
+ } else {
+ purple_debug_info("pidgin",
+ "failed to parse dialog icon");
+ }
+ }
+
+ if (img)
+ return img;
+
+ icon_type = purple_request_cpar_get_icon(cpar);
+ switch (icon_type)
+ {
+ case PURPLE_REQUEST_ICON_REQUEST:
+ icon_stock = PIDGIN_STOCK_DIALOG_QUESTION;
+ break;
+ case PURPLE_REQUEST_ICON_DIALOG:
+ case PURPLE_REQUEST_ICON_INFO:
+ icon_stock = PIDGIN_STOCK_DIALOG_INFO;
+ break;
+ case PURPLE_REQUEST_ICON_WARNING:
+ icon_stock = PIDGIN_STOCK_DIALOG_WARNING;
+ break;
+ case PURPLE_REQUEST_ICON_ERROR:
+ icon_stock = PIDGIN_STOCK_DIALOG_ERROR;
+ break;
+ /* intentionally no default value */
+ }
+
+ img = gtk_image_new_from_stock(icon_stock,
+ gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
+
+ if (img || icon_type == PURPLE_REQUEST_ICON_REQUEST)
+ return img;
+
+ return gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
+ gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
+}
+
static void *
pidgin_request_input(const char *title, const char *primary,
const char *secondary, const char *default_value,
gboolean multiline, gboolean masked, gchar *hint,
const char *ok_text, GCallback ok_cb,
const char *cancel_text, GCallback cancel_cb,
- PurpleAccount *account, const char *who, PurpleConversation *conv,
+ PurpleRequestCommonParameters *cpar,
void *user_data)
{
PidginRequestData *data;
@@ -365,8 +479,7 @@
hbox);
/* Dialog icon. */
- img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
+ img = pidgin_request_dialog_icon(cpar);
gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
@@ -375,11 +488,11 @@
gtk_box_pack_start(GTK_BOX(hbox), vbox, TRUE, TRUE, 0);
- pidgin_widget_decorate_account(hbox, account);
+ pidgin_widget_decorate_account(hbox, purple_request_cpar_get_account(cpar));
/* Descriptive label */
- primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
- secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL;
+ primary_esc = pidgin_request_escape(cpar, primary);
+ secondary_esc = pidgin_request_escape(cpar, secondary);
label_text = g_strdup_printf((primary ? ""
"%s%s%s" : "%s%s%s"),
(primary ? primary_esc : ""),
@@ -468,11 +581,9 @@
static void *
pidgin_request_choice(const char *title, const char *primary,
- const char *secondary, int default_value,
- const char *ok_text, GCallback ok_cb,
- const char *cancel_text, GCallback cancel_cb,
- PurpleAccount *account, const char *who, PurpleConversation *conv,
- void *user_data, va_list args)
+ const char *secondary, gpointer default_value, const char *ok_text,
+ GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
+ PurpleRequestCommonParameters *cpar, void *user_data, va_list args)
{
PidginRequestData *data;
GtkWidget *dialog;
@@ -526,20 +637,19 @@
hbox);
/* Dialog icon. */
- img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
+ img = pidgin_request_dialog_icon(cpar);
gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
- pidgin_widget_decorate_account(hbox, account);
+ pidgin_widget_decorate_account(hbox, purple_request_cpar_get_account(cpar));
/* Vertical box */
vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
/* Descriptive label */
- primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
- secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL;
+ primary_esc = pidgin_request_escape(cpar, primary);
+ secondary_esc = pidgin_request_escape(cpar, secondary);
label_text = g_strdup_printf((primary ? ""
"%s%s%s" : "%s%s%s"),
(primary ? primary_esc : ""),
@@ -560,10 +670,10 @@
vbox2 = gtk_vbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
gtk_box_pack_start(GTK_BOX(vbox), vbox2, FALSE, FALSE, 0);
while ((radio_text = va_arg(args, char*))) {
- int resp = va_arg(args, int);
+ gpointer resp = va_arg(args, gpointer);
radio = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(radio), radio_text);
gtk_box_pack_start(GTK_BOX(vbox2), radio, FALSE, FALSE, 0);
- g_object_set_data(G_OBJECT(radio), "choice_id", GINT_TO_POINTER(resp));
+ g_object_set_data(G_OBJECT(radio), "choice_value", resp);
if (resp == default_value)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
}
@@ -579,12 +689,10 @@
}
static void *
-pidgin_request_action_with_icon(const char *title, const char *primary,
- const char *secondary, int default_action,
- PurpleAccount *account, const char *who,
- PurpleConversation *conv, gconstpointer icon_data,
- gsize icon_size,
- void *user_data, size_t action_count, va_list actions)
+pidgin_request_action(const char *title, const char *primary,
+ const char *secondary, int default_action,
+ PurpleRequestCommonParameters *cpar, void *user_data,
+ size_t action_count, va_list actions)
{
PidginRequestData *data;
GtkWidget *dialog;
@@ -649,38 +757,7 @@
gtk_container_add(GTK_CONTAINER(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),
hbox);
- /* Dialog icon. */
- if (icon_data) {
- GdkPixbuf *pixbuf = pidgin_pixbuf_from_data(icon_data, icon_size);
- if (pixbuf) {
- /* scale the image if it is too large */
- int width = gdk_pixbuf_get_width(pixbuf);
- int height = gdk_pixbuf_get_height(pixbuf);
- if (width > 128 || height > 128) {
- int scaled_width = width > height ? 128 : (128 * width) / height;
- int scaled_height = height > width ? 128 : (128 * height) / width;
- GdkPixbuf *scaled =
- gdk_pixbuf_scale_simple(pixbuf, scaled_width, scaled_height,
- GDK_INTERP_BILINEAR);
-
- purple_debug_info("pidgin",
- "dialog icon was too large, scaled it down\n");
- if (scaled) {
- g_object_unref(pixbuf);
- pixbuf = scaled;
- }
- }
- img = gtk_image_new_from_pixbuf(pixbuf);
- g_object_unref(pixbuf);
- } else {
- purple_debug_info("pidgin", "failed to parse dialog icon\n");
- }
- }
-
- if (!img) {
- img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
- }
+ img = pidgin_request_dialog_icon(cpar);
gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
@@ -688,11 +765,12 @@
vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
gtk_box_pack_start(GTK_BOX(hbox), vbox, FALSE, FALSE, 0);
- pidgin_widget_decorate_account(hbox, account);
+ pidgin_widget_decorate_account(hbox,
+ purple_request_cpar_get_account(cpar));
/* Descriptive label */
- primary_esc = (primary != NULL) ? g_markup_escape_text(primary, -1) : NULL;
- secondary_esc = (secondary != NULL) ? g_markup_escape_text(secondary, -1) : NULL;
+ primary_esc = pidgin_request_escape(cpar, primary);
+ secondary_esc = pidgin_request_escape(cpar, secondary);
label_text = g_strdup_printf((primary ? ""
"%s%s%s" : "%s%s%s"),
(primary ? primary_esc : ""),
@@ -732,17 +810,6 @@
return data;
}
-static void *
-pidgin_request_action(const char *title, const char *primary,
- const char *secondary, int default_action,
- PurpleAccount *account, const char *who, PurpleConversation *conv,
- void *user_data, size_t action_count, va_list actions)
-{
- return pidgin_request_action_with_icon(title, primary, secondary,
- default_action, account, who, conv, NULL, 0, user_data, action_count,
- actions);
-}
-
static void
req_entry_field_changed_cb(GtkWidget *entry, PurpleRequestField *field)
{
@@ -955,22 +1022,37 @@
create_choice_field(PurpleRequestField *field)
{
GtkWidget *widget;
- GList *labels = purple_request_field_choice_get_labels(field);
- int num_labels = g_list_length(labels);
+ GList *elements = purple_request_field_choice_get_elements(field);
+ int num_labels = g_list_length(elements) / 2;
GList *l;
+ gpointer *values = g_new(gpointer, num_labels);
+ gpointer default_value;
+ int i, default_index = -1;
+ default_value = purple_request_field_choice_get_default_value(field);
if (num_labels > 5)
{
widget = gtk_combo_box_text_new();
- for (l = labels; l != NULL; l = l->next)
+ i = 0;
+ l = elements;
+ while (l != NULL)
{
- const char *text = l->data;
+ const char *text;
+ gpointer *value;
+
+ text = l->data;
+ l = g_list_next(l);
+ value = l->data;
+ l = g_list_next(l);
+
gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(widget), text);
+ if (value == default_value)
+ default_index = i;
+ values[i++] = value;
}
- gtk_combo_box_set_active(GTK_COMBO_BOX(widget),
- purple_request_field_choice_get_default_value(field));
+ gtk_combo_box_set_active(GTK_COMBO_BOX(widget), default_index);
gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
@@ -982,7 +1064,6 @@
GtkWidget *box;
GtkWidget *first_radio = NULL;
GtkWidget *radio;
- gint i;
if (num_labels == 2)
box = gtk_hbox_new(FALSE, PIDGIN_HIG_BOX_SPACE);
@@ -993,18 +1074,28 @@
gtk_widget_set_tooltip_text(widget, purple_request_field_get_tooltip(field));
- for (l = labels, i = 0; l != NULL; l = l->next, i++)
+ i = 0;
+ l = elements;
+ while (l != NULL)
{
- const char *text = l->data;
+ const char *text;
+ gpointer *value;
+
+ text = l->data;
+ l = g_list_next(l);
+ value = l->data;
+ l = g_list_next(l);
radio = gtk_radio_button_new_with_label_from_widget(
GTK_RADIO_BUTTON(first_radio), text);
+ g_object_set_data(G_OBJECT(radio), "box", box);
if (first_radio == NULL)
first_radio = radio;
- if (i == purple_request_field_choice_get_default_value(field))
+ if (value == default_value)
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
+ values[i++] = value;
gtk_box_pack_start(GTK_BOX(box), radio, TRUE, TRUE, 0);
gtk_widget_show(radio);
@@ -1014,6 +1105,8 @@
}
}
+ g_object_set_data_full(G_OBJECT(widget), "values", values, g_free);
+
return widget;
}
@@ -1221,11 +1314,9 @@
static void *
pidgin_request_fields(const char *title, const char *primary,
- const char *secondary, PurpleRequestFields *fields,
- const char *ok_text, GCallback ok_cb,
- const char *cancel_text, GCallback cancel_cb,
- PurpleAccount *account, const char *who, PurpleConversation *conv,
- void *user_data)
+ const char *secondary, PurpleRequestFields *fields, const char *ok_text,
+ GCallback ok_cb, const char *cancel_text, GCallback cancel_cb,
+ PurpleRequestCommonParameters *cpar, void *user_data)
{
PidginRequestData *data;
GtkWidget *win;
@@ -1274,8 +1365,7 @@
gtk_widget_show(hbox);
/* Dialog icon. */
- img = gtk_image_new_from_stock(PIDGIN_STOCK_DIALOG_QUESTION,
- gtk_icon_size_from_name(PIDGIN_ICON_SIZE_TANGO_HUGE));
+ img = pidgin_request_dialog_icon(cpar);
gtk_misc_set_alignment(GTK_MISC(img), 0, 0);
gtk_box_pack_start(GTK_BOX(hbox), img, FALSE, FALSE, 0);
gtk_widget_show(img);
@@ -1290,7 +1380,8 @@
gtk_widget_set_can_default(button, TRUE);
gtk_window_set_default(GTK_WINDOW(win), button);
- pidgin_widget_decorate_account(hbox, account);
+ pidgin_widget_decorate_account(hbox,
+ purple_request_cpar_get_account(cpar));
/* Setup the vbox */
vbox = gtk_vbox_new(FALSE, PIDGIN_HIG_BORDER);
@@ -1300,7 +1391,7 @@
sg = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
if(primary) {
- primary_esc = g_markup_escape_text(primary, -1);
+ primary_esc = pidgin_request_escape(cpar, primary);
label_text = g_strdup_printf(
"%s", primary_esc);
g_free(primary_esc);
@@ -1341,7 +1432,7 @@
}
if (secondary) {
- secondary_esc = g_markup_escape_text(secondary, -1);
+ secondary_esc = pidgin_request_escape(cpar, secondary);
label = gtk_label_new(NULL);
gtk_label_set_markup(GTK_LABEL(label), secondary_esc);
@@ -1618,7 +1709,7 @@
(g_file_test(data->u.file.name, G_FILE_TEST_EXISTS))) {
purple_request_action(data, NULL, _("That file already exists"),
_("Would you like to overwrite it?"), 0,
- NULL, NULL, NULL,
+ NULL,
data, 2,
_("Overwrite"), G_CALLBACK(file_yes_no_cb),
_("Choose New Name"), G_CALLBACK(file_yes_no_cb));
@@ -1628,10 +1719,8 @@
static void *
pidgin_request_file(const char *title, const char *filename,
- gboolean savedialog,
- GCallback ok_cb, GCallback cancel_cb,
- PurpleAccount *account, const char *who, PurpleConversation *conv,
- void *user_data)
+ gboolean savedialog, GCallback ok_cb, GCallback cancel_cb,
+ PurpleRequestCommonParameters *cpar, void *user_data)
{
PidginRequestData *data;
GtkWidget *filesel;
@@ -1706,10 +1795,9 @@
}
static void *
-pidgin_request_folder(const char *title, const char *dirname,
- GCallback ok_cb, GCallback cancel_cb,
- PurpleAccount *account, const char *who, PurpleConversation *conv,
- void *user_data)
+pidgin_request_folder(const char *title, const char *dirname, GCallback ok_cb,
+ GCallback cancel_cb, PurpleRequestCommonParameters *cpar,
+ void *user_data)
{
PidginRequestData *data;
GtkWidget *dirsel;
@@ -1790,6 +1878,7 @@
static PurpleRequestUiOps ops =
{
+ PURPLE_REQUEST_FEATURE_HTML,
pidgin_request_input,
pidgin_request_choice,
pidgin_request_action,
@@ -1797,7 +1886,7 @@
pidgin_request_file,
pidgin_close_request,
pidgin_request_folder,
- pidgin_request_action_with_icon,
+ NULL,
NULL,
NULL,
NULL