]> Pileus Git - ~andy/gtk/blobdiff - gtk/gtkpagesetupunixdialog.c
Fix typos
[~andy/gtk] / gtk / gtkpagesetupunixdialog.c
index 72a5cd074c08a1cdbbc46d9e5ab57b951d905b43..4ff8da8bb25f8c8cd7784da5c105ae14a550ebbe 100644 (file)
 #include "config.h"
 #include <string.h>
 #include <locale.h>
+
+#ifdef HAVE__NL_MEASUREMENT_MEASUREMENT
 #include <langinfo.h>
+#endif
 
 #include "gtkintl.h"
 #include "gtkprivate.h"
@@ -79,13 +82,14 @@ struct GtkPageSetupUnixDialogPrivate
   GtkWidget *reverse_landscape_radio;
 
   guint request_details_tag;
+  GtkPrinter *request_details_printer;
   
   GtkPrintSettings *print_settings;
 
   /* Save last setup so we can re-set it after selecting manage custom sizes */
   GtkPageSetup *last_setup;
 
-  char *waiting_for_printer;
+  gchar *waiting_for_printer;
 };
 
 enum {
@@ -100,7 +104,7 @@ enum {
   PAGE_SETUP_LIST_N_COLS
 };
 
-G_DEFINE_TYPE (GtkPageSetupUnixDialog, gtk_page_setup_unix_dialog, GTK_TYPE_DIALOG);
+G_DEFINE_TYPE (GtkPageSetupUnixDialog, gtk_page_setup_unix_dialog, GTK_TYPE_DIALOG)
 
 #define GTK_PAGE_SETUP_UNIX_DIALOG_GET_PRIVATE(o)  \
    (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PAGE_SETUP_UNIX_DIALOG, GtkPageSetupUnixDialogPrivate))
@@ -109,9 +113,20 @@ 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 run_custom_paper_dialog              (GtkPageSetupUnixDialog *dialog);
+static void show_custom_paper_dialog             (GtkPageSetupUnixDialog *dialog);
+static void printer_added_cb                     (GtkPrintBackend        *backend,
+                                                 GtkPrinter             *printer,
+                                                 GtkPageSetupUnixDialog *dialog);
+static void printer_removed_cb                   (GtkPrintBackend        *backend,
+                                                 GtkPrinter             *printer,
+                                                 GtkPageSetupUnixDialog *dialog);
+static void printer_status_cb                    (GtkPrintBackend        *backend,
+                                                 GtkPrinter             *printer,
+                                                 GtkPageSetupUnixDialog *dialog);
+
 
