From d468ea3efa4847d310143654472c0829a53b879d Mon Sep 17 00:00:00 2001 From: Friedrich Beckmann Date: Tue, 16 Jun 2020 16:59:06 +0200 Subject: [PATCH 1/4] quartz: added open capability to gtk_application This patch implements the openFiles delegate which is required to open files which are associated with an application via the Finder or via open on the command line. The patch has been proposed by jessevdk@gmail.com. See: https://gitlab.gnome.org/GNOME/gtk/-/issues/463 I tested the patch with the GNU pspp application on MacOS with the quartz backend. --- gtk/gtkapplication-quartz.c | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/gtk/gtkapplication-quartz.c b/gtk/gtkapplication-quartz.c index 38131f4be0..90ab1705f0 100644 --- a/gtk/gtkapplication-quartz.c +++ b/gtk/gtkapplication-quartz.c @@ -64,6 +64,7 @@ G_DEFINE_TYPE (GtkApplicationImplQuartz, gtk_application_impl_quartz, GTK_TYPE_A - (id)initWithImpl:(GtkApplicationImplQuartz*)impl; - (NSApplicationTerminateReply) applicationShouldTerminate:(NSApplication *)sender; +- (void)application:(NSApplication *)theApplication openFiles:(NSArray *)filenames; @end @implementation GtkApplicationQuartzDelegate @@ -84,6 +85,35 @@ G_DEFINE_TYPE (GtkApplicationImplQuartz, gtk_application_impl_quartz, GTK_TYPE_A */ return quartz->quit_inhibit == 0 ? NSTerminateNow : NSTerminateCancel; } + +-(void)application:(NSApplication *)theApplication openFiles:(NSArray *)filenames +{ + GFile **files; + gint i; + GApplicationFlags flags; + + flags = g_application_get_flags (G_APPLICATION (quartz->impl.application)); + + if (~flags & G_APPLICATION_HANDLES_OPEN) + { + [theApplication replyToOpenOrPrint:NSApplicationDelegateReplyFailure]; + return; + } + + files = g_new (GFile *, [filenames count]); + + for (i = 0; i < [filenames count]; i++) + files[i] = g_file_new_for_path ([(NSString *)[filenames objectAtIndex:i] UTF8String]); + + g_application_open (G_APPLICATION (quartz->impl.application), files, [filenames count], ""); + + for (i = 0; i < [filenames count]; i++) + g_object_unref (files[i]); + + g_free (files); + + [theApplication replyToOpenOrPrint:NSApplicationDelegateReplySuccess]; +} @end /* these exist only for accel handling */ From 2a9c92f8e2bf439065e1db605babdbc3989ce9b6 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Tue, 16 Jun 2020 12:06:34 -0400 Subject: [PATCH 2/4] Drop unused includes This is just cleanup to help tracking down remaining GtkComboBox uses. --- gtk/gtkfontchooserwidget.c | 1 - gtk/gtkiconview.c | 1 - 2 files changed, 2 deletions(-) diff --git a/gtk/gtkfontchooserwidget.c b/gtk/gtkfontchooserwidget.c index 9a3b09454b..1d4cd53aa8 100644 --- a/gtk/gtkfontchooserwidget.c +++ b/gtk/gtkfontchooserwidget.c @@ -51,7 +51,6 @@ #include "gtksettings.h" #include "gtkdialog.h" #include "gtkradiobutton.h" -#include "gtkcombobox.h" #include "gtkgestureclick.h" #include "gtkeventcontrollerscroll.h" #include "gtkroot.h" diff --git a/gtk/gtkiconview.c b/gtk/gtkiconview.c index 2fc1123c07..ea63186622 100644 --- a/gtk/gtkiconview.c +++ b/gtk/gtkiconview.c @@ -27,7 +27,6 @@ #include "gtkcellrenderer.h" #include "gtkcellrendererpixbuf.h" #include "gtkcellrenderertext.h" -#include "gtkcombobox.h" #include "gtkcssnodeprivate.h" #include "gtkdragsource.h" #include "gtkentry.h" From 25c2059abb9f60eb74ffd42029ad63fff136e35e Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 15 Jun 2020 20:31:27 -0400 Subject: [PATCH 3/4] pagesetupdialog: Port the papersize combo Turn the papersize combo into a dropdown. --- gtk/gtkpagesetupunixdialog.c | 327 +++++++++++++++++------------------ 1 file changed, 161 insertions(+), 166 deletions(-) diff --git a/gtk/gtkpagesetupunixdialog.c b/gtk/gtkpagesetupunixdialog.c index 99f2d97c92..91adf5fb19 100644 --- a/gtk/gtkpagesetupunixdialog.c +++ b/gtk/gtkpagesetupunixdialog.c @@ -25,8 +25,6 @@ #include "gtkprivate.h" #include "gtkliststore.h" -#include "gtktreeviewcolumn.h" -#include "gtktreeselection.h" #include "gtktreemodel.h" #include "gtkbutton.h" #include "gtkscrolledwindow.h" @@ -65,15 +63,16 @@ struct _GtkPageSetupUnixDialog GtkDialog parent_instance; GtkListStore *printer_list; - GtkListStore *page_setup_list; - GtkListStore *custom_paper_list; + GListStore *page_setup_list; + GListStore *custom_paper_list; + GListStore *manage_papers_list; + GListStore *paper_size_list; GList *print_backends; GtkWidget *printer_combo; GtkWidget *paper_size_combo; GtkWidget *paper_size_label; - GtkCellRenderer *paper_size_cell; GtkWidget *portrait_radio; GtkWidget *reverse_portrait_radio; @@ -125,18 +124,11 @@ static void printer_status_cb (GtkPrintBackend *backen GtkPrinter *printer, GtkPageSetupUnixDialog *dialog); static void printer_changed_callback (GtkComboBox *combo_box, - GtkPageSetupUnixDialog *dialog); -static void paper_size_changed (GtkComboBox *combo_box, - GtkPageSetupUnixDialog *dialog); -static void page_name_func (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data); + GtkPageSetupUnixDialog *dialog); +static void paper_size_changed (GtkDropDown *combo_box, + GParamSpec *pspec, + GtkPageSetupUnixDialog *dialog); static void load_print_backends (GtkPageSetupUnixDialog *dialog); -static gboolean paper_size_row_is_separator (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer data); static const gchar common_paper_sizes[][16] = { @@ -169,15 +161,12 @@ gtk_page_setup_unix_dialog_class_init (GtkPageSetupUnixDialogClass *class) /* Bind class to template */ gtk_widget_class_set_template_from_resource (widget_class, - "/org/gtk/libgtk/ui/gtkpagesetupunixdialog.ui"); + "/org/gtk/libgtk/ui/gtkpagesetupunixdialog.ui"); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, printer_list); - gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, page_setup_list); - gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, custom_paper_list); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, printer_combo); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, paper_size_combo); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, paper_size_label); - gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, paper_size_cell); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, portrait_radio); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, reverse_portrait_radio); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, landscape_radio); @@ -187,11 +176,74 @@ gtk_page_setup_unix_dialog_class_init (GtkPageSetupUnixDialogClass *class) gtk_widget_class_bind_template_callback (widget_class, paper_size_changed); } +static void +setup_paper_size_item (GtkSignalListItemFactory *factory, + GtkListItem *item) +{ + GtkWidget *label; + + label = gtk_label_new (""); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_list_item_set_child (item, label); +} + +static void +bind_paper_size_list_item (GtkSignalListItemFactory *factory, + GtkListItem *item, + GtkPageSetupUnixDialog *self) +{ + GtkPageSetup *page_setup; + GtkWidget *label; + guint pos; + GListModel *papers; + GListModel *model; + gpointer first; + + page_setup = gtk_list_item_get_item (item); + label = gtk_list_item_get_child (item); + + pos = gtk_list_item_get_position (item); + papers = gtk_drop_down_get_model (GTK_DROP_DOWN (self->paper_size_combo)); + model = gtk_flatten_list_model_get_model_for_item (GTK_FLATTEN_LIST_MODEL (papers), pos); + if (model != G_LIST_MODEL (self->manage_papers_list)) + { + GtkPaperSize *paper_size = gtk_page_setup_get_paper_size (page_setup); + gtk_label_set_text (GTK_LABEL (label), gtk_paper_size_get_display_name (paper_size)); + } + else + gtk_label_set_text (GTK_LABEL (label), _("Manage Custom Sizes…")); + + first = g_list_model_get_item (model, 0); + g_object_unref (first); + if (pos != 0 && + page_setup == GTK_PAGE_SETUP (first)) + gtk_widget_add_css_class (gtk_widget_get_parent (label), "separator"); + else + gtk_widget_remove_css_class (gtk_widget_get_parent (label), "separator"); +} + +static void +bind_paper_size_item (GtkSignalListItemFactory *factory, + GtkListItem *item, + GtkPageSetupUnixDialog *self) +{ + GtkWidget *label; + + bind_paper_size_list_item (factory, item, self); + + label = gtk_list_item_get_child (item); + gtk_widget_remove_css_class (label, "separator-before"); +} + static void gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) { GtkTreeIter iter; gchar *tmp; + GtkListItemFactory *factory; + GListStore *store; + GListModel *paper_size_list; + GtkPageSetup *page_setup; dialog->print_backends = NULL; @@ -212,18 +264,39 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) -1); g_free (tmp); + dialog->page_setup_list = g_list_store_new (GTK_TYPE_PAGE_SETUP); + dialog->custom_paper_list = g_list_store_new (GTK_TYPE_PAGE_SETUP); + dialog->manage_papers_list = g_list_store_new (GTK_TYPE_PAGE_SETUP); + page_setup = gtk_page_setup_new (); + g_list_store_append (dialog->manage_papers_list, page_setup); + g_object_unref (page_setup); + + factory = gtk_signal_list_item_factory_new (); + g_signal_connect (factory, "setup", G_CALLBACK (setup_paper_size_item), dialog); + g_signal_connect (factory, "bind", G_CALLBACK (bind_paper_size_item), dialog); + gtk_drop_down_set_factory (GTK_DROP_DOWN (dialog->paper_size_combo), factory); + g_object_unref (factory); + + factory = gtk_signal_list_item_factory_new (); + g_signal_connect (factory, "setup", G_CALLBACK (setup_paper_size_item), dialog); + g_signal_connect (factory, "bind", G_CALLBACK (bind_paper_size_list_item), dialog); + gtk_drop_down_set_list_factory (GTK_DROP_DOWN (dialog->paper_size_combo), factory); + g_object_unref (factory); + + store = g_list_store_new (G_TYPE_LIST_MODEL); + g_list_store_append (store, dialog->page_setup_list); + g_list_store_append (store, dialog->custom_paper_list); + g_list_store_append (store, dialog->manage_papers_list); + paper_size_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PAGE_SETUP, G_LIST_MODEL (store))); + gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->paper_size_combo), paper_size_list); + g_object_unref (store); + g_object_unref (paper_size_list); + /* After adding the above row, set it active */ gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->printer_combo), 0); - /* Setup cell data func and separator func in code */ - gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (dialog->paper_size_combo), - paper_size_row_is_separator, NULL, NULL); - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (dialog->paper_size_combo), - dialog->paper_size_cell, - page_name_func, NULL, NULL); - /* Load data */ - _gtk_print_load_custom_papers (dialog->custom_paper_list); + gtk_print_load_custom_papers (dialog->custom_paper_list); load_print_backends (dialog); } @@ -249,17 +322,9 @@ gtk_page_setup_unix_dialog_finalize (GObject *object) dialog->printer_list = NULL; } - if (dialog->page_setup_list) - { - g_object_unref (dialog->page_setup_list); - dialog->page_setup_list = NULL; - } - - if (dialog->custom_paper_list) - { - g_object_unref (dialog->custom_paper_list); - dialog->custom_paper_list = NULL; - } + g_clear_object (&dialog->page_setup_list); + g_clear_object (&dialog->custom_paper_list); + g_clear_object (&dialog->manage_papers_list); if (dialog->print_settings) { @@ -412,38 +477,17 @@ load_print_backends (GtkPageSetupUnixDialog *dialog) printer_list_initialize (dialog, GTK_PRINT_BACKEND (node->data)); } -static gboolean -paper_size_row_is_separator (GtkTreeModel *model, - GtkTreeIter *iter, - gpointer data) -{ - gboolean separator; - - gtk_tree_model_get (model, iter, PAGE_SETUP_LIST_COL_IS_SEPARATOR, &separator, -1); - return separator; -} - static GtkPageSetup * get_current_page_setup (GtkPageSetupUnixDialog *dialog) { - GtkPageSetup *current_page_setup; - GtkComboBox *combo_box; - GtkTreeIter iter; + guint selected; + GListModel *model; - current_page_setup = NULL; + selected = gtk_drop_down_get_selected (GTK_DROP_DOWN (dialog->paper_size_combo)); + model = gtk_drop_down_get_model (GTK_DROP_DOWN (dialog->paper_size_combo)); + if (selected != GTK_INVALID_LIST_POSITION) + return g_list_model_get_item (model, selected); - combo_box = GTK_COMBO_BOX (dialog->paper_size_combo); - if (gtk_combo_box_get_active_iter (combo_box, &iter)) - gtk_tree_model_get (GTK_TREE_MODEL (dialog->page_setup_list), &iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, ¤t_page_setup, -1); - - if (current_page_setup) - return current_page_setup; - - /* No selected page size, return the default one. - * This is used to set the first page setup when the dialog is created - * as there is no selection on the first printer_changed. - */ return gtk_page_setup_new (); } @@ -474,47 +518,36 @@ set_paper_size (GtkPageSetupUnixDialog *dialog, gboolean size_only, gboolean add_item) { - GtkTreeModel *model; - GtkTreeIter iter; + GListModel *model; GtkPageSetup *list_page_setup; + guint i; - model = GTK_TREE_MODEL (dialog->page_setup_list); + if (page_setup == NULL) + return FALSE; - if (gtk_tree_model_get_iter_first (model, &iter)) + model = gtk_drop_down_get_model (GTK_DROP_DOWN (dialog->paper_size_combo)); + for (i = 0; i < g_list_model_get_n_items (model); i++) { - do + list_page_setup = g_list_model_get_item (model, i); + if (list_page_setup == NULL) + continue; + + if ((size_only && page_setup_is_same_size (page_setup, list_page_setup)) || + (!size_only && page_setup_is_equal (page_setup, list_page_setup))) { - gtk_tree_model_get (GTK_TREE_MODEL (dialog->page_setup_list), &iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, &list_page_setup, -1); - if (list_page_setup == NULL) - continue; - - if ((size_only && page_setup_is_same_size (page_setup, list_page_setup)) || - (!size_only && page_setup_is_equal (page_setup, list_page_setup))) - { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->paper_size_combo), - &iter); - g_object_unref (list_page_setup); - return TRUE; - } - + gtk_drop_down_set_selected (GTK_DROP_DOWN (dialog->paper_size_combo), i); g_object_unref (list_page_setup); + return TRUE; + } - } while (gtk_tree_model_iter_next (model, &iter)); + g_object_unref (list_page_setup); } if (add_item) { - gtk_list_store_append (dialog->page_setup_list, &iter); - gtk_list_store_set (dialog->page_setup_list, &iter, - PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, - -1); - gtk_list_store_append (dialog->page_setup_list, &iter); - gtk_list_store_set (dialog->page_setup_list, &iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, - -1); - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->paper_size_combo), - &iter); + i = g_list_model_get_n_items (model); + g_list_store_append (dialog->page_setup_list, page_setup); + gtk_drop_down_set_selected (GTK_DROP_DOWN (dialog->paper_size_combo), i); return TRUE; } @@ -522,40 +555,26 @@ set_paper_size (GtkPageSetupUnixDialog *dialog, } static void -fill_custom_paper_sizes (GtkPageSetupUnixDialog *dialog) +check_uniqueness (GtkPageSetupUnixDialog *dialog) { - GtkTreeIter iter, paper_iter; - GtkTreeModel *model; + GListModel *model; + guint i, j, n; - model = GTK_TREE_MODEL (dialog->custom_paper_list); - if (gtk_tree_model_get_iter_first (model, &iter)) + model = gtk_drop_down_get_model (GTK_DROP_DOWN (dialog->paper_size_combo)); + n = g_list_model_get_n_items (model); + g_print ("checking %u\n", n); + for (i = 0; i < n; i++) { - gtk_list_store_append (dialog->page_setup_list, &paper_iter); - gtk_list_store_set (dialog->page_setup_list, &paper_iter, - PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, - -1); - do + gpointer item1 = g_list_model_get_item (model, i); + for (j = i + 1; j < n; j++) { - GtkPageSetup *page_setup; - gtk_tree_model_get (model, &iter, 0, &page_setup, -1); - - gtk_list_store_append (dialog->page_setup_list, &paper_iter); - gtk_list_store_set (dialog->page_setup_list, &paper_iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, - -1); - - g_object_unref (page_setup); - } while (gtk_tree_model_iter_next (model, &iter)); + gpointer item2 = g_list_model_get_item (model, j); + if (item1 == item2) + g_critical ("same! %d %d\n", i, j); + g_object_unref (item2); + } + g_object_unref (item1); } - - gtk_list_store_append (dialog->page_setup_list, &paper_iter); - gtk_list_store_set (dialog->page_setup_list, &paper_iter, - PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, - -1); - gtk_list_store_append (dialog->page_setup_list, &paper_iter); - gtk_list_store_set (dialog->page_setup_list, &paper_iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, NULL, - -1); } static void @@ -565,10 +584,10 @@ fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, GList *list, *l; GtkPageSetup *current_page_setup, *page_setup; GtkPaperSize *paper_size; - GtkTreeIter iter; gint i; - gtk_list_store_clear (dialog->page_setup_list); + check_uniqueness (dialog); + g_list_store_remove_all (dialog->page_setup_list); if (printer == NULL) { @@ -579,10 +598,7 @@ fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, gtk_page_setup_set_paper_size_and_default_margins (page_setup, paper_size); gtk_paper_size_free (paper_size); - gtk_list_store_append (dialog->page_setup_list, &iter); - gtk_list_store_set (dialog->page_setup_list, &iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, - -1); + g_list_store_append (dialog->page_setup_list, page_setup); g_object_unref (page_setup); } } @@ -594,16 +610,13 @@ fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, for (l = list; l != NULL; l = l->next) { page_setup = l->data; - gtk_list_store_append (dialog->page_setup_list, &iter); - gtk_list_store_set (dialog->page_setup_list, &iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, - -1); + g_list_store_append (dialog->page_setup_list, page_setup); g_object_unref (page_setup); } g_list_free (list); } - fill_custom_paper_sizes (dialog); + check_uniqueness (dialog); current_page_setup = NULL; @@ -735,7 +748,7 @@ custom_paper_dialog_response_cb (GtkDialog *custom_paper_dialog, { GtkPageSetupUnixDialog *dialog = GTK_PAGE_SETUP_UNIX_DIALOG (user_data); - _gtk_print_load_custom_papers (dialog->custom_paper_list); + gtk_print_load_custom_papers (dialog->custom_paper_list); /* Update printer page list */ printer_changed_callback (GTK_COMBO_BOX (dialog->printer_combo), dialog); @@ -744,11 +757,12 @@ custom_paper_dialog_response_cb (GtkDialog *custom_paper_dialog, } static void -paper_size_changed (GtkComboBox *combo_box, +paper_size_changed (GtkDropDown *combo_box, + GParamSpec *pspec, GtkPageSetupUnixDialog *dialog) { - GtkTreeIter iter; GtkPageSetup *page_setup, *last_page_setup; + guint selected; GtkUnit unit; gchar *str, *w, *h; gchar *top, *bottom, *left, *right; @@ -757,12 +771,16 @@ paper_size_changed (GtkComboBox *combo_box, label = GTK_LABEL (dialog->paper_size_label); - if (gtk_combo_box_get_active_iter (combo_box, &iter)) + selected = gtk_drop_down_get_selected (GTK_DROP_DOWN (combo_box)); + if (selected != GTK_INVALID_LIST_POSITION) { - gtk_tree_model_get (gtk_combo_box_get_model (combo_box), - &iter, PAGE_SETUP_LIST_COL_PAGE_SETUP, &page_setup, -1); + GListModel *papers, *model; - if (page_setup == NULL) + papers = gtk_drop_down_get_model (GTK_DROP_DOWN (dialog->paper_size_combo)); + page_setup = g_list_model_get_item (papers, selected); + model = gtk_flatten_list_model_get_model_for_item (GTK_FLATTEN_LIST_MODEL (papers), selected); + + if (model == G_LIST_MODEL (dialog->manage_papers_list)) { GtkWidget *custom_paper_dialog; @@ -842,29 +860,6 @@ paper_size_changed (GtkComboBox *combo_box, } } -static void -page_name_func (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - gtk_tree_model_get (tree_model, iter, - PAGE_SETUP_LIST_COL_PAGE_SETUP, &page_setup, -1); - if (page_setup) - { - paper_size = gtk_page_setup_get_paper_size (page_setup); - g_object_set (cell, "text", gtk_paper_size_get_display_name (paper_size), NULL); - g_object_unref (page_setup); - } - else - g_object_set (cell, "text", _("Manage Custom Sizes…"), NULL); - -} - /** * gtk_page_setup_unix_dialog_new: * @title: (allow-none): the title of the dialog, or %NULL From 5bcb01e1829415108fce0884759c85694f3a7345 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Mon, 15 Jun 2020 21:57:39 -0400 Subject: [PATCH 4/4] pagesetupdialog: Convert the printer combo Turn the printer combo into a dropdown. --- gtk/gtkpagesetupunixdialog.c | 306 ++++++++++--------------------- gtk/ui/gtkpagesetupunixdialog.ui | 36 +--- 2 files changed, 103 insertions(+), 239 deletions(-) diff --git a/gtk/gtkpagesetupunixdialog.c b/gtk/gtkpagesetupunixdialog.c index 91adf5fb19..5e2679affd 100644 --- a/gtk/gtkpagesetupunixdialog.c +++ b/gtk/gtkpagesetupunixdialog.c @@ -24,11 +24,8 @@ #include "gtkintl.h" #include "gtkprivate.h" -#include "gtkliststore.h" -#include "gtktreemodel.h" #include "gtkbutton.h" #include "gtkscrolledwindow.h" -#include "gtkcombobox.h" #include "gtktogglebutton.h" #include "gtkradiobutton.h" #include "gtklabel.h" @@ -62,7 +59,7 @@ struct _GtkPageSetupUnixDialog { GtkDialog parent_instance; - GtkListStore *printer_list; + GListModel *printer_list; GListStore *page_setup_list; GListStore *custom_paper_list; GListStore *manage_papers_list; @@ -86,8 +83,6 @@ struct _GtkPageSetupUnixDialog /* Save last setup so we can re-set it after selecting manage custom sizes */ GtkPageSetup *last_setup; - - gchar *waiting_for_printer; }; struct _GtkPageSetupUnixDialogClass @@ -114,16 +109,8 @@ G_DEFINE_TYPE (GtkPageSetupUnixDialog, gtk_page_setup_unix_dialog, GTK_TYPE_DIAL static void gtk_page_setup_unix_dialog_finalize (GObject *object); static void fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, GtkPrinter *printer); -static void printer_added_cb (GtkPrintBackend *backend, - GtkPrinter *printer, - GtkPageSetupUnixDialog *dialog); -static void printer_removed_cb (GtkPrintBackend *backend, - GtkPrinter *printer, - GtkPageSetupUnixDialog *dialog); -static void printer_status_cb (GtkPrintBackend *backend, - GtkPrinter *printer, - GtkPageSetupUnixDialog *dialog); -static void printer_changed_callback (GtkComboBox *combo_box, +static void printer_changed_callback (GtkDropDown *combo_box, + GParamSpec *pspec, GtkPageSetupUnixDialog *dialog); static void paper_size_changed (GtkDropDown *combo_box, GParamSpec *pspec, @@ -163,7 +150,6 @@ gtk_page_setup_unix_dialog_class_init (GtkPageSetupUnixDialogClass *class) gtk_widget_class_set_template_from_resource (widget_class, "/org/gtk/libgtk/ui/gtkpagesetupunixdialog.ui"); - gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, printer_list); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, printer_combo); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, paper_size_combo); gtk_widget_class_bind_template_child (widget_class, GtkPageSetupUnixDialog, paper_size_label); @@ -235,14 +221,56 @@ bind_paper_size_item (GtkSignalListItemFactory *factory, gtk_widget_remove_css_class (label, "separator-before"); } +static gboolean +match_func (gpointer item, gpointer user_data) +{ + return !gtk_printer_is_virtual (GTK_PRINTER (item)); +} + +static void +setup_printer_item (GtkSignalListItemFactory *factory, + GtkListItem *item) +{ + GtkWidget *label; + + label = gtk_label_new (""); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_label_set_xalign (GTK_LABEL (label), 0.0); + gtk_list_item_set_child (item, label); +} + +static void +bind_printer_item (GtkSignalListItemFactory *factory, + GtkListItem *item, + GtkPageSetupUnixDialog *self) +{ + GtkPrinter *printer; + GtkWidget *label; + const char *location; + const char *name; + char *str; + + printer = gtk_list_item_get_item (item); + label = gtk_list_item_get_child (item); + + name = gtk_printer_get_name (printer); + location = gtk_printer_get_location (printer); + str = g_strdup_printf ("%s\n%s", name, location ? location : ""); + gtk_label_set_markup (GTK_LABEL (label), str); + g_free (str); +} + static void gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) { - GtkTreeIter iter; - gchar *tmp; GtkListItemFactory *factory; GListStore *store; GListModel *paper_size_list; + GtkPrinter *printer; + GListStore *printer_list; + GListStore *printer_list_list; + GListModel *full_list; + GtkFilter *filter; GtkPageSetup *page_setup; dialog->print_backends = NULL; @@ -255,15 +283,6 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) NULL); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); - /* Do this in code, we want the translatable strings without the markup */ - gtk_list_store_append (dialog->printer_list, &iter); - tmp = g_strdup_printf ("%s\n%s", _("Any Printer"), _("For portable documents")); - gtk_list_store_set (dialog->printer_list, &iter, - PRINTER_LIST_COL_NAME, tmp, - PRINTER_LIST_COL_PRINTER, NULL, - -1); - g_free (tmp); - dialog->page_setup_list = g_list_store_new (GTK_TYPE_PAGE_SETUP); dialog->custom_paper_list = g_list_store_new (GTK_TYPE_PAGE_SETUP); dialog->manage_papers_list = g_list_store_new (GTK_TYPE_PAGE_SETUP); @@ -292,8 +311,31 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) g_object_unref (store); g_object_unref (paper_size_list); - /* After adding the above row, set it active */ - gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->printer_combo), 0); + /* Do this in code, we want the translatable strings without the markup */ + printer_list_list = g_list_store_new (G_TYPE_LIST_MODEL); + printer_list = g_list_store_new (GTK_TYPE_PRINTER); + printer = gtk_printer_new (_("Any Printer"), NULL, FALSE); + gtk_printer_set_location (printer, _("For portable documents")); + g_list_store_append (printer_list, printer); + g_object_unref (printer); + g_list_store_append (printer_list_list, printer_list); + g_object_unref (printer_list); + + full_list = G_LIST_MODEL (gtk_flatten_list_model_new (GTK_TYPE_PRINTER, G_LIST_MODEL (printer_list_list))); + + filter = gtk_custom_filter_new (match_func, NULL, NULL); + dialog->printer_list = G_LIST_MODEL (gtk_filter_list_model_new (full_list, filter)); + g_object_unref (full_list); + g_object_unref (filter); + + factory = gtk_signal_list_item_factory_new (); + g_signal_connect (factory, "setup", G_CALLBACK (setup_printer_item), dialog); + g_signal_connect (factory, "bind", G_CALLBACK (bind_printer_item), dialog); + gtk_drop_down_set_factory (GTK_DROP_DOWN (dialog->printer_combo), factory); + g_object_unref (factory); + + gtk_drop_down_set_model (GTK_DROP_DOWN (dialog->printer_combo), dialog->printer_list); + printer_changed_callback (GTK_DROP_DOWN (dialog->printer_combo), NULL, dialog); /* Load data */ gtk_print_load_custom_papers (dialog->custom_paper_list); @@ -304,7 +346,6 @@ static void gtk_page_setup_unix_dialog_finalize (GObject *object) { GtkPageSetupUnixDialog *dialog = GTK_PAGE_SETUP_UNIX_DIALOG (object); - GtkPrintBackend *backend; GList *node; if (dialog->request_details_tag) @@ -316,12 +357,7 @@ gtk_page_setup_unix_dialog_finalize (GObject *object) dialog->request_details_tag = 0; } - if (dialog->printer_list) - { - g_object_unref (dialog->printer_list); - dialog->printer_list = NULL; - } - + g_clear_object (&dialog->printer_list); g_clear_object (&dialog->page_setup_list); g_clear_object (&dialog->custom_paper_list); g_clear_object (&dialog->manage_papers_list); @@ -332,149 +368,32 @@ gtk_page_setup_unix_dialog_finalize (GObject *object) dialog->print_settings = NULL; } - g_free (dialog->waiting_for_printer); - dialog->waiting_for_printer = NULL; - for (node = dialog->print_backends; node != NULL; node = node->next) - { - backend = GTK_PRINT_BACKEND (node->data); - - g_signal_handlers_disconnect_by_func (backend, printer_added_cb, dialog); - g_signal_handlers_disconnect_by_func (backend, printer_removed_cb, dialog); - g_signal_handlers_disconnect_by_func (backend, printer_status_cb, dialog); - - gtk_print_backend_destroy (backend); - g_object_unref (backend); - } - - g_list_free (dialog->print_backends); + gtk_print_backend_destroy (GTK_PRINT_BACKEND (node->data)); + g_list_free_full (dialog->print_backends, g_object_unref); dialog->print_backends = NULL; G_OBJECT_CLASS (gtk_page_setup_unix_dialog_parent_class)->finalize (object); } -static void -printer_added_cb (GtkPrintBackend *backend, - GtkPrinter *printer, - GtkPageSetupUnixDialog *dialog) -{ - GtkTreeIter iter; - gchar *str; - const gchar *location; - - if (gtk_printer_is_virtual (printer)) - return; - - location = gtk_printer_get_location (printer); - if (location == NULL) - location = ""; - str = g_strdup_printf ("%s\n%s", - gtk_printer_get_name (printer), - location); - - gtk_list_store_append (dialog->printer_list, &iter); - gtk_list_store_set (dialog->printer_list, &iter, - PRINTER_LIST_COL_NAME, str, - PRINTER_LIST_COL_PRINTER, printer, - -1); - - g_object_set_data_full (G_OBJECT (printer), - "gtk-print-tree-iter", - gtk_tree_iter_copy (&iter), - (GDestroyNotify) gtk_tree_iter_free); - g_free (str); - - if (dialog->waiting_for_printer != NULL && - strcmp (dialog->waiting_for_printer, - gtk_printer_get_name (printer)) == 0) - { - gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->printer_combo), - &iter); - dialog->waiting_for_printer = NULL; - } -} - -static void -printer_removed_cb (GtkPrintBackend *backend, - GtkPrinter *printer, - GtkPageSetupUnixDialog *dialog) -{ - GtkTreeIter *iter; - - iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"); - gtk_list_store_remove (GTK_LIST_STORE (dialog->printer_list), iter); -} - - -static void -printer_status_cb (GtkPrintBackend *backend, - GtkPrinter *printer, - GtkPageSetupUnixDialog *dialog) -{ - GtkTreeIter *iter; - gchar *str; - const gchar *location; - - iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"); - - location = gtk_printer_get_location (printer); - if (location == NULL) - location = ""; - str = g_strdup_printf ("%s\n%s", - gtk_printer_get_name (printer), - location); - gtk_list_store_set (dialog->printer_list, iter, - PRINTER_LIST_COL_NAME, str, - -1); - g_free (str); -} - -static void -printer_list_initialize (GtkPageSetupUnixDialog *dialog, - GtkPrintBackend *print_backend) -{ - GList *list, *node; - - g_return_if_fail (print_backend != NULL); - - g_signal_connect_object (print_backend, - "printer-added", - (GCallback) printer_added_cb, - G_OBJECT (dialog), 0); - - g_signal_connect_object (print_backend, - "printer-removed", - (GCallback) printer_removed_cb, - G_OBJECT (dialog), 0); - - g_signal_connect_object (print_backend, - "printer-status-changed", - (GCallback) printer_status_cb, - G_OBJECT (dialog), 0); - - list = gtk_print_backend_get_printer_list (print_backend); - - node = list; - while (node != NULL) - { - printer_added_cb (print_backend, node->data, dialog); - node = node->next; - } - - g_list_free (list); - -} - static void load_print_backends (GtkPageSetupUnixDialog *dialog) { + GListModel *full_list; + GListStore *printer_list_list; GList *node; + full_list = gtk_filter_list_model_get_model (GTK_FILTER_LIST_MODEL (dialog->printer_list)); + printer_list_list = G_LIST_STORE (gtk_flatten_list_model_get_model (GTK_FLATTEN_LIST_MODEL (full_list))); + if (g_module_supported ()) dialog->print_backends = gtk_print_backend_load_modules (); for (node = dialog->print_backends; node != NULL; node = node->next) - printer_list_initialize (dialog, GTK_PRINT_BACKEND (node->data)); + { + GtkPrintBackend *backend = node->data; + g_list_store_append (printer_list_list, gtk_print_backend_get_printers (backend)); + } } static GtkPageSetup * @@ -554,29 +473,6 @@ set_paper_size (GtkPageSetupUnixDialog *dialog, return FALSE; } -static void -check_uniqueness (GtkPageSetupUnixDialog *dialog) -{ - GListModel *model; - guint i, j, n; - - model = gtk_drop_down_get_model (GTK_DROP_DOWN (dialog->paper_size_combo)); - n = g_list_model_get_n_items (model); - g_print ("checking %u\n", n); - for (i = 0; i < n; i++) - { - gpointer item1 = g_list_model_get_item (model, i); - for (j = i + 1; j < n; j++) - { - gpointer item2 = g_list_model_get_item (model, j); - if (item1 == item2) - g_critical ("same! %d %d\n", i, j); - g_object_unref (item2); - } - g_object_unref (item1); - } -} - static void fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, GtkPrinter *printer) @@ -586,7 +482,6 @@ fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, GtkPaperSize *paper_size; gint i; - check_uniqueness (dialog); g_list_store_remove_all (dialog->page_setup_list); if (printer == NULL) @@ -616,8 +511,6 @@ fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, g_list_free (list); } - check_uniqueness (dialog); - current_page_setup = NULL; /* When selecting a different printer, select its default paper size */ @@ -651,16 +544,12 @@ printer_changed_finished_callback (GtkPrinter *printer, } static void -printer_changed_callback (GtkComboBox *combo_box, +printer_changed_callback (GtkDropDown *combo_box, + GParamSpec *pspec, GtkPageSetupUnixDialog *dialog) { GtkPrinter *printer; - GtkTreeIter iter; - - /* If we're waiting for a specific printer but the user changed - * to another printer, cancel that wait. - */ - g_clear_pointer (&dialog->waiting_for_printer, g_free); + guint selected; if (dialog->request_details_tag) { @@ -671,12 +560,18 @@ printer_changed_callback (GtkComboBox *combo_box, dialog->request_details_tag = 0; } - if (gtk_combo_box_get_active_iter (combo_box, &iter)) + selected = gtk_drop_down_get_selected (GTK_DROP_DOWN (dialog->printer_combo)); + if (selected != GTK_INVALID_LIST_POSITION) { - gtk_tree_model_get (gtk_combo_box_get_model (combo_box), &iter, - PRINTER_LIST_COL_PRINTER, &printer, -1); + GListModel *model; - if (printer == NULL || gtk_printer_has_details (printer)) + model = gtk_drop_down_get_model (GTK_DROP_DOWN (dialog->printer_combo)); + printer = g_list_model_get_item (model, selected); + if (strcmp (gtk_printer_get_name (printer), _("Any Printer")) == 0) + g_clear_object (&printer); + + if (printer == NULL || + gtk_printer_has_details (printer)) fill_paper_sizes_from_printer (dialog, printer); else { @@ -685,7 +580,6 @@ printer_changed_callback (GtkComboBox *combo_box, g_signal_connect (printer, "details-acquired", G_CALLBACK (printer_changed_finished_callback), dialog); gtk_printer_request_details (printer); - } if (printer) @@ -751,7 +645,7 @@ custom_paper_dialog_response_cb (GtkDialog *custom_paper_dialog, gtk_print_load_custom_papers (dialog->custom_paper_list); /* Update printer page list */ - printer_changed_callback (GTK_COMBO_BOX (dialog->printer_combo), dialog); + printer_changed_callback (GTK_DROP_DOWN (dialog->printer_combo), NULL, dialog); gtk_window_destroy (GTK_WINDOW (custom_paper_dialog)); } @@ -1027,9 +921,7 @@ gtk_page_setup_unix_dialog_set_print_settings (GtkPageSetupUnixDialog *dialog, /* Set printer if in list, otherwise set when * that printer is added */ - if (format_for_printer && - !set_active_printer (dialog, format_for_printer)) - dialog->waiting_for_printer = g_strdup (format_for_printer); + set_active_printer (dialog, format_for_printer); } } diff --git a/gtk/ui/gtkpagesetupunixdialog.ui b/gtk/ui/gtkpagesetupunixdialog.ui index 1825498249..237e20b279 100644 --- a/gtk/ui/gtkpagesetupunixdialog.ui +++ b/gtk/ui/gtkpagesetupunixdialog.ui @@ -1,22 +1,5 @@ - - - - - - - - - - - - - - - - -