[ocrfeeder] Refactored SourceImagesSelectorIconView



commit 3403e5da87ed3273d36b2680bb79687215dccfcf
Author: Joaquim Rocha <me joaquimrocha com>
Date:   Sat May 18 01:02:38 2013 +0200

    Refactored SourceImagesSelectorIconView
    
    Now it is called PagesIconView, was separated into its own file
    and was ported to GI.

 src/ocrfeeder/studio/pagesiconview.py |  169 ++++++++++++++++++++++++++++++++
 src/ocrfeeder/studio/studioBuilder.py |   51 +++++-----
 src/ocrfeeder/studio/widgetModeler.py |  173 +++------------------------------
 3 files changed, 207 insertions(+), 186 deletions(-)
---
diff --git a/src/ocrfeeder/studio/pagesiconview.py b/src/ocrfeeder/studio/pagesiconview.py
new file mode 100644
index 0000000..3e1156f
--- /dev/null
+++ b/src/ocrfeeder/studio/pagesiconview.py
@@ -0,0 +1,169 @@
+# -*- coding: utf-8 -*-
+
+###########################################################################
+#    OCRFeeder - The complete OCR suite
+#    Copyright (C) 2009-2013 Joaquim Rocha <me joaquimrocha com>
+#
+#    This program is free software: you can redistribute it and/or modify
+#    it under the terms of the GNU General Public License as published by
+#    the Free Software Foundation, either version 3 of the License, or
+#    (at your option) any later version.
+#
+#    This program is distributed in the hope that it will be useful,
+#    but WITHOUT ANY WARRANTY; without even the implied warranty of
+#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#    GNU General Public License for more details.
+#
+#    You should have received a copy of the GNU General Public License
+#    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+###########################################################################
+
+import os
+import gettext
+from gi.repository import Gtk, Gdk, GdkPixbuf
+_ = gettext.gettext
+
+class PagesListStore(Gtk.ListStore):
+
+    def __init__(self, list_of_images = []):
+        super(PagesListStore, self).__init__(str, GdkPixbuf.Pixbuf, object)
+        if len(list_of_images):
+            for path in list_of_images:
+                self.__renderImage(path, self.__generateImageName(path))
+
+    def addImage(self, page_data):
+        image_name = self.__generateImageName(page_data.image_path)
+        return self.__renderImage(image_name, page_data)
+
+    def __renderImage(self, image_name, page_data):
+        pixbuf = GdkPixbuf.Pixbuf.new_from_file_at_size(page_data.image_path,
+                                                        150, 100)
+        return self.append([image_name, pixbuf, page_data])
+
+    def __countEqualPathsStored(self, path):
+        iter = self.get_iter_first()
+        counter = 0
+        while iter != None:
+            page_data = self.get_value(iter, 2)
+            image_path = page_data.image_path
+            if image_path == path:
+                counter += 1
+            iter = self.iter_next(iter)
+        return counter
+
+    def __generateImageName(self, path):
+        image_name = os.path.basename(path)
+        number_of_equal_paths = self.__countEqualPathsStored(path)
+        if number_of_equal_paths:
+            image_name += ' ('+ str(number_of_equal_paths + 1) + ')'
+        return image_name
+
+    def getPixbufsSorted(self):
+        pixbufs = []
+        iter = self.get_iter_first()
+        while iter != None:
+            pixbufs.append(self.get_value(iter, 2))
+            iter = self.iter_next(iter)
+        return pixbufs
+
+    def removeIter(self, path):
+        iter = self.get_iter(path)
+        self.remove(iter)
+
+class PagesIconView(Gtk.IconView):
+
+    def __init__(self):
+        Gtk.IconView.__init__(self)
+        self.set_model(PagesListStore())
+        self.get_accessible().set_name(_('Pages'))
+        self.set_text_column(0)
+        self.set_pixbuf_column(1)
+        self.set_item_orientation(Gtk.Orientation.VERTICAL)
+        self.set_columns(1)
+        self.set_reorderable(True)
+        self.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
+        self.set_selection_mode(Gtk.SelectionMode.BROWSE)
+        self.connect('button-press-event', self.pressedRightButton)
+
+    def pressedRightButton(self, target, event):
+        if event.button == 3:
+            selected_items = self.get_selected_items()
+            if selected_items:
+                menu = getPopupMenu([(Gtk.STOCK_DELETE, _('Delete'), self.delete_current_page_function)])
+                menu.popup(None, None, None, event.button, event.time)
+
+    def getSelectedPageData(self):
+        selected_items = self.get_selected_items()
+        if len(selected_items):
+            selected_item_path = selected_items[0]
+            model = self.get_model()
+            iter = model.get_iter(selected_item_path)
+            return self.get_model().get_value(iter, 2)
+        return None
+
+    def getAllPages(self):
+        model = self.get_model()
+        pages = []
+        iter = model.get_iter_first()
+        while iter:
+            pages.append(model.get_value(iter, 2))
+            iter = model.iter_next(iter)
+        return pages
+
+    def setDeleteCurrentPageFunction(self, function):
+        self.delete_current_page_function = function
+
+    def deleteCurrentSelection(self):
+        selected_items = self.get_selected_items()
+        if len(selected_items):
+            selected_item_path = selected_items[0]
+            self.get_model().removeIter(selected_item_path)
+            first_iter = self.get_model().get_iter_first()
+            if first_iter:
+                self.select_path(self.get_model().get_path(first_iter))
+
+    def clear(self):
+        self.get_model().clear()
+
+    def _getIndexFromOffset(self, offset):
+        selected_items = self.get_selected_items()
+        if not len(selected_items):
+            return
+        selected_item_path = selected_items[0]
+        model = self.get_model()
+        iter = model.get_iter(selected_item_path)
+        index = model.get_path(iter)[0] + offset
+        number_of_items = model.iter_n_children(None)
+        if index < 0:
+            index = number_of_items + offset
+        elif index == number_of_items:
+            index = 0
+        return index
+
+    def movePage(self, offset):
+        selected_items = self.get_selected_items()
+        if not len(selected_items):
+            return
+        selected_item_path = selected_items[0]
+        model = self.get_model()
+        index = self._getIndexFromOffset(offset)
+        if index != selected_item_path[0] + offset:
+            return
+        model.swap(model.get_iter((index,)),
+                   model.get_iter(selected_item_path))
+        self.select_path(Gtk.TreePath(index))
+
+    def selectPageFromOffset(self, offset):
+        selected_items = self.get_selected_items()
+        if not len(selected_items):
+            return
+        selected_item_path = selected_items[0]
+        model = self.get_model()
+        index = self._getIndexFromOffset(offset)
+        self.select_path(Gtk.TreePath(index))
+
+    def getNumberOfPages(self):
+        return self.get_model().iter_n_children(None)
+
+    def isEmpty(self):
+        return self.get_model().get_iter_first() is None
diff --git a/src/ocrfeeder/studio/studioBuilder.py b/src/ocrfeeder/studio/studioBuilder.py
index 1acab4b..bcca260 100644
--- a/src/ocrfeeder/studio/studioBuilder.py
+++ b/src/ocrfeeder/studio/studioBuilder.py
@@ -24,10 +24,10 @@ import sys
 import os.path
 import urllib
 import widgetPresenter
