Make the gui friendlier to tiny displays/resolutions.
[ugit.git] / ugitlibs / qobserver.py
blobe9fa3747cb5dae69997928206ce5a4a98bd64848
1 #!/usr/bin/env python
2 from PyQt4.QtCore import QObject
3 from PyQt4.QtCore import SIGNAL
4 from PyQt4.QtGui import QSpinBox
5 from PyQt4.QtGui import QPixmap
6 from PyQt4.QtGui import QTextEdit
7 from PyQt4.QtGui import QLineEdit
8 from PyQt4.QtGui import QListWidget
9 from PyQt4.QtGui import QCheckBox
10 from PyQt4.QtGui import QFont
11 from PyQt4.QtGui import QFontComboBox
13 from observer import Observer
16 class QObserver(Observer, QObject):
18 def __init__(self, model, view):
19 Observer.__init__(self, model)
20 QObject.__init__(self)
22 self.view = view
24 self.__actions = {}
25 self.__callbacks = {}
26 self.__model_to_view = {}
27 self.__view_to_model = {}
29 def SLOT(self, *args):
30 '''Default slot to handle all Qt callbacks.
31 This method delegates to callbacks from add_signals.'''
33 widget = self.sender()
34 sender = str(widget.objectName())
36 if sender in self.__callbacks:
37 self.__callbacks[sender](*args)
39 elif sender in self.__view_to_model:
40 model = self.model
41 model_param = self.__view_to_model[sender]
42 if isinstance(widget, QTextEdit):
43 value = str(widget.toPlainText())
44 model.set_param(model_param, value,
45 notify=False)
46 elif isinstance(widget, QLineEdit):
47 value = str(widget.text())
48 model.set_param(model_param, value)
49 elif isinstance(widget, QCheckBox):
50 model.set_param(model_param, widget.isChecked())
51 elif isinstance(widget, QSpinBox):
52 model.set_param(model_param, widget.value())
53 elif isinstance(widget, QFontComboBox):
54 value = unicode(widget.currentFont().toString())
55 model.set_param(model_param, value)
56 else:
57 print("SLOT(): Unknown widget:", sender, widget)
59 def connect(self, obj, signal_str, *args):
60 '''Convenience function so that subclasses do not have
61 to import QtCore.SIGNAL.'''
62 signal = signal_str
63 if type(signal) is str:
64 signal = SIGNAL(signal)
65 return QObject.connect(obj, signal, *args)
67 def add_signals(self, signal_str, *objects):
68 '''Connects object's signal to the QObserver.'''
69 for obj in objects:
70 self.connect(obj, signal_str, self.SLOT)
72 def add_callbacks(self, **callbacks):
73 '''Registers callbacks that are called in response to GUI events.'''
74 for sender, callback in callbacks.iteritems():
75 self.__callbacks[sender] = callback
77 def model_to_view(self, model_param, *widget_names):
78 '''Binds model params to qt widgets(model->view)'''
79 self.__model_to_view[model_param] = widget_names
80 for widget_name in widget_names:
81 self.__view_to_model[widget_name] = model_param
83 def add_actions(self, model_param, callback):
84 '''Register view actions that are called in response to
85 view changes.(view->model)'''
86 self.__actions[model_param] = callback
88 def subject_changed(self, param, value):
89 '''Sends a model param to the view(model->view)'''
91 notify = self.model.get_notify()
92 self.model.set_notify(False)
93 if param in self.__model_to_view:
94 for widget_name in self.__model_to_view[param]:
95 widget = getattr(self.view, widget_name)
96 if isinstance(widget, QSpinBox):
97 widget.setValue(value)
98 elif isinstance(widget, QPixmap):
99 widget.load(value)
100 elif isinstance(widget, QTextEdit):
101 widget.setText(value)
102 elif isinstance(widget, QLineEdit):
103 widget.setText(value)
104 elif isinstance(widget, QListWidget):
105 widget.clear()
106 for i in value: widget.addItem(i)
107 elif isinstance(widget, QCheckBox):
108 widget.setChecked(value)
109 elif isinstance(widget, QFontComboBox):
110 font = widget.currentFont()
111 font.fromString(value)
112 else:
113 print('subject_changed(): '
114 + 'Unknown widget:',
115 widget_name, widget, value)
116 self.model.set_notify(notify)
118 if param not in self.__actions:
119 return
120 widgets = []
121 if param in self.__model_to_view:
122 for widget_name in self.__model_to_view[param]:
123 widget = getattr(self.view, widget_name)
124 widgets.append(widget)
125 # Call the model callback w/ the view's widgets as the args
126 self.__actions[param](*widgets)
128 def refresh_view(self):
129 params = list(self.__model_to_view.keys())
130 for param in self.__actions.keys():
131 if param not in params: params.append(param)
132 self.model.notify_observers(*params)