-static const char * const common_paper_sizes[] = {
+
+static const gchar * const common_paper_sizes[] = {
   "na_letter",
   "na_legal",
   "iso_a4",
@@ -135,12 +150,12 @@ get_default_user_units (void)
    * Do *not* translate it to "predefinito:mm", if it
    * it isn't default:mm or default:inch it will not work 
    */
-  char *e = _("default:mm");
+  gchar *e = _("default:mm");
   
 #ifdef HAVE__NL_MEASUREMENT_MEASUREMENT
-  char *imperial = NULL;
+  gchar *imperial = NULL;
   
-  imperial = nl_langinfo(_NL_MEASUREMENT_MEASUREMENT);
+  imperial = nl_langinfo (_NL_MEASUREMENT_MEASUREMENT);
   if (imperial && imperial[0] == 2 )
     return GTK_UNIT_INCH;  /* imperial */
   if (imperial && imperial[0] == 1 )
@@ -157,7 +172,7 @@ get_default_user_units (void)
 static char *
 custom_paper_get_filename (void)
 {
-  char *filename;
+  gchar *filename;
 
   filename = g_build_filename (g_get_home_dir (), 
                               CUSTOM_PAPER_FILENAME, NULL);
@@ -165,93 +180,78 @@ custom_paper_get_filename (void)
   return filename;
 }
 
-static gboolean
-scan_double (char **text, double *val, gboolean last)
+static void
+load_custom_papers (GtkListStore *store)
 {
-  char *p, *e;
+  GKeyFile *keyfile;
+  gchar *filename;
+  gchar **groups;
+  gsize n_groups, i;
+  gboolean load_ok;
 
-  p = *text;
-  
-  *val = g_ascii_strtod (p, &e);
-  if (p == e)
-    return FALSE;
+  filename = custom_paper_get_filename ();
 
-  p = e;
-  if (!last)
+  keyfile = g_key_file_new ();
+  load_ok = g_key_file_load_from_file (keyfile, filename, 0, NULL);
+  g_free (filename);
+  if (!load_ok)
     {
-      while (g_ascii_isspace(*p))
-       p++;
-      if (*p++ != ',')
-       return FALSE;
+      g_key_file_free (keyfile);
+      return;
     }
-  *text = p;
-  return TRUE;
-}
-
-static void
-load_custom_papers (GtkListStore *store)
-{
-  char *filename;
-  gchar *contents;
-  
-  filename = custom_paper_get_filename ();
 
-  if (g_file_get_contents (filename, &contents, NULL, NULL))
+  groups = g_key_file_get_groups (keyfile, &n_groups);
+  for (i = 0; i < n_groups; ++i)
     {
-      gchar **lines = g_strsplit (contents, "\n", -1);
-      double w, h, top, bottom, left, right;
+      GError *error = NULL;
+      gdouble w, h, top, bottom, left, right;
       GtkPaperSize *paper_size;
       GtkPageSetup *page_setup;
-      char *name, *p;
+      gchar *name;
       GtkTreeIter iter;
-      int i;
 
-      for (i = 0; lines[i]; i++)
-       {
-         name = lines[i];
-         p = strchr(lines[i], ':');
-         if (p == NULL)
-           continue;
-         *p++ = 0;
+      name = g_key_file_get_value (keyfile, groups[i], "Name", NULL);
+      if (!name)
+        continue;
 
-         while (g_ascii_isspace(*p))
-           p++;
-         
-         if (!scan_double (&p, &w, FALSE))
-           continue;
-         if (!scan_double (&p, &h, FALSE))
-           continue;
-         if (!scan_double (&p, &top, FALSE))
-           continue;
-         if (!scan_double (&p, &bottom, FALSE))
-           continue;
-         if (!scan_double (&p, &left, FALSE))
-           continue;
-         if (!scan_double (&p, &right, TRUE))
-           continue;
+#define GET_DOUBLE(kf, name, v) \
+      v = g_key_file_get_double (kf, groups[i], name, &error); \
+      if (error != NULL) \
+        {\
+          g_error_free (error);\
+          continue;\
+        }
 
-         page_setup = gtk_page_setup_new ();
-         paper_size = gtk_paper_size_new_custom (name, name, w, h, GTK_UNIT_MM);
-         gtk_page_setup_set_paper_size (page_setup, paper_size);
-         gtk_paper_size_free (paper_size);
+      GET_DOUBLE (keyfile, "Width", w);
+      GET_DOUBLE (keyfile, "Height", h);
+      GET_DOUBLE (keyfile, "MarginTop", top);
+      GET_DOUBLE (keyfile, "MarginBottom", bottom);
+      GET_DOUBLE (keyfile, "MarginLeft", left);
+      GET_DOUBLE (keyfile, "MarginRight", right);
 
-         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);
+#undef GET_DOUBLE
 
-         gtk_list_store_append (store, &iter);
-         gtk_list_store_set (store, &iter,
-                             0, page_setup, 
-                             -1);
+      page_setup = gtk_page_setup_new ();
+      paper_size = gtk_paper_size_new_custom (name, name, w, h, GTK_UNIT_MM);
+      gtk_page_setup_set_paper_size (page_setup, paper_size);
+      gtk_paper_size_free (paper_size);
 
-         g_object_unref (page_setup);
-       }
-      
-      g_free (contents);
-      g_strfreev (lines);
+      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);
+
+      gtk_list_store_append (store, &iter);
+      gtk_list_store_set (store, &iter,
+                         0, page_setup, 
+                         -1);
+
+      g_object_unref (page_setup);
+      g_free (name);
     }
-  g_free (filename);
+  g_strfreev (groups);
+  g_key_file_free (keyfile);
 }
 
 static void
