d3d6a816793b2cb24ee02a8785151e0f6b8d224b
[meabook] / ui / hildon_ui.py
1 """
2 Hildon UI for Meabook
3 """
4
5 import gtk
6 import hildon
7 import gobject
8 import gettext
9 from meabook.ui.ui import MeabookUI
10
11 _ = gettext.gettext
12
13
14 def create_button(title, value):
15     """Create HildonButton."""
16
17     button = hildon.Button(gtk.HILDON_SIZE_AUTO | \
18         gtk.HILDON_SIZE_FINGER_HEIGHT, \
19         hildon.BUTTON_ARRANGEMENT_VERTICAL, title, value)
20     button.set_style(hildon.BUTTON_STYLE_PICKER)
21     button.set_alignment(0, 0, 0, 0)
22     return button
23
24
25 class HildonMeabook(MeabookUI):
26     def __init__(self, controller):
27         MeabookUI.__init__(self, controller)
28         self.internal_names = []
29         self.handler = None
30         self.level = 1
31         self.window = hildon.StackableWindow()
32         self.window.set_title(_('Meabook'))
33         self.window.connect('destroy', self.exit)
34
35         # create menu buttons
36         menu = hildon.AppMenu()
37         settings_button = hildon.Button(gtk.HILDON_SIZE_AUTO, \
38             hildon.BUTTON_ARRANGEMENT_HORIZONTAL, _('Settings'))
39         about_button = hildon.Button(gtk.HILDON_SIZE_AUTO, \
40             hildon.BUTTON_ARRANGEMENT_HORIZONTAL, _('About'))
41
42         # create filter widgets
43         self.level1_filter = gtk.RadioButton(None, _('level1'))
44         self.level2_filter = gtk.RadioButton(self.level1_filter, _('level2'))
45         self.level3_filter = gtk.RadioButton(self.level2_filter, _('level3'))
46         for filter_widget in [self.level1_filter, self.level2_filter, \
47             self.level3_filter]:
48             filter_widget.set_mode(False)
49
50         # create items list
51         self.selector = hildon.TouchSelector(text=True)
52
53         # connect signals
54         settings_button.connect('clicked', self.show_settings_dialog_cb)
55         about_button.connect('clicked', self.show_about_dialog_cb)
56         self.handler = self.selector.connect('changed', self.select_item_cb)
57         self.level1_filter.connect('toggled', self.apply_filter_cb, \
58             self.controller.get_level1_items)
59         self.level2_filter.connect('toggled', self.apply_filter_cb, \
60             self.controller.get_level2_items)
61         self.level3_filter.connect('toggled', self.apply_filter_cb, \
62             self.controller.get_level3_items)
63
64         # packing widgets
65         self.window.add(self.selector)
66         menu.add_filter(self.level1_filter)
67         menu.add_filter(self.level2_filter)
68         menu.add_filter(self.level3_filter)
69         menu.append(settings_button)
70         menu.append(about_button)
71         menu.show_all()
72         self.window.set_app_menu(menu)
73         self.window.show_all()
74
75     def _set_selector_content(self, selector, handler, items):
76         """Updates selector content."""
77
78         # temporary block handler
79         selector.handler_block(handler)
80
81         self.internal_names = []
82         selector.get_model(0).clear()
83         for item in items:
84             selector.append_text(item[0])
85             self.internal_names.append(item[1])
86         selector.unselect_all(0)
87
88         # reconnect callback
89         selector.handler_unblock(handler)
90
91     def _show_items_dialog(self, title, items):
92         """Creates dialog with items."""
93
94         selector = hildon.TouchSelector(text=True)
95         window = hildon.StackableWindow()
96         window.set_title(title)
97         window.connect('destroy', self._decrease_level)
98         window.add(selector)
99         handler = selector.connect('changed', self.select_item_cb)
100         self._set_selector_content(selector, handler, items)
101         window.show_all()
102
103     def _decrease_level(self, widget):
104         self.level -= 1
105
106     # Implementation of Base UI interface
107     def start(self):
108         gtk.main()
109
110     def exit(self, event):
111         gtk.main_quit()
112         self.controller.stop()
113
114     def get_current_level(self):
115         return self.level
116
117     def show_items(self, items, level):
118         self.level = level
119         if level == 1:  # level1_button is not in gorup, process separately
120             self.level1_filter.set_active(True)
121             self.apply_filter_cb(self.level1_filter, \
122                 self.controller.get_level1_items, items)
123         elif level == 2:
124             self.level2_filter.set_active(True)
125         else:
126             self.level3_filter.set_active(True)
127
128     def show_about_dialog(self):
129         dialog = hildon.Dialog()
130         dialog.set_title(_('About'))
131         label = gtk.Label('\nMeabook v0.1\n')
132         dialog.vbox.add(label)
133         dialog.vbox.show_all()
134         dialog.run()
135         dialog.destroy()
136
137     def show_fields_to_show_dialog(self):
138         ConfigurationDialog(self.controller, page=1)
139
140     def show_fileds_order_dialog(self):
141         ConfigurationDialog(self.controller, page=2)
142
143
144     # Hildon UI callbacks
145     def show_about_dialog_cb(self, widget):
146         """Shows About Dialog."""
147
148         self.show_about_dialog()
149
150     def show_settings_dialog_cb(self, widget):
151         """Shows Config dialog."""
152
153         ConfigurationDialog(self.controller)
154
155     def apply_filter_cb(self, widget, func, items=None):
156         """Updates toplevel selector with different level items."""
157
158         if not widget.get_active():
159             return
160
161         if widget == self.level1_filter: self.level = 1
162         elif widget == self.level2_filter: self.level = 2
163         else: self.level = 3
164
165         # update list content
166         self._set_selector_content(self.selector, self.handler, items or func())
167
168         self.window.set_title(' - '.join([_('Meabook'), widget.get_label()]))
169
170     def select_item_cb(self, widget, column):
171         """Emits when changes selector content."""
172
173         name, internal_name = widget.get_current_text(), \
174             widget.get_active(0)
175         if self.level == 1:
176             items = self.controller.get_level2_items((name, internal_name))
177             self._show_items_dialog(name, items)
178             self.level = 2
179         elif self.level == 2:
180             items = self.controller.get_level3_items((name, internal_name))
181             self._show_items_dialog(name, items)
182             self.level = 3
183         else:
184             print 'show item details'
185
186     def show_item_dialog(self, widget, column):
187         """Shows detailed item information."""
188
189         selected_item = widget.get_current_text()
190         entry = self.database.get_entry(selected_item)
191         window = hildon.StackableWindow()
192         window.set_title(selected_item)
193         pannable_area = hildon.PannableArea()
194         vbox = gtk.VBox()
195
196         for key, value in entry.items():
197             button = create_button(_(key) , value)
198             vbox.pack_start(button)
199
200         pannable_area.add_with_viewport(vbox)
201         window.add(pannable_area)
202         window.show_all()
203
204
205
206
207 class ConfigurationDialog:
208     """Configuration dialog"""
209
210     def __init__(self, controller, page=1):
211         self.controller = controller
212
213         self.window = hildon.StackableWindow()
214         self.window.set_title(_('Settings'))
215         self.window.connect('destroy', self.close_dialog_cb)
216
217         # create menu
218         menu = hildon.AppMenu()
219         self.button_order = gtk.RadioButton(None, _('Order'))
220         self.button_fields = gtk.RadioButton(self.button_order, _('Fields'))
221         self.button_order.set_mode(False)
222         self.button_fields.set_mode(False)
223         menu.add_filter(self.button_fields)
224         menu.add_filter(self.button_order)
225         menu.show_all()
226
227         # create other widgets
228         self.window.set_app_menu(menu)
229         self.selector = hildon.TouchSelector(text=True)
230         self.pannable_area = hildon.PannableArea()
231         vbox = gtk.VBox()
232         vbox.pack_start(self.selector)
233         vbox.pack_start(self.pannable_area)
234         self.window.add(vbox)
235
236         self.window.show_all()
237
238         # switches to necessary page
239         if page == 1:
240             self.button_fields.set_active(True)
241             self.show_fields_settings_cb(None)
242         else:
243             self.button_order.set_active(True)
244             self.show_order_settings_cb(None)
245
246         # connect signals
247         self.button_order.connect('clicked', self.show_order_settings_cb)
248         self.button_fields.connect('clicked', self.show_fields_settings_cb)
249
250     def show_fields_settings_cb(self, widget):
251         """Shows dialog for selecting fields to show."""
252
253         self.pannable_area.hide()
254
255         fields = self.controller.get_fields()
256
257         # fill items list
258         self.selector.get_model(0).clear()
259         for field in fields:
260             self.selector.append_text(_(field))
261
262         self.selector.set_column_selection_mode( \
263                 hildon.TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)
264         self.selector.unselect_all(0)
265
266         # mark necessary fields
267         fields_to_select = self.controller.config.get_fields()
268         model = self.selector.get_model(0)
269         for index, field in enumerate(fields):
270             if field in fields_to_select:
271                 self.selector.select_iter(0, model.get_iter(index), False)
272
273         self.selector.show_all()
274
275     def show_order_settings_cb(self, widget):
276         """Shows dialog for setting fields order."""
277
278
279         def show_fields_chooser(widget):
280             """Shows dialog to select field from fields list."""
281
282             dialog = hildon.PickerDialog(self.window)
283             dialog.set_title(_('Field selection'))
284             selector = hildon.TouchSelector(text=True)
285             dialog.set_selector(selector)
286             selector.set_column_selection_mode( \
287                 hildon.TOUCH_SELECTOR_SELECTION_MODE_SINGLE)
288
289             # fill fields list
290             for field in self.controller.get_fields():
291                 selector.append_text(field)
292
293             dialog.run()
294             widget.set_value(selector.get_current_text())
295             dialog.destroy()
296
297         self.selector.hide()
298
299         vbox = gtk.VBox()
300         for index, field in enumerate(self.controller.config.get_order()):
301             button = create_button(' '.join([_('Position'), str(index)]), \
302                 _(field))
303             button.connect('clicked', show_fields_chooser)
304             vbox.pack_start(button)
305
306         self.pannable_area.add_with_viewport(vbox)
307         self.pannable_area.show_all()
308
309     def close_dialog_cb(self, event):
310         """Save selected options."""
311
312         model = self.selector.get_model(0)
313         selected_items = [model[index][0] for index in [item[0] for item in \
314             self.selector.get_selected_rows(0)]]
315         self.controller.config.set_fields(selected_items)
316
317         try:
318             self.controller.config.set_order([button.get_value() for button in \
319                 self.pannable_area.get_child().get_children()[0].get_children()])
320         except AttributeError:
321             pass