-from widgetModeler import SourceImagesListStore, \
-     SourceImagesSelectorIconView, ImageReviewer_Controler
+from widgetModeler import ImageReviewer_Controler
 from dataHolder import DataBox, TextData
 from customWidgets import SelectableBoxesArea
+from pagesiconview import PagesIconView
 from ocrfeeder.feeder.ocrEngines import Engine, OcrEnginesManager
 from ocrfeeder.feeder.documentGeneration import DocumentGeneratorManager
 from ocrfeeder.util.configuration import ConfigurationManager
@@ -35,12 +35,9 @@ from ocrfeeder.util.asyncworker import AsyncItem
 from optparse import OptionParser
 import gettext
 import locale
+from gi.repository import Gdk, Gtk
 _ = gettext.gettext
 
-import pygtk
-pygtk.require('2.0')
-import gtk
-
 class Studio:
 
     TARGET_TYPE_URI_LIST = 80
@@ -75,22 +72,22 @@ class Studio:
         self.engines_needing_update = \
             self.ocr_engines_manager.makeEnginesFromFolder(user_engines_folder)
         self.ocr_engines = self.ocr_engines_manager.ocr_engines
-        self.source_images_list_store = SourceImagesListStore()
-        self.source_images_icon_view = SourceImagesSelectorIconView(self.source_images_list_store)
-        self.source_images_icon_view.setDeleteCurrentPageFunction(self.deleteCurrentPage)
-        self.source_images_icon_view.connect('drag_data_received', self.dragDataReceived)
-        self.source_images_icon_view.connect('drag_drop', self.dragDrop)
-        self.source_images_icon_view.get_model().connect('row-inserted',
+        self.pages_icon_view = PagesIconView()
+        self.pages_icon_view.setDeleteCurrentPageFunction(self.deleteCurrentPage)
+        self.pages_icon_view.connect('drag_data_received', self.dragDataReceived)
+        self.pages_icon_view.connect('drag_drop', self.dragDrop)
+        self.pages_icon_view.get_model().connect('row-inserted',
                                                  self.__pagesUpdatedCallback)
-        self.source_images_icon_view.get_model().connect('row-deleted',
+        self.pages_icon_view.get_model().connect('row-deleted',
                                                  self.__pagesUpdatedCallback)
-        self.source_images_icon_view.drag_dest_set(gtk.DEST_DEFAULT_MOTION | gtk.DEST_DEFAULT_HIGHLIGHT,
-                                                   [('text/uri-list', 0, self.TARGET_TYPE_URI_LIST)], 
gtk.gdk.ACTION_COPY)
-        self.source_images_icon_view.show()
-        self.main_window.main_area_left.add_with_viewport(self.source_images_icon_view)
+        target_entry = Gtk.TargetEntry.new('text/uri-list', 0, self.TARGET_TYPE_URI_LIST)
+        self.pages_icon_view.drag_dest_set(Gtk.DestDefaults.MOTION | Gtk.DestDefaults.HIGHLIGHT,
+                                           [target_entry], Gdk.DragAction.COPY)
+        self.pages_icon_view.show()
+        self.main_window.main_area_left.add_with_viewport(self.pages_icon_view)
         self.images_selectable_area = {}
         self.source_images_controler = ImageReviewer_Controler(self.main_window,
-                                                               self.source_images_icon_view,
+                                                               self.pages_icon_view,
                                                                self.ocr_engines,
                                                                self.configuration_manager)
         self.project_name = None
@@ -146,7 +143,7 @@ class Studio:
         self.main_window.setHasSelectedBoxes(False)
         self.main_window.setHasContentBoxes(False)
         self.main_window.setNumberOfPages(
-            self.source_images_icon_view.getNumberOfPages())
+            self.pages_icon_view.getNumberOfPages())
 
         # Show dialog to choose system-wide OCR engines when no engine was found
         if not self.ocr_engines:
@@ -330,20 +327,20 @@ class Studio:
         response = delete_dialog.run()
         if response == gtk.RESPONSE_YES:
             self.source_images_controler.deleteCurrentPage()
-            self.source_images_icon_view.deleteCurrentSelection()
+            self.pages_icon_view.deleteCurrentSelection()
         delete_dialog.destroy()
 
     def movePageDown(self, widget):
-        self.source_images_icon_view.movePage(1)
+        self.pages_icon_view.movePage(1)
 
     def movePageUp(self, widget):
-        self.source_images_icon_view.movePage(-1)
+        self.pages_icon_view.movePage(-1)
 
     def selectNextPage(self, widget):
-        self.source_images_icon_view.selectPageFromOffset(1)
+        self.pages_icon_view.selectPageFromOffset(1)
 
     def selectPreviousPage(self, widget):
-        self.source_images_icon_view.selectPageFromOffset(-1)
+        self.pages_icon_view.selectPageFromOffset(-1)
 
     def __addImagesToReviewer(self, images):
         if not images:
@@ -437,7 +434,7 @@ class Studio:
 
     def __pagesUpdatedCallback(self, model, path, iter = None):
         self.main_window.setNumberOfPages(
-            self.source_images_icon_view.getNumberOfPages())
+            self.pages_icon_view.getNumberOfPages())
 
     def __askForEnginesMigration(self):
         auto_update = self.engines_needing_update['auto']