@@ -259,10 +259,12 @@ save_custom_papers (GtkListStore *store)
 {
   GtkTreeModel *model = GTK_TREE_MODEL (store);
   GtkTreeIter iter;
-  GString *string;
-  char *filename;
+  GKeyFile *keyfile;
+  gchar *filename, *data;
+  gsize len;
+  gint i = 0;
 
-  string = g_string_new ("");
+  keyfile = g_key_file_new ();
   
   if (gtk_tree_model_get_iter_first (model, &iter))
     {
@@ -270,47 +272,37 @@ save_custom_papers (GtkListStore *store)
        {
          GtkPaperSize *paper_size;
          GtkPageSetup *page_setup;
-         char buffer[G_ASCII_DTOSTR_BUF_SIZE];
-         
+         gchar group[32];
+
+         g_snprintf (group, sizeof (group), "Paper%u", i);
+
          gtk_tree_model_get (model, &iter, 0, &page_setup, -1);
 
          paper_size = gtk_page_setup_get_paper_size (page_setup);
-         g_string_append_printf (string, "%s: ", gtk_paper_size_get_name (paper_size));
-         
-         g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
-                         gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM));
-         g_string_append (string, buffer);
-         g_string_append (string, ", ");
-         g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
-                         gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM));
-         g_string_append (string, buffer);
-         g_string_append (string, ", ");
-         g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
-                         gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM));
-         g_string_append (string, buffer);
-         g_string_append (string, ", ");
-         g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE, 
-                         gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM));
-         g_string_append (string, buffer);
-         g_string_append (string, ", ");
-         g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
-                         gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM));
-         g_string_append (string, buffer);
-         g_string_append (string, ", ");
-         g_ascii_dtostr (buffer, G_ASCII_DTOSTR_BUF_SIZE,
-                         gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM));
-         g_string_append (string, buffer);
-
-         g_string_append (string, "\n");
+         g_key_file_set_string (keyfile, group, "Name", gtk_paper_size_get_name (paper_size));
+
+         g_key_file_set_double (keyfile, group, "Width",
+                                gtk_page_setup_get_paper_width (page_setup, GTK_UNIT_MM));
+         g_key_file_set_double (keyfile, group, "Height",
+                                gtk_page_setup_get_paper_height (page_setup, GTK_UNIT_MM));
+         g_key_file_set_double (keyfile, group, "MarginTop",
+                                gtk_page_setup_get_top_margin (page_setup, GTK_UNIT_MM));
+         g_key_file_set_double (keyfile, group, "MarginBottom",
+                                gtk_page_setup_get_bottom_margin (page_setup, GTK_UNIT_MM));
+         g_key_file_set_double (keyfile, group, "MarginLeft",
+                                gtk_page_setup_get_left_margin (page_setup, GTK_UNIT_MM));
+         g_key_file_set_double (keyfile, group, "MarginRight",
+                                gtk_page_setup_get_right_margin (page_setup, GTK_UNIT_MM));
          
+         ++i;
        } while (gtk_tree_model_iter_next (model, &iter));
     }
 
   filename = custom_paper_get_filename ();
-  g_file_set_contents (filename, string->str, -1, NULL);
+  data = g_key_file_to_data (keyfile, &len, NULL);
+  g_file_set_contents (filename, data, len, NULL);
+  g_free (data);
   g_free (filename);
-  
-  g_string_free (string, TRUE);
 }
 
 static void
@@ -369,10 +361,15 @@ gtk_page_setup_unix_dialog_finalize (GObject *object)
 {
   GtkPageSetupUnixDialog *dialog = GTK_PAGE_SETUP_UNIX_DIALOG (object);
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
+  GtkPrintBackend *backend;
+  GList *node;
+  
   if (priv->request_details_tag)
     {
-      g_source_remove (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;
     }
   
@@ -397,18 +394,33 @@ gtk_page_setup_unix_dialog_finalize (GObject *object)
   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_page_setup_unix_dialog_parent_class)->finalize (object);
 }
 
 static void
-printer_added_cb (GtkPrintBackend *backend, 
-                 GtkPrinter *printer, 
+printer_added_cb (GtkPrintBackend        *backend, 
+                 GtkPrinter             *printer, 
                  GtkPageSetupUnixDialog *dialog)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
   GtkTreeIter iter;
-  char *str;
-  const char *location;;
+  gchar *str;
+  const gchar *location;;
 
   if (gtk_printer_is_virtual (printer))
     return;
@@ -444,8 +456,8 @@ printer_added_cb (GtkPrintBackend *backend,
 }
 
 static void
-printer_removed_cb (GtkPrintBackend *backend, 
-                   GtkPrinter *printer, 
+printer_removed_cb (GtkPrintBackend        *backend, 
+                   GtkPrinter             *printer, 
                    GtkPageSetupUnixDialog *dialog)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
@@ -457,14 +469,14 @@ printer_removed_cb (GtkPrintBackend *backend,
 
 
 static void
-printer_status_cb (GtkPrintBackend *backend, 
-                   GtkPrinter *printer, 
+printer_status_cb (GtkPrintBackend        *backend, 
+                   GtkPrinter             *printer, 
                   GtkPageSetupUnixDialog *dialog)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
   GtkTreeIter *iter;
-  char *str;
-  const char *location;;
+  gchar *str;
+  const gchar *location;;
   
   iter = g_object_get_data (G_OBJECT (printer), "gtk-print-tree-iter");
 
@@ -481,7 +493,7 @@ printer_status_cb (GtkPrintBackend *backend,
 
 static void
 printer_list_initialize (GtkPageSetupUnixDialog *dialog,
-                        GtkPrintBackend *print_backend)
+                        GtkPrintBackend        *print_backend)
 {
   GList *list, *node;
   
@@ -565,7 +577,8 @@ get_current_page_setup (GtkPageSetupUnixDialog *dialog)
 }
 
 static gboolean
-page_setup_is_equal (GtkPageSetup *a, GtkPageSetup *b)
+page_setup_is_equal (GtkPageSetup *a, 
+                    GtkPageSetup *b)
 {
   return
     gtk_paper_size_is_equal (gtk_page_setup_get_paper_size (a),
@@ -577,7 +590,8 @@ page_setup_is_equal (GtkPageSetup *a, GtkPageSetup *b)
 }
 
 static gboolean
-page_setup_is_same_size (GtkPageSetup *a, GtkPageSetup *b)
+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));
@@ -585,9 +599,9 @@ page_setup_is_same_size (GtkPageSetup *a, GtkPageSetup *b)
 
 static gboolean
 set_paper_size (GtkPageSetupUnixDialog *dialog,
-               GtkPageSetup *page_setup,
-               gboolean size_only,
-               gboolean add_item)
+               GtkPageSetup           *page_setup,
+               gboolean                size_only,
+               gboolean                add_item)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
   GtkTreeModel *model;
@@ -677,14 +691,14 @@ fill_custom_paper_sizes (GtkPageSetupUnixDialog *dialog)
 
 static void
 fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog,
-                              GtkPrinter *printer)
+                              GtkPrinter             *printer)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
   GList *list, *l;
   GtkPageSetup *current_page_setup, *page_setup;
   GtkPaperSize *paper_size;
   GtkTreeIter iter;
