[ocrfeeder] widgetPresenter: Created queued events dialog



commit b0d8ff2d0b2463a7552c75817fbd5649f29c2265
Author: Joaquim Rocha <jrocha igalia com>
Date:   Mon Jul 5 10:44:37 2010 +0200

    widgetPresenter: Created queued events dialog
    
    This dialog manages an asynchronous worker
    and shows a progress bar while the events
    are being processed.
    
    For this, the asyncworker module was introduced,
    it comes from the SeriesFinale project.

 studio/widgetPresenter.py |   78 +++++++++++++++++++++++++++++++++++++++++
 util/asyncworker.py       |   85 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 163 insertions(+), 0 deletions(-)
---
diff --git a/studio/widgetPresenter.py b/studio/widgetPresenter.py
index 0994233..4bda83b 100644
--- a/studio/widgetPresenter.py
+++ b/studio/widgetPresenter.py
@@ -21,6 +21,7 @@
 from customWidgets import PlainFrame, TrippleStatusBar
 from dataHolder import DataBox, TEXT_TYPE, IMAGE_TYPE
 from util import lib, PAPER_SIZES
+from util.asyncworker import AsyncWorker
 from util.constants import *
 from util.graphics import convertPixbufToImage
 import Image
@@ -34,6 +35,7 @@ import signal
 import subprocess
 import sys
 import threading
+import Queue
 import time
 pygtk.require('2.0')
 _ = gettext.gettext
@@ -998,6 +1000,82 @@ class CommandProgressBarDialog(gtk.Dialog):
             return False
         return True
 
+class QueuedEventsProgressDialog(gtk.Dialog):
+
+    def __init__(self, parent, items_list = []):
+        super(QueuedEventsProgressDialog, self).__init__(parent = parent,
+                                                       flags = gtk.DIALOG_MODAL)
+        self.set_icon_from_file(WINDOW_ICON)
+        self.info_list = []
+        self.worker = AsyncWorker()
+        self.setItemsList(items_list)
+        self.label = gtk.Label()
+        self.__makeProgressBar()
+        self.vbox.show_all()
+        self.set_size_request(300, -1)
+        self.pulse_id = 0
+        self.item_number = self.worker.item_number
+        self.connect('delete-event', self._deleteEventCb)
+
+    def setItemsList(self, items_list):
+        for item in items_list:
+            info, async_item = item
+            self.info_list.append(info)
+            self.worker.queue.put(async_item)
+
+    def __makeProgressBar(self):
+        self.vbox.add(self.label)
+        self.progress_bar = gtk.ProgressBar()
+        progress_bar_container = gtk.Alignment(0, 0.5, 1, 0)
+        progress_bar_container.add(self.progress_bar)
+
+        hbox = gtk.HBox()
+        hbox.add(progress_bar_container)
+
+        cancel_button = gtk.Button(stock = gtk.STOCK_CANCEL)
+        cancel_button.connect('clicked', self._cancelButtonClickedCb)
+        hbox.pack_end(cancel_button, False, False, 0)
+
+        self.vbox.pack_start(hbox, False)
+
+    def run(self):
+        self.worker.start()
+        self.pulse_id = gobject.timeout_add(100, self._pulse)
+        self.show_all()
+
+    def cancel(self):
+        self.worker.stop()
+        self.message = _('Cancelled')
+        if self.pulse_id:
+            gobject.source_remove(self.pulse_id)
+        self.destroy()
+
+    def _pulse(self):
+        self.progress_bar.pulse()
+        if self.item_number != self.worker.item_number:
+            self.item_number = self.worker.item_number
+            if self.item_number != -1 and \
+               self.item_number < len(self.info_list):
+                title, message = self.info_list[self.item_number]
+                self.set_title(title)
+                self.message = message
+        return True
+
+    def _deleteEventCb(self, dialog, event):
+        self.worker.stop()
+        return True
+
+    def _cancelButtonClickedCb(self, button):
+        self.cancel()
+
+    def __getMessage(self):
+        return self.label.get_text()
+
+    def __setMessage(self, message):
+        self.label.set_text(message)
+
+    message = property(__getMessage, __setMessage)
+
 class PreferencesDialog(gtk.Dialog):
 
     def __init__(self, configuration_manager, ocr_engines):
diff --git a/util/asyncworker.py b/util/asyncworker.py
new file mode 100644
index 0000000..e1ad5a1
--- /dev/null
+++ b/util/asyncworker.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+
+###########################################################################
+#    OCRFeeder
+#    Copyright (C) 2010 Igalia, S.L.
+#
+#    Author: Joaquim Rocha <jrocha igalia com>
+#
+#    This file was adapted from the SeriesFinale project.
+#
+#    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/>.
+###########################################################################
+
+from threading import Thread
+import Queue
+import gobject
+from lib import debug
+
+class AsyncItem(object):
+
+    def __init__(self, target_method, target_method_args, finish_callback = None, finish_callback_args = ()):
+        self.target_method = target_method
+        self.target_method_args = target_method_args
+        self.finish_callback = finish_callback
+        self.finish_callback_args = finish_callback_args
+        self.canceled = False
+
+    def run(self):
+        if self.canceled:
+            return
+        results = error = None
+        try:
+            results = self.target_method(*self.target_method_args)
+        except Exception, exception:
+            debug(str(exception))
+            error = exception
+        if self.canceled or not self.finish_callback:
+            return
+        self.finish_callback_args += (results,)
+        self.finish_callback_args += (error,)
+        gobject.idle_add(self.finish_callback, *self.finish_callback_args)
+
+    def cancel(self):
+        self.canceled = True
+
+class AsyncWorker(Thread):
+
+    def __init__(self):
+        Thread.__init__(self)
+        self.queue = Queue.Queue(0)
+        self.stopped = False
+        self.async_item = None
+        self.item_number = -1
+
+    def run(self):
+        while not self.stopped:
+            if self.queue.empty():
+                self.stop()
+                break
+            try:
+                self.async_item = self.queue.get()
+                self.item_number += 1
+                self.async_item.run()
+                self.queue.task_done()
+                self.async_item = None
+            except Exception, exception:
+                debug(str(exception))
+                self.stop()
+
+    def stop(self):
+        self.stopped = True
+        if self.async_item:
+            self.async_item.cancel()
+



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