--- plug-ins/common/file-pdf-save.orig	2012-07-27 19:22:21.000000000 +0200
+++ plug-ins/common/file-pdf-save.c	2012-10-14 11:34:16.000000000 +0200
@@ -112,79 +112,22 @@
 #include "libgimp/stdplugins-intl.h"
 
 #define SAVE_PROC               "file-pdf-save"
-#define SAVE_MULTI_PROC         "file-pdf-save-multi"
 #define PLUG_IN_BINARY          "file-pdf-save"
 #define PLUG_IN_ROLE            "gimp-file-pdf-save"
 
-#define DATA_OPTIMIZE           "file-pdf-data-optimize"
-#define DATA_IMAGE_LIST         "file-pdf-data-multi-page"
+#define PLUG_IN_CAPABILITIES    (GIMP_EXPORT_CAN_HANDLE_RGB | \
+              GIMP_EXPORT_CAN_HANDLE_ALPHA | GIMP_EXPORT_CAN_HANDLE_GRAY | \
+              GIMP_EXPORT_CAN_HANDLE_LAYERS | GIMP_EXPORT_CAN_HANDLE_LAYER_MASKS | \
+              GIMP_EXPORT_CAN_HANDLE_INDEXED)
 
-/* Gimp will crash before you reach this limitation :D */
-#define MAX_PAGE_COUNT           350
-#define MAX_FILE_NAME_LENGTH     350
-
-#define THUMB_WIDTH              90
-#define THUMB_HEIGHT             120
-
-typedef struct {
-  gboolean vectorize;
-  gboolean ignore_hidden;
-  gboolean apply_masks;
-} PdfOptimize;
-
-typedef struct {
-  gint32 images[MAX_PAGE_COUNT];
-  guint32 image_count;
-  gchar file_name[MAX_FILE_NAME_LENGTH];
-} PdfMultiPage;
+#define DATA_OPTIONS            "file-pdf-data-options"
 
 typedef struct {
-  PdfOptimize optimize;
-  GArray *images;
-} PdfMultiVals;
-
-enum {
-  THUMB,
-  PAGE_NUMBER,
-  IMAGE_NAME,
-  IMAGE_ID
-};
+  gint32 multipage;
+  gint32 reverse;
+} PdfOptions;
 
-typedef struct {
-  GdkPixbuf *thumb;
-  gint32 page_number;
-  gchar* image_name;
-} Page;
-
-
-static gboolean           init_vals                  (const gchar *name,
-                                                      gint nparams,
-                                                      const GimpParam *param,
-                                                      gboolean *single,
-                                                      gboolean *defaults,
-                                                      GimpRunMode  *run_mode);
-
-static void               init_image_list_defaults   (gint32 image);
-
-static void               validate_image_list        (void);
-
-static gboolean           gui_single                 (void);
-static gboolean           gui_multi                  (void);
-
-static void               choose_file_call           (GtkWidget* browse_button,
-                                                      gpointer file_entry);
-
-static gboolean           get_image_list             (void);
-static GtkTreeModel*      create_model               (void);
-
-static void               add_image_call             (GtkWidget *widget,
-                                                      gpointer img_combo);
-static void               del_image_call             (GtkWidget *widget,
-                                                      gpointer icon_view);
-static void               remove_call                (GtkTreeModel *tree_model,
-                                                      GtkTreePath  *path,
-                                                      gpointer      user_data);
-static void               recount_pages              (void);
+static gboolean           run_gui                    (PdfOptions *options);
 
 static cairo_surface_t   *get_drawable_image         (GimpDrawable *drawable);
 static GimpRGB            get_layer_color            (GimpDrawable *layer,
@@ -202,19 +145,6 @@
                    gint             *nreturn_vals,
                    GimpParam       **return_vals);
 
-static gboolean dnd_remove = TRUE;
-static PdfMultiPage multi_page;
-
-static PdfOptimize optimize = {
-  TRUE, /* vectorize */
-  TRUE, /* ignore_hidden */
-  TRUE  /* apply_masks */
-};
-
-static GtkTreeModel *model;
-static GtkWidget *file_choose;
-static gchar* file_name;
-
 GimpPlugInInfo PLUG_IN_INFO =
   {
     NULL,
@@ -231,26 +161,11 @@
   SA_DRAWABLE,
   SA_FILENAME,
   SA_RAW_FILENAME,
-  SA_VECTORIZE,
-  SA_IGNORE_HIDDEN,
-  SA_APPLY_MASKS,
+  SA_MULTIPAGE,
+  SA_REVERSE,
   SA_ARG_COUNT
 } SaveArgs;
 
