Removing dead code
[multilist] / src / multilist_gtk.py
1 #!/usr/bin/env python
2 # -*- coding: utf-8 -*-
3
4 """
5 This file is part of Multilist.
6
7 Multilist is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 Multilist is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Multilist.  If not, see <http://www.gnu.org/licenses/>.
19
20 Copyright (C) 2008 Christoph Würstle
21 """
22
23 import os
24 import logging
25
26 import gtk
27
28 try:
29         import hildon
30         isHildon = True
31 except:
32         isHildon = False
33
34 try:
35         import osso
36 except ImportError:
37         osso = None
38
39 import constants
40 import hildonize
41 import gtk_toolbox
42
43 import libspeichern
44 import search
45 import sqldialog
46 import settings
47 import libselection
48 import libview
49 import libliststorehandler
50 import libsync
51 import libbottombar
52
53 try:
54         _
55 except NameError:
56         _ = lambda x: x
57
58
59 _moduleLogger = logging.getLogger(__name__)
60 PROFILE_STARTUP = False
61
62
63 class Multilist(hildonize.get_app_class()):
64
65         _user_data = os.path.join(os.path.expanduser("~"), ".%s" % constants.__app_name__)
66         _user_settings = "%s/settings.ini" % _user_data
67
68         def __init__(self):
69                 super(Multilist, self).__init__()
70                 self._clipboard = gtk.clipboard_get()
71
72                 logging.info('Starting Multilist')
73
74                 try:
75                         os.makedirs(self._user_data)
76                 except OSError, e:
77                         if e.errno != 17:
78                                 raise
79
80                 self.db = libspeichern.Speichern()
81                 self.window_in_fullscreen = False #The window isn't in full screen mode initially.
82
83                 #Haupt vbox für alle Elemente
84                 self.window = gtk.Window()
85                 self.vbox = gtk.VBox(homogeneous = False, spacing = 0)
86
87                 self.selection = libselection.Selection(self.db, isHildon)
88                 self._search = search.Search()
89                 self.liststorehandler = libliststorehandler.Liststorehandler(self.db, self.selection)
90                 self.view = libview.View(self.db, self.liststorehandler, self.window)
91                 self.bottombar = libbottombar.Bottombar(self.db, self.view, isHildon)
92
93                 #Menue
94                 if hildonize.GTK_MENU_USED:
95                         fileMenu = gtk.Menu()
96
97                         menu_items = gtk.MenuItem(_("Choose database file"))
98                         menu_items.connect("activate", self.select_db_dialog, None)
99                         fileMenu.append(menu_items)
100
101                         menu_items = gtk.MenuItem(_("SQL history"))
102                         menu_items.connect("activate", self.view_sql_history, None)
103                         fileMenu.append(menu_items)
104
105                         menu_items = gtk.MenuItem(_("SQL optimize"))
106                         menu_items.connect("activate", self.optimizeSQL, None)
107                         fileMenu.append(menu_items)
108
109                         menu_items = gtk.MenuItem(_("Sync items"))
110                         menu_items.connect("activate", self.sync_notes, None)
111                         fileMenu.append(menu_items)
112
113                         menu_items = gtk.MenuItem(_("Quit"))
114                         menu_items.connect("activate", self._on_destroy, None)
115                         fileMenu.append(menu_items)
116
117                         fileMenuItem = gtk.MenuItem(_("File"))
118                         fileMenuItem.show()
119                         fileMenuItem.set_submenu(fileMenu)
120
121                         categorymenu = gtk.Menu()
122
123                         menu_items = gtk.MenuItem(_("Search"))
124                         menu_items.connect("activate", self._on_toggle_search)
125                         categorymenu.append(menu_items)
126
127                         menu_items = gtk.MenuItem(_("Checkout All"))
128                         menu_items.connect("activate", self._on_checkout_all)
129                         categorymenu.append(menu_items)
130
131                         menu_items = gtk.MenuItem(_("Rename Category"))
132                         menu_items.connect("activate", self.bottombar.rename_category, None)
133                         categorymenu.append(menu_items)
134
135                         category_menu = gtk.MenuItem(_("Category"))
136                         category_menu.show()
137                         category_menu.set_submenu(categorymenu)
138
139                         viewMenu = gtk.Menu()
140
141                         menu_items = gtk.MenuItem(_("Show Active"))
142                         menu_items.connect("activate", self._on_toggle_filter, None)
143                         viewMenu.append(menu_items)
144
145                         menu_items = gtk.MenuItem(_("Settings"))
146                         menu_items.connect("activate", self._on_settings, None)
147                         viewMenu.append(menu_items)
148
149                         viewMenuItem = gtk.MenuItem(_("View"))
150                         viewMenuItem.show()
151                         viewMenuItem.set_submenu(viewMenu)
152
153                         toolsMenu = gtk.Menu()
154
155                         menu_items = gtk.MenuItem(_("Rename List"))
156                         menu_items.connect("activate", self.bottombar.rename_list, None)
157                         toolsMenu.append(menu_items)
158
159                         toolsMenuItem = gtk.MenuItem(_("Tools"))
160                         toolsMenuItem.show()
161                         toolsMenuItem.set_submenu(toolsMenu)
162
163                         helpMenu = gtk.Menu()
164                         menu_items = gtk.MenuItem(_("About"))
165                         helpMenu.append(menu_items)
166                         menu_items.connect("activate", self._on_about, None)
167
168                         helpMenuItem = gtk.MenuItem(_("Help"))
169                         helpMenuItem.show()
170                         helpMenuItem.set_submenu(helpMenu)
171
172                         menu_bar = gtk.MenuBar()
173                         menu_bar.show()
174                         menu_bar.append (fileMenuItem)
175                         menu_bar.append (toolsMenuItem)
176                         menu_bar.append (category_menu)
177                         menu_bar.append (viewMenuItem)
178                         # unten -> damit als letztes menu_bar.append (helpMenuItem)
179                         #Als letztes menü
180                         menu_bar.append (helpMenuItem)
181
182                         self.vbox.pack_start(menu_bar, False, False, 0)
183                 else:
184                         menuBar = gtk.MenuBar()
185                         menuBar.show()
186                         self.vbox.pack_start(menuBar, False, False, 0)
187
188                 #add to vbox below (to get it on top)
189                 self.vbox.pack_end(self._search, expand = False, fill = True)
190                 self.vbox.pack_end(self.bottombar, expand = False, fill = True, padding = 0)
191                 self.vbox.pack_end(self.view, expand = True, fill = True, padding = 0)
192                 self.vbox.pack_end(self.selection, expand = False, fill = True, padding = 0)
193
194                 #Get the Main Window, and connect the "destroy" event
195                 self.window.add(self.vbox)
196
197                 self.window = hildonize.hildonize_window(self, self.window)
198                 hildonize.set_application_title(self.window, "%s" % constants.__pretty_app_name__)
199                 menu_bar = hildonize.hildonize_menu(
200                         self.window,
201                         menu_bar,
202                 )
203                 if hildonize.IS_FREMANTLE_SUPPORTED:
204                         button = hildonize.hildon.GtkRadioButton(gtk.HILDON_SIZE_AUTO, None)
205                         button.set_label("All")
206                         menuBar.add_filter(button)
207                         button.connect("clicked", self._on_click_menu_filter, self.liststorehandler.SHOW_ALL)
208                         button.set_mode(False)
209                         filterGroup = button
210
211                         button = hildonize.hildon.GtkRadioButton(gtk.HILDON_SIZE_AUTO, filterGroup)
212                         button.set_label("Active")
213                         menuBar.add_filter(button)
214                         button.connect("clicked", self._on_click_menu_filter, self.liststorehandler.SHOW_ACTIVE)
215                         button.set_mode(False)
216
217                         renameCategoryButton = gtk.Button(_("Rename Category"))
218                         renameCategoryButton.connect("clicked", self.bottombar.rename_category)
219                         menuBar.append(renameCategoryButton)
220
221                         renameListButton= gtk.Button(_("Rename List"))
222                         renameListButton.connect("clicked", self.bottombar.rename_list)
223                         menuBar.append(renameListButton)
224
225                         searchButton= gtk.Button(_("Search Category"))
226                         searchButton.connect("clicked", self._on_toggle_search)
227                         menuBar.append(searchButton)
228
229                         searchButton= gtk.Button(_("Settings"))
230                         searchButton.connect("clicked", self._on_settings)
231                         menuBar.append(searchButton)
232
233                         menuBar.show_all()
234
235                 if not hildonize.IS_HILDON_SUPPORTED:
236                         _moduleLogger.info("No hildonization support")
237
238                 if osso is not None:
239                         self.osso_c = osso.Context(
240                                 constants.__app_name__,
241                                 constants.__version__,
242                                 False
243                         )
244                 else:
245                         _moduleLogger.info("No osso support")
246                         self._osso_c = None
247
248                 self.window.connect("delete_event", self._on_delete_event)
249                 self.window.connect("destroy", self._on_destroy)
250                 self.window.connect("key-press-event", self.on_key_press)
251                 self.window.connect("window-state-event", self._on_window_state_change)
252                 self._search.connect("search_changed", self._on_search)
253
254                 self.window.show_all()
255                 self._search.hide()
256                 self.prepare_sync_dialog()
257                 self.ladeAlles()
258
259         @gtk_toolbox.log_exception(_moduleLogger)
260         def _on_checkout_all(self, widget):
261                 self.liststorehandler.checkout_rows()
262
263         @gtk_toolbox.log_exception(_moduleLogger)
264         def _on_search(self, widget):
265                 self.liststorehandler.get_liststore(self._search.get_search_pattern())
266
267         @gtk_toolbox.log_exception(_moduleLogger)
268         def _on_click_menu_filter(self, button, val):
269                 self.liststorehandler.set_filter(val)
270
271         def _toggle_search(self):
272                 if self._search.get_property("visible"):
273                         self._search.hide()
274                 else:
275                         self._search.show()
276
277         @gtk_toolbox.log_exception(_moduleLogger)
278         def _on_toggle_search(self, *args):
279                 self._toggle_search()
280
281         @gtk_toolbox.log_exception(_moduleLogger)
282         def _on_toggle_filter(self, *args):
283                 if self.liststorehandler.get_filter() == self.liststorehandler.SHOW_ALL:
284                         self.liststorehandler.set_filter(self.liststorehandler.SHOW_ACTIVE)
285                 elif self.liststorehandler.get_filter() == self.liststorehandler.SHOW_ACTIVE:
286                         self.liststorehandler.set_filter(self.liststorehandler.SHOW_ALL)
287                 else:
288                         assert False, "Unknown"
289
290         @gtk_toolbox.log_exception(_moduleLogger)
291         def on_key_press(self, widget, event, *args):
292                 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
293                 isCtrl = bool(event.get_state() & gtk.gdk.CONTROL_MASK)
294                 if (
295                         event.keyval == gtk.keysyms.F6 or
296                         event.keyval in RETURN_TYPES and isCtrl
297                 ):
298                         # The "Full screen" hardware key has been pressed 
299                         if self.window_in_fullscreen:
300                                 self.window.unfullscreen ()
301                         else:
302                                 self.window.fullscreen ()
303                         return True
304                 elif event.keyval == gtk.keysyms.f and isCtrl:
305                         self._toggle_search()
306                         return True
307                 elif (
308                         event.keyval in (gtk.keysyms.w, gtk.keysyms.q) and
309                         event.get_state() & gtk.gdk.CONTROL_MASK
310                 ):
311                         self.window.destroy()
312                 elif event.keyval == gtk.keysyms.l and event.get_state() & gtk.gdk.CONTROL_MASK:
313                         with open(constants._user_logpath_, "r") as f:
314                                 logLines = f.xreadlines()
315                                 log = "".join(logLines)
316                                 self._clipboard.set_text(str(log))
317                         return True
318
319         @gtk_toolbox.log_exception(_moduleLogger)
320         def _on_window_state_change(self, widget, event, *args):
321                 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
322                         self.window_in_fullscreen = True
323                 else:
324                         self.window_in_fullscreen = False
325
326         def speichereAlles(self, data = None, data2 = None):
327                 logging.info("Speichere alles")
328
329         def ladeAlles(self, data = None, data2 = None):
330                 logging.info("Lade alles")
331
332         def beforeSync(self, data = None, data2 = None):
333                 logging.info("Lade alles")
334
335         @gtk_toolbox.log_exception(_moduleLogger)
336         def sync_finished(self, data = None, data2 = None):
337                 self.selection.comboList_changed()
338                 self.selection.comboCategory_changed()
339                 self.liststorehandler.update_list()
340
341         def prepare_sync_dialog(self):
342                 self.sync_dialog = gtk.Dialog(_("Sync"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
343
344                 self.sync_dialog.set_position(gtk.WIN_POS_CENTER)
345                 sync = libsync.Sync(self.db, self.window, 50503)
346                 sync.connect("syncFinished", self.sync_finished)
347                 self.sync_dialog.vbox.pack_start(sync, True, True, 0)
348                 self.sync_dialog.set_size_request(500, 350)
349                 self.sync_dialog.vbox.show_all()
350
351         @gtk_toolbox.log_exception(_moduleLogger)
352         def sync_notes(self, widget = None, data = None):
353                 if self.sync_dialog == None:
354                         self.prepare_sync_dialog()
355                 self.sync_dialog.run()
356                 self.sync_dialog.hide()
357
358         @gtk_toolbox.log_exception(_moduleLogger)
359         def _on_settings(self, *args):
360                 col_dialog = gtk.Dialog(
361                         _("Settings"),
362                         self.window,
363                         gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
364                         (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)
365                 )
366
367                 cols = settings.SettingsDialog(col_dialog.vbox, self.db, self.liststorehandler)
368                 col_dialog.show_all()
369
370                 resp = col_dialog.run()
371                 try:
372                         col_dialog.hide()
373                         if resp == gtk.RESPONSE_ACCEPT:
374                                 logging.info("changing columns")
375                                 cols.save(self.db)
376                                 self.view.reload_view()
377                 finally:
378                         col_dialog.destroy()
379
380         @gtk_toolbox.log_exception(_moduleLogger)
381         def _on_destroy(self, widget = None, data = None):
382                 try:
383                         self.speichereAlles()
384                         self.db.close()
385                         try:
386                                 self._osso_c.close()
387                         except AttributeError:
388                                 pass # Either None or close was removed (in Fremantle)
389                 finally:
390                         gtk.main_quit()
391
392         @gtk_toolbox.log_exception(_moduleLogger)
393         def _on_delete_event(self, widget, event, data = None):
394                 #print "delete event occurred"
395                 return False
396
397         def dlg_delete(self, widget, event, data = None):
398                 return False
399
400         @gtk_toolbox.log_exception(_moduleLogger)
401         def _on_about(self, widget = None, data = None):
402                 dialog = gtk.AboutDialog()
403                 dialog.set_position(gtk.WIN_POS_CENTER)
404                 dialog.set_name(constants.__pretty_app_name__)
405                 dialog.set_version(constants.__version__)
406                 dialog.set_copyright("")
407                 dialog.set_website("http://axique.de/f = Multilist")
408                 comments = "%s is a program to handle multiple lists." % constants.__pretty_app_name__
409                 dialog.set_comments(comments)
410                 dialog.set_authors(["Christoph Wurstle <n800@axique.net>", "Ed Page <eopage@byu.net> (Blame him for the most recent bugs)"])
411                 dialog.run()
412                 dialog.destroy()
413
414         def on_info1_activate(self, menuitem):
415                 self._on_about(menuitem)
416
417         @gtk_toolbox.log_exception(_moduleLogger)
418         def view_sql_history(self, widget = None, data = None, data2 = None):
419                 sqldiag = sqldialog.SqlDialog(self.db)
420                 res = sqldiag.run()
421                 sqldiag.hide()
422
423                 try:
424                         if res != gtk.RESPONSE_OK:
425                                 return
426                         logging.info("exporting sql")
427
428                         if not isHildon:
429                                 dlg = gtk.FileChooserDialog(
430                                         parent = self.window,
431                                         action = gtk.FILE_CHOOSER_ACTION_SAVE
432                                 )
433                                 dlg.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
434                                 dlg.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK)
435                         else:
436                                 dlg = hildon.FileChooserDialog(self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
437
438                         dlg.set_title(_("Select SQL export file"))
439                         exportFileResponse = dlg.run()
440                         try:
441                                 if exportFileResponse == gtk.RESPONSE_OK:
442                                         fileName = dlg.get_filename()
443                                         sqldiag.exportSQL(fileName)
444                         finally:
445                                 dlg.destroy()
446                 finally:
447                         sqldiag.destroy()
448
449         @gtk_toolbox.log_exception(_moduleLogger)
450         def optimizeSQL(self, widget = None, data = None, data2 = None):
451                 #optimiere sql
452                 self.db.speichereSQL("VACUUM", log = False)
453
454         @gtk_toolbox.log_exception(_moduleLogger)
455         def select_db_dialog(self, widget = None, data = None, data2 = None):
456                 if (isHildon == False):
457                         dlg = gtk.FileChooserDialog(parent = self.window, action = gtk.FILE_CHOOSER_ACTION_SAVE)
458                         dlg.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
459                         dlg.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK)
460                 else:
461                         dlg = hildon.FileChooserDialog(self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
462
463                 if self.db.ladeDirekt('datenbank'):
464                         dlg.set_filename(self.db.ladeDirekt('datenbank'))
465                 dlg.set_title(_("Choose your database file"))
466                 resp = dlg.run()
467                 try:
468                         if resp == gtk.RESPONSE_OK:
469                                 fileName = dlg.get_filename()
470                                 self.db.speichereDirekt('datenbank', fileName)
471                                 self.speichereAlles()
472                                 self.db.openDB()
473                                 self.ladeAlles()
474                 finally:
475                         dlg.destroy()
476
477
478 def run_multilist():
479         if hildonize.IS_HILDON_SUPPORTED:
480                 gtk.set_application_name(constants.__pretty_app_name__)
481         app = Multilist()
482         if not PROFILE_STARTUP:
483                 gtk.main()
484
485
486 if __name__ == "__main__":
487         logging.basicConfig(level = logging.DEBUG)
488         run_multilist()