2 # -*- coding: utf-8 -*-
5 This file is part of Multilist.
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.
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.
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/>.
20 Copyright (C) 2008 Christoph Würstle
47 import libliststorehandler
57 _moduleLogger = logging.getLogger(__name__)
58 PROFILE_STARTUP = False
61 class Multilist(hildonize.get_app_class()):
63 _user_data = os.path.join(os.path.expanduser("~"), ".%s" % constants.__app_name__)
64 _user_settings = "%s/settings.ini" % _user_data
67 super(Multilist, self).__init__()
68 self._clipboard = gtk.clipboard_get()
70 logging.info('Starting Multilist')
73 os.makedirs(self._user_data)
78 self.db = libspeichern.Speichern()
79 self.window_in_fullscreen = False #The window isn't in full screen mode initially.
81 #Haupt vbox für alle Elemente
82 self.window = gtk.Window()
83 self.vbox = gtk.VBox(homogeneous = False, spacing = 0)
85 self.selection = libselection.Selection(self.db, isHildon)
86 self.liststorehandler = libliststorehandler.Liststorehandler(self.db, self.selection)
87 self.view = libview.View(self.db, self.liststorehandler, self.window)
88 self.bottombar = libbottombar.Bottombar(self.db, self.view, isHildon)
91 if hildonize.GTK_MENU_USED:
92 dateimenu = gtk.Menu()
94 menu_items = gtk.MenuItem(_("Choose database file"))
95 dateimenu.append(menu_items)
96 menu_items.connect("activate", self.select_db_dialog, None)
98 menu_items = gtk.MenuItem(_("SQL history"))
99 dateimenu.append(menu_items)
100 menu_items.connect("activate", self.view_sql_history, None)
102 menu_items = gtk.MenuItem(_("SQL optimize"))
103 dateimenu.append(menu_items)
104 menu_items.connect("activate", self.optimizeSQL, None)
106 menu_items = gtk.MenuItem(_("Sync items"))
107 dateimenu.append(menu_items)
108 menu_items.connect("activate", self.sync_notes, None)
110 menu_items = gtk.MenuItem(_("Quit"))
111 dateimenu.append(menu_items)
112 menu_items.connect("activate", self.destroy, None)
115 datei_menu = gtk.MenuItem(_("File"))
117 datei_menu.set_submenu(dateimenu)
119 toolsmenu = gtk.Menu()
121 menu_items = gtk.MenuItem(_("Choose columns"))
122 toolsmenu.append(menu_items)
123 menu_items.connect("activate", self.show_columns_dialog, None)
125 menu_items = gtk.MenuItem(_("Rename Category"))
126 toolsmenu.append(menu_items)
127 menu_items.connect("activate", self.bottombar.rename_category, None)
129 menu_items = gtk.MenuItem(_("Rename List"))
130 toolsmenu.append(menu_items)
131 menu_items.connect("activate", self.bottombar.rename_list, None)
133 tools_menu = gtk.MenuItem(_("Tools"))
135 tools_menu.set_submenu(toolsmenu)
137 hilfemenu = gtk.Menu()
138 menu_items = gtk.MenuItem(_("About"))
139 hilfemenu.append(menu_items)
140 menu_items.connect("activate", self.show_about, None)
142 hilfe_menu = gtk.MenuItem(_("Help"))
144 hilfe_menu.set_submenu(hilfemenu)
146 menu_bar = gtk.MenuBar()
148 menu_bar.append (datei_menu)
149 menu_bar.append (tools_menu)
150 # unten -> damit als letztes menu_bar.append (hilfe_menu)
152 menu_bar.append (hilfe_menu)
154 self.vbox.pack_start(menu_bar, False, False, 0)
156 menuBar = gtk.MenuBar()
158 self.vbox.pack_start(menuBar, False, False, 0)
160 #add to vbox below (to get it on top)
161 self.vbox.pack_end(self.bottombar, expand = False, fill = True, padding = 0)
162 self.vbox.pack_end(self.view, expand = True, fill = True, padding = 0)
163 self.vbox.pack_end(self.selection, expand = False, fill = True, padding = 0)
165 #Get the Main Window, and connect the "destroy" event
166 self.window.add(self.vbox)
168 self.window = hildonize.hildonize_window(self, self.window)
169 hildonize.set_application_title(self.window, "%s" % constants.__pretty_app_name__)
170 menu_bar = hildonize.hildonize_menu(
174 if hildonize.IS_FREMANTLE_SUPPORTED:
177 if not hildonize.IS_HILDON_SUPPORTED:
178 _moduleLogger.info("No hildonization support")
181 self.osso_c = osso.Context(
182 constants.__app_name__,
183 constants.__version__,
187 _moduleLogger.info("No osso support")
190 self.window.connect("delete_event", self.delete_event)
191 self.window.connect("destroy", self.destroy)
192 self.window.connect("key-press-event", self.on_key_press)
193 self.window.connect("window-state-event", self.on_window_state_change)
195 self.window.show_all()
196 self.prepare_sync_dialog()
199 @gtk_toolbox.log_exception(_moduleLogger)
200 def on_key_press(self, widget, event, *args):
201 RETURN_TYPES = (gtk.keysyms.Return, gtk.keysyms.ISO_Enter, gtk.keysyms.KP_Enter)
202 isCtrl = bool(event.get_state() & gtk.gdk.CONTROL_MASK)
204 event.keyval == gtk.keysyms.F6 or
205 event.keyval in RETURN_TYPES and isCtrl
207 # The "Full screen" hardware key has been pressed
208 if self.window_in_fullscreen:
209 self.window.unfullscreen ()
211 self.window.fullscreen ()
213 #elif event.keyval == gtk.keysyms.f and isCtrl:
214 # self._toggle_search()
217 event.keyval in (gtk.keysyms.w, gtk.keysyms.q) and
218 event.get_state() & gtk.gdk.CONTROL_MASK
220 self.window.destroy()
221 elif event.keyval == gtk.keysyms.l and event.get_state() & gtk.gdk.CONTROL_MASK:
222 with open(constants._user_logpath_, "r") as f:
223 logLines = f.xreadlines()
224 log = "".join(logLines)
225 self._clipboard.set_text(str(log))
228 @gtk_toolbox.log_exception(_moduleLogger)
229 def on_window_state_change(self, widget, event, *args):
230 if event.new_window_state & gtk.gdk.WINDOW_STATE_FULLSCREEN:
231 self.window_in_fullscreen = True
233 self.window_in_fullscreen = False
235 def speichereAlles(self, data = None, data2 = None):
236 logging.info("Speichere alles")
238 def ladeAlles(self, data = None, data2 = None):
239 logging.info("Lade alles")
241 def beforeSync(self, data = None, data2 = None):
242 logging.info("Lade alles")
244 @gtk_toolbox.log_exception(_moduleLogger)
245 def sync_finished(self, data = None, data2 = None):
246 self.selection.comboList_changed()
247 self.selection.comboCategory_changed()
248 self.liststorehandler.update_list()
250 def prepare_sync_dialog(self):
251 self.sync_dialog = gtk.Dialog(_("Sync"), None, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
253 self.sync_dialog.set_position(gtk.WIN_POS_CENTER)
254 sync = libsync.Sync(self.db, self.window, 50503)
255 sync.connect("syncFinished", self.sync_finished)
256 self.sync_dialog.vbox.pack_start(sync, True, True, 0)
257 self.sync_dialog.set_size_request(500, 350)
258 self.sync_dialog.vbox.show_all()
260 @gtk_toolbox.log_exception(_moduleLogger)
261 def sync_notes(self, widget = None, data = None):
262 if self.sync_dialog == None:
263 self.prepare_sync_dialog()
264 self.sync_dialog.run()
265 self.sync_dialog.hide()
267 @gtk_toolbox.log_exception(_moduleLogger)
268 def show_columns_dialog(self, widget = None, data = None):
269 col_dialog = gtk.Dialog(_("Choose columns"), self.window, gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT, (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
271 col_dialog.set_position(gtk.WIN_POS_CENTER)
272 cols = libview.Columns_dialog(self.db, self.liststorehandler)
274 col_dialog.vbox.pack_start(cols, True, True, 0)
275 col_dialog.set_size_request(500, 350)
276 col_dialog.vbox.show_all()
278 resp = col_dialog.run()
280 if resp == gtk.RESPONSE_ACCEPT:
281 logging.info("changing columns")
282 cols.save_column_setting()
283 self.view.reload_view()
284 #children = self.vbox.get_children()
285 #while len(children)>1:
286 # self.vbox.remove(children[1])
288 #self.vbox.pack_end(self.bottombar, expand = True, fill = True, padding = 0)
289 #self.vbox.pack_end(view, expand = True, fill = True, padding = 0)
290 #self.vbox.pack_end(self.selection, expand = False, fill = True, padding = 0)
294 @gtk_toolbox.log_exception(_moduleLogger)
295 def destroy(self, widget = None, data = None):
297 self.speichereAlles()
301 except AttributeError:
302 pass # Either None or close was removed (in Fremantle)
306 @gtk_toolbox.log_exception(_moduleLogger)
307 def delete_event(self, widget, event, data = None):
308 #print "delete event occurred"
311 def dlg_delete(self, widget, event, data = None):
314 @gtk_toolbox.log_exception(_moduleLogger)
315 def show_about(self, widget = None, data = None):
316 dialog = gtk.AboutDialog()
317 dialog.set_position(gtk.WIN_POS_CENTER)
318 dialog.set_name(constants.__pretty_app_name__)
319 dialog.set_version(constants.__version__)
320 dialog.set_copyright("")
321 dialog.set_website("http://axique.de/f = Multilist")
322 comments = "%s is a program to handle multiple lists." % constants.__pretty_app_name__
323 dialog.set_comments(comments)
324 dialog.set_authors(["Christoph Wurstle <n800@axique.net>", "Ed Page <eopage@byu.net> (Blame him for the most recent bugs)"])
328 def on_info1_activate(self, menuitem):
329 self.show_about(menuitem)
331 @gtk_toolbox.log_exception(_moduleLogger)
332 def view_sql_history(self, widget = None, data = None, data2 = None):
333 sqldiag = sqldialog.SqlDialog(self.db)
338 if res != gtk.RESPONSE_OK:
340 logging.info("exporting sql")
343 dlg = gtk.FileChooserDialog(
344 parent = self.window,
345 action = gtk.FILE_CHOOSER_ACTION_SAVE
347 dlg.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
348 dlg.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK)
350 dlg = hildon.FileChooserDialog(self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
352 dlg.set_title(_("Select SQL export file"))
353 exportFileResponse = dlg.run()
355 if exportFileResponse == gtk.RESPONSE_OK:
356 fileName = dlg.get_filename()
357 sqldiag.exportSQL(fileName)
363 @gtk_toolbox.log_exception(_moduleLogger)
364 def optimizeSQL(self, widget = None, data = None, data2 = None):
366 self.db.speichereSQL("VACUUM", log = False)
368 @gtk_toolbox.log_exception(_moduleLogger)
369 def select_db_dialog(self, widget = None, data = None, data2 = None):
370 if (isHildon == False):
371 dlg = gtk.FileChooserDialog(parent = self.window, action = gtk.FILE_CHOOSER_ACTION_SAVE)
372 dlg.add_button( gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
373 dlg.add_button( gtk.STOCK_OK, gtk.RESPONSE_OK)
375 #dlg = hildon.FileChooserDialog(parent = self.window, action = gtk.FILE_CHOOSER_ACTION_SAVE)
376 dlg = hildon.FileChooserDialog(self.window, gtk.FILE_CHOOSER_ACTION_SAVE)
378 if self.db.ladeDirekt('datenbank'):
379 dlg.set_filename(self.db.ladeDirekt('datenbank'))
380 dlg.set_title(_("Choose your database file"))
381 if dlg.run() == gtk.RESPONSE_OK:
382 fileName = dlg.get_filename()
383 self.db.speichereDirekt('datenbank', fileName)
384 self.speichereAlles()
391 if hildonize.IS_HILDON_SUPPORTED:
392 gtk.set_application_name(constants.__pretty_app_name__)
394 if not PROFILE_STARTUP:
398 if __name__ == "__main__":
399 logging.basicConfig(level = logging.DEBUG)