-#define SA_ARG_COUNT_DEFAULT 5
-
-typedef enum {
-  SMA_RUN_MODE,
-  SMA_IMAGES,
-  SMA_COUNT,
-  SMA_VECTORIZE,
-  SMA_IGNORE_HIDDEN,
-  SMA_APPLY_MASKS,
-  SMA_FILENAME,
-  SMA_RAWFILENAME,
-  SMA_ARG_COUNT
-} SaveMultiArgs;
-
 static void
 query (void)
 {
@@ -261,21 +176,8 @@
       {GIMP_PDB_DRAWABLE, "drawable",     "Input drawable"},
       {GIMP_PDB_STRING,   "filename",     "The name of the file to save the image in"},
       {GIMP_PDB_STRING,   "raw-filename", "The name of the file to save the image in"},
-      {GIMP_PDB_INT32,    "vectorize",    "Convert bitmaps to vector graphics where possible. TRUE or FALSE"},
-      {GIMP_PDB_INT32,    "ignore-hidden","Omit hidden layers and layers with zero opacity. TRUE or FALSE"},
-      {GIMP_PDB_INT32,    "apply-masks",  "Apply layer masks before saving. TRUE or FALSE (Keeping them will not change the output)"}
-    };
-
-  static GimpParamDef save_multi_args[] =
-    {
-      {GIMP_PDB_INT32,      "run-mode",     "Run mode"},
-      {GIMP_PDB_INT32ARRAY, "images",       "Input image for each page (An image can appear more than once)"},
-      {GIMP_PDB_INT32,      "count",        "The amount of images entered (This will be the amount of pages). 1 <= count <= MAX_PAGE_COUNT"},
-      {GIMP_PDB_INT32,      "vectorize",    "Convert bitmaps to vector graphics where possible. TRUE or FALSE"},
-      {GIMP_PDB_INT32,      "ignore-hidden","Omit hidden layers and layers with zero opacity. TRUE or FALSE"},
-      {GIMP_PDB_INT32,      "apply-masks",  "Apply layer masks before saving. TRUE or FALSE (Keeping them will not change the output)"},
-      {GIMP_PDB_STRING,     "filename",     "The name of the file to save the image in"},
-      {GIMP_PDB_STRING,     "raw-filename", "The name of the file to save the image in"}
+      {GIMP_PDB_INT32,    "multipage",    "Whether to save top-level layers as separate pages. TRUE OR FALSE"},
+      {GIMP_PDB_INT32,    "reverse",      "Whether to export layers in reverse order. TRUE or FALSE"}
     };
 
   gimp_install_procedure (SAVE_PROC,
@@ -286,31 +188,13 @@
                           "PostScript.",
                           "Barak Itkin",
                           "Copyright Barak Itkin",
-                          "August 2009",
+                          "July 2012",
                           N_("Portable Document Format"),
                           "RGB*, GRAY*, INDEXED*",
                           GIMP_PLUGIN,
                           G_N_ELEMENTS (save_args), 0,
                           save_args, NULL);
 
-  gimp_install_procedure (SAVE_MULTI_PROC,
-                          "Save files in PDF format",
-                          "Saves files in Adobe's Portable Document Format. "
-                          "PDF is designed to be easily processed by a variety "
-                          "of different platforms, and is a distant cousin of "
-                          "PostScript.",
-                          "Barak Itkin",
-                          "Copyright Barak Itkin",
-                          "August 2009",
-                          N_("_Create multipage PDF..."),
-                          "RGB*, GRAY*, INDEXED*",
-                          GIMP_PLUGIN,
-                          G_N_ELEMENTS (save_multi_args), 0,
-                          save_multi_args, NULL);
-
-/*  gimp_plugin_menu_register (SAVE_MULTI_PROC,
-                             "<Image>/File/Create/PDF"); */
-
   gimp_register_file_handler_mime (SAVE_PROC, "application/pdf");
   gimp_register_save_handler (SAVE_PROC, "pdf", "");
 }
@@ -324,97 +208,150 @@
                                             : CAIRO_STATUS_WRITE_ERROR;
 }
 
-static void
-run (const gchar      *name,
-     gint              nparams,
-     const GimpParam  *param,
-     gint             *nreturn_vals,
-     GimpParam       **return_vals)
+static gboolean
+group_has_text_layer (gint32 layer_id)
 {
-  static GimpParam        values[1];
-  GimpPDBStatusType       status = GIMP_PDB_SUCCESS;
-  GimpRunMode             run_mode;
-
-  /* Plug-in variables */
-  gboolean                single_image;
-  gboolean                defaults_proc;
-
-  /* Plug-In variables */
-  cairo_surface_t        *pdf_file;
-  cairo_t                *cr;
-  GimpExportCapabilities  capabilities;
-
-  guint32                 i = 0;
-  gint32                  j = 0;
-
-  gdouble                 x_res, y_res;
-  gdouble                 x_scale, y_scale;
+  gboolean has_text = FALSE;
+  gint  i, num_children;
+  gint *children;
 
-  gint32                  image_id;
-  gboolean                exported;
-  GimpImageBaseType       type;
+  children = gimp_item_get_children (layer_id, &num_children);
+  for (i = 0; i < num_children && !has_text; ++i)
+    {
+      gint32 child_id = children[num_children-i-1];
+      has_text = (gimp_item_is_text_layer (child_id) ||
+          (gimp_item_is_group (child_id) && group_has_text_layer (child_id)));
+    }
 
-  gint32                  temp;
+  g_free (children);
+  return has_text;
+}
 