-  int i;
+  gint i;
 
   current_page_setup = get_current_page_setup (dialog);
   
@@ -733,13 +747,17 @@ fill_paper_sizes_from_printer (GtkPageSetupUnixDialog *dialog,
 }
 
 static void
-printer_changed_finished_callback (GtkPrinter *printer,
-                                  gboolean success,
+printer_changed_finished_callback (GtkPrinter             *printer,
+                                  gboolean                success,
                                   GtkPageSetupUnixDialog *dialog)
 {
   GtkPageSetupUnixDialogPrivate *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)
     fill_paper_sizes_from_printer (dialog, printer);
@@ -747,7 +765,7 @@ printer_changed_finished_callback (GtkPrinter *printer,
 }
 
 static void
-printer_changed_callback (GtkComboBox *combo_box,
+printer_changed_callback (GtkComboBox            *combo_box,
                          GtkPageSetupUnixDialog *dialog)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
@@ -755,7 +773,8 @@ printer_changed_callback (GtkComboBox *combo_box,
   GtkTreeIter iter;
 
   /* If we're waiting for a specific printer but the user changed
-     to another printer, cancel that wait. */
+   * to another printer, cancel that wait. 
+   */
   if (priv->waiting_for_printer)
     {
       g_free (priv->waiting_for_printer);
@@ -764,7 +783,10 @@ printer_changed_callback (GtkComboBox *combo_box,
   
   if (priv->request_details_tag)
     {
-      g_source_remove (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;
     }
   
@@ -777,6 +799,7 @@ printer_changed_callback (GtkComboBox *combo_box,
        fill_paper_sizes_from_printer (dialog, printer);
       else
        {
+         priv->request_details_printer = g_object_ref (printer);
          priv->request_details_tag =
            g_signal_connect (printer, "details-acquired",
                              G_CALLBACK (printer_changed_finished_callback), dialog);
@@ -803,13 +826,14 @@ printer_changed_callback (GtkComboBox *combo_box,
 /* We do this munging because we don't want to show zero digits
    after the decimal point, and not to many such digits if they
    are nonzero. I wish printf let you specify max precision for %f... */
-static char *
-double_to_string (double d, GtkUnit unit)
+static gchar *
+double_to_string (gdouble d, 
+                 GtkUnit unit)
 {
-  char *val, *p;
+  gchar *val, *p;
   struct lconv *locale_data;
-  const char *decimal_point;
-  int decimal_point_len;
+  const gchar *decimal_point;
+  gint decimal_point_len;
 
   locale_data = localeconv ();
   decimal_point = locale_data->decimal_point;
@@ -836,17 +860,17 @@ double_to_string (double d, GtkUnit unit)
 }
 
 static void
-paper_size_changed (GtkComboBox *combo_box,
+paper_size_changed (GtkComboBox            *combo_box,
                    GtkPageSetupUnixDialog *dialog)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
   GtkTreeIter iter;
   GtkPageSetup *page_setup, *last_page_setup;
   GtkUnit unit;
-  char *str, *w, *h;
-  char *top, *bottom, *left, *right;
+  gchar *str, *w, *h;
+  gchar *top, *bottom, *left, *right;
   GtkLabel *label;
-  const char *unit_str;
+  const gchar *unit_str;
 
   label = GTK_LABEL (priv->paper_size_label);
    
@@ -857,23 +881,18 @@ paper_size_changed (GtkComboBox *combo_box,
 
       if (page_setup == NULL)
        {
-         run_custom_paper_dialog (dialog);
-
-         /* Save current last_setup as it is changed by updating the list */
-         last_page_setup = NULL;
-         if (priv->last_setup)
-           last_page_setup = g_object_ref (priv->last_setup);
-
-         /* Update printer page list */
-         printer_changed_callback (GTK_COMBO_BOX (priv->printer_combo), dialog);
-
-         /* Change from "manage" menu item to last value */
-         if (last_page_setup == NULL)
+          /* Change from "manage" menu item to last value */
+          if (priv->last_setup)
+            last_page_setup = g_object_ref (priv->last_setup);
+          else
            last_page_setup = gtk_page_setup_new (); /* "good" default */
          set_paper_size (dialog, last_page_setup, FALSE, TRUE);
-         g_object_unref (last_page_setup);
-         
-         return;
+          g_object_unref (last_page_setup);
+
+          /* And show the custom paper dialog */
+          show_custom_paper_dialog (dialog);
+
+          return;
        }
 
       if (priv->last_setup)
@@ -960,12 +979,33 @@ page_name_func (GtkCellLayout   *cell_layout,
       
 }
 
+static GtkWidget *
+create_radio_button (GSList      *group,
+                    const gchar *stock_id)
+{
+  GtkWidget *radio_button, *image, *label, *hbox;
+  GtkStockItem item;
+
+  radio_button = gtk_radio_button_new (group);
+  image = gtk_image_new_from_stock (stock_id, GTK_ICON_SIZE_LARGE_TOOLBAR);
+  gtk_stock_lookup (stock_id, &item);
+  label = gtk_label_new (item.label);
+  hbox = gtk_hbox_new (0, 6);
+  gtk_container_add (GTK_CONTAINER (radio_button), hbox);
+  gtk_container_add (GTK_CONTAINER (hbox), image);
+  gtk_container_add (GTK_CONTAINER (hbox), label);
+
+  gtk_widget_show_all (radio_button);
+
+  return radio_button;
+}
+
 static void
 populate_dialog (GtkPageSetupUnixDialog *ps_dialog)
 {
   GtkPageSetupUnixDialogPrivate *priv = ps_dialog->priv;
   GtkDialog *dialog = GTK_DIALOG (ps_dialog);
-  GtkWidget *table, *label, *combo, *radio_button, *ebox, *image;
+  GtkWidget *table, *label, *combo, *radio_button, *ebox;
   GtkCellRenderer *cell;
 
   gtk_window_set_resizable (GTK_WINDOW (dialog), FALSE);
@@ -976,7 +1016,7 @@ populate_dialog (GtkPageSetupUnixDialog *ps_dialog)
   gtk_container_set_border_width (GTK_CONTAINER (dialog->action_area), 5);
   gtk_box_set_spacing (GTK_BOX (dialog->action_area), 6);
 
-  table = gtk_table_new (4, 4, FALSE);
+  table = gtk_table_new (5, 4, FALSE);
   gtk_table_set_row_spacings (GTK_TABLE (table), 6);
   gtk_table_set_col_spacings (GTK_TABLE (table), 12);
   gtk_container_set_border_width (GTK_CONTAINER (table), 5);
@@ -1046,41 +1086,37 @@ populate_dialog (GtkPageSetupUnixDialog *ps_dialog)
                    GTK_FILL, 0, 0, 0);
   gtk_widget_show (label);
 
-  radio_button = gtk_radio_button_new (NULL);
-  image = gtk_image_new_from_stock (GTK_STOCK_ORIENTATION_PORTRAIT,
-                                   GTK_ICON_SIZE_LARGE_TOOLBAR);
-  gtk_widget_show (image);
-  gtk_container_add (GTK_CONTAINER (radio_button), image);
+  radio_button = create_radio_button (NULL, GTK_STOCK_ORIENTATION_PORTRAIT);
   priv->portrait_radio = radio_button;
   gtk_table_attach (GTK_TABLE (table), radio_button,
                    1, 2, 3, 4,
-                   0, 0, 0, 0);
-  gtk_widget_show (radio_button);
+                   GTK_EXPAND|GTK_FILL, 0, 0, 0);
   gtk_label_set_mnemonic_widget (GTK_LABEL (label), radio_button);
 
-  radio_button = gtk_radio_button_new (gtk_radio_button_get_group (GTK_RADIO_BUTTON(radio_button)));
-  image = gtk_image_new_from_stock (GTK_STOCK_ORIENTATION_LANDSCAPE,
-                                   GTK_ICON_SIZE_LARGE_TOOLBAR);
-  gtk_widget_show (image);
-  gtk_container_add (GTK_CONTAINER (radio_button), image);
-  priv->landscape_radio = radio_button;
+  radio_button = create_radio_button (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_button)),
+                                     GTK_STOCK_ORIENTATION_REVERSE_PORTRAIT);
+  priv->reverse_landscape_radio = radio_button;
   gtk_table_attach (GTK_TABLE (table), radio_button,
                    2, 3, 3, 4,
-                   0, 0, 0, 0);
+                   GTK_EXPAND|GTK_FILL, 0, 0, 0);
+
+  radio_button = create_radio_button (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_button)),
+                                     GTK_STOCK_ORIENTATION_LANDSCAPE);
+  priv->landscape_radio = radio_button;
+  gtk_table_attach (GTK_TABLE (table), radio_button,
+                   1, 2, 4, 5,
+                   GTK_EXPAND|GTK_FILL, 0, 0, 0);
   gtk_widget_show (radio_button);
 
   gtk_table_set_row_spacing (GTK_TABLE (table), 3, 0);
   
-  radio_button = gtk_radio_button_new (gtk_radio_button_get_group (GTK_RADIO_BUTTON(radio_button)));
-  image = gtk_image_new_from_stock (GTK_STOCK_ORIENTATION_REVERSE_LANDSCAPE,
-                                   GTK_ICON_SIZE_LARGE_TOOLBAR);
-  gtk_widget_show (image);
-  gtk_container_add (GTK_CONTAINER (radio_button), image);
+  radio_button = create_radio_button (gtk_radio_button_get_group (GTK_RADIO_BUTTON (radio_button)),
+                                     GTK_STOCK_ORIENTATION_REVERSE_LANDSCAPE);
   priv->reverse_landscape_radio = radio_button;
   gtk_table_attach (GTK_TABLE (table), radio_button,
-                   3, 4, 3, 4,
-                   0, 0, 0, 0);
-  gtk_widget_show (radio_button);
+                   2, 3, 4, 5,
+                   GTK_EXPAND|GTK_FILL, 0, 0, 0);
+
 
   priv->tooltips = gtk_tooltips_new ();
 
@@ -1091,9 +1127,20 @@ populate_dialog (GtkPageSetupUnixDialog *ps_dialog)
   load_print_backends (ps_dialog);
 }
 
+/**
+ * gtk_page_setup_unix_dialog_new:
+ * @title: the title of the dialog, or %NULL
+ * @parent: transient parent of the dialog, or %NULL
+ *
+ * Creates a new page setup dialog.
+ *
+ * Returns: the new #GtkPageSetupUnixDialog
+ *
+ * Since: 2.10
+ */
 GtkWidget *
 gtk_page_setup_unix_dialog_new (const gchar *title,
-                               GtkWindow *parent)
+                               GtkWindow   *parent)
 {
   GtkWidget *result;
 
@@ -1125,7 +1172,8 @@ get_orientation (GtkPageSetupUnixDialog *dialog)
 }
 
 static void
-set_orientation (GtkPageSetupUnixDialog *dialog, GtkPageOrientation orientation)
+set_orientation (GtkPageSetupUnixDialog *dialog, 
+                GtkPageOrientation      orientation)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
 
@@ -1144,6 +1192,16 @@ set_orientation (GtkPageSetupUnixDialog *dialog, GtkPageOrientation orientation)
     }
 }
 
