ef89400a8e37bbe69a68a5077fec16f20dd7903a
[meabook] / ui / hildon_ui.py
1 """
2 Hildon UI for Meabook
3 """
4
5 import gtk
6 import hildon
7 import gettext
8 from meabook.config import Config
9 from meabook.database.SQLite import SQLite
10
11 _ = gettext.gettext
12
13
14
15 def create_button(title, value):
16     """Create HildonButton."""
17
18     button = hildon.Button(gtk.HILDON_SIZE_AUTO | \
19         gtk.HILDON_SIZE_FINGER_HEIGHT, \
20         hildon.BUTTON_ARRANGEMENT_VERTICAL, title, value)
21     button.set_style(hildon.BUTTON_STYLE_PICKER)
22     button.set_alignment(0, 0, 0, 0)
23     return button
24
25
26 class HildonMeabook():
27     def __init__(self, basedir):
28         self.database = SQLite(basedir)
29         self.config = Config(basedir, self.database)
30         self.window = hildon.StackableWindow()
31         self.window.set_title(_('Meabook'))
32         self.window.connect('destroy', self.exit)
33
34         # create menu buttons
35         menu = hildon.AppMenu()
36         settings_button = hildon.Button(gtk.HILDON_SIZE_AUTO, \
37             hildon.BUTTON_ARRANGEMENT_HORIZONTAL, _('Settings'))
38         about_button = hildon.Button(gtk.HILDON_SIZE_AUTO, \
39             hildon.BUTTON_ARRANGEMENT_HORIZONTAL, _('About'))
40
41         # create filter widgets
42         self.level1_filter = gtk.RadioButton(None, _('Filiation'))
43         self.level2_filter = gtk.RadioButton(self.level1_filter, _('Depart'))
44         self.level3_filter = gtk.RadioButton(self.level1_filter, _('People'))
45         for filter_widget in [self.level1_filter, self.level2_filter, \
46             self.level3_filter]:
47             filter_widget.set_mode(False)
48
49         # create items list
50         self.selector = hildon.TouchSelector(text=True)
51
52         # connect signals
53         self.callback_id = self.selector.connect('changed', \
54             self.show_middlelevel_dialog)
55         settings_button.connect('clicked', self.show_settings_dialog)
56         about_button.connect('clicked', self.show_about_dialog)
57         self.level1_filter.connect('clicked', self.apply_filter, \
58             self.database.get_toplevel_entries)
59         self.level2_filter.connect('clicked', self.apply_filter, \
60             self.database.get_middlelevel_entries)
61         self.level3_filter.connect('clicked', self.apply_filter, \
62             self.database.get_lowlevel_entries)
63
64         # fill items list
65         for filter_widget in [self.level1_filter, self.level2_filter, \
66             self.level3_filter]:
67             if filter_widget.get_active():
68                 self.apply_filter(filter_widget, self.database.get_toplevel_entries)
69                 break
70
71         # packing widgets
72         self.window.add(self.selector)
73         menu.add_filter(self.level1_filter)
74         menu.add_filter(self.level2_filter)
75         menu.add_filter(self.level3_filter)
76         menu.append(settings_button)
77         menu.append(about_button)
78         menu.show_all()
79         self.window.set_app_menu(menu)
80         self.window.show_all()
81
82     def start(self):
83         """Start the program."""
84
85         gtk.main()
86
87     def exit(self, event):
88         """Exit the program."""
89
90         self.database.close()
91         gtk.main_quit()
92
93     def show_settings_dialog(self, widget):
94         """Shows Config dialog."""
95
96         dialog = ConfigurationDialog(self.database, self.config)
97         dialog.run()
98
99     def show_about_dialog(self, widget):
100         """Shows About dialog."""
101
102         dialog = hildon.Dialog()
103         dialog.set_title(_('About'))
104         label = gtk.Label('\nMeabook v0.1\n')
105         dialog.vbox.add(label)
106         dialog.vbox.show_all()
107         dialog.run()
108         dialog.destroy()
109
110     def apply_filter(self, widget, db_function):
111         """Updates toplevel selector with different level items."""
112
113         # blocks 'change' event for selector
114         self.selector.handler_block(self.callback_id)
115
116         # update list content
117         self.selector.get_model(0).clear()
118         for item in db_function():
119             self.selector.append_text(item)
120         self.selector.unselect_all(0)
121
122         self.window.set_title(' - '.join([_('Meabook'), widget.get_label()]))
123         # reconnect signal. depends on current filter
124         if widget == self.level1_filter:
125             self.callback_id = self.selector.connect('changed', \
126                 self.show_middlelevel_dialog)
127         elif widget == self.level2_filter:
128             self.callback_id = self.selector.connect('changed', \
129                 self.show_lowlevel_dialog)
130         else:
131             self.callback_id = self.selector.connect('changed', \
132                 self.show_item_dialog)
133
134     def _create_items_dialog(self, title):
135         """Creates dialog for showing items."""
136
137         selector = hildon.TouchSelector(text=True)
138         window = hildon.StackableWindow()
139         window.set_title(title)
140         window.add(selector)
141         return window, selector
142
143     def show_middlelevel_dialog(self, widget, column):
144         """Shows subitems of selected level1-item."""
145
146         selected_item = widget.get_current_text()
147         window, selector = self._create_items_dialog(selected_item)
148         selector.connect('changed', self.show_lowlevel_dialog)
149         for item in self.database.get_middlelevel_entries(selected_item):
150             selector.append_text(item)
151         window.show_all()
152
153     def show_lowlevel_dialog(self, widget, column):
154         """Shows lowlevel items."""
155
156         selected_item = widget.get_current_text()
157         window, selector = self._create_items_dialog(selected_item)
158         selector.connect('changed', self.show_item_dialog)
159         for item in self.database.get_lowlevel_entries():
160             selector.append_text(item)
161         window.show_all()
162
163     def show_item_dialog(self, widget, column):
164         """Shows detailed item information."""
165
166         selected_item = widget.get_current_text()
167         entry = self.database.get_entry(selected_item)
168         window = hildon.StackableWindow()
169         window.set_title(selected_item)
170         pannable_area = hildon.PannableArea()
171         vbox = gtk.VBox()
172
173         for key, value in entry.items():
174             button = create_button(_(key) , value)
175             vbox.pack_start(button)
176
177         pannable_area.add_with_viewport(vbox)
178         window.add(pannable_area)
179         window.show_all()
180
181
182
183
184 class ConfigurationDialog:
185     """Configuration dialog"""
186
187     def __init__(self, database, config):
188         self.config = config
189         self.database = database
190         self.window = hildon.StackableWindow()
191         self.window.set_title(_('Configuration'))
192
193         # create menu
194         menu = hildon.AppMenu()
195         self.button_order = gtk.RadioButton(None, _('Order'))
196         self.button_order.set_mode(False)
197         self.button_order.connect('clicked', self.show_order_settings, \
198             self.database.get_fields())
199         self.button_items = gtk.RadioButton(self.button_order, _('Items'))
200         self.button_items.set_mode(False)
201         self.button_items.connect('clicked', self.show_items_settings, \
202             self.database.get_fields())
203         menu.add_filter(self.button_items)
204         menu.add_filter(self.button_order)
205         menu.show_all()
206
207         # create other widgets
208         self.window.set_app_menu(menu)
209         self.selector = hildon.TouchSelector(text=True)
210         self.callback_id = self.selector.connect('changed', \
211             self.save_selected_fields)
212         self.pannable_area = hildon.PannableArea()
213         vbox = gtk.VBox()
214         vbox.pack_start(self.selector)
215         vbox.pack_start(self.pannable_area)
216         self.window.add(vbox)
217
218     def show_items_settings(self, widget, items):
219         """Shows dialog for selecting necessary items."""
220
221         self.pannable_area.hide()
222         # blocks 'change' event for selector
223         self.selector.handler_block(self.callback_id)
224
225         # fill items list
226         for item in items:
227             self.selector.append_text(_(item))
228
229         self.selector.set_column_selection_mode( \
230                 hildon.TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE)
231         self.selector.unselect_all(0)
232
233         # mark necessary items
234         items_to_select = self.config.get_fields()
235         model = self.selector.get_model(0)
236         for index, item in enumerate(items):
237             if item in items_to_select:
238                 self.selector.select_iter(0, model.get_iter(index), False)
239
240         self.selector.show()
241
242         # reconnect signal
243         self.selector.connect('changed', self.save_selected_fields)
244
245     def show_order_settings(self, widget, items):
246         """Shows dialog for selecting items order."""
247
248         self.selector.hide()
249         vbox = gtk.VBox()
250         for item in items:
251             button = create_button(item, '')
252             button.set_style(hildon.BUTTON_STYLE_NORMAL)
253             button.set_alignment(0, 0.5, 0, 0)
254             vbox.pack_start(button)
255         self.pannable_area.add_with_viewport(vbox)
256         self.pannable_area.show_all()
257
258     def run(self):
259         """Runs dialog."""
260
261         # activate first tab
262         # FIXME: read from config
263         self.window.show_all()
264         self.button_items.set_active(True)
265
266     def save_selected_fields(self, widget, column):
267         """Save selected choice."""
268
269         model = self.selector.get_model(0)
270         selected_items = [model[index][0] for index in [item[0] for item in \
271             self.selector.get_selected_rows(0)]]
272         self.config.set_fields(selected_items)