Added interactive diff gui
[ugit.git] / py / qobserver.py
blobafcc28745fc8425b7c23794270e039c0519add9e
1 #!/usr/bin/env python
2 from PyQt4.QtCore import QObject
3 from PyQt4.QtCore import SIGNAL
4 from PyQt4.QtGui import QSpinBox, QPixmap, QTextEdit, QLineEdit
6 from observer import Observer
8 class QObserver (Observer, QObject):
10 def __init__ (self, model, view):
11 Observer.__init__ (self)
12 QObject.__init__ (self)
14 self.model = model
15 self.view = view
16 model.add_observer (self)
18 self.__actions= {}
19 self.__callbacks = {}
20 self.__model_to_view = {}
21 self.__view_to_model = {}
23 def __del__ (self):
24 self.model.remove_observer (self)
25 self.model = None
26 self.view = None
28 del self.__actions
29 del self.__model_to_view
30 del self.__view_to_model
32 def connect (self, obj, signal_str, *args):
33 '''Convenience function so that subclasses do not have
34 to import QtCore.SIGNAL.'''
35 signal = signal_str
36 if type (signal) is str:
37 signal = SIGNAL (signal)
38 return QObject.connect ( obj, signal, *args)
40 def SLOT (self, *args):
41 '''Default slot to handle all Qt callbacks.
42 This method delegates to callbacks from add_signals.'''
44 widget = self.sender()
45 sender = str (widget.objectName())
47 if sender in self.__callbacks:
48 model = self.__callbacks[sender][0]
49 callback = self.__callbacks[sender][1]
50 callback (model, *args)
52 elif sender in self.__view_to_model:
53 model = self.__view_to_model[sender][0]
54 model_attr = self.__view_to_model[sender][1]
55 if isinstance (widget, QTextEdit):
56 value = str (widget.toPlainText())
57 model.set (model_attr, value)
58 elif isinstance (widget, QLineEdit):
59 value = str (widget.text())
60 model.set (model_attr, value)
61 else:
62 print ("SLOT(): Unknown widget:",
63 sender, widget)
65 def add_signals (self, signal_str, *objects):
66 '''Connects object's signal to the QObserver.'''
67 for obj in objects:
68 self.connect (obj, signal_str, self.SLOT)
70 def add_callbacks (self, model, callbacks):
71 '''Registers callbacks that are called in response to GUI events.'''
72 for sender, callback in callbacks.iteritems():
73 self.__callbacks[sender] = ( model, callback )
75 def model_to_view (self, model, model_attr, *widget_names):
76 '''Binds model attributes to qt widgets (model->view)'''
77 self.add_subject (model, model_attr)
78 self.__model_to_view[model_attr] = widget_names
79 for widget_name in widget_names:
80 self.__view_to_model[widget_name] = (model, model_attr)
82 def add_actions (self, model, model_attr, callback):
83 '''Register view actions that are called in response to
84 view changes. (view->model)'''
85 self.add_subject (model, model_attr)
86 self.__actions[model_attr] = callback
88 def subject_changed (self, model, attr, value):
89 '''Sends a model attribute to the view (model->view)'''
90 if attr in self.__model_to_view:
91 for widget_name in self.__model_to_view[attr]:
92 widget = getattr (self.view, widget_name)
93 if isinstance (widget, QSpinBox):
94 widget.setValue (value)
95 elif isinstance (widget, QPixmap):
96 widget.load (value)
97 elif isinstance (widget, QTextEdit):
98 widget.setText (value)
99 elif isinstance (widget, QLineEdit):
100 widget.setText (value)
101 else:
102 print ('subject_changed(): '
103 + 'Unknown widget:',
104 widget_name, widget)
106 if attr not in self.__actions: return
107 widgets = []
108 if attr in self.__model_to_view:
109 for widget_name in self.__model_to_view[attr]:
110 widget = getattr (self.__view, widget_name)
111 widgets.append (widget)
112 # Call the model callback w/ the view's widgets as the args
113 self.__actions[attr] (model, *widgets)