+/**
+ * gtk_page_setup_unix_dialog_set_page_setup:
+ * @dialog: a #GtkPageSetupUnixDialog
+ * @page_setup: a #GtkPageSetup
+ * 
+ * Sets the #GtkPageSetup from which the page setup
+ * dialog takes its values.
+ *
+ * Since: 2.10
+ **/
 void
 gtk_page_setup_unix_dialog_set_page_setup (GtkPageSetupUnixDialog *dialog,
                                           GtkPageSetup           *page_setup)
@@ -1155,6 +1213,16 @@ gtk_page_setup_unix_dialog_set_page_setup (GtkPageSetupUnixDialog *dialog,
     }
 }
 
+/**
+ * gtk_page_setup_unix_dialog_get_page_setup:
+ * @dialog: a #GtkPageSetupUnixDialog
+ * 
+ * Gets the currently selected page setup from the dialog. 
+ * 
+ * Returns: the current page setup 
+ *
+ * Since: 2.10
+ **/
 GtkPageSetup *
 gtk_page_setup_unix_dialog_get_page_setup (GtkPageSetupUnixDialog *dialog)
 {
@@ -1169,7 +1237,7 @@ gtk_page_setup_unix_dialog_get_page_setup (GtkPageSetupUnixDialog *dialog)
 
 static gboolean
 set_active_printer (GtkPageSetupUnixDialog *dialog,
-                   const char *printer_name)
+                   const gchar            *printer_name)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
   GtkTreeModel *model;