@@ -478,8 +475,8 @@ class Studio:
                 self.ocrEngines()
 
     def quit(self, widget = None, data = None):
-        if not self.project_name and not self.source_images_list_store.isEmpty():
-            quit_dialog = widgetPresenter.QuestionDialog('<b>' + _("The project hasn't been saved.") + 
'</b>', gtk.BUTTONS_NONE)
+        if not self.project_name and not self.pages_icon_view.isEmpty():
+            quit_dialog = widgetPresenter.QuestionDialog('<b>' + _("The project hasn't been saved.") + 
'</b>', Gtk.BUTTONS_NONE)
             quit_dialog.format_secondary_text(_('Do you want to save it before closing?'))
             quit_dialog.add_buttons(_('Close anyway'), gtk.RESPONSE_NO, gtk.STOCK_CANCEL, 
gtk.RESPONSE_CANCEL, gtk.STOCK_SAVE_AS, gtk.RESPONSE_YES)
             response = quit_dialog.run()
diff --git a/src/ocrfeeder/studio/widgetModeler.py b/src/ocrfeeder/studio/widgetModeler.py
index eb6aef4..283566b 100644
--- a/src/ocrfeeder/studio/widgetModeler.py
+++ b/src/ocrfeeder/studio/widgetModeler.py
@@ -45,152 +45,7 @@ import sys
 pygtk.require('2.0')
 _ = gettext.gettext
 