-  gint                   *layers;
-  gint32                  num_of_layers;
+static void
+save_layer (gint32 layer_id, cairo_surface_t *pdf_file, cairo_t *cr, gdouble x_res, gdouble y_res, PdfOptions *options)
+{
   GimpDrawable           *layer;
-  cairo_surface_t        *layer_image;
+  GimpImageBaseType       type;
   gdouble                 opacity;
-  gint                    x, y;
-  GimpRGB                 layer_color;
-  gboolean                single_color;
-
-  gint32                  mask_id = -1;
-  GimpDrawable           *mask = NULL;
-  cairo_surface_t        *mask_image = NULL;
-  FILE                   *fp;
 
-  INIT_I18N ();
+  layer = gimp_drawable_get (layer_id);
+  type = gimp_image_base_type (gimp_item_get_image (layer_id));
+  opacity = gimp_layer_get_opacity (layer_id)/100.0;
+
+  /* Gimp doesn't display indexed layers with opacity below 50%
+   * And if it's above 50%, it will be rounded to 100% */
+  if (type == GIMP_INDEXED)
+    {
+      if (opacity <= 0.5)
+        opacity = 0.0;
+      else
+        opacity = 1.0;
+    }
 
-  /* Setting mandatory output values */
-  *nreturn_vals = 1;
-  *return_vals  = values;
+  if (gimp_item_get_visible (layer_id) && opacity > 0.0)
+    {
+      gint32                  mask_id;
+      GimpDrawable           *mask = NULL;
+      cairo_surface_t        *mask_image = NULL;
+      gint                    x, y;
 
-  values[0].type = GIMP_PDB_STATUS;
-  values[0].data.d_status = status;
+      mask_id = gimp_layer_get_mask (layer_id);
+      if (mask_id != -1)
+        {
+          mask = gimp_drawable_get (mask_id);
+          mask_image = get_drawable_image (mask);
+        }
 
-  /* Initializing all the settings */
-  multi_page.image_count = 0;
+      gimp_drawable_offsets (layer_id, &x, &y);
 
-  if (! init_vals (name, nparams, param, &single_image,
-             &defaults_proc, &run_mode))
-    {
-      values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
-      return;
-    }
+      /* For layer groups */
+      if (gimp_item_is_group (layer_id) && group_has_text_layer (layer_id))
+        {
+          gint  i, num_children;
+          gint *children;
 
-  /* Starting the executions */
-  if (run_mode == GIMP_RUN_INTERACTIVE)
-    {
-      if (single_image)
+          children = gimp_item_get_children (layer_id, &num_children);
+          for (i = 0; i < num_children; ++i)
+            {
+              save_layer (children[num_children-i-1], pdf_file, cr, x_res, y_res, options);
+            }
+
+          g_free (children);
+        }
+      /* For raster layers */
+      else if (!gimp_item_is_text_layer (layer_id))
         {
-          if (! gui_single ())
+          cairo_surface_t  *layer_image;
+          GimpRGB           layer_color;
+          gboolean          single_color;
+
+          layer_color = get_layer_color (layer, &single_color);
+          cairo_rectangle (cr, x, y, layer->width, layer->height);
+
+          if (single_color)
             {
-              values[0].data.d_status = GIMP_PDB_CANCEL;
-              return;
+              cairo_set_source_rgba (cr, layer_color.r, layer_color.g, layer_color.b, layer_color.a * opacity);
+              if (mask_id != -1)
+                cairo_mask_surface (cr, mask_image, x, y);
+              else
+                cairo_fill (cr);
+            }
+          else
+            {
+              cairo_clip (cr);
+              layer_image = get_drawable_image (layer);
+              cairo_set_source_surface (cr, layer_image, x, y);
+              cairo_push_group (cr);
+              cairo_paint_with_alpha (cr, opacity);
+              cairo_pop_group_to_source (cr);
+              if (mask_id != -1)
+                cairo_mask_surface (cr, mask_image, x, y);
+              else
+                cairo_paint (cr);
+              cairo_reset_clip (cr);
+
+              cairo_surface_destroy (layer_image);
             }
         }
-      else if (! gui_multi ())
+      /* For text layers */
+      else
         {
-          values[0].data.d_status = GIMP_PDB_CANCEL;
-          return;
+          drawText (layer, opacity, cr, x_res, y_res);
         }
 
-      if (file_name == NULL)
+      /* We are done with the layer - time to free some resources */
+      if (mask_id != -1)
         {
-          values[0].data.d_status = GIMP_PDB_CALLING_ERROR;
-          gimp_message (_("You must select a file to save!"));
-          return;
+          gimp_drawable_detach (mask);
+          cairo_surface_destroy (mask_image);
         }
     }
 
+  gimp_drawable_detach (layer);
+}
+
+static GimpPDBStatusType
+save_image (const gchar *file_name, gint32 image_id, PdfOptions *options)
+{
+  cairo_surface_t        *pdf_file;
+  cairo_t                *cr;
+
+  gint32                  j;
+
+  gdouble                 x_res, y_res;
+  gdouble                 x_scale, y_scale;
+
+  gint                   *layers;
+  gint32                  num_of_layers;
+  gint32                  layer_index;
+
+  FILE                   *fp;
+
+
   fp = g_fopen (file_name, "wb");
+  if (fp == NULL)
+    return GIMP_PDB_EXECUTION_ERROR;
+
   pdf_file = cairo_pdf_surface_create_for_stream (write_func, fp, 1, 1);
   if (cairo_surface_status (pdf_file) != CAIRO_STATUS_SUCCESS)
     {
@@ -427,309 +364,149 @@
       gimp_message (str);
       g_free (str);
 
-      values[0].data.d_status = GIMP_PDB_EXECUTION_ERROR;
-      return;
+      fclose (fp);
+      return GIMP_PDB_EXECUTION_ERROR;
     }
+
+
   cr = cairo_create (pdf_file);
 
-  capabilities = GIMP_EXPORT_CAN_HANDLE_RGB | GIMP_EXPORT_CAN_HANDLE_ALPHA |
-    GIMP_EXPORT_CAN_HANDLE_GRAY | GIMP_EXPORT_CAN_HANDLE_LAYERS |
-    GIMP_EXPORT_CAN_HANDLE_INDEXED;
-  if (optimize.apply_masks)
-    capabilities |= GIMP_EXPORT_CAN_HANDLE_LAYER_MASKS;
+  gimp_image_get_resolution (image_id, &x_res, &y_res);
+  x_scale = 72.0 / x_res;
+  y_scale = 72.0 / y_res;
+
+  cairo_pdf_surface_set_size (pdf_file,
+                              gimp_image_width (image_id) * x_scale,
+                              gimp_image_height (image_id) * y_scale);
+
+  /* This way we set how many pixels are there in every inch.
+   * It's very important for PangoCairo */
+  cairo_surface_set_fallback_resolution (pdf_file, x_res, y_res);
+
+  /* PDF is usually 72 points per inch. If we have a different resolution,
+   * we will need this to fit our drawings */
+  cairo_scale (cr, x_scale, y_scale);
 
-  for (i = 0; i < multi_page.image_count; i++)
+  /* Now, we should loop over the layers of the image */
+  layers = gimp_image_get_layers (image_id, &num_of_layers);
+
+  for (j = 0; j < num_of_layers; j++)
     {
       /* Save the state of the surface before any changes, so that settings
        * from one page won't affect all the others */
-      cairo_save (cr);
-
-      image_id =  multi_page.images[i];
-
-      /* We need the active layer in order to use gimp_image_export */
-      temp = gimp_image_get_active_drawable (image_id);
-      if (temp == -1)
-        exported = gimp_export_image (&image_id, &temp, NULL, capabilities) == GIMP_EXPORT_EXPORT;
-      else
-        exported = FALSE;
-      type = gimp_image_base_type (image_id);
-
-      gimp_image_get_resolution (image_id, &x_res, &y_res);
-      x_scale = 72.0 / x_res;
-      y_scale = 72.0 / y_res;
+      if (options->multipage)
+        cairo_save (cr);
 
-      cairo_pdf_surface_set_size (pdf_file,
-                                  gimp_image_width (image_id) * x_scale,
-                                  gimp_image_height (image_id) * y_scale);
+      layer_index = options->reverse ? j : num_of_layers-j-1;
+      save_layer (layers [layer_index], pdf_file, cr, x_res, y_res, options);
 
-      /* This way we set how many pixels are there in every inch.
-       * It's very important for PangoCairo */
-      cairo_surface_set_fallback_resolution (pdf_file, x_res, y_res);
-
-      /* PDF is usually 72 points per inch. If we have a different resolution,
-       * we will need this to fit our drawings */
-      cairo_scale (cr, x_scale, y_scale);
-
-      /* Now, we should loop over the layers of each image */
-      layers = gimp_image_get_layers (image_id, &num_of_layers);
-
-      for (j = 0; j < num_of_layers; j++)
+      if (options->multipage)
         {
-          layer = gimp_drawable_get (layers [num_of_layers-j-1]);
-          opacity = gimp_layer_get_opacity (layer->drawable_id)/100.0;
-
-          /* Gimp doesn't display indexed layers with opacity below 50%
-           * And if it's above 50%, it will be rounded to 100% */
-          if (type == GIMP_INDEXED)
-            {
-              if (opacity <= 0.5)
-                opacity = 0.0;
-              else
-                opacity = 1.0;
-            }
-
-          if (gimp_item_get_visible (layer->drawable_id)
-              && (! optimize.ignore_hidden || (optimize.ignore_hidden && opacity > 0.0)))
-            {
-              mask_id = gimp_layer_get_mask (layer->drawable_id);
-              if (mask_id != -1)
-                {
-                  mask = gimp_drawable_get (mask_id);
-                  mask_image = get_drawable_image (mask);
-                }
-
-              gimp_drawable_offsets (layer->drawable_id, &x, &y);
-
-              /* For raster layers */
-              if (!gimp_item_is_text_layer (layer->drawable_id))
-                {
-                  layer_color = get_layer_color (layer, &single_color);
-                  cairo_rectangle (cr, x, y, layer->width, layer->height);
-
-                  if (optimize.vectorize && single_color)
-                    {
-                      cairo_set_source_rgba (cr, layer_color.r, layer_color.g, layer_color.b, layer_color.a * opacity);
-                      if (mask_id != -1)
-                        cairo_mask_surface (cr, mask_image, x, y);
-                      else
-                        cairo_fill (cr);
-                    }
-                  else
-                    {
-                      cairo_clip (cr);
-                      layer_image = get_drawable_image (layer);
-                      cairo_set_source_surface (cr, layer_image, x, y);
-                      cairo_push_group (cr);
-                      cairo_paint_with_alpha (cr, opacity);
-                      cairo_pop_group_to_source (cr);
-                      if (mask_id != -1)
-                        cairo_mask_surface (cr, mask_image, x, y);
-                      else
-                        cairo_paint (cr);
-                      cairo_reset_clip (cr);
-
-                      cairo_surface_destroy (layer_image);
-                    }
-                }
-              /* For text layers */
-              else
-                {
-                  drawText (layer, opacity, cr, x_res, y_res);
-                }
-            }
-
-          /* We are done with the layer - time to free some resources */
-          gimp_drawable_detach (layer);
-          if (mask_id != -1)
-            {
-              gimp_drawable_detach (mask);
-              cairo_surface_destroy (mask_image);
-            }
+          cairo_show_page (cr);
+          cairo_restore (cr);
         }
-      /* We are done with this image - Show it! */
-      cairo_show_page (cr);
-      cairo_restore (cr);
-
-      if (exported)
-        gimp_image_delete (image_id);
     }
 
+  g_free (layers);
+
+  /* We are done with this image - Show it! */
+  if (!options->multipage)
+    cairo_show_page (cr);
+
   /* We are done with all the images - time to free the resources */
   cairo_surface_destroy (pdf_file);
   cairo_destroy (cr);
 
   fclose (fp);
-  /* Finally done, let's save the parameters */
-  gimp_set_data (DATA_OPTIMIZE, &optimize, sizeof (optimize));
-  if (!single_image)
-    {
-      g_strlcpy (multi_page.file_name, file_name, MAX_FILE_NAME_LENGTH);
-      gimp_set_data (DATA_IMAGE_LIST, &multi_page, sizeof (multi_page));
-    }
 
+  return GIMP_PDB_SUCCESS;
 }
 
-/******************************************************/
-/* Begining of parameter handling functions           */
-/******************************************************/
-
-/* A function that takes care of loading the basic
- * parameters */
-static gboolean
-init_vals (const gchar      *name,
-           gint              nparams,
-           const GimpParam  *param,
-           gboolean         *single_image,
-           gboolean         *defaults_proc,
-           GimpRunMode      *run_mode)
+static void
+run (const gchar      *name,
+     gint              nparams,
+     const GimpParam  *param,
+     gint             *nreturn_vals,
+     GimpParam       **return_vals)
 {
-  gboolean had_saved_list = FALSE;
-  gboolean single;
-  gboolean defaults = FALSE;
-  gint32   i;
-  gint32   image;
-
-  if (g_str_equal (name, SAVE_PROC))
-    {
-      single = TRUE;
-      if (nparams != SA_ARG_COUNT && nparams != SA_ARG_COUNT_DEFAULT)
-        return FALSE;
-
-      *run_mode = param[SA_RUN_MODE].data.d_int32;
-      image = param[SA_IMAGE].data.d_int32;
-      file_name = param[SA_FILENAME].data.d_string;
-
-      if (nparams == SA_ARG_COUNT)
-        {
-          optimize.apply_masks = param[SA_APPLY_MASKS].data.d_int32;
-          optimize.vectorize = param[SA_VECTORIZE].data.d_int32;
-          optimize.ignore_hidden = param[SA_IGNORE_HIDDEN].data.d_int32;
-        }
-      else
-        defaults = TRUE;
-    }
-  else if (g_str_equal (name, SAVE_MULTI_PROC))
-    {
-      single = FALSE;
-      if (nparams != SMA_ARG_COUNT)
-        return FALSE;
-
-      *run_mode = param[SMA_RUN_MODE].data.d_int32;
-      image = -1;
-      file_name = param[SA_FILENAME].data.d_string;
-
-      optimize.apply_masks = param[SMA_APPLY_MASKS].data.d_int32;
-      optimize.vectorize = param[SMA_VECTORIZE].data.d_int32;
-      optimize.ignore_hidden = param[SMA_IGNORE_HIDDEN].data.d_int32;
-    }
-  else
-    return FALSE;
+  static GimpParam        values[1];
+  GimpRunMode             run_mode;
+  GimpExportReturn        export;
 
-  switch (*run_mode)
-    {
+  PdfOptions              options = { FALSE, FALSE };
+  gint32                  image_id, drawable_id;
+  const gchar            *file_name;
 
-    case GIMP_RUN_NONINTERACTIVE:
-      if (single)
-        {
-          init_image_list_defaults (image);
-        }
-      else
-        {
-          multi_page.image_count = param[SMA_COUNT].data.d_int32;
-          if (param[SMA_IMAGES].data.d_int32array != NULL)
-            for (i = 0; i < param[SMA_COUNT].data.d_int32; i++)
-              multi_page.images[i] = param[SMA_IMAGES].data.d_int32array[i];
-        }
-      break;
+  INIT_I18N ();
 
-    case GIMP_RUN_INTERACTIVE:
-      /* Possibly retrieve data */
-      gimp_get_data (DATA_OPTIMIZE, &optimize);
-      had_saved_list = gimp_get_data (DATA_IMAGE_LIST, &multi_page);
+  /* Setting mandatory output values */
+  *nreturn_vals = 1;
+  *return_vals  = values;
 
-      if (had_saved_list && (file_name == NULL || strlen (file_name) == 0))
-        {
-          file_name = multi_page.file_name;
-        }
+  values[0].type = GIMP_PDB_STATUS;
+  values[0].data.d_status = GIMP_PDB_SUCCESS;
 
-      if (single || ! had_saved_list )
-        init_image_list_defaults (image);
+  run_mode = param[SA_RUN_MODE].data.d_int32;
+  image_id = param[SA_IMAGE].data.d_int32;
+  drawable_id = param[SA_DRAWABLE].data.d_int32;
+  file_name = param[SA_FILENAME].data.d_string;
 
-      break;
+  if (run_mode == GIMP_RUN_NONINTERACTIVE)
+    {
+      options.multipage = param[SA_MULTIPAGE].data.d_int32;
+      options.reverse = param[SA_REVERSE].data.d_int32;
+    }
+  else
+    {
+      gimp_get_data (DATA_OPTIONS, &options);
+    }
 
-    case GIMP_RUN_WITH_LAST_VALS:
-      /* Possibly retrieve data */
-      if (!single)
-        {
-          had_saved_list = gimp_get_data (DATA_IMAGE_LIST, &multi_page);
-          if (had_saved_list)
-            {
-              file_name = multi_page.file_name;
-            }
-        }
-      else
+  /* Starting the executions */
+  if (run_mode == GIMP_RUN_INTERACTIVE)
+    {
+      if (! run_gui (&options))
         {
-          init_image_list_defaults (image);
+          values[0].data.d_status = GIMP_PDB_CANCEL;
+          return;
         }
-      gimp_get_data (DATA_OPTIMIZE, &optimize);
-
-      break;
     }
 
-  *defaults_proc = defaults;
-  *single_image = single;
-
-  validate_image_list ();
-
-  return TRUE;
-}
-
-/* A function that initializes the image list to default values */
-static void
-init_image_list_defaults (gint32 image)
-{
-  if (image != -1)
+  export = gimp_export_image (&image_id, &drawable_id, NULL, PLUG_IN_CAPABILITIES);
+  if (export == GIMP_EXPORT_CANCEL)
     {
-      multi_page.images[0] = image;
-      multi_page.image_count = 1;
+      values[0].data.d_status = GIMP_PDB_CANCEL;
     }
-  else {
-    multi_page.image_count = 0;
-  }
-}
+  else
+    {
+      values[0].data.d_status = save_image (file_name, image_id, &options);
 
-/* A function that removes images that are no longer valid from
- * the image list */
-static void
-validate_image_list (void)
-{
-  gint32  valid = 0;
-  guint32 i = 0;
+      /* Finally done, let's save the parameters */
+      gimp_set_data (DATA_OPTIONS, &options, sizeof (options));
 
-  for (i = 0 ; i < MAX_PAGE_COUNT && i < multi_page.image_count ; i++)
-    {
-      if (gimp_image_is_valid (multi_page.images[i]))
-        {
-          multi_page.images[valid] = multi_page.images[i];
-          valid++;
-        }
+      if (export == GIMP_EXPORT_EXPORT)
+        gimp_image_delete (image_id);
     }
-  multi_page.image_count = valid;
 }
 
 /******************************************************/
-/* Begining of GUI functions                          */
+/* Beginning of GUI functions                         */
 /******************************************************/
-/* The main GUI function for saving single-paged PDFs */
+
+static void
+multipage_toggled (GtkToggleButton *multipage_c, GtkWidget *reverse_c)
+{
+  gtk_widget_set_sensitive (reverse_c, gtk_toggle_button_get_active (multipage_c));
+}
+
+/* The main GUI function for saving PDFs */
 static gboolean
-gui_single (void)
+run_gui (PdfOptions *options)
 {
   GtkWidget *window;
   GtkWidget *vbox;
 
-  GtkWidget *vectorize_c;
-  GtkWidget *ignore_hidden_c;
-  GtkWidget *apply_c;
+  GtkWidget *multipage_c;
+  GtkWidget *reverse_c;
 
   gboolean   run;
 
@@ -743,381 +520,30 @@
 
   gtk_container_set_border_width (GTK_CONTAINER (window), 12);
 
-  ignore_hidden_c = gtk_check_button_new_with_label (_("Omit hidden layers and layers with zero opacity"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ignore_hidden_c), optimize.ignore_hidden);
-  gtk_box_pack_end (GTK_BOX (vbox), ignore_hidden_c, TRUE, TRUE, 0);
-
-  vectorize_c = gtk_check_button_new_with_label (_("Convert bitmaps to vector graphics where possible"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vectorize_c), optimize.vectorize);
-  gtk_box_pack_end (GTK_BOX (vbox), vectorize_c, TRUE, TRUE, 0);
-
-  apply_c = gtk_check_button_new_with_label (_("Apply layer masks before saving"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apply_c), optimize.apply_masks);
-  gtk_box_pack_end (GTK_BOX (vbox), apply_c, TRUE, TRUE, 0);
-  gimp_help_set_help_data (apply_c, _("Keeping the masks will not change the output"), NULL);
+  reverse_c = gtk_check_button_new_with_label (_("Export pages in reverse order"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (reverse_c), options->reverse);
+  gtk_widget_set_sensitive (reverse_c, options->multipage);
+  gtk_box_pack_end (GTK_BOX (vbox), reverse_c, TRUE, TRUE, 0);
+
+  multipage_c = gtk_check_button_new_with_label (_("Export top-level layers as separate pages"));
+  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (multipage_c), options->multipage);
+  gtk_box_pack_end (GTK_BOX (vbox), multipage_c, TRUE, TRUE, 0);
+  g_signal_connect (multipage_c, "toggled", G_CALLBACK (multipage_toggled), reverse_c);
 
   gtk_widget_show_all (window);
 
   run = gtk_dialog_run (GTK_DIALOG (window)) == GTK_RESPONSE_OK;
 
-  optimize.ignore_hidden = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ignore_hidden_c));
-  optimize.vectorize = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (vectorize_c));
-  optimize.apply_masks = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (apply_c));
+  options->multipage = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (multipage_c));
+  options->reverse = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (reverse_c)) &&
+                        gtk_widget_is_sensitive (reverse_c);
 
   gtk_widget_destroy (window);
   return run;
 }
