diff -r cc8312cb5017 -r f225f7dfb0bc pidgin/gtkrequest.c --- a/pidgin/gtkrequest.c Mon May 06 00:07:59 2024 -0500 +++ b/pidgin/gtkrequest.c Mon May 06 00:11:54 2024 -0500 @@ -108,79 +108,6 @@ } static void -input_response_cb(G_GNUC_UNUSED GtkDialog *dialog, gint id, - PidginRequestData *data) -{ - const char *value; - char *multiline_value = NULL; - - generic_response_start(data); - - if(data->u.input.multiline || purple_strequal(data->u.input.hint, "html")) { - GtkTextBuffer *buffer = NULL; - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(data->u.input.entry)); - - if (purple_strequal(data->u.input.hint, "html")) { - multiline_value = pidgin_text_buffer_get_html(buffer); - } else { - GtkTextIter start_iter, end_iter; - - gtk_text_buffer_get_start_iter(buffer, &start_iter); - gtk_text_buffer_get_end_iter(buffer, &end_iter); - - multiline_value = gtk_text_buffer_get_text(buffer, &start_iter, - &end_iter, FALSE); - } - - value = multiline_value; - } else { - value = gtk_editable_get_text(GTK_EDITABLE(data->u.input.entry)); - } - - if (id >= 0 && (gsize)id < data->cb_count && data->cbs[id] != NULL) - ((PurpleRequestInputCb)data->cbs[id])(data->user_data, value); - else if (data->cbs[1] != NULL) - ((PurpleRequestInputCb)data->cbs[1])(data->user_data, value); - - if (data->u.input.multiline) { - g_free(multiline_value); - } - - purple_request_close(PURPLE_REQUEST_INPUT, data); -} - -static void -action_response_cb(G_GNUC_UNUSED GtkDialog *dialog, gint id, - PidginRequestData *data) -{ - generic_response_start(data); - - if (id >= 0 && (gsize)id < data->cb_count && data->cbs[id] != NULL) - ((PurpleRequestActionCb)data->cbs[id])(data->user_data, id); - - purple_request_close(PURPLE_REQUEST_INPUT, data); -} - - -static void -choice_response_cb(GtkDialog *dialog, gint id, PidginRequestData *data) { - GtkDropDown *dropdown = g_object_get_data(G_OBJECT(dialog), "dropdown"); - - generic_response_start(data); - - if(0 <= id && (gsize)id < data->cb_count && data->cbs[id] != NULL) { - GObject *item = gtk_drop_down_get_selected_item(dropdown); - if(G_IS_OBJECT(item)) { - gpointer value = g_object_get_data(item, "choice_value"); - ((PurpleRequestChoiceCb)data->cbs[id])(data->user_data, value); - } - } - - purple_request_close(PURPLE_REQUEST_INPUT, data); -} - -static void field_choice_option_cb(GObject *obj, G_GNUC_UNUSED GParamSpec *pspec, gpointer data) { @@ -232,28 +159,6 @@ purple_request_close(PURPLE_REQUEST_FIELDS, data); } -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(PurpleRequestType dialog_type, PurpleRequestCommonParameters *cpar) @@ -386,563 +291,6 @@ G_CALLBACK(pidgin_request_help_clicked), NULL); } -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, - PurpleRequestCommonParameters *cpar, - void *user_data) -{ - PidginRequestData *data; - GtkWidget *dialog; - GtkWidget *vbox; - GtkWidget *hbox; - GtkLabel *label; - GtkWidget *img; - GtkWidget *content; - char *label_text; - char *primary_esc, *secondary_esc; - - data = g_new0(PidginRequestData, 1); - data->type = PURPLE_REQUEST_INPUT; - data->user_data = user_data; - - data->cb_count = 2; - data->cbs = g_new0(GCallback, 2); - - data->cbs[0] = ok_cb; - data->cbs[1] = cancel_cb; - - /* Create the dialog. */ - dialog = gtk_dialog_new_with_buttons(title ? title : PIDGIN_ALERT_TITLE, - NULL, 0, - cancel_text, 1, - ok_text, 0, - NULL); - data->dialog = dialog; - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(input_response_cb), data); - - /* Setup the dialog */ - gtk_widget_set_margin_top(dialog, 6); - gtk_widget_set_margin_bottom(dialog, 6); - gtk_widget_set_margin_start(dialog, 6); - gtk_widget_set_margin_end(dialog, 6); - - content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - gtk_widget_set_margin_top(content, 6); - gtk_widget_set_margin_bottom(content, 6); - gtk_widget_set_margin_start(content, 6); - gtk_widget_set_margin_end(content, 6); - - if (!multiline) - gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); - gtk_dialog_set_default_response(GTK_DIALOG(dialog), 0); - gtk_box_set_spacing(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))), - 12); - - /* Setup the main horizontal box */ - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_append(GTK_BOX(content), hbox); - - /* Dialog icon. */ - img = pidgin_request_dialog_icon(PURPLE_REQUEST_INPUT, cpar); - gtk_widget_set_halign(img, GTK_ALIGN_START); - gtk_widget_set_valign(img, GTK_ALIGN_START); - gtk_box_append(GTK_BOX(hbox), img); - - pidgin_request_add_help(GTK_DIALOG(dialog), cpar); - - /* Vertical box */ - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); - gtk_widget_set_hexpand(vbox, TRUE); - gtk_box_append(GTK_BOX(hbox), vbox); - - pidgin_widget_decorate_account(vbox, - purple_request_cpar_get_account(cpar)); - - /* Descriptive label */ - 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 : ""), - ((primary && secondary) ? "\n\n" : ""), - (secondary ? secondary_esc : "")); - g_free(primary_esc); - g_free(secondary_esc); - - label = GTK_LABEL(gtk_label_new(NULL)); - - gtk_label_set_markup(label, label_text); - gtk_label_set_wrap(label, TRUE); - gtk_label_set_xalign(label, 0); - gtk_label_set_yalign(label, 0); - gtk_box_append(GTK_BOX(vbox), GTK_WIDGET(label)); - - g_free(label_text); - - /* Entry field. */ - data->u.input.multiline = multiline; - data->u.input.hint = g_strdup(hint); - - if(multiline || purple_strequal(data->u.input.hint, "html")) { - GtkWidget *sw = NULL; - GtkWidget *view = NULL; - GtkTextBuffer *buffer = NULL; - - sw = gtk_scrolled_window_new(); - gtk_widget_set_vexpand(sw, TRUE); - gtk_box_append(GTK_BOX(vbox), sw); - - view = gtk_text_view_new(); - gtk_widget_set_size_request(view, 320, 130); - gtk_widget_set_name(view, "pidgin_request_input"); - gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(sw), view); - - buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(view)); - - if(!purple_strempty(default_value)) { - if(purple_strequal(data->u.input.hint, "html")) { - GtkTextIter start; - - gtk_text_buffer_get_start_iter(buffer, &start); - gtk_text_buffer_insert_markup(buffer, &start, default_value, - -1); - } else { - gtk_text_buffer_set_text(buffer, default_value, -1); - } - } - - data->u.input.entry = view; - } else { - GtkWidget *entry = NULL; - - if(masked) { - entry = gtk_password_entry_new(); - g_object_set(entry, "activates-default", TRUE, - "show-peek-icon", TRUE, NULL); - } else { - entry = gtk_entry_new(); - gtk_entry_set_activates_default(GTK_ENTRY(entry), TRUE); - } - - gtk_box_append(GTK_BOX(vbox), entry); - - if(default_value != NULL) { - gtk_editable_set_text(GTK_EDITABLE(entry), default_value); - } - - data->u.input.entry = entry; - } - - pidgin_set_accessible_label(data->u.input.entry, label); - - pidgin_auto_parent_window(dialog); - - /* Show everything. */ - gtk_widget_set_visible(dialog, TRUE); - - return data; -} - -static void * -pidgin_request_choice(const char *title, const char *primary, - 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; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *img; - GtkWidget *dropdown; - GListModel *model; - GtkWidget *content; - char *label_text; - const char *radio_text; - char *primary_esc, *secondary_esc; - guint index, selected; - - data = g_new0(PidginRequestData, 1); - data->type = PURPLE_REQUEST_ACTION; - data->user_data = user_data; - - data->cb_count = 2; - data->cbs = g_new0(GCallback, 2); - data->cbs[0] = cancel_cb; - data->cbs[1] = ok_cb; - - /* Create the dialog. */ - data->dialog = dialog = gtk_dialog_new(); - - if (title != NULL) - gtk_window_set_title(GTK_WINDOW(dialog), title); -#ifdef _WIN32 - gtk_window_set_title(GTK_WINDOW(dialog), PIDGIN_ALERT_TITLE); -#endif - - gtk_dialog_add_button(GTK_DIALOG(dialog), cancel_text, 0); - gtk_dialog_add_button(GTK_DIALOG(dialog), ok_text, 1); - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(choice_response_cb), data); - - /* Setup the dialog */ - gtk_widget_set_margin_top(dialog, 6); - gtk_widget_set_margin_bottom(dialog, 6); - gtk_widget_set_margin_start(dialog, 6); - gtk_widget_set_margin_end(dialog, 6); - gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); - - content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - gtk_widget_set_margin_top(content, 6); - gtk_widget_set_margin_bottom(content, 6); - gtk_widget_set_margin_start(content, 6); - gtk_widget_set_margin_end(content, 6); - gtk_box_set_spacing(GTK_BOX(content), 12); - - /* Setup the main horizontal box */ - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_append(GTK_BOX(content), hbox); - - /* Dialog icon. */ - img = pidgin_request_dialog_icon(PURPLE_REQUEST_CHOICE, cpar); - gtk_widget_set_halign(img, GTK_ALIGN_START); - gtk_widget_set_valign(img, GTK_ALIGN_START); - gtk_box_append(GTK_BOX(hbox), img); - - pidgin_request_add_help(GTK_DIALOG(dialog), cpar); - - /* Vertical box */ - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); - gtk_box_append(GTK_BOX(hbox), vbox); - - pidgin_widget_decorate_account(vbox, - purple_request_cpar_get_account(cpar)); - - /* Descriptive label */ - 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 : ""), - ((primary && secondary) ? "\n\n" : ""), - (secondary ? secondary_esc : "")); - g_free(primary_esc); - g_free(secondary_esc); - - label = gtk_label_new(NULL); - - gtk_label_set_markup(GTK_LABEL(label), label_text); - gtk_label_set_wrap(GTK_LABEL(label), TRUE); - gtk_label_set_xalign(GTK_LABEL(label), 0); - gtk_label_set_yalign(GTK_LABEL(label), 0); - gtk_widget_set_vexpand(label, TRUE); - gtk_box_append(GTK_BOX(vbox), label); - - g_free(label_text); - - dropdown = gtk_drop_down_new_from_strings(NULL); - gtk_box_append(GTK_BOX(vbox), dropdown); - g_object_set_data(G_OBJECT(dialog), "dropdown", dropdown); - - index = 0; - selected = GTK_INVALID_LIST_POSITION; - model = gtk_drop_down_get_model(GTK_DROP_DOWN(dropdown)); - while((radio_text = va_arg(args, const char *))) { - GObject *item = NULL; - gpointer resp = va_arg(args, gpointer); - - gtk_string_list_append(GTK_STRING_LIST(model), radio_text); - item = g_list_model_get_item(model, index); - g_object_set_data(item, "choice_value", resp); - if (resp == default_value) { - selected = index; - } - - g_clear_object(&item); - index++; - } - - if(selected != GTK_INVALID_LIST_POSITION) { - gtk_drop_down_set_selected(GTK_DROP_DOWN(dropdown), selected); - } - - /* Show everything. */ - pidgin_auto_parent_window(dialog); - - gtk_widget_set_visible(dialog, TRUE); - - return data; -} - -static void * -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; - GtkWidget *vbox; - GtkWidget *hbox; - GtkWidget *label; - GtkWidget *img = NULL; - GtkWidget *content; - void **buttons; - char *label_text; - char *primary_esc, *secondary_esc; - gsize i; - - data = g_new0(PidginRequestData, 1); - data->type = PURPLE_REQUEST_ACTION; - data->user_data = user_data; - - data->cb_count = action_count; - data->cbs = g_new0(GCallback, action_count); - - /* Reverse the buttons */ - buttons = g_new0(void *, action_count * 2); - - for (i = 0; i < action_count * 2; i += 2) { - buttons[(action_count * 2) - i - 2] = va_arg(actions, char *); - buttons[(action_count * 2) - i - 1] = va_arg(actions, GCallback); - } - - /* Create the dialog. */ - data->dialog = dialog = gtk_dialog_new(); - - gtk_window_set_deletable(GTK_WINDOW(data->dialog), FALSE); - - if (title != NULL) - gtk_window_set_title(GTK_WINDOW(dialog), title); -#ifdef _WIN32 - else - gtk_window_set_title(GTK_WINDOW(dialog), PIDGIN_ALERT_TITLE); -#endif - - for (i = 0; i < action_count; i++) { - gtk_dialog_add_button(GTK_DIALOG(dialog), buttons[2 * i], i); - - data->cbs[i] = buttons[2 * i + 1]; - } - - g_free(buttons); - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(action_response_cb), data); - - /* Setup the dialog */ - gtk_widget_set_margin_top(dialog, 6); - gtk_widget_set_margin_bottom(dialog, 6); - gtk_widget_set_margin_start(dialog, 6); - gtk_widget_set_margin_end(dialog, 6); - gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); - - content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - gtk_widget_set_margin_top(content, 6); - gtk_widget_set_margin_bottom(content, 6); - gtk_widget_set_margin_start(content, 6); - gtk_widget_set_margin_end(content, 6); - gtk_box_set_spacing(GTK_BOX(content), 12); - - /* Setup the main horizontal box */ - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_append(GTK_BOX(content), hbox); - - img = pidgin_request_dialog_icon(PURPLE_REQUEST_ACTION, cpar); - gtk_widget_set_halign(img, GTK_ALIGN_START); - gtk_widget_set_valign(img, GTK_ALIGN_START); - gtk_box_append(GTK_BOX(hbox), img); - - /* Vertical box */ - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); - gtk_box_append(GTK_BOX(hbox), vbox); - - pidgin_widget_decorate_account(vbox, - purple_request_cpar_get_account(cpar)); - - pidgin_request_add_help(GTK_DIALOG(dialog), cpar); - - /* Descriptive label */ - 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 : ""), - ((primary && secondary) ? "\n\n" : ""), - (secondary ? secondary_esc : "")); - g_free(primary_esc); - g_free(secondary_esc); - - label = gtk_label_new(NULL); - - gtk_label_set_markup(GTK_LABEL(label), label_text); - gtk_label_set_wrap(GTK_LABEL(label), TRUE); - gtk_label_set_xalign(GTK_LABEL(label), 0); - gtk_label_set_yalign(GTK_LABEL(label), 0); - gtk_label_set_selectable(GTK_LABEL(label), TRUE); - gtk_widget_set_vexpand(label, TRUE); - gtk_box_append(GTK_BOX(vbox), label); - - g_free(label_text); - - - if (default_action != PURPLE_DEFAULT_ACTION_NONE) { - /* - * Need to invert the default_action number because the - * buttons are added to the dialog in reverse order. - */ - gtk_dialog_set_default_response(GTK_DIALOG(dialog), action_count - 1 - default_action); - } - - /* Show everything. */ - pidgin_auto_parent_window(dialog); - - gtk_widget_set_visible(dialog, TRUE); - - return data; -} - -static void -wait_response_cb(G_GNUC_UNUSED GtkDialog *dialog, G_GNUC_UNUSED gint id, - PidginRequestData *data) -{ - generic_response_start(data); - - if (data->cbs[0] != NULL) - ((PurpleRequestCancelCb)data->cbs[0])(data->user_data); - - purple_request_close(PURPLE_REQUEST_FIELDS, data); -} - -static void * -pidgin_request_wait(const char *title, const char *primary, - const char *secondary, gboolean with_progress, - PurpleRequestCancelCb cancel_cb, PurpleRequestCommonParameters *cpar, - void *user_data) -{ - PidginRequestData *data; - GtkWidget *dialog, *content; - GtkWidget *hbox, *vbox, *img, *label; - gchar *primary_esc, *secondary_esc, *label_text; - - data = g_new0(PidginRequestData, 1); - data->type = PURPLE_REQUEST_WAIT; - data->user_data = user_data; - - data->cb_count = 1; - data->cbs = g_new0(GCallback, 1); - data->cbs[0] = (GCallback)cancel_cb; - - data->dialog = dialog = gtk_dialog_new(); - - g_signal_connect(G_OBJECT(dialog), "response", - G_CALLBACK(wait_response_cb), data); - - gtk_window_set_deletable(GTK_WINDOW(data->dialog), cancel_cb != NULL); - - if (title != NULL) - gtk_window_set_title(GTK_WINDOW(dialog), title); - else - gtk_window_set_title(GTK_WINDOW(dialog), _("Please wait")); - - /* Setup the dialog */ - gtk_widget_set_margin_top(dialog, 6); - gtk_widget_set_margin_bottom(dialog, 6); - gtk_widget_set_margin_start(dialog, 6); - gtk_widget_set_margin_end(dialog, 6); - gtk_window_set_resizable(GTK_WINDOW(dialog), FALSE); - - content = gtk_dialog_get_content_area(GTK_DIALOG(dialog)); - gtk_widget_set_margin_top(content, 6); - gtk_widget_set_margin_bottom(content, 6); - gtk_widget_set_margin_start(content, 6); - gtk_widget_set_margin_end(content, 6); - gtk_box_set_spacing(GTK_BOX(content), 12); - - /* Setup the main horizontal box */ - hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 12); - gtk_box_append(GTK_BOX(content), hbox); - - img = pidgin_request_dialog_icon(PURPLE_REQUEST_WAIT, cpar); - gtk_widget_set_halign(img, GTK_ALIGN_START); - gtk_widget_set_valign(img, GTK_ALIGN_START); - gtk_box_append(GTK_BOX(hbox), img); - - /* Cancel button */ - gtk_dialog_add_button(GTK_DIALOG(dialog), _("Cancel"), GTK_RESPONSE_CANCEL); - - /* Vertical box */ - vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 12); - gtk_box_append(GTK_BOX(hbox), vbox); - - pidgin_widget_decorate_account(vbox, - purple_request_cpar_get_account(cpar)); - - pidgin_request_add_help(GTK_DIALOG(dialog), cpar); - - /* Descriptive label */ - 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 : ""), - ((primary && secondary) ? "\n\n" : ""), - (secondary ? secondary_esc : "")); - g_free(primary_esc); - g_free(secondary_esc); - - label = gtk_label_new(NULL); - - gtk_label_set_markup(GTK_LABEL(label), label_text); - gtk_label_set_wrap(GTK_LABEL(label), TRUE); - gtk_label_set_xalign(GTK_LABEL(label), 0); - gtk_label_set_yalign(GTK_LABEL(label), 0); - gtk_label_set_selectable(GTK_LABEL(label), FALSE); - gtk_widget_set_vexpand(label, TRUE); - gtk_box_append(GTK_BOX(vbox), label); - - g_free(label_text); - - if (with_progress) { - GtkProgressBar *bar; - - bar = data->u.wait.progress_bar = - GTK_PROGRESS_BAR(gtk_progress_bar_new()); - gtk_progress_bar_set_fraction(bar, 0); - gtk_box_append(GTK_BOX(vbox), GTK_WIDGET(bar)); - } - - /* Show everything. */ - pidgin_auto_parent_window(dialog); - - gtk_widget_set_visible(dialog, TRUE); - - return data; -} - -static void -pidgin_request_wait_update(void *ui_handle, gboolean pulse, gfloat fraction) -{ - GtkProgressBar *bar; - PidginRequestData *data = ui_handle; - - g_return_if_fail(data->type == PURPLE_REQUEST_WAIT); - - bar = data->u.wait.progress_bar; - if (pulse) - gtk_progress_bar_pulse(bar); - else - gtk_progress_bar_set_fraction(bar, fraction); -} - static GtkWidget * create_label_field(void) { GtkWidget *row = NULL; @@ -1619,265 +967,6 @@ return data; } -static void -pidgin_request_file_response_cb(GObject *obj, GAsyncResult *result, - gpointer user_data) -{ - PidginRequestData *data = user_data; - GFile *path = NULL; - GFile *parent = NULL; - GError *error = NULL; - - if(data->u.file.savedialog) { - path = gtk_file_dialog_save_finish(GTK_FILE_DIALOG(obj), result, - &error); - } else { - path = gtk_file_dialog_open_finish(GTK_FILE_DIALOG(obj), result, - &error); - } - if(path == NULL) { - if(!g_error_matches(error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_CANCELLED)) { - if(data->cbs[0] != NULL) { - ((PurpleRequestFileCb)data->cbs[0])(data->user_data, NULL); - } - purple_request_close(data->type, data); - } - g_clear_error(&error); - return; - } - - parent = g_file_get_parent(path); - if(parent != NULL) { - char *current_folder = g_file_get_path(parent); - if (data->u.file.savedialog) { - purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_save_folder", - current_folder); - } else { - purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", - current_folder); - } - g_free(current_folder); - } - - if(data->cbs[1] != NULL) { - char *filename = g_file_get_path(path); - ((PurpleRequestFileCb)data->cbs[1])(data->user_data, filename); - g_free(filename); - } - - g_clear_object(&parent); - g_clear_object(&path); - g_clear_object(&data->cancellable); - purple_request_close(data->type, data); -} - -static void -pidgin_request_folder_response_cb(GObject *obj, GAsyncResult *result, - gpointer user_data) -{ - PidginRequestData *data = user_data; - GFile *path = NULL; - char *folder = NULL; - GError *error = NULL; - - path = gtk_file_dialog_select_folder_finish(GTK_FILE_DIALOG(obj), result, - &error); - if(path == NULL) { - if(!g_error_matches(error, GTK_DIALOG_ERROR, GTK_DIALOG_ERROR_CANCELLED)) { - if(data->cbs[0] != NULL) { - ((PurpleRequestFileCb)data->cbs[0])(data->user_data, NULL); - } - purple_request_close(data->type, data); - } - g_clear_error(&error); - return; - } - - folder = g_file_get_path(path); - purple_prefs_set_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder", - folder); - - if(data->cbs[1] != NULL) { - ((PurpleRequestFileCb)data->cbs[1])(data->user_data, folder); - } - - g_free(folder); - g_clear_object(&path); - g_clear_object(&data->cancellable); - purple_request_close(data->type, data); -} - -static void * -pidgin_request_file(const char *title, const char *filename, - gboolean savedialog, GCallback ok_cb, GCallback cancel_cb, - G_GNUC_UNUSED PurpleRequestCommonParameters *cpar, - gpointer user_data) -{ - PidginRequestData *data; - GtkFileDialog *dialog = NULL; -#ifdef _WIN32 - const gchar *current_folder; - gboolean folder_set = FALSE; -#endif - - data = g_new0(PidginRequestData, 1); - data->type = PURPLE_REQUEST_FILE; - data->user_data = user_data; - data->cb_count = 2; - data->cbs = g_new0(GCallback, 2); - data->cbs[0] = cancel_cb; - data->cbs[1] = ok_cb; - data->u.file.savedialog = savedialog; - - data->dialog = dialog = gtk_file_dialog_new(); - gtk_file_dialog_set_title(dialog, - title ? title - : (savedialog ? _("Save File...") - : _("Open File..."))); - - if(!purple_strempty(filename)) { - GFile *path = g_file_new_for_path(filename); - - if(savedialog || g_file_test(filename, G_FILE_TEST_EXISTS)) { - gtk_file_dialog_set_initial_file(dialog, path); - } - - g_object_unref(path); - } - -#ifdef _WIN32 - if (savedialog) { - current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_save_folder"); - } else { - current_folder = purple_prefs_get_path(PIDGIN_PREFS_ROOT "/filelocations/last_open_folder"); - } - - if((purple_strempty(filename) || !g_file_test(filename, G_FILE_TEST_EXISTS)) && - !purple_strempty(current_folder)) - { - GFile *file = g_file_new_for_path(current_folder); - gtk_file_dialog_set_initial_folder(dialog, file); - folder_set = TRUE; - g_clear_object(&file); - } - - if(!folder_set && - (purple_strempty(filename) || !g_file_test(filename, G_FILE_TEST_EXISTS))) - { - const char *my_documents = NULL; - - my_documents = g_get_user_special_dir(G_USER_DIRECTORY_DOCUMENTS); - if (my_documents != NULL) { - GFile *file = g_file_new_for_path(my_documents); - - gtk_file_dialog_set_initial_folder(dialog, file); - - g_clear_object(&file); - } - } -#endif - - data->cancellable = g_cancellable_new(); - if(savedialog) { - gtk_file_dialog_save(dialog, NULL, data->cancellable, - pidgin_request_file_response_cb, data); - } else { - gtk_file_dialog_open(dialog, NULL, data->cancellable, - pidgin_request_file_response_cb, data); - } - - return (void *)data; -} - -static void * -pidgin_request_folder(const char *title, const char *dirname, GCallback ok_cb, - GCallback cancel_cb, - G_GNUC_UNUSED PurpleRequestCommonParameters *cpar, - gpointer user_data) -{ - PidginRequestData *data; - GtkFileDialog *dialog = NULL; - - data = g_new0(PidginRequestData, 1); - data->type = PURPLE_REQUEST_FOLDER; - data->user_data = user_data; - data->cb_count = 2; - data->cbs = g_new0(GCallback, 2); - data->cbs[0] = cancel_cb; - data->cbs[1] = ok_cb; - data->u.file.savedialog = FALSE; - - data->cancellable = g_cancellable_new(); - data->dialog = dialog = gtk_file_dialog_new(); - gtk_file_dialog_set_title(dialog, title ? title : _("Select Folder...")); - - if(!purple_strempty(dirname)) { - GFile *path = g_file_new_for_path(dirname); - gtk_file_dialog_set_initial_folder(dialog, path); - g_object_unref(path); - } - - gtk_file_dialog_select_folder(dialog, NULL, data->cancellable, - pidgin_request_folder_response_cb, data); - - return (void *)data; -} - -/* if request callback issues another request, it should be attached to the - * primary request parent */ -static void -pidgin_window_detach_children(GtkWindow* win) -{ - GList *it; - GtkWindow *par; - - g_return_if_fail(win != NULL); - - par = gtk_window_get_transient_for(win); - it = gtk_window_list_toplevels(); - for (it = g_list_first(it); it != NULL; it = g_list_delete_link(it, it)) { - GtkWindow *child = GTK_WINDOW(it->data); - if (gtk_window_get_transient_for(child) != win) - continue; - if (gtk_window_get_destroy_with_parent(child)) { -#ifdef _WIN32 - /* XXX test/verify it: Win32 gtk ignores - * gtk_window_set_destroy_with_parent(..., FALSE). */ - gtk_window_set_transient_for(child, NULL); -#endif - continue; - } - gtk_window_set_transient_for(child, par); - } -} - -static void -pidgin_close_request(PurpleRequestType type, void *ui_handle) -{ - PidginRequestData *data = (PidginRequestData *)ui_handle; - - if(data->cancellable != NULL) { - g_cancellable_cancel(data->cancellable); - } - - if (type == PURPLE_REQUEST_FILE || type == PURPLE_REQUEST_FOLDER) { - /* Will be a GtkFileDialog, not GtkDialog. */ - g_clear_object(&data->dialog); - } else { - pidgin_window_detach_children(GTK_WINDOW(data->dialog)); - - gtk_window_destroy(GTK_WINDOW(data->dialog)); - } - - if(type == PURPLE_REQUEST_FIELDS) { - g_clear_object(&data->u.multifield.page); - } - - g_clear_object(&data->cancellable); - g_free(data->cbs); - g_free(data); -} - GtkWindow * pidgin_request_get_dialog_window(void *ui_handle) { @@ -1897,16 +986,7 @@ } static PurpleRequestUiOps ops = { - .features = PURPLE_REQUEST_FEATURE_HTML, - .request_input = pidgin_request_input, - .request_choice = pidgin_request_choice, - .request_action = pidgin_request_action, - .request_wait = pidgin_request_wait, - .request_wait_update = pidgin_request_wait_update, .request_fields = pidgin_request_fields, - .request_file = pidgin_request_file, - .request_folder = pidgin_request_folder, - .close_request = pidgin_close_request, }; PurpleRequestUiOps *