Added commit message menu, other fixes
[ugit.git] / ugitlibs / qobserver.py
blobf19805e896d5fa6e0661b5ecd08bb10db5014d7e
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)