-/* The main GUI function for saving multi-paged PDFs */
-static gboolean
-gui_multi (void)
-{
-  GtkWidget   *window;
-  GtkWidget   *vbox;
-
-  GtkWidget   *file_label;
-  GtkWidget   *file_entry;
-  GtkWidget   *file_browse;
-  GtkWidget   *file_hbox;
-
-  GtkWidget   *vectorize_c;
-  GtkWidget   *ignore_hidden_c;
-  GtkWidget   *apply_c;
-
-  GtkWidget   *scroll;
-  GtkWidget   *page_view;
-
-  GtkWidget   *h_but_box;
-  GtkWidget   *del;
-
-  GtkWidget   *h_box;
-  GtkWidget   *img_combo;
-  GtkWidget   *add_image;
-
-  gboolean     run;
-  const gchar *temp;
-
-  gimp_ui_init (PLUG_IN_BINARY, FALSE);
-
-  window = gimp_export_dialog_new ("PDF", PLUG_IN_ROLE, SAVE_MULTI_PROC);
-
-  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 10);
-  gtk_box_pack_start (GTK_BOX (gimp_export_dialog_get_content_area (window)),
-                      vbox, TRUE, TRUE, 0);
-
-  gtk_container_set_border_width (GTK_CONTAINER (window), 12);
-
-  file_hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-  file_label = gtk_label_new (_("Save to:"));
-  file_entry = gtk_entry_new ();
-  if (file_name != NULL)
-    gtk_entry_set_text (GTK_ENTRY (file_entry), file_name);
-  file_browse = gtk_button_new_with_label (_("Browse..."));
-  file_choose = gtk_file_chooser_dialog_new (_("Multipage PDF export"),
-                                             GTK_WINDOW (window), GTK_FILE_CHOOSER_ACTION_SAVE,
-                                             "gtk-save", GTK_RESPONSE_OK,
-                                             "gtk-cancel", GTK_RESPONSE_CANCEL,
-                                             NULL);
-
-  gtk_box_pack_start (GTK_BOX (file_hbox), file_label, FALSE, FALSE, 0);
-  gtk_box_pack_start (GTK_BOX (file_hbox), file_entry, TRUE, TRUE, 0);
-  gtk_box_pack_start (GTK_BOX (file_hbox), file_browse, FALSE, FALSE, 0);
-
-  gtk_box_pack_start (GTK_BOX (vbox), file_hbox, TRUE, TRUE, 0);
-
-  page_view = gtk_icon_view_new ();
-  model = create_model ();
-  gtk_icon_view_set_model (GTK_ICON_VIEW (page_view), model);
-  gtk_icon_view_set_reorderable (GTK_ICON_VIEW (page_view), TRUE);
-  gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (page_view), GTK_SELECTION_MULTIPLE);
-
-  gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (page_view), THUMB);
-  gtk_icon_view_set_text_column (GTK_ICON_VIEW (page_view), PAGE_NUMBER);
-  gtk_icon_view_set_tooltip_column (GTK_ICON_VIEW (page_view), IMAGE_NAME);
-
-  scroll = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_set_size_request (scroll, -1, 300);
-
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-  gtk_container_add (GTK_CONTAINER (scroll), page_view);
-
-  gtk_box_pack_start (GTK_BOX (vbox), scroll, TRUE, TRUE, 0);
-
-  h_but_box = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
-  gtk_button_box_set_layout (GTK_BUTTON_BOX (h_but_box), GTK_BUTTONBOX_START);
-
-  del = gtk_button_new_with_label (_("Remove the selected pages"));
-  gtk_box_pack_start (GTK_BOX (h_but_box), del, TRUE, TRUE, 0);
-
-  gtk_box_pack_start (GTK_BOX (vbox), h_but_box, FALSE, FALSE, 0);
-
-  h_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 5);
-
-  img_combo = gimp_image_combo_box_new (NULL, NULL);
-  gtk_box_pack_start (GTK_BOX (h_box), img_combo, FALSE, FALSE, 0);
-
-  add_image = gtk_button_new_with_label (_("Add this image"));
-  gtk_box_pack_start (GTK_BOX (h_box), add_image, FALSE, FALSE, 0);
-
-  gtk_box_pack_start (GTK_BOX (vbox), h_box, FALSE, FALSE, 0);
-
-  ignore_hidden_c = gtk_check_button_new_with_label (_("Omit hidden layers and layers with zero opacity"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ignore_hidden_c), optimize.ignore_hidden);
-  gtk_box_pack_end (GTK_BOX (vbox), ignore_hidden_c, FALSE, FALSE, 0);
-
-  vectorize_c = gtk_check_button_new_with_label (_("Convert bitmaps to vector graphics where possible"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (vectorize_c), optimize.vectorize);
-  gtk_box_pack_end (GTK_BOX (vbox), vectorize_c, FALSE, FALSE, 0);
-
-  apply_c = gtk_check_button_new_with_label (_("Apply layer masks before saving"));
-  gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (apply_c), optimize.apply_masks);
-  gtk_box_pack_end (GTK_BOX (vbox), apply_c, FALSE, FALSE, 0);
-  gimp_help_set_help_data (apply_c, _("Keeping the masks will not change the output"), NULL);
-
-  gtk_widget_show_all (window);
-
-  g_signal_connect (G_OBJECT (file_browse), "clicked",
-                    G_CALLBACK (choose_file_call), G_OBJECT (file_entry));
-
-  g_signal_connect (G_OBJECT (add_image), "clicked",
-                    G_CALLBACK (add_image_call), G_OBJECT (img_combo));
-
-  g_signal_connect (G_OBJECT (del), "clicked",
-                    G_CALLBACK (del_image_call), G_OBJECT (page_view));
-
-  g_signal_connect (G_OBJECT (model), "row-deleted",
-                    G_CALLBACK (remove_call), NULL);
-
-  run = gtk_dialog_run (GTK_DIALOG (window)) == GTK_RESPONSE_OK;
-
-  run &= get_image_list ();
-
-  temp = gtk_entry_get_text (GTK_ENTRY (file_entry));
-  g_stpcpy (file_name, temp);
-
-  optimize.ignore_hidden = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (ignore_hidden_c));
-  optimize.vectorize = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (vectorize_c));
-  optimize.apply_masks = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (apply_c));
-
-  gtk_widget_destroy (window);
-  return run;
-}
-
-/* A function that is called when the button for browsing for file
- * locations was clicked */
-static void
-choose_file_call (GtkWidget *browse_button,
-                  gpointer   file_entry)
-{
-  GFile *file = g_file_new_for_path (gtk_entry_get_text (GTK_ENTRY (file_entry)));
-  gtk_file_chooser_set_uri (GTK_FILE_CHOOSER (file_choose), g_file_get_uri (file));
-
-  if (gtk_dialog_run (GTK_DIALOG (file_choose)) == GTK_RESPONSE_OK)
-    {
-      file = gtk_file_chooser_get_file (GTK_FILE_CHOOSER (file_choose));
-      gtk_entry_set_text (GTK_ENTRY (file_entry), g_file_get_path (file));
-    };
-
-  file_name = g_file_get_path (file);
-  gtk_widget_hide (file_choose);
-}
-
-/* A function to create the basic GtkTreeModel for the icon view */
-static GtkTreeModel*
-create_model (void)
-{
-  GtkListStore *model;
-  GtkTreeIter   iter;
-  guint32       i;
-  gint32        image = multi_page.images[0];
-
-  /* validate_image_list was called earlier, so all the images
-   * up to multi_page.image_count are valid */
-  model = gtk_list_store_new (4,
-                              GDK_TYPE_PIXBUF, /* THUMB */
-                              G_TYPE_STRING,   /* PAGE_NUMBER */
-                              G_TYPE_STRING,   /* IMAGE_NAME */
-                              G_TYPE_INT);     /* IMAGE_ID */
-
-  for (i = 0 ; i < multi_page.image_count && i < MAX_PAGE_COUNT ; i++)
-    {
-      image = multi_page.images[i];
-
-      gtk_list_store_append (model, &iter);
-      gtk_list_store_set (model, &iter,
-                          THUMB, gimp_image_get_thumbnail (image, THUMB_WIDTH, THUMB_HEIGHT, GIMP_PIXBUF_SMALL_CHECKS),
-                          PAGE_NUMBER, g_strdup_printf ("Page %d", i+1),
-                          IMAGE_NAME, gimp_image_get_name (image),
-                          IMAGE_ID, image,
-                          -1);
-
-    }
-
-  return GTK_TREE_MODEL (model);
-}
-
-/* A function that puts the images from the model inside the
- * images (pages) array */
-static gboolean
-get_image_list (void)
-{
-  GtkTreeIter iter;
-  gboolean    valid = gtk_tree_model_get_iter_first (model, &iter);
-  gint32      image;
-
-  multi_page.image_count = 0;
-
-  if (!valid)
-    {
-      gimp_message (_("Error! In order to save the file, at least one image should be added!"));
-      return FALSE;
-    }
-
-  while (valid)
-    {
-      gtk_tree_model_get (model, &iter,
-                          IMAGE_ID, &image,
-                          -1);
-      multi_page.images[multi_page.image_count] = image;
-
-      valid = gtk_tree_model_iter_next (model, &iter);
-      multi_page.image_count++;
-    }
-
-  return TRUE;
-}
-
-/* A function that is called when the button for adding an image
- * was clicked */
-static void
-add_image_call (GtkWidget *widget,
-                gpointer   img_combo)
-{
-  GtkListStore *store;
-  GtkTreeIter   iter;
-  gint32        image;
-
-  dnd_remove = FALSE;
-
-  gimp_int_combo_box_get_active (img_combo, &image);
-
-  store = GTK_LIST_STORE (model);
-
-  gtk_list_store_append (store, &iter);
-  gtk_list_store_set (store, &iter,
-                      PAGE_NUMBER, g_strdup_printf ("Page %d", multi_page.image_count+1),
-                      THUMB, gimp_image_get_thumbnail (image, THUMB_WIDTH, THUMB_HEIGHT, GIMP_PIXBUF_SMALL_CHECKS),
-                      IMAGE_NAME, gimp_image_get_name (image),
-                      IMAGE_ID, image,
-                      -1
-                      );
-
-  multi_page.image_count++;
-
-  dnd_remove = TRUE;
-}
-
-/* A function that is called when the button for deleting the
- * selected images was clicked */
-static void
-del_image_call (GtkWidget *widget,
-                gpointer   icon_view)
-{
-  GList                *list;
-  GtkTreeRowReference **items;
-  GtkTreePath          *item_path;
-  GtkTreeIter           item;
-  guint32               i;
-  gpointer              temp;
-
-  guint32               len;
-
-  GdkPixbuf            *thumb;
-  gchar*                name;
-
-  dnd_remove = FALSE;
-
-  list = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (icon_view));
-
-  len = g_list_length (list);
-  if (len > 0)
-    {
-      items = g_newa (GtkTreeRowReference*, len);
-
-      for (i = 0; i < len; i++)
-        {
-          temp = g_list_nth_data (list, i);
-          items[i] = gtk_tree_row_reference_new (model, temp);
-          gtk_tree_path_free (temp);
-        }
-      g_list_free (list);
-
-      for (i = 0; i < len; i++)
-        {
-          item_path = gtk_tree_row_reference_get_path (items[i]);
-          gtk_tree_model_get_iter (model, &item, item_path);
-
-          /* Get the data that should be freed */
-          gtk_tree_model_get (model, &item,
-                              THUMB, &thumb, IMAGE_NAME, &name, -1);
-
-          /* Only after you have the pointers, remove them from the tree */
-          gtk_list_store_remove (GTK_LIST_STORE (model), &item);
-
-          /* Now you can free the data */
-          g_object_unref(thumb);
-          g_free (name);
-
-          gtk_tree_path_free (item_path);
-          gtk_tree_row_reference_free (items[i]);
-          multi_page.image_count--;
-        }
-
-      g_free (items);
-    }
-
-  dnd_remove = TRUE;
-
-  recount_pages ();
-}
-
-/* A function that is called on rows-deleted signal. It will
- * call the function to relabel the pages */
-static void
-remove_call (GtkTreeModel *tree_model,
-             GtkTreePath  *path,
-             gpointer      user_data)
-{
-
-  if (dnd_remove)
-    /* The gtk documentation says that we should not free the indices array */
-    recount_pages ();
-}
-
-/* A function to relabel the pages in the icon view, when
- * their order was changed */
-static void
-recount_pages (void)
-{
-  GtkListStore *store;
-  GtkTreeIter   iter;
-  gboolean      valid;
-  gint32        i = 0;
-
-  store = GTK_LIST_STORE (model);
-
-  valid = gtk_tree_model_get_iter_first (model, &iter);
-  while (valid)
-    {
-      gtk_list_store_set (store, &iter,
-                          PAGE_NUMBER, g_strdup_printf ("Page %d", i + 1),
-                          -1);
-      valid = gtk_tree_model_iter_next (model, &iter);
-      i++;
-    }
-}
 
 /******************************************************/
-/* Begining of the actual PDF functions               */
+/* Beginning of the actual PDF functions              */
 /******************************************************/
 
 /* A function to get a cairo image surface from a drawable.
@@ -1356,7 +782,7 @@
 
   if (gimp_drawable_is_indexed (id))
     {
-      /* FIXME: We can't do a propper histogram on indexed layers! */
+      /* FIXME: We can't do a proper histogram on indexed layers! */
       *single = FALSE;
       col. r = col.g = col.b = col.a = 0;
       return col;