-
-
-class SourceImagesListStore(gtk.ListStore):
-
-    def __init__(self, list_of_images = []):
-        super(SourceImagesListStore, self).__init__(str, gtk.gdk.Pixbuf, object)
-        if len(list_of_images):
-            for path in list_of_images:
-                self.__renderImage(path, self.__generateImageName(path))
-
-    def addImage(self, page_data):
-        image_name = self.__generateImageName(page_data.image_path)
-        return self.__renderImage(image_name, page_data)
-
-    def __renderImage(self, image_name, page_data):
-        pixbuf = gtk.gdk.pixbuf_new_from_file_at_size(page_data.image_path,
-                                                      150, 100)
-        return self.append([image_name, pixbuf, page_data])
-
-    def __countEqualPathsStored(self, path):
-        iter = self.get_iter_root()
-        counter = 0
-        while iter != None:
-            page_data = self.get_value(iter, 2)
-            image_path = page_data.image_path
-            if image_path == path:
-                counter += 1
-            iter = self.iter_next(iter)
-        return counter
-
-    def __generateImageName(self, path):
-        image_name = os.path.basename(path)
-        number_of_equal_paths = self.__countEqualPathsStored(path)
-        if number_of_equal_paths:
-            image_name += ' ('+ str(number_of_equal_paths + 1) + ')'
-        return image_name
-
-    def getPixbufsSorted(self):
-        pixbufs = []
-        iter = self.get_iter_root()
-        while iter != None:
-            pixbufs.append(self.get_value(iter, 2))
-            iter = self.iter_next(iter)
-        return pixbufs
-
-    def removeIter(self, path):
-        iter = self.get_iter(path)
-        self.remove(iter)
-
-    def isEmpty(self):
-        return self.get_iter_first() == None
-
-class SourceImagesSelectorIconView(gtk.IconView):
-
-    def __init__(self, source_images_list_store):
-        super(SourceImagesSelectorIconView, self).__init__(source_images_list_store)
-        self.get_accessible().set_name(_('Pages'))
-        self.set_text_column(0)
-        self.set_pixbuf_column(1)
-        self.set_orientation(gtk.ORIENTATION_VERTICAL)
-        self.set_columns(1)
-        self.set_reorderable(True)
-        self.add_events(gtk.gdk.BUTTON_PRESS_MASK)
-        self.set_selection_mode(gtk.SELECTION_BROWSE)
-        self.connect('button-press-event', self.pressedRightButton)
-
-    def pressedRightButton(self, target, event):
-        if event.button == 3:
-            selected_items = self.get_selected_items()
-            if selected_items:
-                menu = getPopupMenu([(gtk.STOCK_DELETE, _('Delete'), self.delete_current_page_function)])
-                menu.popup(None, None, None, event.button, event.time)
-
-    def getSelectedPageData(self):
-        selected_items = self.get_selected_items()
-        if len(selected_items):
-            selected_item_path = selected_items[0]
-            model = self.get_model()
-            iter = model.get_iter(selected_item_path)
-            return self.get_model().get_value(iter, 2)
-        return None
-
-    def getAllPages(self):
-        model = self.get_model()
-        pages = []
-        iter = model.get_iter_root()
-        while iter:
-            pages.append(model.get_value(iter, 2))
-            iter = model.iter_next(iter)
-        return pages
-
-    def setDeleteCurrentPageFunction(self, function):
-        self.delete_current_page_function = function
-
-    def deleteCurrentSelection(self):
-        selected_items = self.get_selected_items()
-        if len(selected_items):
-            selected_item_path = selected_items[0]
-            self.get_model().removeIter(selected_item_path)
-            if not self.get_model().isEmpty():
-                self.select_path(0)
-
-    def clear(self):
-        self.get_model().clear()
-
-    def _getIndexFromOffset(self, offset):
-        selected_items = self.get_selected_items()
-        if not len(selected_items):
-            return
-        selected_item_path = selected_items[0]
-        model = self.get_model()
-        iter = model.get_iter(selected_item_path)
-        index = model.get_path(iter)[0] + offset
-        number_of_items = model.iter_n_children(None)
-        if index < 0:
-            index = number_of_items + offset
-        elif index == number_of_items:
-            index = 0
-        return index
-
-    def movePage(self, offset):
-        selected_items = self.get_selected_items()
-        if not len(selected_items):
-            return
-        selected_item_path = selected_items[0]
-        model = self.get_model()
-        index = self._getIndexFromOffset(offset)
-        if index != selected_item_path[0] + offset:
-            return
-        model.swap(model.get_iter((index,)),
-                   model.get_iter(selected_item_path))
-        self.select_path((index,))
-
-    def selectPageFromOffset(self, offset):
-        selected_items = self.get_selected_items()
-        if not len(selected_items):
-            return
-        selected_item_path = selected_items[0]
-        model = self.get_model()
-        index = self._getIndexFromOffset(offset)
-        self.select_path((index,))
-
-    def getNumberOfPages(self):
-        return self.get_model().iter_n_children(None)
-
-class ImageReviewer(gtk.HPaned):
+class ImageReviewer(Gtk.HPaned):
 
     def __init__(self, main_window, page_data, ocr_engines):
         super(ImageReviewer, self).__init__()
