diff options
-rw-r--r-- | demos/gtk-demo/printing.c | 1 | ||||
-rw-r--r-- | docs/reference/gtk/gtk-sections.txt | 5 | ||||
-rw-r--r-- | gtk/Makefile.am | 2 | ||||
-rw-r--r-- | gtk/gtk.symbols | 5 | ||||
-rw-r--r-- | gtk/gtkcustompaperunixdialog.c | 1190 | ||||
-rw-r--r-- | gtk/gtkcustompaperunixdialog.h | 74 | ||||
-rw-r--r-- | gtk/gtkpagesetupunixdialog.c | 919 | ||||
-rw-r--r-- | gtk/gtkprintoperation-private.h | 1 | ||||
-rw-r--r-- | gtk/gtkprintoperation-unix.c | 17 | ||||
-rw-r--r-- | gtk/gtkprintoperation.c | 71 | ||||
-rw-r--r-- | gtk/gtkprintoperation.h | 3 | ||||
-rw-r--r-- | gtk/gtkprintunixdialog.c | 732 | ||||
-rw-r--r-- | gtk/gtkprintunixdialog.h | 42 |
13 files changed, 2135 insertions, 927 deletions
diff --git a/demos/gtk-demo/printing.c b/demos/gtk-demo/printing.c index a2d1647a82..07c7ab2838 100644 --- a/demos/gtk-demo/printing.c +++ b/demos/gtk-demo/printing.c @@ -166,6 +166,7 @@ do_printing (GtkWidget *do_widget) gtk_print_operation_set_use_full_page (operation, FALSE); gtk_print_operation_set_unit (operation, GTK_UNIT_POINTS); + gtk_print_operation_set_embed_page_setup (operation, TRUE); settings = gtk_print_settings_new (); dir = g_get_user_special_dir (G_USER_DIRECTORY_DOCUMENTS); diff --git a/docs/reference/gtk/gtk-sections.txt b/docs/reference/gtk/gtk-sections.txt index 24261f98dd..b5274ef4f7 100644 --- a/docs/reference/gtk/gtk-sections.txt +++ b/docs/reference/gtk/gtk-sections.txt @@ -6605,6 +6605,8 @@ gtk_print_operation_set_support_selection gtk_print_operation_get_support_selection gtk_print_operation_set_has_selection gtk_print_operation_get_has_selection +gtk_print_operation_set_embed_page_setup +gtk_print_operation_get_embed_page_setup gtk_print_run_page_setup_dialog GtkPageSetupDoneFunc gtk_print_run_page_setup_dialog_async @@ -6653,6 +6655,9 @@ gtk_print_unix_dialog_set_support_selection gtk_print_unix_dialog_get_support_selection gtk_print_unix_dialog_set_has_selection gtk_print_unix_dialog_get_has_selection +gtk_print_unix_dialog_set_embed_page_setup +gtk_print_unix_dialog_get_embed_page_setup +gtk_print_unix_dialog_get_page_setup_set GtkPrintCapabilities gtk_print_unix_dialog_set_manual_capabilities gtk_print_unix_dialog_get_manual_capabilities diff --git a/gtk/Makefile.am b/gtk/Makefile.am index 48b1f74ecf..62d5352eea 100644 --- a/gtk/Makefile.am +++ b/gtk/Makefile.am @@ -358,6 +358,7 @@ gtk_private_h_sources = \ gtkdndcursors.h \ gtkentryprivate.h \ gtkbuilderprivate.h \ + gtkcustompaperunixdialog.h\ gtkfilechooserdefault.h \ gtkfilechooserembed.h \ gtkfilechooserentry.h \ @@ -662,6 +663,7 @@ gtk_c_sources = $(gtk_base_c_sources) gtk_all_c_sources = $(gtk_base_c_sources) gtk_os_unix_c_sources = \ + gtkcustompaperunixdialog.c \ gtkpagesetupunixdialog.c \ gtkprinter.c \ gtkprinteroption.c \ diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index f523840006..6f411b2837 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -2998,6 +2998,8 @@ gtk_print_operation_set_support_selection gtk_print_operation_get_support_selection gtk_print_operation_set_has_selection gtk_print_operation_get_has_selection +gtk_print_operation_set_embed_page_setup +gtk_print_operation_get_embed_page_setup #endif #endif @@ -3127,6 +3129,9 @@ gtk_print_unix_dialog_set_support_selection gtk_print_unix_dialog_get_support_selection gtk_print_unix_dialog_set_has_selection gtk_print_unix_dialog_get_has_selection +gtk_print_unix_dialog_set_embed_page_setup +gtk_print_unix_dialog_get_embed_page_setup +gtk_print_unix_dialog_get_page_setup_set #endif #endif #endif diff --git a/gtk/gtkcustompaperunixdialog.c b/gtk/gtkcustompaperunixdialog.c new file mode 100644 index 0000000000..972ab1640b --- /dev/null +++ b/gtk/gtkcustompaperunixdialog.c @@ -0,0 +1,1190 @@ +/* GtkCustomPaperUnixDialog + * Copyright (C) 2006 Alexander Larsson <alexl@redhat.com> + * Copyright © 2006, 2007, 2008 Christian Persch + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + + +#include "config.h" +#include <string.h> +#include <locale.h> + +#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT +#include <langinfo.h> +#endif + +#include "gtkintl.h" +#include "gtkprivate.h" + +#include "gtkliststore.h" + +#include "gtktreeviewcolumn.h" +#include "gtklabel.h" +#include "gtkspinbutton.h" + +#include "gtkcustompaperunixdialog.h" +#include "gtkprintbackend.h" +#include "gtkprintutils.h" +#include "gtkprinter-private.h" +#include "gtkalias.h" + +#define CUSTOM_PAPER_FILENAME ".gtk-custom-papers" + + +typedef struct +{ + GtkUnit display_unit; + GtkWidget *spin_button; +} UnitWidget; + +struct GtkCustomPaperUnixDialogPrivate +{ + + GtkWidget *treeview; + GtkWidget *values_box; + GtkWidget *printer_combo; + GtkWidget *width_widget; + GtkWidget *height_widget; + GtkWidget *top_widget; + GtkWidget *bottom_widget; + GtkWidget *left_widget; + GtkWidget *right_widget; + + GtkTreeViewColumn *text_column; + + gulong printer_inserted_tag; + gulong printer_removed_tag; + + guint request_details_tag; + GtkPrinter *request_details_printer; + + guint non_user_change : 1; + + GtkListStore *custom_paper_list; + GtkListStore *printer_list; + + GList *print_backends; + + gchar *waiting_for_printer; +}; + +enum { + PRINTER_LIST_COL_NAME, + PRINTER_LIST_COL_PRINTER, + PRINTER_LIST_N_COLS +}; + +G_DEFINE_TYPE (GtkCustomPaperUnixDialog, gtk_custom_paper_unix_dialog, GTK_TYPE_DIALOG) + +#define GTK_CUSTOM_PAPER_UNIX_DIALOG_GET_PRIVATE(o) \ + (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialogPrivate)) + +static void gtk_custom_paper_unix_dialog_finalize (GObject *object); +static void populate_dialog (GtkCustomPaperUnixDialog *dialog); +static void printer_added_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog); +static void printer_removed_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog); +static void printer_status_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog); + + + +GtkUnit +_gtk_print_get_default_user_units (void) +{ + /* Translate to the default units to use for presenting + * lengths to the user. Translate to default:inch if you + * want inches, otherwise translate to default:mm. + * Do *not* translate it to "predefinito:mm", if it + * it isn't default:mm or default:inch it will not work + */ + gchar *e = _("default:mm"); + +#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT + gchar *imperial = NULL; + + imperial = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT); + if (imperial && imperial[0] == 2 ) + return GTK_UNIT_INCH; /* imperial */ + if (imperial && imperial[0] == 1 ) + return GTK_UNIT_MM; /* metric */ +#endif + + if (strcmp (e, "default:inch")==0) + return GTK_UNIT_INCH; + else if (strcmp (e, "default:mm")) + g_warning ("Whoever translated default:mm did so wrongly.\n"); + return GTK_UNIT_MM; +} + +static char * +custom_paper_get_filename (void) +{ + gchar *filename; + + filename = g_build_filename (g_get_home_dir (), + CUSTOM_PAPER_FILENAME, NULL); + g_assert (filename != NULL); + return filename; +} + +GList * +_gtk_load_custom_papers (void) +{ + GKeyFile *keyfile; + gchar *filename; + gchar **groups; + gsize n_groups, i; + gboolean load_ok; + GList *result = NULL; + + filename = custom_paper_get_filename (); + + keyfile = g_key_file_new (); + load_ok = g_key_file_load_from_file (keyfile, filename, 0, NULL); + g_free (filename); + if (!load_ok) + { + g_key_file_free (keyfile); + return NULL; + } + + groups = g_key_file_get_groups (keyfile, &n_groups); + for (i = 0; i < n_groups; ++i) + { + GtkPageSetup *page_setup; + + page_setup = gtk_page_setup_new_from_key_file (keyfile, groups[i], NULL); + if (!page_setup) + continue; + + result = g_list_prepend (result, page_setup); + } + + g_strfreev (groups); + g_key_file_free (keyfile); + + return g_list_reverse (result); +} + +void +_gtk_print_load_custom_papers (GtkListStore *store) +{ + GtkTreeIter iter; + GList *papers, *p; + GtkPageSetup *page_setup; + + gtk_list_store_clear (store); + + papers = _gtk_load_custom_papers (); + for (p = papers; p; p = p->next) + { + page_setup = p->data; + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, + 0, page_setup, + -1); + g_object_unref (page_setup); + } + + g_list_free (papers); +} + +void +_gtk_print_save_custom_papers (GtkListStore *store) +{ + GtkTreeModel *model = GTK_TREE_MODEL (store); + GtkTreeIter iter; + GKeyFile *keyfile; + gchar *filename, *data; + gsize len; + gint i = 0; + + keyfile = g_key_file_new (); + + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + GtkPageSetup *page_setup; + gchar group[32]; + + g_snprintf (group, sizeof (group), "Paper%u", i); + + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + gtk_page_setup_to_key_file (page_setup, keyfile, group); + + ++i; + } while (gtk_tree_model_iter_next (model, &iter)); + } + + filename = custom_paper_get_filename (); + data = g_key_file_to_data (keyfile, &len, NULL); + g_file_set_contents (filename, data, len, NULL); + g_free (data); + g_free (filename); +} + +static void +gtk_custom_paper_unix_dialog_class_init (GtkCustomPaperUnixDialogClass *class) +{ + GObjectClass *object_class; + GtkWidgetClass *widget_class; + + object_class = (GObjectClass *) class; + widget_class = (GtkWidgetClass *) class; + + object_class->finalize = gtk_custom_paper_unix_dialog_finalize; + + g_type_class_add_private (class, sizeof (GtkCustomPaperUnixDialogPrivate)); +} + +static void +custom_paper_dialog_response_cb (GtkDialog *dialog, + gint response, + gpointer user_data) +{ + GtkCustomPaperUnixDialogPrivate *priv = GTK_CUSTOM_PAPER_UNIX_DIALOG (dialog)->priv; + + _gtk_print_save_custom_papers (priv->custom_paper_list); +} + +static void +gtk_custom_paper_unix_dialog_init (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv; + GtkTreeIter iter; + + priv = dialog->priv = GTK_CUSTOM_PAPER_UNIX_DIALOG_GET_PRIVATE (dialog); + + priv->print_backends = NULL; + + priv->request_details_printer = NULL; + priv->request_details_tag = 0; + + priv->printer_list = gtk_list_store_new (PRINTER_LIST_N_COLS, + G_TYPE_STRING, + G_TYPE_OBJECT); + + gtk_list_store_append (priv->printer_list, &iter); + + priv->custom_paper_list = gtk_list_store_new (1, G_TYPE_OBJECT); + _gtk_print_load_custom_papers (priv->custom_paper_list); + + populate_dialog (dialog); + + gtk_dialog_add_buttons (GTK_DIALOG (dialog), + GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CLOSE); + + g_signal_connect (dialog, "response", G_CALLBACK (custom_paper_dialog_response_cb), NULL); +} + +static void +gtk_custom_paper_unix_dialog_finalize (GObject *object) +{ + GtkCustomPaperUnixDialog *dialog = GTK_CUSTOM_PAPER_UNIX_DIALOG (object); + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkPrintBackend *backend; + GList *node; + + if (priv->printer_list) + { + g_signal_handler_disconnect (priv->printer_list, priv->printer_inserted_tag); + g_signal_handler_disconnect (priv->printer_list, priv->printer_removed_tag); + g_object_unref (priv->printer_list); + priv->printer_list = NULL; + } + + if (priv->request_details_tag) + { + g_signal_handler_disconnect (priv->request_details_printer, + priv->request_details_tag); + g_object_unref (priv->request_details_printer); + priv->request_details_printer = NULL; + priv->request_details_tag = 0; + } + + if (priv->custom_paper_list) + { + g_object_unref (priv->custom_paper_list); + priv->custom_paper_list = NULL; + } + + g_free (priv->waiting_for_printer); + priv->waiting_for_printer = NULL; + + for (node = priv->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 (priv->print_backends); + priv->print_backends = NULL; + + G_OBJECT_CLASS (gtk_custom_paper_unix_dialog_parent_class)->finalize (object); +} + +/** + * gtk_custom_paper_unix_dialog_new: + * @title: the title of the dialog, or %NULL + * @parent: transient parent of the dialog, or %NULL + * + * Creates a new custom paper dialog. + * + * Returns: the new #GtkCustomPaperUnixDialog + * + * Since: 2.18 + */ +GtkWidget * +_gtk_custom_paper_unix_dialog_new (GtkWindow *parent, + const gchar *title) +{ + GtkWidget *result; + + if (title == NULL) + title = _("Manage Custom Sizes"); + + result = g_object_new (GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, + "title", title, + NULL); + + if (parent) + { + gtk_window_set_modal (GTK_WINDOW (result), TRUE); + gtk_window_set_transient_for (GTK_WINDOW (result), parent); + } + + return result; +} + +static void +printer_added_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + gchar *str; + + if (gtk_printer_is_virtual (printer)) + return; + + str = g_strdup_printf ("<b>%s</b>", + gtk_printer_get_name (printer)); + + gtk_list_store_append (priv->printer_list, &iter); + gtk_list_store_set (priv->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 (priv->waiting_for_printer != NULL && + strcmp (priv->waiting_for_printer, + gtk_printer_get_name (printer)) == 0) + { + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->printer_combo), + &iter); + priv->waiting_for_printer = NULL; + } +} + +static void +printer_removed_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter *iter; + + iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"); + gtk_list_store_remove (GTK_LIST_STORE (priv->printer_list), iter); +} + + +static void +printer_status_cb (GtkPrintBackend *backend, + GtkPrinter *printer, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter *iter; + gchar *str; + + iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter"); + + str = g_strdup_printf ("<b>%s</b>", + gtk_printer_get_name (printer)); + gtk_list_store_set (priv->printer_list, iter, + PRINTER_LIST_COL_NAME, str, + -1); + g_free (str); +} + +static void +printer_list_initialize (GtkCustomPaperUnixDialog *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 (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GList *node; + + if (g_module_supported ()) + priv->print_backends = gtk_print_backend_load_modules (); + + for (node = priv->print_backends; node != NULL; node = node->next) + printer_list_initialize (dialog, GTK_PRINT_BACKEND (node->data)); +} + +static void unit_widget_changed (GtkCustomPaperUnixDialog *dialog); + +static GtkWidget * +new_unit_widget (GtkCustomPaperUnixDialog *dialog, + GtkUnit unit, + GtkWidget *mnemonic_label) +{ + GtkWidget *hbox, *button, *label; + UnitWidget *data; + + data = g_new0 (UnitWidget, 1); + data->display_unit = unit; + + hbox = gtk_hbox_new (FALSE, 6); + + button = gtk_spin_button_new_with_range (0.0, 9999.0, 1); + if (unit == GTK_UNIT_INCH) + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 2); + else + gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 1); + + gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); + gtk_widget_show (button); + + data->spin_button = button; + + g_signal_connect_swapped (button, "value-changed", + G_CALLBACK (unit_widget_changed), dialog); + + if (unit == GTK_UNIT_INCH) + label = gtk_label_new (_("inch")); + else + label = gtk_label_new (_("mm")); + + gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); + gtk_widget_show (label); + gtk_label_set_mnemonic_widget (GTK_LABEL (mnemonic_label), button); + + g_object_set_data_full (G_OBJECT (hbox), "unit-data", data, g_free); + + return hbox; +} + +static double +unit_widget_get (GtkWidget *unit_widget) +{ + UnitWidget *data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); + return _gtk_print_convert_to_mm (gtk_spin_button_get_value (GTK_SPIN_BUTTON (data->spin_button)), + data->display_unit); +} + +static void +unit_widget_set (GtkWidget *unit_widget, + gdouble value) +{ + UnitWidget *data; + + data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (data->spin_button), + _gtk_print_convert_from_mm (value, data->display_unit)); +} + +static void +custom_paper_printer_data_func (GtkCellLayout *cell_layout, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkPrinter *printer; + + gtk_tree_model_get (tree_model, iter, + PRINTER_LIST_COL_PRINTER, &printer, -1); + + if (printer) + g_object_set (cell, "text", gtk_printer_get_name (printer), NULL); + else + g_object_set (cell, "text", _("Margins from Printer..."), NULL); + + if (printer) + g_object_unref (printer); +} + +static void +update_combo_sensitivity_from_printers (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + gboolean sensitive; + GtkTreeSelection *selection; + GtkTreeModel *model; + + sensitive = FALSE; + model = GTK_TREE_MODEL (priv->printer_list); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + if (gtk_tree_model_get_iter_first (model, &iter) && + gtk_tree_model_iter_next (model, &iter) && + gtk_tree_selection_get_selected (selection, NULL, &iter)) + sensitive = TRUE; + + gtk_widget_set_sensitive (priv->printer_combo, sensitive); +} + +static void +update_custom_widgets_from_list (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeSelection *selection; + GtkTreeModel *model; + GtkTreeIter iter; + GtkPageSetup *page_setup; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + + priv->non_user_change = TRUE; + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + unit_widget_set (priv->width_widget, + gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->height_widget, + gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->top_widget, + gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->bottom_widget, + gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->left_widget, + gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); + unit_widget_set (priv->right_widget, + gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); + + gtk_widget_set_sensitive (priv->values_box, TRUE); + } + else + { + gtk_widget_set_sensitive (priv->values_box, FALSE); + } + + if (priv->printer_list) + update_combo_sensitivity_from_printers (dialog); + priv->non_user_change = FALSE; +} + +static void +selected_custom_paper_changed (GtkTreeSelection *selection, + GtkCustomPaperUnixDialog *dialog) +{ + update_custom_widgets_from_list (dialog); +} + +static void +unit_widget_changed (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + gdouble w, h, top, bottom, left, right; + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + if (priv->non_user_change) + return; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + gtk_tree_model_get (GTK_TREE_MODEL (priv->custom_paper_list), &iter, 0, &page_setup, -1); + + w = unit_widget_get (priv->width_widget); + h = unit_widget_get (priv->height_widget); + + paper_size = gtk_page_setup_get_paper_size (page_setup); + gtk_paper_size_set_size (paper_size, w, h, GTK_UNIT_MM); + + top = unit_widget_get (priv->top_widget); + bottom = unit_widget_get (priv->bottom_widget); + left = unit_widget_get (priv->left_widget); + right = unit_widget_get (priv->right_widget); + + gtk_page_setup_set_top_margin (page_setup, top, GTK_UNIT_MM); + gtk_page_setup_set_bottom_margin (page_setup, bottom, GTK_UNIT_MM); + gtk_page_setup_set_left_margin (page_setup, left, GTK_UNIT_MM); + gtk_page_setup_set_right_margin (page_setup, right, GTK_UNIT_MM); + + g_object_unref (page_setup); + } +} + +static gboolean +custom_paper_name_used (GtkCustomPaperUnixDialog *dialog, + const gchar *name) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeModel *model; + GtkTreeIter iter; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->treeview)); + + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + paper_size = gtk_page_setup_get_paper_size (page_setup); + if (strcmp (name, + gtk_paper_size_get_name (paper_size)) == 0) + { + g_object_unref (page_setup); + return TRUE; + } + g_object_unref (page_setup); + } while (gtk_tree_model_iter_next (model, &iter)); + } + + return FALSE; +} + +static void +add_custom_paper (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkListStore *store; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + GtkTreeSelection *selection; + GtkTreePath *path; + GtkTreeIter iter; + gchar *name; + gint i; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + store = priv->custom_paper_list; + + i = 1; + name = NULL; + do + { + g_free (name); + name = g_strdup_printf (_("Custom Size %d"), i); + i++; + } while (custom_paper_name_used (dialog, name)); + + page_setup = gtk_page_setup_new (); + paper_size = gtk_paper_size_new_custom (name, name, + gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), + gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), + GTK_UNIT_MM); + gtk_page_setup_set_paper_size (page_setup, paper_size); + gtk_paper_size_free (paper_size); + + gtk_list_store_append (store, &iter); + gtk_list_store_set (store, &iter, 0, page_setup, -1); + g_object_unref (page_setup); + + gtk_tree_selection_select_iter (selection, &iter); + path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); + gtk_widget_grab_focus (priv->treeview); + gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->treeview), path, + priv->text_column, TRUE); + gtk_tree_path_free (path); + g_free (name); +} + +static void +remove_custom_paper (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeSelection *selection; + GtkTreeIter iter; + GtkListStore *store; + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->treeview)); + store = priv->custom_paper_list; + + if (gtk_tree_selection_get_selected (selection, NULL, &iter)) + { + GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); + gtk_list_store_remove (store, &iter); + + if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) + gtk_tree_selection_select_iter (selection, &iter); + else if (gtk_tree_path_prev (path) && gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) + gtk_tree_selection_select_iter (selection, &iter); + + gtk_tree_path_free (path); + } +} + +static void +set_margins_from_printer (GtkCustomPaperUnixDialog *dialog, + GtkPrinter *printer) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + gdouble top, bottom, left, right; + + top = bottom = left = right = 0; + _gtk_printer_get_hard_margins (printer, &top, &bottom, &left, &right); + + priv->non_user_change = TRUE; + unit_widget_set (priv->top_widget, _gtk_print_convert_to_mm (top, GTK_UNIT_POINTS)); + unit_widget_set (priv->bottom_widget, _gtk_print_convert_to_mm (bottom, GTK_UNIT_POINTS)); + unit_widget_set (priv->left_widget, _gtk_print_convert_to_mm (left, GTK_UNIT_POINTS)); + unit_widget_set (priv->right_widget, _gtk_print_convert_to_mm (right, GTK_UNIT_POINTS)); + priv->non_user_change = FALSE; + + /* Only send one change */ + unit_widget_changed (dialog); +} + +static void +get_margins_finished_callback (GtkPrinter *printer, + gboolean success, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + + g_signal_handler_disconnect (priv->request_details_printer, + priv->request_details_tag); + g_object_unref (priv->request_details_printer); + priv->request_details_tag = 0; + priv->request_details_printer = NULL; + + if (success) + set_margins_from_printer (dialog, printer); + + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->printer_combo), 0); +} + +static void +margins_from_printer_changed (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + GtkComboBox *combo; + GtkPrinter *printer; + + combo = GTK_COMBO_BOX (priv->printer_combo); + + if (priv->request_details_tag) + { + g_signal_handler_disconnect (priv->request_details_printer, + priv->request_details_tag); + g_object_unref (priv->request_details_printer); + priv->request_details_printer = NULL; + priv->request_details_tag = 0; + } + + if (gtk_combo_box_get_active_iter (combo, &iter)) + { + gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, + PRINTER_LIST_COL_PRINTER, &printer, -1); + + if (printer) + { + if (gtk_printer_has_details (printer)) + { + set_margins_from_printer (dialog, printer); + gtk_combo_box_set_active (combo, 0); + } + else + { + priv->request_details_printer = g_object_ref (printer); + priv->request_details_tag = + g_signal_connect (printer, "details-acquired", + G_CALLBACK (get_margins_finished_callback), dialog); + gtk_printer_request_details (printer); + } + + g_object_unref (printer); + } + } +} + +static void +custom_size_name_edited (GtkCellRenderer *cell, + gchar *path_string, + gchar *new_text, + GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkTreePath *path; + GtkTreeIter iter; + GtkListStore *store; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + store = priv->custom_paper_list; + path = gtk_tree_path_new_from_string (path_string); + gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path); + gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &page_setup, -1); + gtk_tree_path_free (path); + + paper_size = gtk_paper_size_new_custom (new_text, new_text, + gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), + gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), + GTK_UNIT_MM); + gtk_page_setup_set_paper_size (page_setup, paper_size); + gtk_paper_size_free (paper_size); + + g_object_unref (page_setup); +} + +static void +custom_name_func (GtkTreeViewColumn *tree_column, + GtkCellRenderer *cell, + GtkTreeModel *tree_model, + GtkTreeIter *iter, + gpointer data) +{ + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + + gtk_tree_model_get (tree_model, iter, 0, &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); + } +} + +static GtkWidget * +wrap_in_frame (const gchar *label, + GtkWidget *child) +{ + GtkWidget *frame, *alignment, *label_widget; + gchar *bold_text; + + label_widget = gtk_label_new (NULL); + gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); + gtk_widget_show (label_widget); + + bold_text = g_markup_printf_escaped ("<b>%s</b>", label); + gtk_label_set_markup (GTK_LABEL (label_widget), bold_text); + g_free (bold_text); + + frame = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (frame), label_widget, FALSE, FALSE, 0); + + alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); + gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), + 0, 0, 12, 0); + gtk_box_pack_start (GTK_BOX (frame), alignment, FALSE, FALSE, 0); + + gtk_container_add (GTK_CONTAINER (alignment), child); + + gtk_widget_show (frame); + gtk_widget_show (alignment); + + return frame; +} + +static void +populate_dialog (GtkCustomPaperUnixDialog *dialog) +{ + GtkCustomPaperUnixDialogPrivate *priv = dialog->priv; + GtkWidget *image, *table, *label, *widget, *frame, *combo; + GtkWidget *hbox, *vbox, *treeview, *scrolled, *button_box, *button; + GtkCellRenderer *cell; + GtkTreeViewColumn *column; + GtkTreeIter iter; + GtkTreeSelection *selection; + GtkUnit user_units; + + gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE); + gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->vbox), 2); /* 2 * 5 + 2 = 12 */ + gtk_container_set_border_width (GTK_CONTAINER (GTK_DIALOG (dialog)->action_area), 5); + gtk_box_set_spacing (GTK_BOX (GTK_DIALOG (dialog)->action_area), 6); + + hbox = gtk_hbox_new (FALSE, 18); + gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); + gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, TRUE, TRUE, 0); + gtk_widget_show (hbox); + + vbox = gtk_vbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show (vbox); + + scrolled = gtk_scrolled_window_new (NULL, NULL); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), + GTK_POLICY_AUTOMATIC, + GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), + GTK_SHADOW_IN); + gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0); + gtk_widget_show (scrolled); + + treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->custom_paper_list)); + priv->treeview = treeview; + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); + gtk_widget_set_size_request (treeview, 140, -1); + + selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); + gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); + g_signal_connect (selection, "changed", G_CALLBACK (selected_custom_paper_changed), dialog); + + cell = gtk_cell_renderer_text_new (); + g_object_set (cell, "editable", TRUE, NULL); + g_signal_connect (cell, "edited", + G_CALLBACK (custom_size_name_edited), dialog); + priv->text_column = column = + gtk_tree_view_column_new_with_attributes ("paper", cell, + NULL); + gtk_tree_view_column_set_cell_data_func (column, cell, custom_name_func, NULL, NULL); + + gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); + + gtk_container_add (GTK_CONTAINER (scrolled), treeview); + gtk_widget_show (treeview); + + button_box = gtk_hbox_new (FALSE, 6); + gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 0); + gtk_widget_show (button_box); + + button = gtk_button_new (); + image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_custom_paper), dialog); + + button = gtk_button_new (); + image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON); + gtk_widget_show (image); + gtk_container_add (GTK_CONTAINER (button), image); + gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); + gtk_widget_show (button); + + g_signal_connect_swapped (button, "clicked", G_CALLBACK (remove_custom_paper), dialog); + + user_units = _gtk_print_get_default_user_units (); + + vbox = gtk_vbox_new (FALSE, 18); + priv->values_box = vbox; + gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); + gtk_widget_show (vbox); + + table = gtk_table_new (2, 2, FALSE); + + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 12); + + label = gtk_label_new_with_mnemonic (_("_Width:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 0, 1, GTK_FILL, 0, 0, 0); + + widget = new_unit_widget (dialog, user_units, label); + priv->width_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 0, 1, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Height:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 1, 2, GTK_FILL, 0, 0, 0); + + widget = new_unit_widget (dialog, user_units, label); + priv->height_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 1, 2, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + frame = wrap_in_frame (_("Paper Size"), table); + gtk_widget_show (table); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + table = gtk_table_new (5, 2, FALSE); + gtk_table_set_row_spacings (GTK_TABLE (table), 6); + gtk_table_set_col_spacings (GTK_TABLE (table), 12); + + label = gtk_label_new_with_mnemonic (_("_Top:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 0, 1, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->top_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 0, 1, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Bottom:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1 , 1, 2, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->bottom_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 1, 2, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Left:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 2, 3, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->left_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 2, 3, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + label = gtk_label_new_with_mnemonic (_("_Right:")); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 3, 4, GTK_FILL, 0, 0, 0); + gtk_widget_show (label); + + widget = new_unit_widget (dialog, user_units, label); + priv->right_widget = widget; + gtk_table_attach (GTK_TABLE (table), widget, + 1, 2, 3, 4, GTK_FILL, 0, 0, 0); + gtk_widget_show (widget); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_table_attach (GTK_TABLE (table), hbox, + 0, 2, 4, 5, GTK_FILL | GTK_EXPAND, 0, 0, 0); + gtk_widget_show (hbox); + + combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (priv->printer_list)); + priv->printer_combo = combo; + + priv->printer_inserted_tag = + g_signal_connect_swapped (priv->printer_list, "row-inserted", + G_CALLBACK (update_combo_sensitivity_from_printers), dialog); + priv->printer_removed_tag = + g_signal_connect_swapped (priv->printer_list, "row-deleted", + G_CALLBACK (update_combo_sensitivity_from_printers), dialog); + update_combo_sensitivity_from_printers (dialog); + + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell, + custom_paper_printer_data_func, + NULL, NULL); + + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); + gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); + gtk_widget_show (combo); + + g_signal_connect_swapped (combo, "changed", + G_CALLBACK (margins_from_printer_changed), dialog); + + frame = wrap_in_frame (_("Paper Margins"), table); + gtk_widget_show (table); + gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); + gtk_widget_show (frame); + + update_custom_widgets_from_list (dialog); + + /* If no custom sizes, add one */ + if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->custom_paper_list), + &iter)) + { + /* Need to realize treeview so we can start the rename */ + gtk_widget_realize (treeview); + add_custom_paper (dialog); + } + + gtk_window_present (GTK_WINDOW (dialog)); + + load_print_backends (dialog); +} + + +#define __GTK_CUSTOM_PAPER_UNIX_DIALOG_C__ +#include "gtkaliasdef.c" diff --git a/gtk/gtkcustompaperunixdialog.h b/gtk/gtkcustompaperunixdialog.h new file mode 100644 index 0000000000..f1d6ae63b7 --- /dev/null +++ b/gtk/gtkcustompaperunixdialog.h @@ -0,0 +1,74 @@ +/* GtkCustomPaperUnixDialog + * Copyright (C) 2006 Alexander Larsson <alexl@redhat.com> + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#if defined(GTK_DISABLE_SINGLE_INCLUDES) && !defined (__GTK_UNIX_PRINT_H_INSIDE__) && !defined (GTK_COMPILATION) +#error "Only <gtk/gtkunixprint.h> can be included directly." +#endif + +#ifndef __GTK_CUSTOM_PAPER_UNIX_DIALOG_H__ +#define __GTK_CUSTOM_PAPER_UNIX_DIALOG_H__ + +#include <gtk/gtk.h> + +G_BEGIN_DECLS + +#define GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG (gtk_custom_paper_unix_dialog_get_type ()) +#define GTK_CUSTOM_PAPER_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialog)) +#define GTK_CUSTOM_PAPER_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialogClass)) +#define GTK_IS_CUSTOM_PAPER_UNIX_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG)) +#define GTK_IS_CUSTOM_PAPER_UNIX_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG)) +#define GTK_CUSTOM_PAPER_UNIX_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_CUSTOM_PAPER_UNIX_DIALOG, GtkCustomPaperUnixDialogClass)) + + +typedef struct _GtkCustomPaperUnixDialog GtkCustomPaperUnixDialog; +typedef struct _GtkCustomPaperUnixDialogClass GtkCustomPaperUnixDialogClass; +typedef struct GtkCustomPaperUnixDialogPrivate GtkCustomPaperUnixDialogPrivate; + +struct _GtkCustomPaperUnixDialog +{ + GtkDialog parent_instance; + + GtkCustomPaperUnixDialogPrivate *GSEAL (priv); +}; + +struct _GtkCustomPaperUnixDialogClass +{ + GtkDialogClass parent_class; + + /* Padding for future expansion */ + void (*_gtk_reserved1) (void); + void (*_gtk_reserved2) (void); + void (*_gtk_reserved3) (void); + void (*_gtk_reserved4) (void); + void (*_gtk_reserved5) (void); + void (*_gtk_reserved6) (void); + void (*_gtk_reserved7) (void); +}; + +GType gtk_custom_paper_unix_dialog_get_type (void) G_GNUC_CONST; +GtkWidget * _gtk_custom_paper_unix_dialog_new (GtkWindow *parent, + const gchar *title); +GtkUnit _gtk_print_get_default_user_units (void); +void _gtk_print_load_custom_papers (GtkListStore *store); +void _gtk_print_save_custom_papers (GtkListStore *store); + + +G_END_DECLS + +#endif /* __GTK_CUSTOM_PAPER_UNIX_DIALOG_H__ */ diff --git a/gtk/gtkpagesetupunixdialog.c b/gtk/gtkpagesetupunixdialog.c index 8d9cbc787e..0fae189579 100644 --- a/gtk/gtkpagesetupunixdialog.c +++ b/gtk/gtkpagesetupunixdialog.c @@ -23,10 +23,6 @@ #include <string.h> #include <locale.h> -#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT -#include <langinfo.h> -#endif - #include "gtkintl.h" #include "gtkprivate.h" @@ -54,14 +50,13 @@ #include "gtkhbbox.h" #include "gtkpagesetupunixdialog.h" +#include "gtkcustompaperunixdialog.h" #include "gtkprintbackend.h" #include "gtkprinter-private.h" #include "gtkpapersize.h" #include "gtkprintutils.h" #include "gtkalias.h" -#define CUSTOM_PAPER_FILENAME ".gtk-custom-papers" - struct GtkPageSetupUnixDialogPrivate { @@ -112,7 +107,6 @@ static void gtk_page_setup_unix_dialog_finalize (GObject *object static void populate_dialog (GtkPageSetupUnixDialog *dialog); static void fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog, GtkPrinter *printer); -static void show_custom_paper_dialog (GtkPageSetupUnixDialog *dialog); static void printer_added_cb (GtkPrintBackend *backend, GtkPrinter *printer, GtkPageSetupUnixDialog *dialog); @@ -140,140 +134,6 @@ static const gchar const common_paper_sizes[][16] = { "iso_a3", }; -static GtkUnit -get_default_user_units (void) -{ - /* Translate to the default units to use for presenting - * lengths to the user. Translate to default:inch if you - * want inches, otherwise translate to default:mm. - * Do *not* translate it to "predefinito:mm", if it - * it isn't default:mm or default:inch it will not work - */ - gchar *e = _("default:mm"); - -#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT - gchar *imperial = NULL; - - imperial = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT); - if (imperial && imperial[0] == 2 ) - return GTK_UNIT_INCH; /* imperial */ - if (imperial && imperial[0] == 1 ) - return GTK_UNIT_MM; /* metric */ -#endif - - if (strcmp (e, "default:inch")==0) - return GTK_UNIT_INCH; - else if (strcmp (e, "default:mm")) - g_warning ("Whoever translated default:mm did so wrongly.\n"); - return GTK_UNIT_MM; -} - -static char * -custom_paper_get_filename (void) -{ - gchar *filename; - - filename = g_build_filename (g_get_home_dir (), - CUSTOM_PAPER_FILENAME, NULL); - g_assert (filename != NULL); - return filename; -} - -GList * -_gtk_load_custom_papers (void) -{ - GKeyFile *keyfile; - gchar *filename; - gchar **groups; - gsize n_groups, i; - gboolean load_ok; - GList *result = NULL; - - filename = custom_paper_get_filename (); - - keyfile = g_key_file_new (); - load_ok = g_key_file_load_from_file (keyfile, filename, 0, NULL); - g_free (filename); - if (!load_ok) - { - g_key_file_free (keyfile); - return NULL; - } - - groups = g_key_file_get_groups (keyfile, &n_groups); - for (i = 0; i < n_groups; ++i) - { - GtkPageSetup *page_setup; - - page_setup = gtk_page_setup_new_from_key_file (keyfile, groups[i], NULL); - if (!page_setup) - continue; - - result = g_list_prepend (result, page_setup); - } - - g_strfreev (groups); - g_key_file_free (keyfile); - - return g_list_reverse (result); -} - -static void -load_custom_papers (GtkListStore *store) -{ - GtkTreeIter iter; - GList *papers, *p; - GtkPageSetup *page_setup; - - papers = _gtk_load_custom_papers (); - for (p = papers; p; p = p->next) - { - page_setup = p->data; - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, - 0, page_setup, - -1); - g_object_unref (page_setup); - } - - g_list_free (papers); -} - -static void -save_custom_papers (GtkListStore *store) -{ - GtkTreeModel *model = GTK_TREE_MODEL (store); - GtkTreeIter iter; - GKeyFile *keyfile; - gchar *filename, *data; - gsize len; - gint i = 0; - - keyfile = g_key_file_new (); - - if (gtk_tree_model_get_iter_first (model, &iter)) - { - do - { - GtkPageSetup *page_setup; - gchar group[32]; - - g_snprintf (group, sizeof (group), "Paper%u", i); - - gtk_tree_model_get (model, &iter, 0, &page_setup, -1); - - gtk_page_setup_to_key_file (page_setup, keyfile, group); - - ++i; - } while (gtk_tree_model_iter_next (model, &iter)); - } - - filename = custom_paper_get_filename (); - data = g_key_file_to_data (keyfile, &len, NULL); - g_file_set_contents (filename, data, len, NULL); - g_free (data); - g_free (filename); -} static void gtk_page_setup_unix_dialog_class_init (GtkPageSetupUnixDialogClass *class) @@ -314,7 +174,7 @@ gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog) G_TYPE_BOOLEAN); priv->custom_paper_list = gtk_list_store_new (1, G_TYPE_OBJECT); - load_custom_papers (priv->custom_paper_list); + _gtk_print_load_custom_papers (priv->custom_paper_list); populate_dialog (dialog); @@ -847,6 +707,23 @@ double_to_string (gdouble d, return val; } + +static void +custom_paper_dialog_response_cb (GtkDialog *custom_paper_dialog, + gint response_id, + gpointer user_data) +{ + GtkPageSetupUnixDialog *page_setup_dialog = GTK_PAGE_SETUP_UNIX_DIALOG (user_data); + GtkPageSetupUnixDialogPrivate *priv = page_setup_dialog->priv; + + _gtk_print_load_custom_papers (priv->custom_paper_list); + + /* Update printer page list */ + printer_changed_callback (GTK_COMBO_BOX (priv->printer_combo), page_setup_dialog); + + gtk_widget_destroy (GTK_WIDGET (custom_paper_dialog)); +} + static void paper_size_changed (GtkComboBox *combo_box, GtkPageSetupUnixDialog *dialog) @@ -869,6 +746,8 @@ paper_size_changed (GtkComboBox *combo_box, if (page_setup == NULL) { + GtkWidget *custom_paper_dialog; + /* Change from "manage" menu item to last value */ if (priv->last_setup) last_page_setup = g_object_ref (priv->last_setup); @@ -878,7 +757,9 @@ paper_size_changed (GtkComboBox *combo_box, g_object_unref (last_page_setup); /* And show the custom paper dialog */ - show_custom_paper_dialog (dialog); + custom_paper_dialog = _gtk_custom_paper_unix_dialog_new (GTK_WINDOW (dialog), NULL); + g_signal_connect (custom_paper_dialog, "response", G_CALLBACK (custom_paper_dialog_response_cb), dialog); + gtk_window_present (GTK_WINDOW (custom_paper_dialog)); return; } @@ -888,7 +769,7 @@ paper_size_changed (GtkComboBox *combo_box, priv->last_setup = g_object_ref (page_setup); - unit = get_default_user_units (); + unit = _gtk_print_get_default_user_units (); if (unit == GTK_UNIT_MM) unit_str = _("mm"); @@ -1311,755 +1192,5 @@ gtk_page_setup_unix_dialog_get_print_settings (GtkPageSetupUnixDialog *dialog) return priv->print_settings; } -static GtkWidget * -wrap_in_frame (const gchar *label, - GtkWidget *child) -{ - GtkWidget *frame, *alignment, *label_widget; - gchar *bold_text; - - label_widget = gtk_label_new (NULL); - gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5); - gtk_widget_show (label_widget); - - bold_text = g_markup_printf_escaped ("<b>%s</b>", label); - gtk_label_set_markup (GTK_LABEL (label_widget), bold_text); - g_free (bold_text); - - frame = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (frame), label_widget, FALSE, FALSE, 0); - - alignment = gtk_alignment_new (0.0, 0.0, 1.0, 1.0); - gtk_alignment_set_padding (GTK_ALIGNMENT (alignment), - 0, 0, 12, 0); - gtk_box_pack_start (GTK_BOX (frame), alignment, FALSE, FALSE, 0); - - gtk_container_add (GTK_CONTAINER (alignment), child); - - gtk_widget_show (frame); - gtk_widget_show (alignment); - - return frame; -} - -typedef struct -{ - GtkUnit display_unit; - GtkWidget *spin_button; -} UnitWidget; - -typedef struct -{ - GtkPageSetupUnixDialog *dialog; - GtkWidget *treeview; - GtkTreeViewColumn *text_column; - GtkWidget *values_box; - GtkWidget *printer_combo; - GtkWidget *width_widget; - GtkWidget *height_widget; - GtkWidget *top_widget; - GtkWidget *bottom_widget; - GtkWidget *left_widget; - GtkWidget *right_widget; - gulong printer_inserted_tag; - gulong printer_removed_tag; - guint request_details_tag; - GtkPrinter *request_details_printer; - guint non_user_change : 1; -} CustomPaperDialog; - -static void unit_widget_changed (CustomPaperDialog *data); - -static GtkWidget * -new_unit_widget (CustomPaperDialog *dialog, - GtkUnit unit, - GtkWidget *mnemonic_label) -{ - GtkWidget *hbox, *button, *label; - UnitWidget *data; - - data = g_new0 (UnitWidget, 1); - data->display_unit = unit; - - hbox = gtk_hbox_new (FALSE, 6); - - button = gtk_spin_button_new_with_range (0.0, 9999.0, 1); - if (unit == GTK_UNIT_INCH) - gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 2); - else - gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 1); - - gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0); - gtk_widget_show (button); - - data->spin_button = button; - - g_signal_connect_swapped (button, "value-changed", - G_CALLBACK (unit_widget_changed), dialog); - - if (unit == GTK_UNIT_INCH) - label = gtk_label_new (_("inch")); - else - label = gtk_label_new (_("mm")); - - gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); - gtk_widget_show (label); - gtk_label_set_mnemonic_widget (GTK_LABEL (mnemonic_label), button); - - g_object_set_data_full (G_OBJECT (hbox), "unit-data", data, g_free); - - return hbox; -} - -static double -unit_widget_get (GtkWidget *unit_widget) -{ - UnitWidget *data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); - return _gtk_print_convert_to_mm (gtk_spin_button_get_value (GTK_SPIN_BUTTON (data->spin_button)), - data->display_unit); -} - -static void -unit_widget_set (GtkWidget *unit_widget, - gdouble value) -{ - UnitWidget *data; - - data = g_object_get_data (G_OBJECT (unit_widget), "unit-data"); - gtk_spin_button_set_value (GTK_SPIN_BUTTON (data->spin_button), - _gtk_print_convert_from_mm (value, data->display_unit)); -} - -static void -custom_paper_printer_data_func (GtkCellLayout *cell_layout, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkPrinter *printer; - - gtk_tree_model_get (tree_model, iter, - PRINTER_LIST_COL_PRINTER, &printer, -1); - - if (printer) - g_object_set (cell, "text", gtk_printer_get_name (printer), NULL); - else - g_object_set (cell, "text", _("Margins from Printer..."), NULL); - - if (printer) - g_object_unref (printer); -} - -static void -update_combo_sensitivity_from_printers (CustomPaperDialog *data) -{ - GtkTreeIter iter; - gboolean sensitive; - GtkTreeSelection *selection; - GtkTreeModel *model; - - sensitive = FALSE; - model = GTK_TREE_MODEL (data->dialog->priv->printer_list); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - if (gtk_tree_model_get_iter_first (model, &iter) && - gtk_tree_model_iter_next (model, &iter) && - gtk_tree_selection_get_selected (selection, NULL, &iter)) - sensitive = TRUE; - - gtk_widget_set_sensitive (data->printer_combo, sensitive); -} - -static void -update_custom_widgets_from_list (CustomPaperDialog *data) -{ - GtkTreeSelection *selection; - GtkTreeModel *model; - GtkTreeIter iter; - GtkPageSetup *page_setup; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->treeview)); - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - - data->non_user_change = TRUE; - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - gtk_tree_model_get (model, &iter, 0, &page_setup, -1); - - unit_widget_set (data->width_widget, - gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->height_widget, - gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->top_widget, - gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->bottom_widget, - gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->left_widget, - gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM)); - unit_widget_set (data->right_widget, - gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM)); - - gtk_widget_set_sensitive (data->values_box, TRUE); - } - else - { - gtk_widget_set_sensitive (data->values_box, FALSE); - } - - update_combo_sensitivity_from_printers (data); - data->non_user_change = FALSE; -} - -static void -selected_custom_paper_changed (GtkTreeSelection *selection, - CustomPaperDialog *data) -{ - update_custom_widgets_from_list (data); -} - -static void -unit_widget_changed (CustomPaperDialog *data) -{ - gdouble w, h, top, bottom, left, right; - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - if (data->non_user_change) - return; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - gtk_tree_model_get (GTK_TREE_MODEL (data->dialog->priv->custom_paper_list), &iter, 0, &page_setup, -1); - - w = unit_widget_get (data->width_widget); - h = unit_widget_get (data->height_widget); - - paper_size = gtk_page_setup_get_paper_size (page_setup); - gtk_paper_size_set_size (paper_size, w, h, GTK_UNIT_MM); - - top = unit_widget_get (data->top_widget); - bottom = unit_widget_get (data->bottom_widget); - left = unit_widget_get (data->left_widget); - right = unit_widget_get (data->right_widget); - - gtk_page_setup_set_top_margin (page_setup, top, GTK_UNIT_MM); - gtk_page_setup_set_bottom_margin (page_setup, bottom, GTK_UNIT_MM); - gtk_page_setup_set_left_margin (page_setup, left, GTK_UNIT_MM); - gtk_page_setup_set_right_margin (page_setup, right, GTK_UNIT_MM); - - g_object_unref (page_setup); - } -} - -static gboolean -custom_paper_name_used (CustomPaperDialog *data, - const gchar *name) -{ - GtkTreeModel *model; - GtkTreeIter iter; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->treeview)); - - if (gtk_tree_model_get_iter_first (model, &iter)) - { - do - { - gtk_tree_model_get (model, &iter, 0, &page_setup, -1); - paper_size = gtk_page_setup_get_paper_size (page_setup); - if (strcmp (name, - gtk_paper_size_get_name (paper_size)) == 0) - { - g_object_unref (page_setup); - return TRUE; - } - g_object_unref (page_setup); - } while (gtk_tree_model_iter_next (model, &iter)); - } - - return FALSE; -} - -static void -add_custom_paper (CustomPaperDialog *data) -{ - GtkListStore *store; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - GtkTreeSelection *selection; - GtkTreePath *path; - GtkTreeIter iter; - gchar *name; - gint i; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - store = data->dialog->priv->custom_paper_list; - - i = 1; - name = NULL; - do - { - g_free (name); - name = g_strdup_printf (_("Custom Size %d"), i); - i++; - } while (custom_paper_name_used (data, name)); - - page_setup = gtk_page_setup_new (); - paper_size = gtk_paper_size_new_custom (name, name, - gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), - gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), - GTK_UNIT_MM); - gtk_page_setup_set_paper_size (page_setup, paper_size); - gtk_paper_size_free (paper_size); - - gtk_list_store_append (store, &iter); - gtk_list_store_set (store, &iter, 0, page_setup, -1); - g_object_unref (page_setup); - - gtk_tree_selection_select_iter (selection, &iter); - path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); - gtk_widget_grab_focus (data->treeview); - gtk_tree_view_set_cursor (GTK_TREE_VIEW (data->treeview), path, - data->text_column, TRUE); - gtk_tree_path_free (path); - g_free (name); -} - -static void -remove_custom_paper (CustomPaperDialog *data) -{ - GtkTreeSelection *selection; - GtkTreeIter iter; - GtkListStore *store; - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview)); - store = data->dialog->priv->custom_paper_list; - - if (gtk_tree_selection_get_selected (selection, NULL, &iter)) - { - GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter); - gtk_list_store_remove (store, &iter); - - if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) - gtk_tree_selection_select_iter (selection, &iter); - else if (gtk_tree_path_prev (path) && gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path)) - gtk_tree_selection_select_iter (selection, &iter); - - gtk_tree_path_free (path); - } -} - -static void -set_margins_from_printer (CustomPaperDialog *data, - GtkPrinter *printer) -{ - gdouble top, bottom, left, right; - - top = bottom = left = right = 0; - _gtk_printer_get_hard_margins (printer, &top, &bottom, &left, &right); - - data->non_user_change = TRUE; - unit_widget_set (data->top_widget, _gtk_print_convert_to_mm (top, GTK_UNIT_POINTS)); - unit_widget_set (data->bottom_widget, _gtk_print_convert_to_mm (bottom, GTK_UNIT_POINTS)); - unit_widget_set (data->left_widget, _gtk_print_convert_to_mm (left, GTK_UNIT_POINTS)); - unit_widget_set (data->right_widget, _gtk_print_convert_to_mm (right, GTK_UNIT_POINTS)); - data->non_user_change = FALSE; - - /* Only send one change */ - unit_widget_changed (data); -} - -static void -get_margins_finished_callback (GtkPrinter *printer, - gboolean success, - CustomPaperDialog *data) -{ - g_signal_handler_disconnect (data->request_details_printer, - data->request_details_tag); - g_object_unref (data->request_details_printer); - data->request_details_tag = 0; - data->request_details_printer = NULL; - - if (success) - set_margins_from_printer (data, printer); - - gtk_combo_box_set_active (GTK_COMBO_BOX (data->printer_combo), 0); -} - -static void -margins_from_printer_changed (CustomPaperDialog *data) -{ - GtkTreeIter iter; - GtkComboBox *combo; - GtkPrinter *printer; - - combo = GTK_COMBO_BOX (data->printer_combo); - - if (data->request_details_tag) - { - g_signal_handler_disconnect (data->request_details_printer, - data->request_details_tag); - g_object_unref (data->request_details_printer); - data->request_details_printer = NULL; - data->request_details_tag = 0; - } - - if (gtk_combo_box_get_active_iter (combo, &iter)) - { - gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter, - PRINTER_LIST_COL_PRINTER, &printer, -1); - - if (printer) - { - if (gtk_printer_has_details (printer)) - { - set_margins_from_printer (data, printer); - gtk_combo_box_set_active (combo, 0); - } - else - { - data->request_details_printer = g_object_ref (printer); - data->request_details_tag = - g_signal_connect (printer, "details-acquired", - G_CALLBACK (get_margins_finished_callback), data); - gtk_printer_request_details (printer); - } - - g_object_unref (printer); - } - } -} - - -static void -custom_paper_dialog_free (gpointer p) -{ - CustomPaperDialog *data = p; - GtkPageSetupUnixDialogPrivate *priv = data->dialog->priv; - - g_signal_handler_disconnect (priv->printer_list, data->printer_inserted_tag); - g_signal_handler_disconnect (priv->printer_list, data->printer_removed_tag); - - if (data->request_details_tag) - { - g_signal_handler_disconnect (data->request_details_printer, - data->request_details_tag); - g_object_unref (data->request_details_printer); - data->request_details_printer = NULL; - data->request_details_tag = 0; - } - - g_free (data); -} - -static void -custom_size_name_edited (GtkCellRenderer *cell, - gchar *path_string, - gchar *new_text, - CustomPaperDialog *data) -{ - GtkTreePath *path; - GtkTreeIter iter; - GtkListStore *store; - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - store = data->dialog->priv->custom_paper_list; - path = gtk_tree_path_new_from_string (path_string); - gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path); - gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &page_setup, -1); - gtk_tree_path_free (path); - - paper_size = gtk_paper_size_new_custom (new_text, new_text, - gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM), - gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM), - GTK_UNIT_MM); - gtk_page_setup_set_paper_size (page_setup, paper_size); - gtk_paper_size_free (paper_size); - - g_object_unref (page_setup); -} - -static void -custom_name_func (GtkTreeViewColumn *tree_column, - GtkCellRenderer *cell, - GtkTreeModel *tree_model, - GtkTreeIter *iter, - gpointer data) -{ - GtkPageSetup *page_setup; - GtkPaperSize *paper_size; - - gtk_tree_model_get (tree_model, iter, 0, &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); - } -} - -static void -custom_paper_dialog_response_cb (GtkWidget *custom_dialog, - gint response, - CustomPaperDialog *data) -{ - GtkPageSetupUnixDialog *dialog = data->dialog; - GtkPageSetupUnixDialogPrivate *priv = dialog->priv; - - save_custom_papers (priv->custom_paper_list); - - /* Update printer page list */ - printer_changed_callback (GTK_COMBO_BOX (priv->printer_combo), dialog); - - gtk_widget_destroy (custom_dialog); -} - -static void -show_custom_paper_dialog (GtkPageSetupUnixDialog *ps_dialog) -{ - GtkPageSetupUnixDialogPrivate *priv = ps_dialog->priv; - GtkWidget *custom_dialog, *image, *table, *label, *widget, *frame, *combo; - GtkWidget *hbox, *vbox, *treeview, *scrolled, *button_box, *button; - GtkDialog *dialog; - GtkCellRenderer *cell; - GtkTreeViewColumn *column; - GtkTreeIter iter; - GtkTreeSelection *selection; - CustomPaperDialog *data; - GtkUnit user_units; - - custom_dialog = gtk_dialog_new_with_buttons (_("Manage Custom Sizes"), - GTK_WINDOW (ps_dialog), - GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR, - GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE, - NULL); - - dialog = GTK_DIALOG (custom_dialog); - - data = g_new0 (CustomPaperDialog, 1); - data->dialog = ps_dialog; - g_object_set_data_full (G_OBJECT (custom_dialog), "custom-dialog", data, - custom_paper_dialog_free); - g_signal_connect (dialog, "response", - G_CALLBACK (custom_paper_dialog_response_cb), data); - - gtk_dialog_set_has_separator (dialog, FALSE); - gtk_container_set_border_width (GTK_CONTAINER (dialog), 5); - gtk_box_set_spacing (GTK_BOX (dialog->vbox), 2); /* 2 * 5 + 2 = 12 */ - gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5); - gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6); - - hbox = gtk_hbox_new (FALSE, 18); - gtk_container_set_border_width (GTK_CONTAINER (hbox), 5); - gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0); - gtk_widget_show (hbox); - - vbox = gtk_vbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - scrolled = gtk_scrolled_window_new (NULL, NULL); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), - GTK_POLICY_AUTOMATIC, - GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled), - GTK_SHADOW_IN); - gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0); - gtk_widget_show (scrolled); - - treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (priv->custom_paper_list)); - data->treeview = treeview; - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); - gtk_widget_set_size_request (treeview, 140, -1); - - selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview)); - gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE); - g_signal_connect (selection, "changed", G_CALLBACK (selected_custom_paper_changed), data); - - cell = gtk_cell_renderer_text_new (); - g_object_set (cell, "editable", TRUE, NULL); - g_signal_connect (cell, "edited", - G_CALLBACK (custom_size_name_edited), data); - data->text_column = column = - gtk_tree_view_column_new_with_attributes ("paper", cell, - NULL); - gtk_tree_view_column_set_cell_data_func (column, cell, custom_name_func, NULL, NULL); - - gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); - - gtk_container_add (GTK_CONTAINER (scrolled), treeview); - gtk_widget_show (treeview); - - button_box = gtk_hbox_new (FALSE, 6); - gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 0); - gtk_widget_show (button_box); - - button = gtk_button_new (); - image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (image); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_custom_paper), data); - - button = gtk_button_new (); - image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON); - gtk_widget_show (image); - gtk_container_add (GTK_CONTAINER (button), image); - gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0); - gtk_widget_show (button); - - g_signal_connect_swapped (button, "clicked", G_CALLBACK (remove_custom_paper), data); - - user_units = get_default_user_units (); - - vbox = gtk_vbox_new (FALSE, 18); - data->values_box = vbox; - gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0); - gtk_widget_show (vbox); - - table = gtk_table_new (2, 2, FALSE); - - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - - label = gtk_label_new_with_mnemonic (_("_Width:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - - widget = new_unit_widget (data, user_units, label); - data->width_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Height:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_widget_show (label); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 1, 2, GTK_FILL, 0, 0, 0); - - widget = new_unit_widget (data, user_units, label); - data->height_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - frame = wrap_in_frame (_("Paper Size"), table); - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - - table = gtk_table_new (5, 2, FALSE); - gtk_table_set_row_spacings (GTK_TABLE (table), 6); - gtk_table_set_col_spacings (GTK_TABLE (table), 12); - - label = gtk_label_new_with_mnemonic (_("_Top:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->top_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 0, 1, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Bottom:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1 , 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->bottom_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 1, 2, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Left:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 2, 3, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->left_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 2, 3, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - label = gtk_label_new_with_mnemonic (_("_Right:")); - gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); - gtk_table_attach (GTK_TABLE (table), label, - 0, 1, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (label); - - widget = new_unit_widget (data, user_units, label); - data->right_widget = widget; - gtk_table_attach (GTK_TABLE (table), widget, - 1, 2, 3, 4, GTK_FILL, 0, 0, 0); - gtk_widget_show (widget); - - hbox = gtk_hbox_new (FALSE, 0); - gtk_table_attach (GTK_TABLE (table), hbox, - 0, 2, 4, 5, GTK_FILL | GTK_EXPAND, 0, 0, 0); - gtk_widget_show (hbox); - - combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (priv->printer_list)); - data->printer_combo = combo; - - data->printer_inserted_tag = - g_signal_connect_swapped (priv->printer_list, "row-inserted", - G_CALLBACK (update_combo_sensitivity_from_printers), data); - data->printer_removed_tag = - g_signal_connect_swapped (priv->printer_list, "row-deleted", - G_CALLBACK (update_combo_sensitivity_from_printers), data); - update_combo_sensitivity_from_printers (data); - - cell = gtk_cell_renderer_text_new (); - gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); - gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell, - custom_paper_printer_data_func, - NULL, NULL); - - gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); - gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0); - gtk_widget_show (combo); - - g_signal_connect_swapped (combo, "changed", - G_CALLBACK (margins_from_printer_changed), data); - - frame = wrap_in_frame (_("Paper Margins"), table); - gtk_widget_show (table); - gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0); - gtk_widget_show (frame); - - update_custom_widgets_from_list (data); - - /* If no custom sizes, add one */ - if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (priv->custom_paper_list), - &iter)) - { - /* Need to realize treeview so we can start the rename */ - gtk_widget_realize (treeview); - add_custom_paper (data); - } - - gtk_window_present (GTK_WINDOW (dialog)); -} - - #define __GTK_PAGE_SETUP_UNIX_DIALOG_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkprintoperation-private.h b/gtk/gtkprintoperation-private.h index 8c800eaea5..5e28007bee 100644 --- a/gtk/gtkprintoperation-private.h +++ b/gtk/gtkprintoperation-private.h @@ -56,6 +56,7 @@ struct _GtkPrintOperationPrivate guint is_sync : 1; guint support_selection : 1; guint has_selection : 1; + guint embed_page_setup : 1; GtkPageDrawingState page_drawing_state; diff --git a/gtk/gtkprintoperation-unix.c b/gtk/gtkprintoperation-unix.c index 765752b158..c31f324acb 100644 --- a/gtk/gtkprintoperation-unix.c +++ b/gtk/gtkprintoperation-unix.c @@ -414,10 +414,14 @@ get_print_dialog (GtkPrintOperation *op, if (priv->print_settings) gtk_print_unix_dialog_set_settings (GTK_PRINT_UNIX_DIALOG (pd), priv->print_settings); + if (priv->default_page_setup) gtk_print_unix_dialog_set_page_setup (GTK_PRINT_UNIX_DIALOG (pd), priv->default_page_setup); + gtk_print_unix_dialog_set_embed_page_setup (GTK_PRINT_UNIX_DIALOG (pd), + priv->embed_page_setup); + gtk_print_unix_dialog_set_current_page (GTK_PRINT_UNIX_DIALOG (pd), priv->current_page); @@ -477,7 +481,8 @@ static void finish_print (PrintResponseData *rdata, GtkPrinter *printer, GtkPageSetup *page_setup, - GtkPrintSettings *settings) + GtkPrintSettings *settings, + gboolean page_setup_set) { GtkPrintOperation *op = rdata->op; GtkPrintOperationPrivate *priv = op->priv; @@ -488,7 +493,9 @@ finish_print (PrintResponseData *rdata, gtk_print_operation_set_print_settings (op, settings); priv->print_context = _gtk_print_context_new (op); - if ( (page_setup != NULL) && (gtk_print_operation_get_default_page_setup (op) == NULL)) + if (page_setup != NULL && + (gtk_print_operation_get_default_page_setup (op) == NULL || + page_setup_set)) gtk_print_operation_set_default_page_setup (op, page_setup); _gtk_print_context_set_page_setup (priv->print_context, page_setup); @@ -561,6 +568,7 @@ handle_print_response (GtkWidget *dialog, GtkPrintSettings *settings = NULL; GtkPageSetup *page_setup = NULL; GtkPrinter *printer = NULL; + gboolean page_setup_set = FALSE; if (response == GTK_RESPONSE_OK) { @@ -585,11 +593,12 @@ handle_print_response (GtkWidget *dialog, { settings = gtk_print_unix_dialog_get_settings (GTK_PRINT_UNIX_DIALOG (pd)); page_setup = gtk_print_unix_dialog_get_page_setup (GTK_PRINT_UNIX_DIALOG (pd)); + page_setup_set = gtk_print_unix_dialog_get_page_setup_set (GTK_PRINT_UNIX_DIALOG (pd)); g_signal_emit_by_name (rdata->op, "custom-widget-apply", rdata->op->priv->custom_widget); } - finish_print (rdata, printer, page_setup, settings); + finish_print (rdata, printer, page_setup, settings, page_setup_set); if (settings) g_object_unref (settings); @@ -631,7 +640,7 @@ found_printer (GtkPrinter *printer, page_setup = gtk_page_setup_new (); } - finish_print (rdata, printer, page_setup, settings); + finish_print (rdata, printer, page_setup, settings, FALSE); if (settings) g_object_unref (settings); diff --git a/gtk/gtkprintoperation.c b/gtk/gtkprintoperation.c index f3ebd85af3..765e7d0b25 100644 --- a/gtk/gtkprintoperation.c +++ b/gtk/gtkprintoperation.c @@ -69,7 +69,8 @@ enum PROP_EXPORT_FILENAME, PROP_STATUS, PROP_STATUS_STRING, - PROP_CUSTOM_TAB_LABEL + PROP_CUSTOM_TAB_LABEL, + PROP_EMBED_PAGE_SETUP }; static guint signals[LAST_SIGNAL] = { 0 }; @@ -165,6 +166,7 @@ gtk_print_operation_init (GtkPrintOperation *operation) priv->is_sync = FALSE; priv->support_selection = FALSE; priv->has_selection = FALSE; + priv->embed_page_setup = FALSE; priv->page_drawing_state = GTK_PAGE_DRAWING_STATE_READY; @@ -320,6 +322,9 @@ gtk_print_operation_set_property (GObject *object, case PROP_CUSTOM_TAB_LABEL: gtk_print_operation_set_custom_tab_label (op, g_value_get_string (value)); break; + case PROP_EMBED_PAGE_SETUP: + gtk_print_operation_set_embed_page_setup (op, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -379,6 +384,9 @@ gtk_print_operation_get_property (GObject *object, case PROP_CUSTOM_TAB_LABEL: g_value_set_string (value, priv->custom_tab_label); break; + case PROP_EMBED_PAGE_SETUP: + g_value_set_boolean (value, priv->embed_page_setup); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1229,6 +1237,21 @@ gtk_print_operation_class_init (GtkPrintOperationClass *class) FALSE, GTK_PARAM_READWRITE)); + + /** + * GtkPrintOperation:embed-page-setup: + * + * If %TRUE, page size combo box and orientation combo box are embedded into page setup page. + * + * Since: 2.18 + */ + g_object_class_install_property (gobject_class, + PROP_EMBED_PAGE_SETUP, + g_param_spec_boolean ("embed-page-setup", + P_("Embed Page Setup"), + P_("TRUE if page setup combos are embedded in GtkPrintDialog"), + FALSE, + GTK_PARAM_READWRITE)); } /** @@ -2198,6 +2221,52 @@ gtk_print_operation_set_defer_drawing (GtkPrintOperation *op) } /** + * gtk_print_operation_set_embed_page_setup: + * @op: a #GtkPrintOperation + * @embed: %TRUE to embed page setup selection in the #GtkPrintDialog + * + * Embed page size combo box and orientation combo box into page setup page. + * Selected page setup is stored as default page setup in #GtkPrintOperation. + * + * Since: 2.18 + **/ +void +gtk_print_operation_set_embed_page_setup (GtkPrintOperation *op, + gboolean embed) +{ + GtkPrintOperationPrivate *priv; + + g_return_if_fail (GTK_IS_PRINT_OPERATION (op)); + + priv = op->priv; + + embed = embed != FALSE; + if (priv->embed_page_setup != embed) + { + priv->embed_page_setup = embed; + g_object_notify (G_OBJECT (op), "embed-page-setup"); + } +} + +/** + * gtk_print_operation_get_embed_page_setup: + * @op: a #GtkPrintOperation + * + * Gets the value of #GtkPrintOperation::embed-page-setup property. + * + * Returns: whether page setup selection combos are embedded + * + * Since: 2.18 + */ +gboolean +gtk_print_operation_get_embed_page_setup (GtkPrintOperation *op) +{ + g_return_val_if_fail (GTK_IS_PRINT_OPERATION (op), FALSE); + + return op->priv->embed_page_setup; +} + +/** * gtk_print_operation_draw_page_finish: * @op: a #GtkPrintOperation * diff --git a/gtk/gtkprintoperation.h b/gtk/gtkprintoperation.h index aee3d95ec6..7ac38d4c2a 100644 --- a/gtk/gtkprintoperation.h +++ b/gtk/gtkprintoperation.h @@ -184,6 +184,9 @@ gboolean gtk_print_operation_get_support_selection (GtkPrintOper void gtk_print_operation_set_has_selection (GtkPrintOperation *op, gboolean has_selection); gboolean gtk_print_operation_get_has_selection (GtkPrintOperation *op); +void gtk_print_operation_set_embed_page_setup (GtkPrintOperation *op, + gboolean embed); +gboolean gtk_print_operation_get_embed_page_setup (GtkPrintOperation *op); GtkPageSetup *gtk_print_run_page_setup_dialog (GtkWindow *parent, GtkPageSetup *page_setup, diff --git a/gtk/gtkprintunixdialog.c b/gtk/gtkprintunixdialog.c index afd7e72f1a..38b43a1a5c 100644 --- a/gtk/gtkprintunixdialog.c +++ b/gtk/gtkprintunixdialog.c @@ -50,16 +50,21 @@ #include "gtkeventbox.h" #include "gtkbuildable.h" +#include "gtkcustompaperunixdialog.h" #include "gtkprintbackend.h" #include "gtkprinter-private.h" #include "gtkprintunixdialog.h" #include "gtkprinteroptionwidget.h" +#include "gtkprintutils.h" #include "gtkalias.h" #include "gtkmessagedialog.h" #include "gtkbutton.h" #define EXAMPLE_PAGE_AREA_SIZE 140 +#define RULER_DISTANCE 7.5 +#define RULER_RADIUS 2 + #define GTK_PRINT_UNIX_DIALOG_GET_PRIVATE(o) \ (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINT_UNIX_DIALOG, GtkPrintUnixDialogPrivate)) @@ -103,6 +108,7 @@ static void set_cell_sensitivity_func (GtkTreeViewColumn *tree_colu gpointer data); static gboolean set_active_printer (GtkPrintUnixDialog *dialog, const gchar *printer_name); +static void redraw_page_layout_preview (GtkPrintUnixDialog *dialog); /* GtkBuildable */ static void gtk_print_unix_dialog_buildable_init (GtkBuildableIface *iface); @@ -110,6 +116,27 @@ static GObject *gtk_print_unix_dialog_buildable_get_internal_child (GtkBuildabl GtkBuilder *builder, const gchar *childname); +static const gchar const common_paper_sizes[][16] = { + "na_letter", + "na_legal", + "iso_a4", + "iso_a5", + "roc_16k", + "iso_b5", + "jis_b5", + "na_number-10", + "iso_dl", + "jpn_chou3", + "na_ledger", + "iso_a3", +}; + +enum { + PAGE_SETUP_LIST_COL_PAGE_SETUP, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, + PAGE_SETUP_LIST_N_COLS +}; + enum { PROP_0, PROP_PAGE_SETUP, @@ -118,7 +145,8 @@ enum { PROP_SELECTED_PRINTER, PROP_MANUAL_CAPABILITIES, PROP_SUPPORT_SELECTION, - PROP_HAS_SELECTION + PROP_HAS_SELECTION, + PROP_EMBED_PAGE_SETUP }; enum { @@ -145,6 +173,9 @@ struct GtkPrintUnixDialogPrivate GtkPageSetup *page_setup; gboolean page_setup_set; + gboolean embed_page_setup; + GtkListStore *page_setup_list; + GtkListStore *custom_paper_list; gboolean support_selection; gboolean has_selection; @@ -168,6 +199,11 @@ struct GtkPrintUnixDialogPrivate GtkWidget *print_at_entry; GtkWidget *print_hold_radio; GtkWidget *preview_button; + GtkWidget *paper_size_combo; + GtkWidget *paper_size_combo_label; + GtkWidget *orientation_combo; + GtkWidget *orientation_combo_label; + gboolean internal_page_setup_change; gboolean updating_print_at; GtkPrinterOptionWidget *pages_per_sheet; GtkPrinterOptionWidget *duplex; @@ -319,6 +355,14 @@ gtk_print_unix_dialog_class_init (GtkPrintUnixDialogClass *class) FALSE, GTK_PARAM_READWRITE)); + g_object_class_install_property (object_class, + PROP_EMBED_PAGE_SETUP, + g_param_spec_boolean ("embed-page-setup", + P_("Embed Page Setup"), + P_("TRUE if page setup combos are embedded in GtkPrintUnixDialog"), + FALSE, + GTK_PARAM_READWRITE)); + g_type_class_add_private (class, sizeof (GtkPrintUnixDialogPrivate)); } @@ -459,6 +503,8 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) priv->page_setup = gtk_page_setup_new (); priv->page_setup_set = FALSE; + priv->embed_page_setup = FALSE; + priv->internal_page_setup_change = FALSE; priv->support_selection = FALSE; priv->has_selection = FALSE; @@ -473,6 +519,11 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) (GCallback) error_dialogs, NULL); + g_signal_connect (dialog, + "notify::page-setup", + (GCallback) redraw_page_layout_preview, + NULL); + priv->preview_button = gtk_button_new_from_stock (GTK_STOCK_PRINT_PREVIEW); gtk_widget_show (priv->preview_button); @@ -492,6 +543,13 @@ gtk_print_unix_dialog_init (GtkPrintUnixDialog *dialog) gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); gtk_dialog_set_response_sensitive (GTK_DIALOG (dialog), GTK_RESPONSE_OK, FALSE); + priv->page_setup_list = gtk_list_store_new (PAGE_SETUP_LIST_N_COLS, + G_TYPE_OBJECT, + G_TYPE_BOOLEAN); + + priv->custom_paper_list = gtk_list_store_new (1, G_TYPE_OBJECT); + _gtk_print_load_custom_papers (priv->custom_paper_list); + populate_dialog (dialog); } @@ -540,6 +598,12 @@ gtk_print_unix_dialog_finalize (GObject *object) priv->printer_list = NULL; } + if (priv->custom_paper_list) + { + g_object_unref (priv->custom_paper_list); + priv->custom_paper_list = NULL; + } + if (priv->printer_list_filter) { g_object_unref (priv->printer_list_filter); @@ -603,6 +667,12 @@ gtk_print_unix_dialog_finalize (GObject *object) g_list_free (priv->print_backends); priv->print_backends = NULL; + if (priv->page_setup_list) + { + g_object_unref (priv->page_setup_list); + priv->page_setup_list = NULL; + } + G_OBJECT_CLASS (gtk_print_unix_dialog_parent_class)->finalize (object); } @@ -826,6 +896,9 @@ gtk_print_unix_dialog_set_property (GObject *object, case PROP_HAS_SELECTION: gtk_print_unix_dialog_set_has_selection (dialog, g_value_get_boolean (value)); break; + case PROP_EMBED_PAGE_SETUP: + gtk_print_unix_dialog_set_embed_page_setup (dialog, g_value_get_boolean (value)); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -864,6 +937,9 @@ gtk_print_unix_dialog_get_property (GObject *object, case PROP_HAS_SELECTION: g_value_set_boolean (value, priv->has_selection); break; + case PROP_EMBED_PAGE_SETUP: + g_value_set_boolean (value, priv->embed_page_setup); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1348,6 +1424,196 @@ update_dialog_from_capabilities (GtkPrintUnixDialog *dialog) gtk_tree_model_filter_refilter (priv->printer_list_filter); } +static gboolean +page_setup_is_equal (GtkPageSetup *a, + GtkPageSetup *b) +{ + return + gtk_paper_size_is_equal (gtk_page_setup_get_paper_size (a), + gtk_page_setup_get_paper_size (b)) && + gtk_page_setup_get_top_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_top_margin (b, GTK_UNIT_MM) && + gtk_page_setup_get_bottom_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_bottom_margin (b, GTK_UNIT_MM) && + gtk_page_setup_get_left_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_left_margin (b, GTK_UNIT_MM) && + gtk_page_setup_get_right_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_right_margin (b, GTK_UNIT_MM); +} + +static gboolean +page_setup_is_same_size (GtkPageSetup *a, + GtkPageSetup *b) +{ + return gtk_paper_size_is_equal (gtk_page_setup_get_paper_size (a), + gtk_page_setup_get_paper_size (b)); +} + +static gboolean +set_paper_size (GtkPrintUnixDialog *dialog, + GtkPageSetup *page_setup, + gboolean size_only, + gboolean add_item) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkTreeModel *model; + GtkTreeIter iter; + GtkPageSetup *list_page_setup; + + if (!priv->internal_page_setup_change) + return TRUE; + + if (page_setup == NULL) + return FALSE; + + model = GTK_TREE_MODEL (priv->page_setup_list); + + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + gtk_tree_model_get (GTK_TREE_MODEL (priv->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 (priv->paper_size_combo), + &iter); + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->orientation_combo), + gtk_page_setup_get_orientation (page_setup)); + g_object_unref (list_page_setup); + return TRUE; + } + + g_object_unref (list_page_setup); + + } while (gtk_tree_model_iter_next (model, &iter)); + } + + if (add_item) + { + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, + -1); + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, + -1); + gtk_combo_box_set_active_iter (GTK_COMBO_BOX (priv->paper_size_combo), + &iter); + gtk_combo_box_set_active (GTK_COMBO_BOX (priv->orientation_combo), + gtk_page_setup_get_orientation (page_setup)); + return TRUE; + } + + return FALSE; +} + +static void +fill_custom_paper_sizes (GtkPrintUnixDialog *dialog) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter, paper_iter; + GtkTreeModel *model; + + model = GTK_TREE_MODEL (priv->custom_paper_list); + if (gtk_tree_model_get_iter_first (model, &iter)) + { + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->page_setup_list, &paper_iter, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, + -1); + do + { + GtkPageSetup *page_setup; + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->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)); + } + + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->page_setup_list, &paper_iter, + PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE, + -1); + gtk_list_store_append (priv->page_setup_list, &paper_iter); + gtk_list_store_set (priv->page_setup_list, &paper_iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, NULL, + -1); +} + +static void +fill_paper_sizes (GtkPrintUnixDialog *dialog, + GtkPrinter *printer) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GList *list, *l; + GtkPageSetup *page_setup; + GtkPaperSize *paper_size; + GtkTreeIter iter; + gint i; + + gtk_list_store_clear (priv->page_setup_list); + + if (printer == NULL || (list = gtk_printer_list_papers (printer)) == NULL) + { + for (i = 0; i < G_N_ELEMENTS (common_paper_sizes); i++) + { + page_setup = gtk_page_setup_new (); + paper_size = gtk_paper_size_new (common_paper_sizes[i]); + gtk_page_setup_set_paper_size_and_default_margins (page_setup, paper_size); + gtk_paper_size_free (paper_size); + + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, + -1); + g_object_unref (page_setup); + } + } + else + { + for (l = list; l != NULL; l = l->next) + { + page_setup = l->data; + gtk_list_store_append (priv->page_setup_list, &iter); + gtk_list_store_set (priv->page_setup_list, &iter, + PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup, + -1); + g_object_unref (page_setup); + } + g_list_free (list); + } + + fill_custom_paper_sizes (dialog); +} + +static void +update_paper_sizes (GtkPrintUnixDialog *dialog) +{ + GtkPageSetup *current_page_setup = NULL; + GtkPrinter *printer; + + printer = gtk_print_unix_dialog_get_selected_printer (dialog); + + fill_paper_sizes (dialog, printer); + + current_page_setup = gtk_page_setup_copy (gtk_print_unix_dialog_get_page_setup (dialog)); + + if (current_page_setup) + { + if (!set_paper_size (dialog, current_page_setup, FALSE, FALSE)) + set_paper_size (dialog, current_page_setup, TRUE, TRUE); + + g_object_unref (current_page_setup); + } +} + static void mark_conflicts (GtkPrintUnixDialog *dialog) { @@ -1581,6 +1847,9 @@ selected_printer_changed (GtkTreeSelection *selection, if (!page_setup) page_setup = gtk_page_setup_new (); + if (page_setup && priv->page_setup) + gtk_page_setup_set_orientation (page_setup, gtk_page_setup_get_orientation (priv->page_setup)); + g_object_unref (priv->page_setup); priv->page_setup = page_setup; } @@ -1598,6 +1867,10 @@ selected_printer_changed (GtkTreeSelection *selection, update_dialog_from_settings (dialog); update_dialog_from_capabilities (dialog); + priv->internal_page_setup_change = TRUE; + update_paper_sizes (dialog); + priv->internal_page_setup_change = FALSE; + g_object_notify ( G_OBJECT(dialog), "selected-printer"); } @@ -2260,6 +2533,10 @@ draw_page_cb (GtkWidget *widget, gint start_x, end_x, start_y, end_y; gint dx, dy; gboolean horizontal; + GtkPageSetup *page_setup; + gdouble paper_width, paper_height; + gdouble pos_x, pos_y; + gint pages_per_sheet; orientation = gtk_page_setup_get_orientation (priv->page_setup); landscape = @@ -2270,14 +2547,49 @@ draw_page_cb (GtkWidget *widget, cr = gdk_cairo_create (widget->window); - cairo_translate (cr, widget->allocation.x, widget->allocation.y); + cairo_save (cr); + + page_setup = gtk_print_unix_dialog_get_page_setup (dialog); + + if (page_setup != NULL) + { + if (!landscape) + { + paper_width = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM); + paper_height = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM); + } + else + { + paper_width = gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM); + paper_height = gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM); + } - ratio = G_SQRT2; + if (paper_width < paper_height) + { + h = EXAMPLE_PAGE_AREA_SIZE - 3; + w = (paper_height != 0) ? h * paper_width / paper_height : 0; + } + else + { + w = EXAMPLE_PAGE_AREA_SIZE - 3; + h = (paper_width != 0) ? w * paper_height / paper_width : 0; + } - w = (EXAMPLE_PAGE_AREA_SIZE - 3) / ratio; - h = w * ratio; + if (paper_width == 0) + w = 0; - switch (dialog_get_pages_per_sheet (dialog)) + if (paper_height == 0) + h = 0; + } + else + { + ratio = G_SQRT2; + w = (EXAMPLE_PAGE_AREA_SIZE - 3) / ratio; + h = EXAMPLE_PAGE_AREA_SIZE - 3; + } + + pages_per_sheet = dialog_get_pages_per_sheet (dialog); + switch (pages_per_sheet) { default: case 1: @@ -2313,6 +2625,11 @@ draw_page_cb (GtkWidget *widget, pages_y = tmp; } + pos_x = widget->allocation.x + (widget->allocation.width - w) / 2; + pos_y = widget->allocation.y + (widget->allocation.height - h) / 2 - 10; + color = &widget->style->text[GTK_STATE_NORMAL]; + cairo_translate (cr, pos_x, pos_y); + shadow_offset = 3; color = &widget->style->text[GTK_STATE_NORMAL]; @@ -2324,7 +2641,7 @@ draw_page_cb (GtkWidget *widget, cairo_rectangle (cr, 1, 1, w, h); cairo_fill (cr); cairo_set_line_width (cr, 1.0); - cairo_rectangle (cr, 0.5, 0.5, w+1, h+1); + cairo_rectangle (cr, 0.5, 0.5, w + 1, h + 1); gdk_cairo_set_source_color (cr, &widget->style->text[GTK_STATE_NORMAL]); cairo_stroke (cr); @@ -2338,7 +2655,12 @@ draw_page_cb (GtkWidget *widget, font = pango_font_description_new (); pango_font_description_set_family (font, "sans"); - pango_font_description_set_absolute_size (font, page_height * 0.4 * PANGO_SCALE); + + if (page_height > 0) + pango_font_description_set_absolute_size (font, page_height * 0.4 * PANGO_SCALE); + else + pango_font_description_set_absolute_size (font, 1); + pango_layout_set_font_description (layout, font); pango_font_description_free (font); @@ -2460,6 +2782,112 @@ draw_page_cb (GtkWidget *widget, } g_object_unref (layout); + + if (page_setup != NULL) + { + pos_x += 1; + pos_y += 1; + + if (pages_per_sheet == 2 || pages_per_sheet == 6) + { + paper_width = gtk_page_setup_get_paper_height (page_setup, _gtk_print_get_default_user_units ()); + paper_height = gtk_page_setup_get_paper_width (page_setup, _gtk_print_get_default_user_units ()); + } + else + { + paper_width = gtk_page_setup_get_paper_width (page_setup, _gtk_print_get_default_user_units ()); + paper_height = gtk_page_setup_get_paper_height (page_setup, _gtk_print_get_default_user_units ()); + } + + cairo_restore (cr); + cairo_save (cr); + + layout = pango_cairo_create_layout (cr); + + font = pango_font_description_new (); + pango_font_description_set_family (font, "sans"); + + PangoContext *pango_c = NULL; + PangoFontDescription *pango_f = NULL; + gint font_size = 12 * PANGO_SCALE; + + pango_c = gtk_widget_get_pango_context (widget); + if (pango_c != NULL) + { + pango_f = pango_context_get_font_description (pango_c); + if (pango_f != NULL) + font_size = pango_font_description_get_size (pango_f); + } + + pango_font_description_set_size (font, font_size); + pango_layout_set_font_description (layout, font); + pango_font_description_free (font); + + pango_layout_set_width (layout, -1); + pango_layout_set_alignment (layout, PANGO_ALIGN_CENTER); + + if (_gtk_print_get_default_user_units () == GTK_UNIT_MM) + text = g_strdup_printf ("%.1f mm", paper_height); + else + text = g_strdup_printf ("%.2f inch", paper_height); + + pango_layout_set_text (layout, text, -1); + g_free (text); + pango_layout_get_size (layout, &layout_w, &layout_h); + + cairo_translate (cr, pos_x - layout_w / PANGO_SCALE - 2 * RULER_DISTANCE, + widget->allocation.y + (widget->allocation.height - layout_h / PANGO_SCALE) / 2); + + pango_cairo_show_layout (cr, layout); + + cairo_restore (cr); + cairo_save (cr); + + if (_gtk_print_get_default_user_units () == GTK_UNIT_MM) + text = g_strdup_printf ("%.1f mm", paper_width); + else + text = g_strdup_printf ("%.2f inch", paper_width); + + pango_layout_set_text (layout, text, -1); + g_free (text); + pango_layout_get_size (layout, &layout_w, &layout_h); + + cairo_translate (cr, widget->allocation.x + (widget->allocation.width - layout_w / PANGO_SCALE) / 2, + pos_y + h + shadow_offset + 2 * RULER_DISTANCE); + + pango_cairo_show_layout (cr, layout); + + g_object_unref (layout); + + cairo_restore (cr); + + cairo_set_line_width (cr, 1); + + cairo_move_to (cr, pos_x - RULER_DISTANCE, pos_y); + cairo_line_to (cr, pos_x - RULER_DISTANCE, pos_y + h); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x - RULER_DISTANCE - RULER_RADIUS, pos_y - 0.5); + cairo_line_to (cr, pos_x - RULER_DISTANCE + RULER_RADIUS, pos_y - 0.5); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x - RULER_DISTANCE - RULER_RADIUS, pos_y + h + 0.5); + cairo_line_to (cr, pos_x - RULER_DISTANCE + RULER_RADIUS, pos_y + h + 0.5); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x, pos_y + h + shadow_offset + RULER_DISTANCE); + cairo_line_to (cr, pos_x + w, pos_y + h + shadow_offset + RULER_DISTANCE); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x - 0.5, pos_y + h + shadow_offset + RULER_DISTANCE - RULER_RADIUS); + cairo_line_to (cr, pos_x - 0.5, pos_y + h + shadow_offset + RULER_DISTANCE + RULER_RADIUS); + cairo_stroke (cr); + + cairo_move_to (cr, pos_x + w + 0.5, pos_y + h + shadow_offset + RULER_DISTANCE - RULER_RADIUS); + cairo_line_to (cr, pos_x + w + 0.5, pos_y + h + shadow_offset + RULER_DISTANCE + RULER_RADIUS); + cairo_stroke (cr); + } + cairo_destroy (cr); return TRUE; @@ -2610,12 +3038,163 @@ update_number_up_layout (GtkPrintUnixDialog *dialog) } static void +custom_paper_dialog_response_cb (GtkDialog *custom_paper_dialog, + gint response_id, + gpointer user_data) +{ + GtkPrintUnixDialog *print_dialog = GTK_PRINT_UNIX_DIALOG (user_data); + GtkPrintUnixDialogPrivate *priv = print_dialog->priv; + GtkTreeModel *model; + GtkTreeIter iter; + + _gtk_print_load_custom_papers (priv->custom_paper_list); + + priv->internal_page_setup_change = TRUE; + update_paper_sizes (print_dialog); + priv->internal_page_setup_change = FALSE; + + if (priv->page_setup_set) + { + model = GTK_TREE_MODEL (priv->custom_paper_list); + if (gtk_tree_model_get_iter_first (model, &iter)) + { + do + { + GtkPageSetup *page_setup; + gtk_tree_model_get (model, &iter, 0, &page_setup, -1); + + if (page_setup && + g_strcmp0 (gtk_paper_size_get_display_name (gtk_page_setup_get_paper_size (page_setup)), + gtk_paper_size_get_display_name (gtk_page_setup_get_paper_size (priv->page_setup))) == 0) + gtk_print_unix_dialog_set_page_setup (print_dialog, page_setup); + + g_object_unref (page_setup); + } while (gtk_tree_model_iter_next (model, &iter)); + } + } + + gtk_widget_destroy (GTK_WIDGET (custom_paper_dialog)); +} + +static void +orientation_changed (GtkComboBox *combo_box, + GtkPrintUnixDialog *dialog) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkPageOrientation orientation; + GtkPageSetup *page_setup; + + if (priv->internal_page_setup_change) + return; + + orientation = (GtkPageOrientation) gtk_combo_box_get_active (GTK_COMBO_BOX (priv->orientation_combo)); + + if (priv->page_setup) + { + page_setup = gtk_page_setup_copy (priv->page_setup); + if (page_setup) + gtk_page_setup_set_orientation (page_setup, orientation); + + gtk_print_unix_dialog_set_page_setup (dialog, page_setup); + } + + redraw_page_layout_preview (dialog); +} + +static void +paper_size_changed (GtkComboBox *combo_box, + GtkPrintUnixDialog *dialog) +{ + GtkPrintUnixDialogPrivate *priv = dialog->priv; + GtkTreeIter iter; + GtkPageSetup *page_setup, *last_page_setup; + GtkPageOrientation orientation; + + if (priv->internal_page_setup_change) + return; + + if (gtk_combo_box_get_active_iter (combo_box, &iter)) + { + gtk_tree_model_get (gtk_combo_box_get_model (combo_box), + &iter, PAGE_SETUP_LIST_COL_PAGE_SETUP, &page_setup, -1); + + if (page_setup == NULL) + { + GtkWidget *custom_paper_dialog; + + /* Change from "manage" menu item to last value */ + if (priv->page_setup) + last_page_setup = g_object_ref (priv->page_setup); + else + last_page_setup = gtk_page_setup_new (); /* "good" default */ + + if (!set_paper_size (dialog, last_page_setup, FALSE, FALSE)) + set_paper_size (dialog, last_page_setup, TRUE, TRUE); + g_object_unref (last_page_setup); + + /* And show the custom paper dialog */ + custom_paper_dialog = _gtk_custom_paper_unix_dialog_new (GTK_WINDOW (dialog), _("Manage Custom Sizes")); + g_signal_connect (custom_paper_dialog, "response", G_CALLBACK (custom_paper_dialog_response_cb), dialog); + gtk_window_present (GTK_WINDOW (custom_paper_dialog)); + + return; + } + + if (priv->page_setup) + orientation = gtk_page_setup_get_orientation (priv->page_setup); + else + orientation = GTK_PAGE_ORIENTATION_PORTRAIT; + + gtk_page_setup_set_orientation (page_setup, orientation); + gtk_print_unix_dialog_set_page_setup (dialog, page_setup); + + g_object_unref (page_setup); + } + + redraw_page_layout_preview (dialog); +} + +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 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); +} + +static void create_page_setup_page (GtkPrintUnixDialog *dialog) { GtkPrintUnixDialogPrivate *priv = dialog->priv; GtkWidget *main_vbox, *label, *hbox, *hbox2; GtkWidget *frame, *table, *widget; GtkWidget *combo, *spinbutton, *draw; + GtkCellRenderer *cell; main_vbox = gtk_vbox_new (FALSE, 18); gtk_container_set_border_width (GTK_CONTAINER (main_vbox), 12); @@ -2776,6 +3355,55 @@ create_page_setup_page (GtkPrintUnixDialog *dialog) 0, 0); gtk_label_set_mnemonic_widget (GTK_LABEL (label), widget); + + label = gtk_label_new_with_mnemonic (_("_Paper size:")); + priv->paper_size_combo_label = GTK_WIDGET (label); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 3, 4, GTK_FILL, 0, + 0, 0); + + combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (priv->page_setup_list)); + priv->paper_size_combo = GTK_WIDGET (combo); + gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo), + paper_size_row_is_separator, NULL, NULL); + cell = gtk_cell_renderer_text_new (); + gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE); + gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell, + page_name_func, NULL, NULL); + gtk_table_attach (GTK_TABLE (table), combo, + 1, 2, 3, 4, GTK_FILL, 0, + 0, 0); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); + gtk_widget_set_sensitive (combo, FALSE); + gtk_widget_show (combo); + + + label = gtk_label_new_with_mnemonic (_("Or_ientation:")); + priv->orientation_combo_label = GTK_WIDGET (label); + gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); + gtk_widget_show (label); + gtk_table_attach (GTK_TABLE (table), label, + 0, 1, 4, 5, + GTK_FILL, 0, 0, 0); + + combo = gtk_combo_box_new_text (); + priv->orientation_combo = GTK_WIDGET (combo); + gtk_table_attach (GTK_TABLE (table), combo, + 1, 2, 4, 5, GTK_FILL, 0, + 0, 0); + gtk_label_set_mnemonic_widget (GTK_LABEL (label), combo); + /* In enum order */ + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Portrait")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Landscape")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Reverse portrait")); + gtk_combo_box_append_text (GTK_COMBO_BOX (combo), _("Reverse landscape")); + gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); + gtk_widget_set_sensitive (combo, FALSE); + gtk_widget_show (combo); + + /* Add the page layout preview */ hbox2 = gtk_hbox_new (FALSE, 0); gtk_widget_show (hbox2); @@ -2784,7 +3412,7 @@ create_page_setup_page (GtkPrintUnixDialog *dialog) draw = gtk_drawing_area_new (); GTK_WIDGET_SET_FLAGS (draw, GTK_NO_WINDOW); priv->page_layout_preview = draw; - gtk_widget_set_size_request (draw, 200, 200); + gtk_widget_set_size_request (draw, 350, 200); g_signal_connect (draw, "expose-event", G_CALLBACK (draw_page_cb), dialog); gtk_widget_show (draw); @@ -3193,6 +3821,24 @@ gtk_print_unix_dialog_get_page_setup (GtkPrintUnixDialog *dialog) } /** + * gtk_print_unix_dialog_get_page_setup_set: + * @dialog: a #GtkPrintUnixDialog + * + * Gets the page setup that is used by the #GtkPrintUnixDialog. + * + * Returns: whether a page setup was set by user. + * + * Since: 2.18 + */ +gboolean +gtk_print_unix_dialog_get_page_setup_set (GtkPrintUnixDialog *dialog) +{ + g_return_val_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog), FALSE); + + return dialog->priv->page_setup_set; +} + +/** * gtk_print_unix_dialog_set_current_page: * @dialog: a #GtkPrintUnixDialog * @current_page: the current page number. @@ -3620,5 +4266,73 @@ gtk_print_unix_dialog_get_has_selection (GtkPrintUnixDialog *dialog) return dialog->priv->has_selection; } +/** + * gtk_print_unix_dialog_set_embed_page_setup + * @dialog: a #GtkPrintUnixDialog + * @embed: embed page setup selection + * + * Embed page size combo box and orientation combo box into page setup page. + * + * Since: 2.18 + */ +void +gtk_print_unix_dialog_set_embed_page_setup (GtkPrintUnixDialog *dialog, + gboolean embed) +{ + GtkPrintUnixDialogPrivate *priv; + + g_return_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog)); + + priv = dialog->priv; + + embed = embed != FALSE; + if (priv->embed_page_setup != embed) + { + priv->embed_page_setup = embed; + + gtk_widget_set_sensitive (priv->paper_size_combo, priv->embed_page_setup); + gtk_widget_set_sensitive (priv->orientation_combo, priv->embed_page_setup); + + if (priv->embed_page_setup) + { + if (priv->paper_size_combo != NULL) + g_signal_connect (priv->paper_size_combo, "changed", G_CALLBACK (paper_size_changed), dialog); + + if (priv->orientation_combo) + g_signal_connect (priv->orientation_combo, "changed", G_CALLBACK (orientation_changed), dialog); + } + else + { + if (priv->paper_size_combo != NULL) + g_signal_handlers_disconnect_by_func (priv->paper_size_combo, G_CALLBACK (paper_size_changed), dialog); + + if (priv->orientation_combo) + g_signal_handlers_disconnect_by_func (priv->orientation_combo, G_CALLBACK (orientation_changed), dialog); + } + + priv->internal_page_setup_change = TRUE; + update_paper_sizes (dialog); + priv->internal_page_setup_change = FALSE; + } +} + +/** + * gtk_print_unix_dialog_get_embed_page_setup: + * @dialog: a #GtkPrintUnixDialog + * + * Gets the value of #GtkPrintUnixDialog::embed-page-setup property. + * + * Returns: whether there is a selection + * + * Since: 2.18 + */ +gboolean +gtk_print_unix_dialog_get_embed_page_setup (GtkPrintUnixDialog *dialog) +{ + g_return_val_if_fail (GTK_IS_PRINT_UNIX_DIALOG (dialog), FALSE); + + return dialog->priv->embed_page_setup; +} + #define __GTK_PRINT_UNIX_DIALOG_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkprintunixdialog.h b/gtk/gtkprintunixdialog.h index 0d7efccfc3..4ff22e4ed8 100644 --- a/gtk/gtkprintunixdialog.h +++ b/gtk/gtkprintunixdialog.h @@ -64,25 +64,25 @@ struct _GtkPrintUnixDialogClass void (*_gtk_reserved7) (void); }; -GType gtk_print_unix_dialog_get_type (void) G_GNUC_CONST; -GtkWidget * gtk_print_unix_dialog_new (const gchar *title, - GtkWindow *parent); - -void gtk_print_unix_dialog_set_page_setup (GtkPrintUnixDialog *dialog, - GtkPageSetup *page_setup); -GtkPageSetup * gtk_print_unix_dialog_get_page_setup (GtkPrintUnixDialog *dialog); -void gtk_print_unix_dialog_set_current_page (GtkPrintUnixDialog *dialog, - gint current_page); -gint gtk_print_unix_dialog_get_current_page (GtkPrintUnixDialog *dialog); -void gtk_print_unix_dialog_set_settings (GtkPrintUnixDialog *dialog, - GtkPrintSettings *settings); -GtkPrintSettings *gtk_print_unix_dialog_get_settings (GtkPrintUnixDialog *dialog); -GtkPrinter * gtk_print_unix_dialog_get_selected_printer (GtkPrintUnixDialog *dialog); -void gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog, - GtkWidget *child, - GtkWidget *tab_label); -void gtk_print_unix_dialog_set_manual_capabilities (GtkPrintUnixDialog *dialog, - GtkPrintCapabilities capabilities); +GType gtk_print_unix_dialog_get_type (void) G_GNUC_CONST; +GtkWidget * gtk_print_unix_dialog_new (const gchar *title, + GtkWindow *parent); + +void gtk_print_unix_dialog_set_page_setup (GtkPrintUnixDialog *dialog, + GtkPageSetup *page_setup); +GtkPageSetup * gtk_print_unix_dialog_get_page_setup (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_set_current_page (GtkPrintUnixDialog *dialog, + gint current_page); +gint gtk_print_unix_dialog_get_current_page (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_set_settings (GtkPrintUnixDialog *dialog, + GtkPrintSettings *settings); +GtkPrintSettings * gtk_print_unix_dialog_get_settings (GtkPrintUnixDialog *dialog); +GtkPrinter * gtk_print_unix_dialog_get_selected_printer (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_add_custom_tab (GtkPrintUnixDialog *dialog, + GtkWidget *child, + GtkWidget *tab_label); +void gtk_print_unix_dialog_set_manual_capabilities (GtkPrintUnixDialog *dialog, + GtkPrintCapabilities capabilities); GtkPrintCapabilities gtk_print_unix_dialog_get_manual_capabilities (GtkPrintUnixDialog *dialog); void gtk_print_unix_dialog_set_support_selection (GtkPrintUnixDialog *dialog, gboolean support_selection); @@ -90,6 +90,10 @@ gboolean gtk_print_unix_dialog_get_support_selection (GtkPrintUnix void gtk_print_unix_dialog_set_has_selection (GtkPrintUnixDialog *dialog, gboolean has_selection); gboolean gtk_print_unix_dialog_get_has_selection (GtkPrintUnixDialog *dialog); +void gtk_print_unix_dialog_set_embed_page_setup (GtkPrintUnixDialog *dialog, + gboolean embed); +gboolean gtk_print_unix_dialog_get_embed_page_setup (GtkPrintUnixDialog *dialog); +gboolean gtk_print_unix_dialog_get_page_setup_set (GtkPrintUnixDialog *dialog); G_END_DECLS |