@@ -1203,12 +1271,22 @@ set_active_printer (GtkPageSetupUnixDialog *dialog,
   return FALSE;
 }
 
+/**
+ * gtk_page_setup_unix_dialog_set_print_settings:
+ * @dialog: a #GtkPageSetupUnixDialog
+ * @print_settings: a #GtkPrintSettings
+ * 
+ * Sets the #GtkPrintSettings from which the page setup dialog
+ * takes its values.
+ * 
+ * Since: 2.10
+ **/
 void
 gtk_page_setup_unix_dialog_set_print_settings (GtkPageSetupUnixDialog *dialog,
                                               GtkPrintSettings       *print_settings)
 {
   GtkPageSetupUnixDialogPrivate *priv = dialog->priv;
-  const char *format_for_printer;
+  const gchar *format_for_printer;
 
   if (priv->print_settings == print_settings) return;
 
@@ -1223,14 +1301,25 @@ gtk_page_setup_unix_dialog_set_print_settings (GtkPageSetupUnixDialog *dialog,
 
       format_for_printer = gtk_print_settings_get (print_settings, "format-for-printer");
 
-      /* Set printer if in list, otherwise set when that printer
-        is added */
+      /* Set printer if in list, otherwise set when 
+       * that printer is added 
+       */
       if (format_for_printer &&
          !set_active_printer (dialog, format_for_printer))
        priv->waiting_for_printer = g_strdup (format_for_printer); 
     }
 }
 
