Simplify site of pyside bug to better determine issue
[gc-dialer] / src / util / qore_utils.py
1 import logging
2
3 import qt_compat
4 QtCore = qt_compat.QtCore
5
6 import misc
7
8
9 _moduleLogger = logging.getLogger(__name__)
10
11
12 class QThread44(QtCore.QThread):
13         """
14         This is to imitate QThread in Qt 4.4+ for when running on older version
15         See http://labs.trolltech.com/blogs/2010/06/17/youre-doing-it-wrong
16         (On Lucid I have Qt 4.7 and this is still an issue)
17         """
18
19         def __init__(self, parent = None):
20                 QtCore.QThread.__init__(self, parent)
21
22         def run(self):
23                 self.exec_()
24
25
26 class _WorkerThread(QtCore.QObject):
27
28         _taskComplete  = qt_compat.Signal(object)
29
30         def __init__(self, futureThread):
31                 QtCore.QObject.__init__(self)
32                 self._futureThread = futureThread
33                 self._futureThread._addTask.connect(self._on_task_added)
34                 self._taskComplete.connect(self._futureThread._on_task_complete)
35
36         @qt_compat.Slot(object)
37         @misc.log_exception(_moduleLogger)
38         def _on_task_added(self, task):
39                 if not self._futureThread._isRunning:
40                         _moduleLogger.error("Dropping task")
41
42                 func, args, kwds, on_success, on_error = task
43
44                 try:
45                         result = func(*args, **kwds)
46                         isError = False
47                 except Exception, e:
48                         _moduleLogger.error("Error, passing it back to the main thread")
49                         result = e
50                         isError = True
51
52                 taskResult = on_success, on_error, isError, result
53                 self._taskComplete.emit(taskResult)
54
55
56 class FutureThread(QtCore.QObject):
57
58         _addTask = qt_compat.Signal(object)
59
60         def __init__(self):
61                 QtCore.QObject.__init__(self)
62                 self._thread = QThread44()
63                 self._isRunning = False
64                 self._worker = _WorkerThread(self)
65                 self._worker.moveToThread(self._thread)
66
67         def start(self):
68                 self._thread.start()
69                 self._isRunning = True
70
71         def stop(self):
72                 self._isRunning = False
73                 self._thread.quit()
74
75         def add_task(self, func, args, kwds, on_success, on_error):
76                 assert self._isRunning, "Task queue not started"
77                 task = func, args, kwds, on_success, on_error
78                 self._addTask.emit(task)
79
80         @qt_compat.Slot(object)
81         @misc.log_exception(_moduleLogger)
82         def _on_task_complete(self, taskResult):
83                 on_success, on_error, isError, result = taskResult
84                 if not self._isRunning:
85                         if isError:
86                                 _moduleLogger.error("Masking: %s" % (result, ))
87                         isError = True
88                         result = StopIteration("Cancelling all callbacks")
89                 callback = on_success if not isError else on_error
90                 try:
91                         callback(result)
92                 except Exception:
93                         _moduleLogger.exception("Callback errored")