1 /* GtkPageSetupUnixDialog
2 * Copyright (C) 2006 Alexander Larsson <alexl@redhat.com>
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the
16 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 * Boston, MA 02111-1307, USA.
27 #include "gtkprivate.h"
29 #include "gtkliststore.h"
31 #include "gtktreeviewcolumn.h"
32 #include "gtktreeselection.h"
33 #include "gtktreemodel.h"
34 #include "gtkbutton.h"
35 #include "gtkscrolledwindow.h"
39 #include "gtkeventbox.h"
40 #include "gtkcombobox.h"
41 #include "gtktogglebutton.h"
42 #include "gtkradiobutton.h"
45 #include "gtktooltips.h"
46 #include "gtkcelllayout.h"
47 #include "gtkcellrenderertext.h"
48 #include "gtkalignment.h"
49 #include "gtkspinbutton.h"
51 #include "gtkpagesetupunixdialog.h"
52 #include "gtkprintbackend.h"
53 #include "gtkprinter-private.h"
54 #include "gtkpapersize.h"
57 #define CUSTOM_PAPER_FILENAME ".gtk-custom-papers"
59 #define MM_PER_INCH 25.4
60 #define POINTS_PER_INCH 72
63 struct GtkPageSetupUnixDialogPrivate
65 GtkListStore *printer_list;
66 GtkListStore *page_setup_list;
67 GtkListStore *custom_paper_list;
69 GList *print_backends;
71 GtkWidget *printer_combo;
72 GtkWidget *paper_size_combo;
73 GtkWidget *paper_size_label;
74 GtkWidget *paper_size_eventbox;
75 GtkTooltips *tooltips;
77 GtkWidget *portrait_radio;
78 GtkWidget *landscape_radio;
79 GtkWidget *reverse_landscape_radio;
81 guint request_details_tag;
83 GtkPrintSettings *print_settings;
85 /* Save last setup so we can re-set it after selecting manage custom sizes */
86 GtkPageSetup *last_setup;
88 char *waiting_for_printer;
92 PRINTER_LIST_COL_NAME,
93 PRINTER_LIST_COL_PRINTER,
98 PAGE_SETUP_LIST_COL_PAGE_SETUP,
99 PAGE_SETUP_LIST_COL_IS_SEPARATOR,
100 PAGE_SETUP_LIST_N_COLS
103 G_DEFINE_TYPE (GtkPageSetupUnixDialog, gtk_page_setup_unix_dialog, GTK_TYPE_DIALOG);
105 #define GTK_PAGE_SETUP_UNIX_DIALOG_GET_PRIVATE(o) \
106 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PAGE_SETUP_UNIX_DIALOG, GtkPageSetupUnixDialogPrivate))
108 static void gtk_page_setup_unix_dialog_finalize (GObject *object);
109 static void populate_dialog (GtkPageSetupUnixDialog *dialog);
110 static void fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog,
111 GtkPrinter *printer);
112 static void run_custom_paper_dialog (GtkPageSetupUnixDialog *dialog);
113 static void gtk_page_setup_unix_dialog_style_set (GtkWidget *widget,
114 GtkStyle *previous_style);
116 static const char * const common_paper_sizes[] = {
132 to_mm (double len, GtkUnit unit)
139 return len * MM_PER_INCH;
142 g_warning ("Unsupported unit");
144 case GTK_UNIT_POINTS:
145 return len * (MM_PER_INCH / POINTS_PER_INCH);
151 from_mm (double len, GtkUnit unit)
158 return len / MM_PER_INCH;
161 g_warning ("Unsupported unit");
163 case GTK_UNIT_POINTS:
164 return len / (MM_PER_INCH / POINTS_PER_INCH);
170 get_default_user_units (void)
172 /* Translate to the default units to use for presenting
173 * lengths to the user. Translate to default:inch if you
174 * want inches, otherwise translate to default:mm.
175 * Do *not* translate it to "predefinito:mm", if it
176 * it isn't default:mm or default:inch it will not work
178 char *e = _("default:mm");
180 #ifdef HAVE__NL_MEASUREMENT_MEASUREMENT
181 char *imperial = NULL;
183 imperial = nl_langinfo(_NL_MEASUREMENT_MEASUREMENT);
184 if (imperial && imperial[0] == 2 )
185 return GTK_UNIT_INCH; /* imperial */
186 if (imperial && imperial[0] == 1 )
187 return GTK_UNIT_MM; /* metric */
190 if (strcmp (e, "default:inch")==0)
191 return GTK_UNIT_INCH;
192 else if (strcmp (e, "default:mm"))
193 g_warning ("Whoever translated default:mm did so wrongly.\n");
198 custom_paper_get_filename (void)
202 filename = g_build_filename (g_get_home_dir (),
203 CUSTOM_PAPER_FILENAME, NULL);
204 g_assert (filename != NULL);
209 scan_double (char **text, double *val, gboolean last)
215 *val = g_ascii_strtod (p, &e);
222 while (g_ascii_isspace(*p))
232 load_custom_papers (GtkListStore *store)
237 filename = custom_paper_get_filename ();
239 if (g_file_get_contents (filename, &contents, NULL, NULL))
241 gchar **lines = g_strsplit (contents, "\n", -1);
242 double w, h, top, bottom, left, right;
243 GtkPaperSize *paper_size;
244 GtkPageSetup *page_setup;
249 for (i = 0; lines[i]; i++)
252 p = strchr(lines[i], ':');
257 while (g_ascii_isspace(*p))
260 if (!scan_double (&p, &w, FALSE))
262 if (!scan_double (&p, &h, FALSE))
264 if (!scan_double (&p, &top, FALSE))
266 if (!scan_double (&p, &bottom, FALSE))
268 if (!scan_double (&p, &left, FALSE))
270 if (!scan_double (&p, &right, TRUE))
273 page_setup = gtk_page_setup_new ();
274 paper_size = gtk_paper_size_new_custom (name, name, w, h, GTK_UNIT_MM);
275 gtk_page_setup_set_paper_size (page_setup, paper_size);
276 gtk_paper_size_free (paper_size);
278 gtk_page_setup_set_top_margin (page_setup, top, GTK_UNIT_MM);
279 gtk_page_setup_set_bottom_margin (page_setup, bottom, GTK_UNIT_MM);
280 gtk_page_setup_set_left_margin (page_setup, left, GTK_UNIT_MM);
281 gtk_page_setup_set_right_margin (page_setup, right, GTK_UNIT_MM);
283 gtk_list_store_append (store, &iter);
284 gtk_list_store_set (store, &iter,
288 g_object_unref (page_setup);
298 save_custom_papers (GtkListStore *store)
300 GtkTreeModel *model = GTK_TREE_MODEL (store);
305 string = g_string_new ("");
307 if (gtk_tree_model_get_iter_first (model, &iter))
311 GtkPaperSize *paper_size;
312 GtkPageSetup *page_setup;
313 char buffer[G_ASCII_DTOSTR_BUF_SIZE];
315 gtk_tree_model_get (model, &iter, 0, &page_setup, -1);
317 paper_size = gtk_page_setup_get_paper_size (page_setup);
318 g_string_append_printf (string, "%s: ", gtk_paper_size_get_name (paper_size));
320 g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
321 gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM));
322 g_string_append (string, buffer);
323 g_string_append (string, ", ");
324 g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
325 gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM));
326 g_string_append (string, buffer);
327 g_string_append (string, ", ");
328 g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
329 gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM));
330 g_string_append (string, buffer);
331 g_string_append (string, ", ");
332 g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
333 gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM));
334 g_string_append (string, buffer);
335 g_string_append (string, ", ");
336 g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
337 gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM));
338 g_string_append (string, buffer);
339 g_string_append (string, ", ");
340 g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
341 gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM));
342 g_string_append (string, buffer);
344 g_string_append (string, "\n");
346 } while (gtk_tree_model_iter_next (model, &iter));
349 filename = custom_paper_get_filename ();
350 g_file_set_contents (filename, string->str, -1, NULL);
353 g_string_free (string, TRUE);
357 gtk_page_setup_unix_dialog_class_init (GtkPageSetupUnixDialogClass *class)
359 GObjectClass *object_class;
360 GtkWidgetClass *widget_class;
362 object_class = (GObjectClass *) class;
363 widget_class = (GtkWidgetClass *) class;
365 object_class->finalize = gtk_page_setup_unix_dialog_finalize;
367 widget_class->style_set = gtk_page_setup_unix_dialog_style_set;
369 g_type_class_add_private (class, sizeof (GtkPageSetupUnixDialogPrivate));
373 gtk_page_setup_unix_dialog_init (GtkPageSetupUnixDialog *dialog)
377 gtk_dialog_set_has_separator (GTK_DIALOG (dialog), FALSE);
379 dialog->priv = GTK_PAGE_SETUP_UNIX_DIALOG_GET_PRIVATE (dialog);
380 dialog->priv->print_backends = NULL;
382 dialog->priv->printer_list = gtk_list_store_new (PRINTER_LIST_N_COLS,
386 gtk_list_store_append (dialog->priv->printer_list, &iter);
387 gtk_list_store_set (dialog->priv->printer_list, &iter,
388 PRINTER_LIST_COL_NAME, _("<b>Any Printer</b>\nFor portable documents"),
389 PRINTER_LIST_COL_PRINTER, NULL,
392 dialog->priv->page_setup_list = gtk_list_store_new (PAGE_SETUP_LIST_N_COLS,
396 dialog->priv->custom_paper_list = gtk_list_store_new (1, G_TYPE_OBJECT);
397 load_custom_papers (dialog->priv->custom_paper_list);
399 populate_dialog (dialog);
401 gtk_dialog_add_buttons (GTK_DIALOG (dialog),
402 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
403 GTK_STOCK_APPLY, GTK_RESPONSE_OK,
406 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
410 gtk_page_setup_unix_dialog_finalize (GObject *object)
412 GtkPageSetupUnixDialog *dialog = GTK_PAGE_SETUP_UNIX_DIALOG (object);
414 g_return_if_fail (object != NULL);
416 if (dialog->priv->request_details_tag)
418 g_source_remove (dialog->priv->request_details_tag);
419 dialog->priv->request_details_tag = 0;
422 if (dialog->priv->printer_list)
424 g_object_unref (dialog->priv->printer_list);
425 dialog->priv->printer_list = NULL;
428 if (dialog->priv->page_setup_list)
430 g_object_unref (dialog->priv->page_setup_list);
431 dialog->priv->page_setup_list = NULL;
434 if (dialog->priv->print_settings)
436 g_object_unref (dialog->priv->print_settings);
437 dialog->priv->print_settings = NULL;
440 g_free (dialog->priv->waiting_for_printer);
441 dialog->priv->waiting_for_printer = NULL;
443 if (G_OBJECT_CLASS (gtk_page_setup_unix_dialog_parent_class)->finalize)
444 G_OBJECT_CLASS (gtk_page_setup_unix_dialog_parent_class)->finalize (object);
448 gtk_page_setup_unix_dialog_style_set (GtkWidget *widget,
449 GtkStyle *previous_style)
453 if (GTK_WIDGET_CLASS (gtk_page_setup_unix_dialog_parent_class)->style_set)
454 GTK_WIDGET_CLASS (gtk_page_setup_unix_dialog_parent_class)->style_set (widget, previous_style);
456 dialog = GTK_DIALOG (widget);
458 /* Override the style properties with HIG-compliant spacings. Ugh.
459 * http://developer.gnome.org/projects/gup/hig/1.0/layout.html#layout-dialogs
460 * http://developer.gnome.org/projects/gup/hig/1.0/windows.html#alert-spacing
463 gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 12);
464 gtk_box_set_spacing (GTK_BOX (dialog->vbox), 24);
466 gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 0);
467 gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6);
472 printer_added_cb (GtkPrintBackend *backend,
474 GtkPageSetupUnixDialog *dialog)
478 const char *location;;
480 if (gtk_printer_is_virtual (printer))
483 location = gtk_printer_get_location (printer);
484 if (location == NULL)
486 str = g_strdup_printf ("<b>%s</b>\n%s",
487 gtk_printer_get_name (printer),
490 gtk_list_store_append (dialog->priv->printer_list, &iter);
491 gtk_list_store_set (dialog->priv->printer_list, &iter,
492 PRINTER_LIST_COL_NAME, str,
493 PRINTER_LIST_COL_PRINTER, printer,
496 g_object_set_data_full (G_OBJECT (printer),
497 "gtk-print-tree-iter",
498 gtk_tree_iter_copy (&iter),
499 (GDestroyNotify) gtk_tree_iter_free);
503 if (dialog->priv->waiting_for_printer != NULL &&
504 strcmp (dialog->priv->waiting_for_printer,
505 gtk_printer_get_name (printer)) == 0)
507 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->priv->printer_combo),
509 dialog->priv->waiting_for_printer = NULL;
514 printer_removed_cb (GtkPrintBackend *backend,
516 GtkPageSetupUnixDialog *dialog)
519 iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter");
520 gtk_list_store_remove (GTK_LIST_STORE (dialog->priv->printer_list), iter);
525 printer_status_cb (GtkPrintBackend *backend,
527 GtkPageSetupUnixDialog *dialog)
531 const char *location;;
533 iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter");
535 location = gtk_printer_get_location (printer);
536 if (location == NULL)
538 str = g_strdup_printf ("<b>%s</b>\n%s",
539 gtk_printer_get_name (printer),
541 gtk_list_store_set (dialog->priv->printer_list, iter,
542 PRINTER_LIST_COL_NAME, str,
547 printer_list_initialize (GtkPageSetupUnixDialog *dialog,
548 GtkPrintBackend *print_backend)
552 g_return_if_fail (print_backend != NULL);
554 g_signal_connect_object (print_backend,
556 (GCallback) printer_added_cb,
557 G_OBJECT (dialog), 0);
559 g_signal_connect_object (print_backend,
561 (GCallback) printer_removed_cb,
562 G_OBJECT (dialog), 0);
564 g_signal_connect_object (print_backend,
565 "printer-status-changed",
566 (GCallback) printer_status_cb,
567 G_OBJECT (dialog), 0);
569 list = gtk_print_backend_get_printer_list (print_backend);
574 printer_added_cb (print_backend, node->data, dialog);
583 load_print_backends (GtkPageSetupUnixDialog *dialog)
587 if (g_module_supported ())
588 dialog->priv->print_backends = gtk_print_backend_load_modules ();
590 for (node = dialog->priv->print_backends; node != NULL; node = node->next)
591 printer_list_initialize (dialog, GTK_PRINT_BACKEND (node->data));
595 paper_size_row_is_separator (GtkTreeModel *model,
601 gtk_tree_model_get (model, iter, PAGE_SETUP_LIST_COL_IS_SEPARATOR, &separator, -1);
605 static GtkPageSetup *
606 get_current_page_setup (GtkPageSetupUnixDialog *dialog)
608 GtkPageSetup *current_page_setup;
609 GtkComboBox *combo_box;
612 current_page_setup = NULL;
614 combo_box = GTK_COMBO_BOX (dialog->priv->paper_size_combo);
615 if (gtk_combo_box_get_active_iter (combo_box, &iter))
616 gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->page_setup_list), &iter,
617 PAGE_SETUP_LIST_COL_PAGE_SETUP, ¤t_page_setup, -1);
619 if (current_page_setup)
620 return current_page_setup;
622 /* No selected page size, return the default one.
623 * This is used to set the first page setup when the dialog is created
624 * as there is no selection on the first printer_changed.
626 return gtk_page_setup_new ();
630 page_setup_is_equal (GtkPageSetup *a, GtkPageSetup *b)
633 gtk_paper_size_is_equal (gtk_page_setup_get_paper_size (a),
634 gtk_page_setup_get_paper_size (b)) &&
635 gtk_page_setup_get_top_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_top_margin (b, GTK_UNIT_MM) &&
636 gtk_page_setup_get_bottom_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_bottom_margin (b, GTK_UNIT_MM) &&
637 gtk_page_setup_get_left_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_left_margin (b, GTK_UNIT_MM) &&
638 gtk_page_setup_get_right_margin (a, GTK_UNIT_MM) == gtk_page_setup_get_right_margin (b, GTK_UNIT_MM);
642 page_setup_is_same_size (GtkPageSetup *a, GtkPageSetup *b)
644 return gtk_paper_size_is_equal (gtk_page_setup_get_paper_size (a),
645 gtk_page_setup_get_paper_size (b));
649 set_paper_size (GtkPageSetupUnixDialog *dialog,
650 GtkPageSetup *page_setup,
656 GtkPageSetup *list_page_setup;
658 model = GTK_TREE_MODEL (dialog->priv->page_setup_list);
660 if (gtk_tree_model_get_iter_first (model, &iter))
664 gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->page_setup_list), &iter,
665 PAGE_SETUP_LIST_COL_PAGE_SETUP, &list_page_setup, -1);
666 if (list_page_setup == NULL)
669 if ((size_only && page_setup_is_same_size (page_setup, list_page_setup)) ||
670 (!size_only && page_setup_is_equal (page_setup, list_page_setup)))
672 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->priv->paper_size_combo),
674 g_object_unref (list_page_setup);
678 g_object_unref (list_page_setup);
680 } while (gtk_tree_model_iter_next (model, &iter));
685 gtk_list_store_append (dialog->priv->page_setup_list, &iter);
686 gtk_list_store_set (dialog->priv->page_setup_list, &iter,
687 PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE,
689 gtk_list_store_append (dialog->priv->page_setup_list, &iter);
690 gtk_list_store_set (dialog->priv->page_setup_list, &iter,
691 PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup,
693 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->priv->paper_size_combo),
702 fill_custom_paper_sizes (GtkPageSetupUnixDialog *dialog)
704 GtkTreeIter iter, paper_iter;
707 model = GTK_TREE_MODEL (dialog->priv->custom_paper_list);
708 if (gtk_tree_model_get_iter_first (model, &iter))
710 gtk_list_store_append (dialog->priv->page_setup_list, &paper_iter);
711 gtk_list_store_set (dialog->priv->page_setup_list, &paper_iter,
712 PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE,
716 GtkPageSetup *page_setup;
717 gtk_tree_model_get (model, &iter, 0, &page_setup, -1);
719 gtk_list_store_append (dialog->priv->page_setup_list, &paper_iter);
720 gtk_list_store_set (dialog->priv->page_setup_list, &paper_iter,
721 PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup,
724 g_object_unref (page_setup);
725 } while (gtk_tree_model_iter_next (model, &iter));
728 gtk_list_store_append (dialog->priv->page_setup_list, &paper_iter);
729 gtk_list_store_set (dialog->priv->page_setup_list, &paper_iter,
730 PAGE_SETUP_LIST_COL_IS_SEPARATOR, TRUE,
732 gtk_list_store_append (dialog->priv->page_setup_list, &paper_iter);
733 gtk_list_store_set (dialog->priv->page_setup_list, &paper_iter,
734 PAGE_SETUP_LIST_COL_PAGE_SETUP, NULL,
739 fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog,
743 GtkPageSetup *current_page_setup, *page_setup;
744 GtkPaperSize *paper_size;
748 current_page_setup = get_current_page_setup (dialog);
750 gtk_list_store_clear (dialog->priv->page_setup_list);
754 for (i = 0; i < G_N_ELEMENTS (common_paper_sizes); i++)
756 page_setup = gtk_page_setup_new ();
757 paper_size = gtk_paper_size_new (common_paper_sizes[i]);
758 gtk_page_setup_set_paper_size_and_default_margins (page_setup, paper_size);
759 gtk_paper_size_free (paper_size);
761 gtk_list_store_append (dialog->priv->page_setup_list, &iter);
762 gtk_list_store_set (dialog->priv->page_setup_list, &iter,
763 PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup,
765 g_object_unref (page_setup);
770 list = _gtk_printer_list_papers (printer);
771 /* TODO: We should really sort this list so interesting size
773 for (l = list; l != NULL; l = l->next)
775 page_setup = l->data;
776 gtk_list_store_append (dialog->priv->page_setup_list, &iter);
777 gtk_list_store_set (dialog->priv->page_setup_list, &iter,
778 PAGE_SETUP_LIST_COL_PAGE_SETUP, page_setup,
780 g_object_unref (page_setup);
785 fill_custom_paper_sizes (dialog);
787 if (!set_paper_size (dialog, current_page_setup, FALSE, FALSE))
788 set_paper_size (dialog, current_page_setup, TRUE, TRUE);
790 if (current_page_setup)
791 g_object_unref (current_page_setup);
795 printer_changed_finished_callback (GtkPrinter *printer,
797 GtkPageSetupUnixDialog *dialog)
799 dialog->priv->request_details_tag = 0;
802 fill_paper_sizes_from_printer (dialog, printer);
807 printer_changed_callback (GtkComboBox *combo_box,
808 GtkPageSetupUnixDialog *dialog)
813 /* If we're waiting for a specific printer but the user changed
814 to another printer, cancel that wait. */
815 if (dialog->priv->waiting_for_printer)
817 g_free (dialog->priv->waiting_for_printer);
818 dialog->priv->waiting_for_printer = NULL;
821 if (dialog->priv->request_details_tag)
823 g_source_remove (dialog->priv->request_details_tag);
824 dialog->priv->request_details_tag = 0;
827 if (gtk_combo_box_get_active_iter (combo_box, &iter))
829 gtk_tree_model_get (gtk_combo_box_get_model (combo_box), &iter,
830 PRINTER_LIST_COL_PRINTER, &printer, -1);
832 if (printer == NULL || _gtk_printer_has_details (printer))
833 fill_paper_sizes_from_printer (dialog, printer);
836 dialog->priv->request_details_tag =
837 g_signal_connect (printer, "details-acquired",
838 G_CALLBACK (printer_changed_finished_callback), dialog);
839 _gtk_printer_request_details (printer);
844 g_object_unref (printer);
846 if (dialog->priv->print_settings)
848 const char *name = NULL;
851 name = gtk_printer_get_name (printer);
853 gtk_print_settings_set (dialog->priv->print_settings,
854 "format-for-printer", name);
859 /* We do this munging because we don't want to show zero digits
860 after the decimal point, and not to many such digits if they
861 are nonzero. I wish printf let you specify max precision for %f... */
863 double_to_string (double d, GtkUnit unit)
866 struct lconv *locale_data;
867 const char *decimal_point;
868 int decimal_point_len;
870 locale_data = localeconv ();
871 decimal_point = locale_data->decimal_point;
872 decimal_point_len = strlen (decimal_point);
874 /* Max two decimal digits for inch, max one for mm */
875 if (unit == GTK_UNIT_INCH)
876 val = g_strdup_printf ("%.2f", d);
878 val = g_strdup_printf ("%.1f", d);
880 if (strstr (val, decimal_point))
882 p = val + strlen (val) - 1;
885 if (p - val + 1 >= decimal_point_len &&
886 strncmp (p - (decimal_point_len - 1), decimal_point, decimal_point_len) == 0)
887 p -= decimal_point_len;
895 paper_size_changed (GtkComboBox *combo_box, GtkPageSetupUnixDialog *dialog)
898 GtkPageSetup *page_setup, *last_page_setup;
901 char *top, *bottom, *left, *right;
903 const char *unit_str;
905 label = GTK_LABEL (dialog->priv->paper_size_label);
907 if (gtk_combo_box_get_active_iter (combo_box, &iter))
909 gtk_tree_model_get (gtk_combo_box_get_model (combo_box),
910 &iter, PAGE_SETUP_LIST_COL_PAGE_SETUP, &page_setup, -1);
912 if (page_setup == NULL)
914 run_custom_paper_dialog (dialog);
916 /* Save current last_setup as it is changed by updating the list */
917 last_page_setup = NULL;
918 if (dialog->priv->last_setup)
919 last_page_setup = g_object_ref (dialog->priv->last_setup);
921 /* Update printer page list */
922 printer_changed_callback (GTK_COMBO_BOX (dialog->priv->printer_combo), dialog);
924 /* Change from "manage" menu item to last value */
925 if (last_page_setup == NULL)
926 last_page_setup = gtk_page_setup_new (); /* "good" default */
927 set_paper_size (dialog, last_page_setup, FALSE, TRUE);
928 g_object_unref (last_page_setup);
933 if (dialog->priv->last_setup)
934 g_object_unref (dialog->priv->last_setup);
936 dialog->priv->last_setup = g_object_ref (page_setup);
938 unit = get_default_user_units ();
940 if (unit == GTK_UNIT_MM)
943 unit_str = _("inch");
946 w = double_to_string (gtk_page_setup_get_paper_width (page_setup, unit),
948 h = double_to_string (gtk_page_setup_get_paper_height (page_setup, unit),
950 str = g_strdup_printf ("%s x %s %s", w, h, unit_str);
954 gtk_label_set_text (label, str);
957 top = double_to_string (gtk_page_setup_get_top_margin (page_setup, unit), unit);
958 bottom = double_to_string (gtk_page_setup_get_bottom_margin (page_setup, unit), unit);
959 left = double_to_string (gtk_page_setup_get_left_margin (page_setup, unit), unit);
960 right = double_to_string (gtk_page_setup_get_right_margin (page_setup, unit), unit);
962 str = g_strdup_printf (_("Margins:\n"
977 gtk_tooltips_set_tip (GTK_TOOLTIPS (dialog->priv->tooltips),
978 dialog->priv->paper_size_eventbox, str, NULL);
981 g_object_unref (page_setup);
985 gtk_label_set_text (label, "");
986 gtk_tooltips_set_tip (GTK_TOOLTIPS (dialog->priv->tooltips),
987 dialog->priv->paper_size_eventbox, NULL, NULL);
988 if (dialog->priv->last_setup)
989 g_object_unref (dialog->priv->last_setup);
990 dialog->priv->last_setup = NULL;
995 page_name_func (GtkCellLayout *cell_layout,
996 GtkCellRenderer *cell,
997 GtkTreeModel *tree_model,
1001 GtkPageSetup *page_setup;
1002 GtkPaperSize *paper_size;
1004 gtk_tree_model_get (tree_model, iter,
1005 PAGE_SETUP_LIST_COL_PAGE_SETUP, &page_setup, -1);
1008 paper_size = gtk_page_setup_get_paper_size (page_setup);
1009 g_object_set (cell, "text", gtk_paper_size_get_display_name (paper_size), NULL);
1010 g_object_unref (page_setup);
1013 g_object_set (cell, "text", _("Manage Custom Sizes..."), NULL);
1019 populate_dialog (GtkPageSetupUnixDialog *dialog)
1021 GtkPageSetupUnixDialogPrivate *priv;
1022 GtkWidget *table, *label, *combo, *radio_button, *ebox, *image;
1023 GtkCellRenderer *cell;
1025 g_return_if_fail (GTK_IS_PAGE_SETUP_UNIX_DIALOG (dialog));
1027 priv = dialog->priv;
1029 table = gtk_table_new (4, 4, FALSE);
1030 gtk_table_set_row_spacings (GTK_TABLE (table), 12);
1031 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
1032 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox),
1033 table, TRUE, TRUE, 6);
1034 gtk_widget_show (table);
1036 label = gtk_label_new_with_mnemonic (_("_Format for:"));
1037 gtk_table_attach (GTK_TABLE (table), label,
1040 gtk_widget_show (label);
1042 combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (dialog->priv->printer_list));
1043 dialog->priv->printer_combo = combo;
1045 cell = gtk_cell_renderer_text_new ();
1046 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
1047 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo), cell,
1048 "markup", PRINTER_LIST_COL_NAME,
1051 gtk_table_attach (GTK_TABLE (table), combo,
1053 GTK_FILL | GTK_EXPAND, 0, 0, 0);
1054 gtk_widget_show (combo);
1056 label = gtk_label_new_with_mnemonic (_("_Paper size:"));
1057 gtk_table_attach (GTK_TABLE (table), label,
1060 gtk_widget_show (label);
1062 combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (dialog->priv->page_setup_list));
1063 dialog->priv->paper_size_combo = combo;
1064 gtk_combo_box_set_row_separator_func (GTK_COMBO_BOX (combo),
1065 paper_size_row_is_separator, NULL, NULL);
1067 cell = gtk_cell_renderer_text_new ();
1068 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
1069 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell,
1070 page_name_func, NULL, NULL);
1072 gtk_table_attach (GTK_TABLE (table), combo,
1074 GTK_FILL | GTK_EXPAND, 0, 0, 0);
1075 gtk_widget_show (combo);
1077 gtk_table_set_row_spacing (GTK_TABLE (table), 1, 0);
1079 ebox = gtk_event_box_new ();
1080 dialog->priv->paper_size_eventbox = ebox;
1081 gtk_event_box_set_visible_window (GTK_EVENT_BOX (ebox), FALSE);
1082 gtk_table_attach (GTK_TABLE (table), ebox,
1085 gtk_widget_show (ebox);
1087 label = gtk_label_new_with_mnemonic ("");
1088 dialog->priv->paper_size_label = label;
1089 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
1090 gtk_misc_set_padding (GTK_MISC (label), 12, 4);
1091 gtk_container_add (GTK_CONTAINER (ebox), label);
1092 gtk_widget_show (label);
1094 label = gtk_label_new_with_mnemonic (_("_Orientation:"));
1095 gtk_table_attach (GTK_TABLE (table), label,
1098 gtk_widget_show (label);
1100 radio_button = gtk_radio_button_new (NULL);
1101 image = gtk_image_new_from_stock (GTK_STOCK_ORIENTATION_PORTRAIT,
1102 GTK_ICON_SIZE_LARGE_TOOLBAR);
1103 gtk_widget_show (image);
1104 gtk_container_add (GTK_CONTAINER (radio_button), image);
1105 dialog->priv->portrait_radio = radio_button;
1106 gtk_table_attach (GTK_TABLE (table), radio_button,
1109 gtk_widget_show (radio_button);
1111 radio_button = gtk_radio_button_new (gtk_radio_button_get_group (GTK_RADIO_BUTTON(radio_button)));
1112 image = gtk_image_new_from_stock (GTK_STOCK_ORIENTATION_LANDSCAPE,
1113 GTK_ICON_SIZE_LARGE_TOOLBAR);
1114 gtk_widget_show (image);
1115 gtk_container_add (GTK_CONTAINER (radio_button), image);
1116 dialog->priv->landscape_radio = radio_button;
1117 gtk_table_attach (GTK_TABLE (table), radio_button,
1120 gtk_widget_show (radio_button);
1122 gtk_table_set_row_spacing (GTK_TABLE (table), 3, 0);
1124 radio_button = gtk_radio_button_new (gtk_radio_button_get_group (GTK_RADIO_BUTTON(radio_button)));
1125 image = gtk_image_new_from_stock (GTK_STOCK_ORIENTATION_REVERSE_LANDSCAPE,
1126 GTK_ICON_SIZE_LARGE_TOOLBAR);
1127 gtk_widget_show (image);
1128 gtk_container_add (GTK_CONTAINER (radio_button), image);
1129 dialog->priv->reverse_landscape_radio = radio_button;
1130 gtk_table_attach (GTK_TABLE (table), radio_button,
1133 gtk_widget_show (radio_button);
1135 dialog->priv->tooltips = gtk_tooltips_new ();
1137 g_signal_connect (dialog->priv->paper_size_combo, "changed", G_CALLBACK (paper_size_changed), dialog);
1138 g_signal_connect (dialog->priv->printer_combo, "changed", G_CALLBACK (printer_changed_callback), dialog);
1139 gtk_combo_box_set_active (GTK_COMBO_BOX (dialog->priv->printer_combo), 0);
1141 load_print_backends (dialog);
1145 gtk_page_setup_unix_dialog_new (const gchar *title,
1151 title = _("Page Setup");
1153 result = g_object_new (GTK_TYPE_PAGE_SETUP_UNIX_DIALOG,
1158 gtk_window_set_transient_for (GTK_WINDOW (result), parent);
1163 static GtkPageOrientation
1164 get_orientation (GtkPageSetupUnixDialog *dialog)
1166 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->portrait_radio)))
1167 return GTK_PAGE_ORIENTATION_PORTRAIT;
1168 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->landscape_radio)))
1169 return GTK_PAGE_ORIENTATION_LANDSCAPE;
1170 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (dialog->priv->reverse_landscape_radio)))
1171 return GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE;
1172 return GTK_PAGE_ORIENTATION_PORTRAIT;
1176 set_orientation (GtkPageSetupUnixDialog *dialog, GtkPageOrientation orientation)
1178 switch (orientation)
1180 case GTK_PAGE_ORIENTATION_REVERSE_PORTRAIT:
1181 case GTK_PAGE_ORIENTATION_PORTRAIT:
1182 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->portrait_radio), TRUE);
1184 case GTK_PAGE_ORIENTATION_LANDSCAPE:
1185 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->landscape_radio), TRUE);
1187 case GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE:
1188 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (dialog->priv->reverse_landscape_radio), TRUE);
1195 gtk_page_setup_unix_dialog_set_page_setup (GtkPageSetupUnixDialog *dialog,
1196 GtkPageSetup *page_setup)
1200 set_paper_size (dialog, page_setup, FALSE, TRUE);
1201 set_orientation (dialog, gtk_page_setup_get_orientation (page_setup));
1206 gtk_page_setup_unix_dialog_get_page_setup (GtkPageSetupUnixDialog *dialog)
1208 GtkPageSetup *page_setup;
1210 page_setup = get_current_page_setup (dialog);
1211 if (page_setup == NULL)
1212 page_setup = gtk_page_setup_new ();
1214 gtk_page_setup_set_orientation (page_setup, get_orientation (dialog));
1220 set_active_printer (GtkPageSetupUnixDialog *dialog,
1221 const char *printer_name)
1223 GtkTreeModel *model;
1225 GtkPrinter *printer;
1227 model = GTK_TREE_MODEL (dialog->priv->printer_list);
1229 if (gtk_tree_model_get_iter_first (model, &iter))
1233 gtk_tree_model_get (GTK_TREE_MODEL (dialog->priv->printer_list), &iter,
1234 PRINTER_LIST_COL_PRINTER, &printer, -1);
1235 if (printer == NULL)
1238 if (strcmp (gtk_printer_get_name (printer), printer_name) == 0)
1240 gtk_combo_box_set_active_iter (GTK_COMBO_BOX (dialog->priv->printer_combo),
1242 g_object_unref (printer);
1246 g_object_unref (printer);
1248 } while (gtk_tree_model_iter_next (model, &iter));
1255 gtk_page_setup_unix_dialog_set_print_settings (GtkPageSetupUnixDialog *dialog,
1256 GtkPrintSettings *print_settings)
1258 const char *format_for_printer;
1260 if (dialog->priv->print_settings)
1261 g_object_unref (dialog->priv->print_settings);
1263 dialog->priv->print_settings = print_settings;
1267 g_object_ref (print_settings);
1269 format_for_printer = gtk_print_settings_get (print_settings, "format-for-printer");
1271 /* Set printer if in list, otherwise set when that printer
1273 if (format_for_printer &&
1274 !set_active_printer (dialog, format_for_printer))
1275 dialog->priv->waiting_for_printer = g_strdup (format_for_printer);
1280 gtk_page_setup_unix_dialog_get_print_settings (GtkPageSetupUnixDialog *dialog)
1282 return dialog->priv->print_settings;
1286 wrap_in_frame (const char *label, GtkWidget *child)
1288 GtkWidget *frame, *alignment, *label_widget;
1291 label_widget = gtk_label_new ("");
1292 gtk_widget_show (label_widget);
1294 bold_text = g_markup_printf_escaped ("<b>%s</b>", label);
1295 gtk_label_set_markup (GTK_LABEL (label_widget), bold_text);
1298 frame = gtk_frame_new ("");
1299 gtk_frame_set_label_widget (GTK_FRAME (frame), label_widget);
1300 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
1302 alignment = gtk_alignment_new (0.5, 0.5, 1.0, 1.0);
1303 gtk_alignment_set_padding (GTK_ALIGNMENT (alignment),
1305 gtk_container_add (GTK_CONTAINER (frame), alignment);
1307 gtk_container_add (GTK_CONTAINER (alignment), child);
1309 gtk_widget_show (frame);
1310 gtk_widget_show (alignment);
1316 GtkUnit display_unit;
1317 GtkWidget *spin_button;
1321 GtkPageSetupUnixDialog *dialog;
1322 GtkWidget *treeview;
1323 GtkTreeViewColumn *text_column;
1324 gboolean non_user_change;
1325 GtkWidget *printer_combo;
1326 GtkWidget *width_widget;
1327 GtkWidget *height_widget;
1328 GtkWidget *top_widget;
1329 GtkWidget *bottom_widget;
1330 GtkWidget *left_widget;
1331 GtkWidget *right_widget;
1332 guint request_details_tag;
1333 } CustomPaperDialog;
1335 static void unit_widget_changed (CustomPaperDialog *data);
1338 new_unit_widget (CustomPaperDialog *dialog, GtkUnit unit)
1340 GtkWidget *hbox, *button, *label;
1343 data = g_new0 (UnitWidget, 1);
1344 data->display_unit = unit;
1346 hbox = gtk_hbox_new (FALSE, 0);
1348 button = gtk_spin_button_new_with_range (0.0, 9999.0, 1);
1349 if (unit == GTK_UNIT_INCH)
1350 gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 2);
1352 gtk_spin_button_set_digits (GTK_SPIN_BUTTON (button), 1);
1354 gtk_box_pack_start (GTK_BOX (hbox), button, TRUE, TRUE, 0);
1355 gtk_widget_show (button);
1357 data->spin_button = button;
1359 g_signal_connect_swapped (button, "value_changed",
1360 G_CALLBACK (unit_widget_changed), dialog);
1362 if (unit == GTK_UNIT_INCH)
1363 label = gtk_label_new (_(" inch"));
1365 label = gtk_label_new (_(" mm"));
1367 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
1368 gtk_widget_show (label);
1370 g_object_set_data_full (G_OBJECT (hbox), "unit-data", data, g_free);
1376 unit_widget_get (GtkWidget *unit_widget)
1378 UnitWidget *data = g_object_get_data (G_OBJECT (unit_widget), "unit-data");
1379 return to_mm (gtk_spin_button_get_value (GTK_SPIN_BUTTON (data->spin_button)),
1380 data->display_unit);
1384 unit_widget_set (GtkWidget *unit_widget, double val)
1386 UnitWidget *data = g_object_get_data (G_OBJECT (unit_widget), "unit-data");
1387 gtk_spin_button_set_value (GTK_SPIN_BUTTON (data->spin_button),
1388 from_mm (val, data->display_unit));
1393 unit_widget_set_sensitive (GtkWidget *unit_widget, gboolean sensitive)
1395 UnitWidget *data = g_object_get_data (G_OBJECT (unit_widget), "unit-data");
1396 gtk_widget_set_sensitive (data->spin_button, sensitive);
1400 custom_paper_printer_data_func (GtkCellLayout *cell_layout,
1401 GtkCellRenderer *cell,
1402 GtkTreeModel *tree_model,
1406 GtkPrinter *printer;
1407 gtk_tree_model_get (tree_model, iter,
1408 PRINTER_LIST_COL_PRINTER, &printer, -1);
1411 g_object_set (cell, "text", gtk_printer_get_name (printer), NULL);
1413 g_object_set (cell, "text", _("Margins from Printer..."), NULL);
1416 g_object_unref (printer);
1420 update_combo_sensitivity_from_printers (CustomPaperDialog *data)
1424 GtkTreeSelection *selection;
1425 GtkTreeModel *model;
1428 model = GTK_TREE_MODEL (data->dialog->priv->printer_list);
1429 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview));
1430 if (gtk_tree_model_get_iter_first (model, &iter) &&
1431 gtk_tree_model_iter_next (model, &iter) &&
1432 gtk_tree_selection_get_selected (selection, NULL, &iter))
1435 g_print ("sensitive: %d\n", sensitive);
1436 gtk_widget_set_sensitive (data->printer_combo, sensitive);
1440 update_custom_widgets_from_list (CustomPaperDialog *data)
1442 GtkTreeSelection *selection;
1443 GtkTreeModel *model;
1445 GtkPageSetup *page_setup;
1447 model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->treeview));
1448 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview));
1450 data->non_user_change = TRUE;
1451 if (gtk_tree_selection_get_selected (selection, NULL, &iter))
1453 gtk_tree_model_get (model, &iter, 0, &page_setup, -1);
1455 unit_widget_set (data->width_widget,
1456 gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM));
1457 unit_widget_set (data->height_widget,
1458 gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM));
1459 unit_widget_set (data->top_widget,
1460 gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM));
1461 unit_widget_set (data->bottom_widget,
1462 gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM));
1463 unit_widget_set (data->left_widget,
1464 gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM));
1465 unit_widget_set (data->right_widget,
1466 gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM));
1468 unit_widget_set_sensitive (data->width_widget, TRUE);
1469 unit_widget_set_sensitive (data->height_widget, TRUE);
1470 unit_widget_set_sensitive (data->top_widget, TRUE);
1471 unit_widget_set_sensitive (data->bottom_widget, TRUE);
1472 unit_widget_set_sensitive (data->left_widget, TRUE);
1473 unit_widget_set_sensitive (data->right_widget, TRUE);
1477 unit_widget_set_sensitive (data->width_widget, FALSE);
1478 unit_widget_set_sensitive (data->height_widget, FALSE);
1479 unit_widget_set_sensitive (data->top_widget, FALSE);
1480 unit_widget_set_sensitive (data->bottom_widget, FALSE);
1481 unit_widget_set_sensitive (data->left_widget, FALSE);
1482 unit_widget_set_sensitive (data->right_widget, FALSE);
1485 update_combo_sensitivity_from_printers (data);
1486 data->non_user_change = FALSE;
1490 selected_custom_paper_changed (GtkTreeSelection *selection,
1491 CustomPaperDialog *data)
1493 update_custom_widgets_from_list (data);
1497 unit_widget_changed (CustomPaperDialog *data)
1499 double w, h, top, bottom, left, right;
1500 GtkTreeSelection *selection;
1502 GtkPageSetup *page_setup;
1503 GtkPaperSize *paper_size;
1505 if (data->non_user_change)
1508 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview));
1510 if (gtk_tree_selection_get_selected (selection, NULL, &iter))
1512 gtk_tree_model_get (GTK_TREE_MODEL (data->dialog->priv->custom_paper_list), &iter, 0, &page_setup, -1);
1514 w = unit_widget_get (data->width_widget);
1515 h = unit_widget_get (data->height_widget);
1517 paper_size = gtk_page_setup_get_paper_size (page_setup);
1518 gtk_paper_size_set_size (paper_size, w, h, GTK_UNIT_MM);
1520 top = unit_widget_get (data->top_widget);
1521 bottom = unit_widget_get (data->bottom_widget);
1522 left = unit_widget_get (data->left_widget);
1523 right = unit_widget_get (data->right_widget);
1525 gtk_page_setup_set_top_margin (page_setup, top, GTK_UNIT_MM);
1526 gtk_page_setup_set_bottom_margin (page_setup, bottom, GTK_UNIT_MM);
1527 gtk_page_setup_set_left_margin (page_setup, left, GTK_UNIT_MM);
1528 gtk_page_setup_set_right_margin (page_setup, right, GTK_UNIT_MM);
1530 g_object_unref (page_setup);
1535 custom_paper_name_used (CustomPaperDialog *data, const char *name)
1537 GtkTreeModel *model;
1539 GtkPageSetup *page_setup;
1540 GtkPaperSize *paper_size;
1542 model = gtk_tree_view_get_model (GTK_TREE_VIEW (data->treeview));
1544 if (gtk_tree_model_get_iter_first (model, &iter))
1548 gtk_tree_model_get (model, &iter, 0, &page_setup, -1);
1549 paper_size = gtk_page_setup_get_paper_size (page_setup);
1551 gtk_paper_size_get_name (paper_size)) == 0)
1553 g_object_unref (page_setup);
1556 g_object_unref (page_setup);
1557 } while (gtk_tree_model_iter_next (model, &iter));
1564 add_custom_paper (CustomPaperDialog *data)
1566 GtkListStore *store;
1567 GtkPageSetup *page_setup;
1568 GtkPaperSize *paper_size;
1569 GtkTreeSelection *selection;
1575 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview));
1576 store = data->dialog->priv->custom_paper_list;
1583 name = g_strdup_printf (_("Custom Size %d"), i);
1585 } while (custom_paper_name_used (data, name));
1587 page_setup = gtk_page_setup_new ();
1588 paper_size = gtk_paper_size_new_custom (name, name,
1589 gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM),
1590 gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM),
1592 gtk_page_setup_set_paper_size (page_setup, paper_size);
1593 gtk_paper_size_free (paper_size);
1595 gtk_list_store_append (store, &iter);
1596 gtk_list_store_set (store, &iter, 0, page_setup, -1);
1597 g_object_unref (page_setup);
1599 gtk_tree_selection_select_iter (selection, &iter);
1600 path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
1601 gtk_widget_grab_focus (data->treeview);
1602 gtk_tree_view_set_cursor (GTK_TREE_VIEW (data->treeview), path,
1603 data->text_column, TRUE);
1604 gtk_tree_path_free (path);
1609 remove_custom_paper (CustomPaperDialog *data)
1611 GtkTreeSelection *selection;
1613 GtkListStore *store;
1615 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview));
1616 store = data->dialog->priv->custom_paper_list;
1618 if (gtk_tree_selection_get_selected (selection, NULL, &iter))
1620 GtkTreePath *path = gtk_tree_model_get_path (GTK_TREE_MODEL (store), &iter);
1621 gtk_list_store_remove (store, &iter);
1623 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
1624 gtk_tree_selection_select_iter (selection, &iter);
1625 else if (gtk_tree_path_prev (path) && gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path))
1626 gtk_tree_selection_select_iter (selection, &iter);
1628 gtk_tree_path_free (path);
1633 set_margins_from_printer (CustomPaperDialog *data,
1634 GtkPrinter *printer)
1636 double top, bottom, left, right;
1638 top = bottom = left = right = 0;
1639 _gtk_printer_get_hard_margins (printer, &top, &bottom, &left, &right);
1641 data->non_user_change = TRUE;
1642 unit_widget_set (data->top_widget, to_mm (top, GTK_UNIT_POINTS));
1643 unit_widget_set (data->bottom_widget, to_mm (bottom, GTK_UNIT_POINTS));
1644 unit_widget_set (data->left_widget, to_mm (left, GTK_UNIT_POINTS));
1645 unit_widget_set (data->right_widget, to_mm (right, GTK_UNIT_POINTS));
1646 data->non_user_change = FALSE;
1648 /* Only send one change */
1649 unit_widget_changed (data);
1653 get_margins_finished_callback (GtkPrinter *printer,
1655 CustomPaperDialog *data)
1657 data->request_details_tag = 0;
1660 set_margins_from_printer (data, printer);
1662 gtk_combo_box_set_active (GTK_COMBO_BOX (data->printer_combo), 0);
1666 margins_from_printer_changed (CustomPaperDialog *data)
1670 GtkPrinter *printer;
1672 combo = GTK_COMBO_BOX (data->printer_combo);
1674 if (data->request_details_tag)
1676 g_source_remove (data->request_details_tag);
1677 data->request_details_tag = 0;
1680 if (gtk_combo_box_get_active_iter (combo, &iter))
1682 gtk_tree_model_get (gtk_combo_box_get_model (combo), &iter,
1683 PRINTER_LIST_COL_PRINTER, &printer, -1);
1687 if (_gtk_printer_has_details (printer))
1689 set_margins_from_printer (data, printer);
1690 gtk_combo_box_set_active (combo, 0);
1694 data->request_details_tag =
1695 g_signal_connect (printer, "details-acquired",
1696 G_CALLBACK (get_margins_finished_callback), data);
1697 _gtk_printer_request_details (printer);
1700 g_object_unref (printer);
1707 custom_paper_dialog_free (gpointer p)
1709 CustomPaperDialog *data = p;
1710 if (data->request_details_tag)
1712 g_source_remove (data->request_details_tag);
1713 data->request_details_tag = 0;
1720 custom_size_name_edited (GtkCellRenderer *cell,
1723 CustomPaperDialog *data)
1727 GtkListStore *store;
1728 GtkPageSetup *page_setup;
1729 GtkPaperSize *paper_size;
1731 store = data->dialog->priv->custom_paper_list;
1732 path = gtk_tree_path_new_from_string (path_string);
1733 gtk_tree_model_get_iter (GTK_TREE_MODEL (store), &iter, path);
1734 gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, 0, &page_setup, -1);
1735 gtk_tree_path_free (path);
1737 paper_size = gtk_paper_size_new_custom (new_text, new_text,
1738 gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM),
1739 gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM),
1741 gtk_page_setup_set_paper_size (page_setup, paper_size);
1742 gtk_paper_size_free (paper_size);
1744 g_object_unref (page_setup);
1748 custom_name_func (GtkTreeViewColumn *tree_column,
1749 GtkCellRenderer *cell,
1750 GtkTreeModel *tree_model,
1754 GtkPageSetup *page_setup;
1755 GtkPaperSize *paper_size;
1757 gtk_tree_model_get (tree_model, iter, 0, &page_setup, -1);
1760 paper_size = gtk_page_setup_get_paper_size (page_setup);
1761 g_object_set (cell, "text", gtk_paper_size_get_display_name (paper_size), NULL);
1762 g_object_unref (page_setup);
1767 set_dialog_hig_spacing (GtkWidget *widget,
1768 GtkStyle *previous_style,
1771 gtk_container_set_border_width (GTK_CONTAINER (dialog->vbox), 12);
1772 gtk_box_set_spacing (GTK_BOX (dialog->vbox), 24);
1773 gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 0);
1774 gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6);
1778 run_custom_paper_dialog (GtkPageSetupUnixDialog *dialog)
1780 GtkWidget *custom_dialog, *image, *table, *label, *widget, *frame, *combo;
1781 GtkWidget *hbox, *vbox, *treeview, *scrolled, *button_box, *button;
1782 GtkCellRenderer *cell;
1783 GtkTreeViewColumn *column;
1785 GtkTreeSelection *selection;
1786 CustomPaperDialog *data;
1788 gulong printer_tag1, printer_tag2;
1790 custom_dialog = gtk_dialog_new_with_buttons (_("Manage Custom Sizes"),
1791 GTK_WINDOW (dialog),
1792 GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
1793 GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
1796 g_signal_connect (custom_dialog, "style-set", G_CALLBACK (set_dialog_hig_spacing), custom_dialog);
1798 data = g_new0 (CustomPaperDialog, 1);
1799 data->dialog = dialog;
1800 g_object_set_data_full (G_OBJECT (custom_dialog), "custom-dialog", data, custom_paper_dialog_free);
1802 hbox = gtk_hbox_new (FALSE, 12);
1803 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (custom_dialog)->vbox), hbox, TRUE, TRUE, 0);
1804 gtk_widget_show (hbox);
1806 vbox = gtk_vbox_new (FALSE, 6);
1807 gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
1808 gtk_widget_show (vbox);
1810 scrolled = gtk_scrolled_window_new (NULL, NULL);
1811 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled),
1812 GTK_POLICY_AUTOMATIC,
1813 GTK_POLICY_AUTOMATIC);
1814 gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolled),
1816 gtk_box_pack_start (GTK_BOX (vbox), scrolled, TRUE, TRUE, 0);
1817 gtk_widget_show (scrolled);
1819 treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (dialog->priv->custom_paper_list));
1820 data->treeview = treeview;
1821 gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
1822 gtk_widget_set_size_request (treeview, 140, -1);
1824 selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (treeview));
1825 gtk_tree_selection_set_mode (selection, GTK_SELECTION_BROWSE);
1826 g_signal_connect (selection, "changed", G_CALLBACK (selected_custom_paper_changed), data);
1828 cell = gtk_cell_renderer_text_new ();
1829 g_object_set (cell, "editable", TRUE, NULL);
1830 g_signal_connect (cell, "edited",
1831 G_CALLBACK (custom_size_name_edited), data);
1832 data->text_column = column =
1833 gtk_tree_view_column_new_with_attributes ("paper", cell,
1835 gtk_tree_view_column_set_cell_data_func (column, cell, custom_name_func, NULL, NULL);
1837 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
1839 gtk_container_add (GTK_CONTAINER (scrolled), treeview);
1840 gtk_widget_show (treeview);
1842 button_box = gtk_hbox_new (FALSE, 6);
1843 gtk_box_pack_start (GTK_BOX (vbox), button_box, FALSE, FALSE, 0);
1844 gtk_widget_show (button_box);
1846 button = gtk_button_new ();
1847 image = gtk_image_new_from_stock (GTK_STOCK_ADD, GTK_ICON_SIZE_BUTTON);
1848 gtk_widget_show (image);
1849 gtk_container_add (GTK_CONTAINER (button), image);
1850 gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
1851 gtk_widget_show (button);
1853 g_signal_connect_swapped (button, "clicked", G_CALLBACK (add_custom_paper), data);
1855 button = gtk_button_new ();
1856 image = gtk_image_new_from_stock (GTK_STOCK_REMOVE, GTK_ICON_SIZE_BUTTON);
1857 gtk_widget_show (image);
1858 gtk_container_add (GTK_CONTAINER (button), image);
1859 gtk_box_pack_start (GTK_BOX (button_box), button, FALSE, FALSE, 0);
1860 gtk_widget_show (button);
1862 g_signal_connect_swapped (button, "clicked", G_CALLBACK (remove_custom_paper), data);
1864 user_units = get_default_user_units ();
1866 vbox = gtk_vbox_new (FALSE, 6);
1867 gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
1868 gtk_widget_show (vbox);
1870 table = gtk_table_new (2, 2, FALSE);
1872 label = gtk_label_new (_("Width:"));
1873 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1874 gtk_table_set_col_spacings (GTK_TABLE (table), 12);
1875 gtk_widget_show (label);
1876 gtk_table_attach (GTK_TABLE (table), label,
1877 0, 1, 0, 1, 0, 0, 0, 0);
1879 widget = new_unit_widget (data, user_units);
1880 data->width_widget = widget;
1881 gtk_table_attach (GTK_TABLE (table), widget,
1882 1, 2, 0, 1, 0, 0, 0, 0);
1883 gtk_widget_show (widget);
1885 label = gtk_label_new (_("Height:"));
1886 gtk_widget_show (label);
1887 gtk_table_attach (GTK_TABLE (table), label,
1888 0, 1, 1, 2, 0, 0, 0, 0);
1890 widget = new_unit_widget (data, user_units);
1891 data->height_widget = widget;
1892 gtk_table_attach (GTK_TABLE (table), widget,
1893 1, 2, 1, 2, 0, 0, 0, 0);
1894 gtk_widget_show (widget);
1896 frame = wrap_in_frame (_("Paper Size"), table);
1897 gtk_widget_show (table);
1898 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1899 gtk_widget_show (frame);
1902 table = gtk_table_new (3, 5, FALSE);
1903 gtk_table_set_row_spacings (GTK_TABLE (table), 6);
1904 gtk_table_set_col_spacings (GTK_TABLE (table), 0);
1906 widget = new_unit_widget (data, user_units);
1907 data->top_widget = widget;
1908 gtk_table_attach (GTK_TABLE (table), widget,
1909 1, 2, 0, 1, 0, 0, 0, 0);
1910 gtk_widget_show (widget);
1912 label = gtk_label_new (_("top"));
1913 gtk_table_attach (GTK_TABLE (table), label,
1914 1, 2, 1, 2, 0, GTK_FILL|GTK_EXPAND, 0, 0);
1915 gtk_misc_set_alignment (GTK_MISC (label),
1917 gtk_widget_show (label);
1919 widget = new_unit_widget (data, user_units);
1920 data->bottom_widget = widget;
1921 gtk_table_attach (GTK_TABLE (table), widget,
1922 1, 2, 2, 3, 0, 0, 0, 0);
1923 gtk_widget_show (widget);
1925 label = gtk_label_new (_("bottom"));
1926 gtk_table_attach (GTK_TABLE (table), label,
1927 1, 2, 3, 4, 0, GTK_FILL|GTK_EXPAND, 0, 0);
1928 gtk_misc_set_alignment (GTK_MISC (label),
1930 gtk_widget_show (label);
1932 widget = new_unit_widget (data, user_units);
1933 data->left_widget = widget;
1934 gtk_table_attach (GTK_TABLE (table), widget,
1935 0, 1, 1, 2, 0, 0, 0, 0);
1936 gtk_widget_show (widget);
1938 label = gtk_label_new (_("left"));
1939 gtk_table_attach (GTK_TABLE (table), label,
1940 0, 1, 2, 3, 0, GTK_FILL|GTK_EXPAND, 0, 0);
1941 gtk_misc_set_alignment (GTK_MISC (label),
1943 gtk_widget_show (label);
1945 widget = new_unit_widget (data, user_units);
1946 data->right_widget = widget;
1947 gtk_table_attach (GTK_TABLE (table), widget,
1948 2, 3, 1, 2, 0, 0, 0, 0);
1949 gtk_widget_show (widget);
1951 label = gtk_label_new (_("right"));
1952 gtk_table_attach (GTK_TABLE (table), label,
1953 2, 3, 2, 3, 0, GTK_FILL|GTK_EXPAND, 0, 0);
1954 gtk_misc_set_alignment (GTK_MISC (label),
1956 gtk_widget_show (label);
1958 hbox = gtk_hbox_new (FALSE, 0);
1959 gtk_table_attach (GTK_TABLE (table), hbox,
1960 0, 3, 4, 5, GTK_FILL | GTK_EXPAND, 0, 0, 0);
1961 gtk_widget_show (hbox);
1962 gtk_table_set_row_spacing (GTK_TABLE (table), 3, 8);
1964 combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (dialog->priv->printer_list));
1965 data->printer_combo = combo;
1968 g_signal_connect_swapped (dialog->priv->printer_list, "row_inserted",
1969 G_CALLBACK (update_combo_sensitivity_from_printers), data);
1971 g_signal_connect_swapped (dialog->priv->printer_list, "row_deleted",
1972 G_CALLBACK (update_combo_sensitivity_from_printers), data);
1973 update_combo_sensitivity_from_printers (data);
1975 cell = gtk_cell_renderer_text_new ();
1976 gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), cell, TRUE);
1977 gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (combo), cell,
1978 custom_paper_printer_data_func,
1981 gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
1982 gtk_box_pack_start (GTK_BOX (hbox), combo, FALSE, FALSE, 0);
1983 gtk_widget_show (combo);
1985 g_signal_connect_swapped (combo, "changed",
1986 G_CALLBACK (margins_from_printer_changed), data);
1988 frame = wrap_in_frame (_("Paper Margins"), table);
1989 gtk_widget_show (table);
1990 gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
1991 gtk_widget_show (frame);
1993 update_custom_widgets_from_list (data);
1995 /* If no custom sizes, add one */
1996 if (!gtk_tree_model_get_iter_first (GTK_TREE_MODEL (dialog->priv->custom_paper_list),
1999 /* Need to realize treeview so we can start the rename */
2000 gtk_widget_realize (treeview);
2001 add_custom_paper (data);
2004 gtk_dialog_run (GTK_DIALOG (custom_dialog));
2005 gtk_widget_destroy (custom_dialog);
2007 save_custom_papers (dialog->priv->custom_paper_list);
2009 g_signal_handler_disconnect (dialog->priv->printer_list, printer_tag1);
2010 g_signal_handler_disconnect (dialog->priv->printer_list, printer_tag2);
2015 #define __GTK_PAGE_SETUP_UNIX_DIALOG_C__
2016 #include "gtkaliasdef.c"