+/**
+ * gtk_page_setup_unix_dialog_get_print_settings:
+ * @dialog: a #GtkPageSetupUnixDialog
+ * 
+ * Gets the current print settings from the dialog.
+ * 
+ * Returns: the current print settings
+ *
+ * Since: 2.10
+ **/
 GtkPrintSettings *
 gtk_page_setup_unix_dialog_get_print_settings (GtkPageSetupUnixDialog *dialog)
 {
@@ -1244,7 +1333,7 @@ wrap_in_frame (const gchar *label,
                GtkWidget   *child)
 {
   GtkWidget *frame, *alignment, *label_widget;
-  char *bold_text;
+  gchar *bold_text;
 
   label_widget = gtk_label_new ("");
   gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
@@ -1270,16 +1359,17 @@ wrap_in_frame (const gchar *label,
   return frame;
 }
 
-typedef struct {
+typedef struct 
+{
   GtkUnit display_unit;
   GtkWidget *spin_button;
 } UnitWidget;
 
-typedef struct {
+typedef struct 
+{
   GtkPageSetupUnixDialog *dialog;
   GtkWidget *treeview;
   GtkTreeViewColumn *text_column;
-  gboolean non_user_change;
   GtkWidget *values_box;
   GtkWidget *printer_combo;
   GtkWidget *width_widget;
@@ -1288,13 +1378,19 @@ typedef struct {
   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)
+new_unit_widget (CustomPaperDialog *dialog, 
+                GtkUnit            unit, 
+                GtkWidget         *mnemonic_label)
 {
   GtkWidget *hbox, *button, *label;
   UnitWidget *data;
@@ -1315,7 +1411,7 @@ new_unit_widget (CustomPaperDialog *dialog, GtkUnit unit, GtkWidget *mnemonic_la
 
   data->spin_button = button;
 
-  g_signal_connect_swapped (button, "value_changed",
+  g_signal_connect_swapped (button, "value-changed",
                            G_CALLBACK (unit_widget_changed), dialog);
   
   if (unit == GTK_UNIT_INCH)
@@ -1337,16 +1433,18 @@ 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);
+                                  data->display_unit);
 }
 
 static void
-unit_widget_set (GtkWidget *unit_widget, double val)
+unit_widget_set (GtkWidget *unit_widget, 
+                gdouble    value)
 {
-  UnitWidget *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 (val, data->display_unit));
+  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
@@ -1357,6 +1455,7 @@ custom_paper_printer_data_func (GtkCellLayout   *cell_layout,
                                gpointer         data)
 {
   GtkPrinter *printer;
+
   gtk_tree_model_get (tree_model, iter,
                      PRINTER_LIST_COL_PRINTER, &printer, -1);
 
@@ -1429,7 +1528,7 @@ update_custom_widgets_from_list (CustomPaperDialog *data)
 }
 
 static void
-selected_custom_paper_changed (GtkTreeSelection *selection,
+selected_custom_paper_changed (GtkTreeSelection  *selection,
                               CustomPaperDialog *data)
 {
   update_custom_widgets_from_list (data);
@@ -1438,7 +1537,7 @@ selected_custom_paper_changed (GtkTreeSelection *selection,
 static void
 unit_widget_changed (CustomPaperDialog *data)
 {
-  double w, h, top, bottom, left, right;
+  gdouble w, h, top, bottom, left, right;
   GtkTreeSelection *selection;
   GtkTreeIter iter;
   GtkPageSetup *page_setup;
@@ -1474,7 +1573,8 @@ unit_widget_changed (CustomPaperDialog *data)
 }
 
 static gboolean
-custom_paper_name_used (CustomPaperDialog *data, const char *name)
+custom_paper_name_used (CustomPaperDialog *data, 
+                       const gchar       *name)
 {
   GtkTreeModel *model;
   GtkTreeIter iter;
@@ -1511,8 +1611,8 @@ add_custom_paper (CustomPaperDialog *data)
   GtkTreeSelection *selection;
   GtkTreePath *path;
   GtkTreeIter iter;
-  char *name;
-  int i;
+  gchar *name;
+  gint i;
   
   selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (data->treeview));
   store = data->dialog->priv->custom_paper_list;
@@ -1533,7 +1633,7 @@ add_custom_paper (CustomPaperDialog *data)
                                          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);
@@ -1572,9 +1672,9 @@ remove_custom_paper (CustomPaperDialog *data)
 
 static void
 set_margins_from_printer (CustomPaperDialog *data,
-                         GtkPrinter *printer)
+                         GtkPrinter        *printer)
 {
-  double top, bottom, left, right;
+  gdouble top, bottom, left, right;
 
   top = bottom = left = right = 0;
   _gtk_printer_get_hard_margins (printer, &top, &bottom, &left, &right);
@@ -1591,11 +1691,15 @@ set_margins_from_printer (CustomPaperDialog *data,
 }
 
 static void
-get_margins_finished_callback (GtkPrinter *printer,
-                              gboolean success,
+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);
@@ -1614,7 +1718,10 @@ margins_from_printer_changed (CustomPaperDialog *data)
 
   if (data->request_details_tag)
     {
-      g_source_remove (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;
     }
   
@@ -1632,6 +1739,7 @@ margins_from_printer_changed (CustomPaperDialog *data)
            }
          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);
@@ -1648,9 +1756,17 @@ 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_source_remove (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;
     }
   
@@ -1705,41 +1821,59 @@ custom_name_func (GtkTreeViewColumn *tree_column,
 }
 
 static void
-run_custom_paper_dialog (GtkPageSetupUnixDialog *ps_dialog)
+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 *ddialog;
+  GtkDialog *dialog;
   GtkCellRenderer *cell;
   GtkTreeViewColumn *column;
   GtkTreeIter iter;
   GtkTreeSelection *selection;
   CustomPaperDialog *data;
   GtkUnit user_units;
-  gulong printer_tag1, printer_tag2;
   
   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_OK, GTK_RESPONSE_ACCEPT,
+                                              GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE,
                                               NULL);
 
-  ddialog = GTK_DIALOG (custom_dialog);
+  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_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 (ddialog, FALSE);
-  gtk_container_set_border_width (GTK_CONTAINER (ddialog), 5);
-  gtk_box_set_spacing (GTK_BOX (ddialog->vbox), 2); /* 2 * 5 + 2 = 12 */
-  gtk_container_set_border_width (GTK_CONTAINER (ddialog->action_area), 5);
-  gtk_box_set_spacing (GTK_BOX (ddialog->action_area), 6);
+  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 (ddialog->vbox), hbox, TRUE, TRUE, 0);
+  gtk_box_pack_start (GTK_BOX (dialog->vbox), hbox, TRUE, TRUE, 0);
   gtk_widget_show (hbox);
 
   vbox = gtk_vbox_new (FALSE, 6);
@@ -1902,11 +2036,11 @@ run_custom_paper_dialog (GtkPageSetupUnixDialog *ps_dialog)
   combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (priv->printer_list));
   data->printer_combo = combo;
 
-  printer_tag1 =
-    g_signal_connect_swapped (priv->printer_list, "row_inserted",
+  data->printer_inserted_tag =
+    g_signal_connect_swapped (priv->printer_list, "row-inserted",
                              G_CALLBACK (update_combo_sensitivity_from_printers), data);
-  printer_tag2 =
-    g_signal_connect_swapped (priv->printer_list, "row_deleted",
+  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);
   
@@ -1939,14 +2073,7 @@ run_custom_paper_dialog (GtkPageSetupUnixDialog *ps_dialog)
       add_custom_paper (data);
     }
 
-  gtk_dialog_run (GTK_DIALOG (custom_dialog));
-  gtk_widget_destroy (custom_dialog);
-
-  save_custom_papers (priv->custom_paper_list);
-
-  g_signal_handler_disconnect (priv->printer_list, printer_tag1);
-  g_signal_handler_disconnect (priv->printer_list, printer_tag2);
-  
+  gtk_window_present (GTK_WINDOW (dialog));
 }