@@ -434,16 +289,16 @@ class ImageReviewer_Controler:
 
     REVIEWER_CACHE_LENGTH = 5
 
-    def __init__(self, main_window, source_images_selector_widget,
+    def __init__(self, main_window, pages_icon_view,
                  ocr_engines, configuration_manager):
         self.main_window = main_window
         self.notebook = self.main_window.notebook
-        self.source_images_selector_widget = source_images_selector_widget
+        self.pages_icon_view = pages_icon_view
         self.ocr_engines = ocr_engines
         self.configuration_manager = configuration_manager
         self.statusbar = self.main_window.statusbar
         self._page_info_message_id = self.statusbar.get_context_id('page_info_message')
-        self.source_images_selector_widget.connect('selection-changed', self.selectImageReviewer)
+        self.pages_icon_view.connect('selection-changed', self.selectImageReviewer)
         self.__updateStatusBar()
 
     def __createdImageReviewer(self, page_data):
@@ -506,11 +361,11 @@ class ImageReviewer_Controler:
             return None
         if page_data is None:
             page_data = PageData(image_path)
-        iter = self.source_images_selector_widget.get_model().addImage(page_data)
+        iter = self.pages_icon_view.get_model().addImage(page_data)
         if select_image:
             path = \
-                self.source_images_selector_widget.get_model().get_path(iter)
-            self.source_images_selector_widget.select_path(path)
+                self.pages_icon_view.get_model().get_path(iter)
+            self.pages_icon_view.select_path(path)
         return page_data
 
     def __deskewImage(self, image_path, target_image_path = None):
@@ -544,7 +399,7 @@ class ImageReviewer_Controler:
         dialog.cancel()
 
     def selectImageReviewer(self, widget):
-        page_data = self.source_images_selector_widget.getSelectedPageData()
+        page_data = self.pages_icon_view.getSelectedPageData()
         if not page_data:
             return
         reviewer = self.__setImageReviewerFromPageData(page_data)
@@ -629,7 +484,7 @@ class ImageReviewer_Controler:
         dialog.run()
 
     def recognizeDocument(self):
-        pages = self.source_images_selector_widget.getAllPages()
+        pages = self.pages_icon_view.getAllPages()
         dialog = QueuedEventsProgressDialog(self.main_window.window)
         items = []
         i = 1
@@ -768,7 +623,7 @@ class ImageReviewer_Controler:
         image_reviewer.savePageData()
         if not project_name.endswith('.ocrf'):
             project_name += '.ocrf'
-        pages_data = self.source_images_selector_widget.getAllPages()
+        pages_data = self.pages_icon_view.getAllPages()
         project_saver = ProjectSaver(pages_data)
         project_saver.serialize(project_name)
 
@@ -796,7 +651,7 @@ class ImageReviewer_Controler:
         # Sync the current reviewer's page with its data
         self.__getCurrentReviewer().savePageData()
         export_dialog = PagesToExportDialog(title)
-        pages = self.source_images_selector_widget.getAllPages()
+        pages = self.pages_icon_view.getAllPages()
         # When there's only one document loaded or none,
         # we don't ask for the number of pages to export
         if len(pages) < 2:
@@ -845,7 +700,7 @@ class ImageReviewer_Controler:
         if response == gtk.RESPONSE_ACCEPT:
             size = page_size_dialog.getSize()
             if page_size_dialog.all_pages_radio.get_active():
-                for page in self.source_images_selector_widget.getAllPages():
+                for page in self.pages_icon_view.getAllPages():
                     page.setSize(size)
             else:
                 current_reviewer.page.setSize(size)
@@ -879,11 +734,11 @@ class ImageReviewer_Controler:
         # remove all pages from notebook
         for index in range(self.notebook.get_n_pages()):
             self.notebook.remove_page(0)
-        self.source_images_selector_widget.clear()
+        self.pages_icon_view.clear()
         self.__updateStatusBar()
 
     def getPixbufsSorted(self):
-        return self.source_images_selector_widget.source_images_selector.getPixbufsSorted()
+        return self.pages_icon_view.source_images_selector.getPixbufsSorted()
 
     def updateFromConfiguration(self):
         for index in range(self.notebook.get_n_pages()):


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