[pdfmod] Make Export Images a page action



commit 2aabd9d8afd6b3cdf57134b73ff26a643763562f
Author: Gabriel Burt <gabriel burt gmail com>
Date:   Tue Sep 14 16:01:36 2010 -0500

    Make Export Images a page action
    
    That is, it acts on the selected pages (like extract page and rotate
    do).  Additionally, it now displays the number of images that will be
    exported, and is insensitive if none can be exported (bgo#594457)
    
    Also, escape the created directory and filenames properly (bgo#606432)

 src/PdfMod/Gui/Actions.cs                    |   29 +++++++++----
 src/PdfMod/Pdf/Actions/ExportImagesAction.cs |   59 ++++++++++++++++++-------
 src/Resources/UIManager.xml                  |    7 ++-
 3 files changed, 68 insertions(+), 27 deletions(-)
---
diff --git a/src/PdfMod/Gui/Actions.cs b/src/PdfMod/Gui/Actions.cs
index 7496b2b..276a0e5 100644
--- a/src/PdfMod/Gui/Actions.cs
+++ b/src/PdfMod/Gui/Actions.cs
@@ -46,12 +46,12 @@ namespace PdfMod.Gui
 
         static string [] require_doc_actions = new string[] {
             "Save", "SaveAs", "Properties", "Undo", "Redo", "ZoomFit", "OpenInViewer",
-            "SelectAll", "SelectEvens", "SelectOdds", "SelectMatching", "SelectInverse", "InsertFrom", "ExportImages",
+            "SelectAll", "SelectEvens", "SelectOdds", "SelectMatching", "SelectInverse", "InsertFrom",
             "ViewBookmarks", "AddBookmark", "EditBookmarks"
         };
 
         static string [] require_page_actions = new string[] {
-            "Remove", "Extract", "RotateRight", "RotateLeft"
+            "Remove", "Extract", "RotateRight", "RotateLeft", "ExportImages"
         };
 
         public UndoManager UndoManager { get { return undo_manager; } }
@@ -67,7 +67,6 @@ namespace PdfMod.Gui
                 new ActionEntry ("Save",   Gtk.Stock.Save,   null, "<control>S", Catalog.GetString ("Save changes to this document, overwriting the existing file"), OnSave),
                 new ActionEntry ("SaveAs", Gtk.Stock.SaveAs, null, "<control><shift>S", Catalog.GetString ("Save this document to a new file"), OnSaveAs),
                 new ActionEntry ("RecentMenu", null, Catalog.GetString ("Recent _Files"), null, null, null),
-                new ActionEntry ("ExportImages", null, Catalog.GetString ("Export Images"), null, Catalog.GetString ("Save all images in this document to a new folder"), OnExportImages),
                 new ActionEntry ("InsertFrom", Gtk.Stock.Add, Catalog.GetString("_Insert From..."), null, Catalog.GetString("Insert pages from another document"), OnInsertFrom),
                 new ActionEntry ("Close", Gtk.Stock.Close, null, "<control>W", null, OnClose),
 
@@ -78,6 +77,7 @@ namespace PdfMod.Gui
                 new ActionEntry ("Remove", Gtk.Stock.Remove, null, "Delete", null, OnRemove),
                 new ActionEntry ("RotateLeft", null, Catalog.GetString ("Rotate Left"), "bracketleft", Catalog.GetString ("Rotate left"), OnRotateLeft),
                 new ActionEntry ("RotateRight", null, Catalog.GetString ("Rotate Right"), "bracketright", Catalog.GetString ("Rotate right"), OnRotateRight),
+                new ActionEntry ("ExportImages", null, null, null, null, OnExportImages),
                 new ActionEntry ("SelectAll", Stock.SelectAll, null, "<control>A", null, OnSelectAll),
                 new ActionEntry ("SelectOdds", null, Catalog.GetString ("Select Odd Pages"), null, null, OnSelectOdds),
                 new ActionEntry ("SelectEvens", null, Catalog.GetString ("Select Even Pages"), null, null, OnSelectEvens),
@@ -177,6 +177,17 @@ namespace PdfMod.Gui
             foreach (string action in require_page_actions)
                 UpdateAction (action, true, have_page);
 
+            int exportable_imgs = 0;
+            if (have_page) {
+                exportable_imgs = new ExportImagesAction (app.Document, app.IconView.SelectedPages).ExportableImageCount;
+            }
+            UpdateAction ("ExportImages", true, exportable_imgs > 0);
+            this["ExportImages"].Label = String.Format (Catalog.GetPluralString (
+                "Export Image", "Export {0} Images", exportable_imgs), exportable_imgs);
+
+            this["ExportImages"].Tooltip = String.Format (Catalog.GetPluralString (
+                "Save image from the selected pages to a new folder", "Save {0} images from the selected pages to a new folder", exportable_imgs), exportable_imgs);
+
             UpdateAction ("Undo", true, have_doc && undo_manager.CanUndo);
             UpdateAction ("Redo", true, have_doc && undo_manager.CanRedo);
 
@@ -266,7 +277,8 @@ namespace PdfMod.Gui
 
         void OnExportImages (object o, EventArgs args)
         {
-            var action = new ExportImagesAction (app.Document, app.Document.Pages);
+            var pages = app.IconView.SelectedPages.ToList ();
+            var action = new ExportImagesAction (app.Document, pages);
             if (action.ExportableImageCount == 0) {
                 Log.Information ("Found zero exportable images in the selected pages");
                 return;
@@ -274,8 +286,9 @@ namespace PdfMod.Gui
 
             var export_path_base = Path.Combine (
                 Path.GetDirectoryName (app.Document.SuggestedSavePath),
-                Hyena.StringUtil.EscapeFilename (
-                    System.IO.Path.GetFileNameWithoutExtension (app.Document.Filename))
+                Hyena.StringUtil.EscapeFilename (String.Format ("{0} [{1}]",
+                    Path.GetFileNameWithoutExtension (app.Document.SuggestedSavePath),
+                    GLib.Markup.EscapeText (Document.GetPageSummary (pages, 10))))
             );
 
             var export_path = export_path_base;
@@ -361,9 +374,9 @@ namespace PdfMod.Gui
 
             app.LoadPath (path, Path.Combine (
                 Path.GetDirectoryName (app.Document.SuggestedSavePath),
-                String.Format ("{0} [{1}].pdf",
+                Hyena.StringUtil.EscapeFilename (String.Format ("{0} [{1}].pdf",
                     Path.GetFileNameWithoutExtension (app.Document.SuggestedSavePath),
-                    GLib.Markup.EscapeText (Document.GetPageSummary (pages, 10)))
+                    GLib.Markup.EscapeText (Document.GetPageSummary (pages, 10))))
             ));
         }
 
diff --git a/src/PdfMod/Pdf/Actions/ExportImagesAction.cs b/src/PdfMod/Pdf/Actions/ExportImagesAction.cs
index 31c1fd9..ff45dbf 100644
--- a/src/PdfMod/Pdf/Actions/ExportImagesAction.cs
+++ b/src/PdfMod/Pdf/Actions/ExportImagesAction.cs
@@ -35,9 +35,12 @@
 
 using System;
 using System.IO;
+using System.Text;
 using System.Collections.Generic;
 using System.Linq;
 
+using Mono.Unix;
+
 using PdfSharp.Pdf;
 using PdfSharp.Pdf.Advanced;
 
@@ -46,10 +49,13 @@ namespace PdfMod.Pdf.Actions
     public class ExportImagesAction
     {
         List<ImageInfo> image_objects;
+        int max_page_index;
 
         public ExportImagesAction (Document document, IEnumerable<Page> pages)
         {
-            image_objects = GetImageObjectsFrom (pages).Where (IsExportable).ToList ();
+            var page_list = pages.ToList ();
+            max_page_index = page_list.Last ().Index;
+            image_objects = GetImageObjectsFrom (page_list).ToList ();
         }
 
         public int ExportableImageCount {
@@ -65,20 +71,17 @@ namespace PdfMod.Pdf.Actions
 
         IEnumerable<ImageInfo> GetImageObjectsFrom (IEnumerable<Page> pages)
         {
-            // Doesn't seem like you can get the images just on one page; the following
-            // gets all the images in the whole document, so only need to do it from one page
-            //foreach (var page in pages) {
-                var page = pages.First ();
+            foreach (var page in pages) {
                 var resources = page.Pdf.Elements.GetDictionary ("/Resources");
                 if (resources == null)
-                    yield break;
+                    continue;
 
                 var x_objects = resources.Elements.GetDictionary ("/XObject");
                 if (x_objects == null)
-                    yield break;
+                    continue;
 
                 int i = 0;
-                var items = x_objects.Elements.Values;
+                var items = x_objects.Elements.Values.ToList ();
                 foreach (var item in items) {
                     var reference = item as PdfReference;
                     if (reference == null)
@@ -88,10 +91,15 @@ namespace PdfMod.Pdf.Actions
                     // Put this in a variable to pass to GetString so that it's not pulled out as a translation string
                     var subtype = "/Subtype";
                     if (x_object != null && x_object.Elements.GetString (subtype) == "/Image") {
-                        yield return new ImageInfo () { Page = page, ImageObject = x_object, PageIndex = i++ };
+                        var img = new ImageInfo () { Page = page, ImageObject = x_object, PageIndex = i++, PageCount = items.Count };
+                        if (IsExportable (img)) {
+                            yield return img;
+                        } else {
+                            i--;
+                        }
                     }
                 }
-            //}
+            }
         }
 
         bool IsExportable (ImageInfo image)
@@ -103,7 +111,7 @@ namespace PdfMod.Pdf.Actions
         /// <summary>
         /// Currently extracts only JPEG images.
         /// </summary>
-        static void Export (ImageInfo image, string to_path)
+        void Export (ImageInfo image, string to_path)
         {
             string filter = image.ImageObject.Elements.GetName("/Filter");
             switch (filter) {
@@ -116,20 +124,36 @@ namespace PdfMod.Pdf.Actions
             }
         }
 
-        static string GetFilename (ImageInfo image, string to_path, string ext)
+        string GetFilename (ImageInfo image, string to_path, string ext)
         {
-            var name = image.ImageObject.Elements.GetName ("/Name");
+            string name = image.ImageObject.Elements.GetName ("/Name");
+            if (name == "/X") { name = null; }
             var name_fragment = String.IsNullOrEmpty (name) ? null : String.Format (" ({0})", name);
             var path = Path.Combine (
                 to_path,
-                Hyena.StringUtil.EscapeFilename (
-                    String.Format ("{0:00}{1}.{2}", image.PageIndex, name_fragment, ext))
-                //String.Format ("Page {0} - #{1:00}{2}.{3}",
-                    //image.Page.Index, image.PageIndex, name_fragment, ext)
+                Hyena.StringUtil.EscapeFilename (String.Format (
+                    "{0} - {1}{2}.{3}",
+                    String.Format (Catalog.GetString ("Page {0}"),
+                        SortableNumberString (image.Page.Index + 1, max_page_index + 1)),
+                    SortableNumberString (image.PageIndex + 1, image.PageCount),
+                    name_fragment, ext
+                ))
             );
             return path;
         }
 
+        static string SortableNumberString (int num, int count)
+        {
+            var fmt = new StringBuilder ("{0:");
+            int places = count.ToString ().Length;
+            for (int i = 0; i < places; i++) {
+                fmt.Append ('0');
+            }
+            fmt.Append ('}');
+
+            return String.Format (fmt.ToString (), num);
+        }
+
         /// <summary>
         /// Exports a JPEG image.
         /// </summary>
@@ -166,6 +190,7 @@ namespace PdfMod.Pdf.Actions
             public Page Page { get; set; }
             public PdfDictionary ImageObject { get; set; }
             public int PageIndex { get; set; }
+            public int PageCount { get; set; }
         }
     }
 }
diff --git a/src/Resources/UIManager.xml b/src/Resources/UIManager.xml
index 035eb05..0a59ba8 100644
--- a/src/Resources/UIManager.xml
+++ b/src/Resources/UIManager.xml
@@ -6,7 +6,6 @@
       <menuitem action="SaveAs"/>
       <menuitem action="RecentMenu"/>
       <separator/>
-      <menuitem action="ExportImages"/>
       <menuitem action="InsertFrom"/>
       <separator/>
       <menuitem action="Properties"/>
@@ -24,6 +23,8 @@
       <menuitem action="RotateRight"/>
       <!--<menuitem action="RotateArbitrary"/>-->
       <separator/>
+      <menuitem action="ExportImages"/>
+      <separator/>
       <menuitem action="SelectAll"/>
       <menuitem action="SelectOdds"/>
       <menuitem action="SelectEvens"/>
@@ -62,13 +63,13 @@
     <separator/>
     <toolitem action="Properties"/>
     <toolitem action="ViewBookmarks"/>
-    <toolitem action="ExportImages"/>
     <toolitem action="InsertFrom"/>
     <separator/>
     <toolitem action="Extract"/>
     <toolitem action="Remove"/>
     <toolitem action="RotateLeft"/>
     <toolitem action="RotateRight"/>
+    <toolitem action="ExportImages"/>
     <separator/>
     <!-- Commented out until we have a good icon <toolitem action="OpenInViewer"/>-->
   </toolbar>
@@ -81,6 +82,8 @@
     <menuitem action="RotateRight"/>
     <!--<menuitem action="RotateArbitrary"/>-->
     <separator/>
+    <menuitem action="ExportImages"/>
+    <separator/>
     <menuitem action="SelectAll"/>
     <menuitem action="SelectOdds"/>
     <menuitem action="SelectEvens"/>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]