Prepping for Mer support
[quicknote] / src / libnotizen.py
1 #!/usr/bin/env python2.5
2 # -*- coding: utf-8 -*-
3
4 """
5  Copyright (C) 2007 Christoph Würstle
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License version 2 as
9 published by the Free Software Foundation.
10 """
11
12 import time
13 import logging
14 import uuid
15
16 import gobject
17 import gtk
18
19 import simple_list
20
21
22 try:
23         _
24 except NameError:
25         _ = lambda x: x
26
27
28 class Notizen(gtk.HBox):
29
30         def __init__(self, db, topBox):
31                 self._db = db
32                 self._topBox = topBox
33                 self.noteId = -1
34                 self._pos = -1
35                 self._noteBody = None #Last notetext
36                 self._categoryName = ""
37
38                 gtk.HBox.__init__(self, homogeneous = False, spacing = 0)
39                 logging.info("libnotizen, init")
40
41                 self._noteslist = simple_list.SimpleList()
42                 self._noteslist.set_eventfunction_cursor_changed(self._update_noteslist)
43
44                 self._noteslist.set_size_request(250, -1)
45
46                 vbox = gtk.VBox(homogeneous = False, spacing = 0)
47
48                 frame = gtk.Frame(_("Titles"))
49                 frame.add(self._noteslist)
50                 vbox.pack_start(frame, expand = True, fill = True, padding = 3)
51
52                 buttonHBox = gtk.HBox()
53                 vbox.pack_start(buttonHBox, expand = False, fill = True, padding = 3)
54
55                 button = gtk.Button(stock = gtk.STOCK_ADD)
56                 button.connect("clicked", self._on_add_note, None)
57                 buttonHBox.pack_start(button, expand = True, fill = True, padding = 3)
58
59                 button = gtk.Button(stock = gtk.STOCK_DELETE)
60                 button.connect("clicked", self._on_delete_note, None)
61                 buttonHBox.pack_start(button, expand = True, fill = True, padding = 3)
62
63                 self.pack_start(vbox, expand = False, fill = True, padding = 3)
64
65                 self._noteBodyView = gtk.TextView()
66                 self._noteBodyView.connect("focus-out-event", self.save_note, "focus-out-event")
67                 buf = self._noteBodyView.get_buffer()
68                 buf.set_text("")
69                 buf.connect("changed", self._on_note_changed, None)
70
71                 #self.textviewNotiz.set_size_request(-1, 50)
72                 self._noteScrollWindow = gtk.ScrolledWindow()
73                 self._noteScrollWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
74                 self._noteScrollWindow.add(self._noteBodyView)
75
76                 frame = gtk.Frame(_("Note"))
77                 frame.add(self._noteScrollWindow)
78
79                 vbox = gtk.VBox(homogeneous = False, spacing = 0)
80                 vbox.pack_start(frame, expand = True, fill = True, padding = 3)
81
82                 self._historyBox = gtk.HBox(homogeneous = False, spacing = 0)
83
84                 self._historyStatusLabel = gtk.Label(_("No History"))
85                 self._historyStatusLabel.set_alignment(0.0, 0.5)
86                 self._historyBox.pack_start(self._historyStatusLabel, expand = True, fill = True, padding = 3)
87
88                 button = gtk.Button(_("History"))
89                 button.connect("clicked", self._on_show_history, None)
90                 self._historyBox.pack_start(button, expand = True, fill = True, padding = 3)
91
92                 vbox.pack_start(self._historyBox, expand = False, fill = True, padding = 3)
93
94                 self.pack_start(vbox, expand = True, fill = True, padding = 3)
95
96                 self.load_notes()
97                 self._topBox.connect("reload_notes", self.load_notes)
98
99         def set_wordwrap(self, enableWordWrap):
100                 if enableWordWrap:
101                         self._noteScrollWindow.set_policy(gtk.POLICY_NEVER, gtk.POLICY_AUTOMATIC)
102                         self._noteBodyView.set_wrap_mode(gtk.WRAP_WORD)
103                 else:
104                         self._noteScrollWindow.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC)
105                         self._noteBodyView.set_wrap_mode(gtk.WRAP_NONE)
106
107         def show_history_area(self, visible):
108                 if visible:
109                         self._historyBox.show()
110                 else:
111                         self._historyBox.hide()
112
113         def load_notes(self, data = None):
114                 logging.info("load_notes params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
115                 self._noteslist.clear_items()
116                 self._noteslist.append_item(_("New Note..."), "new")
117
118                 self._categoryName = self._topBox.get_category()
119                 search = self._topBox.get_search_pattern()
120                 notes = self._db.searchNotes(search, self._categoryName)
121
122                 if notes is not None:
123                         for note in notes:
124                                 noteid, category, noteText = note
125                                 title = self._get_title(noteText)
126                                 self._noteslist.append_item(title, noteid)
127
128                 self.noteId = -1
129                 self._pos = -1
130                 self._noteBodyView.get_buffer().set_text("")
131
132         def save_note(self, widget = None, data = None, data2 = None):
133                 logging.info("save_note params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
134                 #print "params:", data, data2
135                 buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
136                 if buf is None or len(buf) == 0:
137                         return
138
139                 if buf == self._noteBody:
140                         return
141
142                 logging.info("Saving note: "+buf)
143                 if self._pos == -1 or self.noteId == -1:
144                         self._pos = -1
145                         self.noteId = str(uuid.uuid4())
146                         self._db.saveNote(self.noteId, buf, self._categoryName)
147                         self._noteslist.append_item(self._get_title(buf), self.noteId)
148                         self._pos = self._noteslist.select_last_item()
149                 else:
150                         self._db.saveNote(self.noteId, buf, self._categoryName)
151
152                 self._topBox.define_this_category()
153
154         def _get_title(self, buf):
155                 """
156                 @returns the title of the current note
157                 """
158                 eol = buf.find("\n")
159                 if -1 == eol:
160                         eol = len(buf)
161                 title = buf[:eol]
162                 return title
163
164         def _set_focus(self):
165                 self._noteBodyView.grab_focus()
166                 return False
167
168         def _update_noteslist(self, data = None, data2 = None):
169                 if self._pos != -1:
170                         self.save_note()
171
172                 try:
173                         (pos, key, value) = self._noteslist.get_selection_data()
174                         if (pos == -1):
175                                 return
176                 except StandardError:
177                         if data != "new":
178                                 return
179                         key = None
180
181                 if key == "new" or data == "new":
182                         #both methods supported click add note or new note (first one disabled)
183                         self.noteId = str(uuid.uuid4())
184                         self._db.saveNote(self.noteId, "", self._categoryName)
185                         self._pos = -1
186                         self._noteslist.append_item("", self.noteId)
187                         self._noteBodyView.get_buffer().set_text("")
188                         self._pos = self._noteslist.select_last_item()
189                 else:
190                         self._pos = pos
191                         self.noteId, pcdatum, self._categoryName, self._noteBody = self._db.loadNote(key)
192                         self._historyStatusLabel.set_text(time.strftime(_("Last change: %d.%m.%y %H:%M"), time.localtime(pcdatum)))
193                         buf = self._noteBodyView.get_buffer()
194                         buf.set_text(self._noteBody)
195
196                 gobject.timeout_add(200, self._set_focus)
197
198         def _on_note_changed(self, widget = None, data = None):
199                 if self._pos == -1 or self.noteId == -1:
200                         return
201
202                 buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
203
204                 title = self._get_title(buf)
205                 value, key = self._noteslist.get_item(self._pos)
206
207                 if value != title:
208                         self._noteslist.change_item(self._pos, title, self.noteId)
209
210         def _on_add_note(self, widget = None, data = None):
211                 self._update_noteslist("new")
212
213         def _on_delete_note(self, widget = None, data = None):
214                 if (self.noteId == -1):
215                         return
216                 mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, _("Really delete?"))
217                 response = mbox.run()
218                 mbox.hide()
219                 mbox.destroy()
220                 if response == gtk.RESPONSE_YES:
221                         self._db.delNote(self.noteId)
222                         self.noteId = -1
223                         self._noteslist.remove_item(self._pos)
224                         self._pos = -1
225                         self._noteBodyView.get_buffer().set_text("")
226
227         def _on_show_history(self, widget = None, data = None, label = None):
228                 if self.noteId == -1:
229                         mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("No note selected."))
230                         response = mbox.run()
231                         mbox.hide()
232                         mbox.destroy()
233                         return
234
235                 rows = self._db.getNoteHistory(self.noteId)
236
237                 import libhistory
238                 dialog = libhistory.Dialog()
239
240                 lastNoteStr = ""
241                 for row in rows:
242                         daten = row[4][1]
243                         if daten != "" and lastNoteStr != daten:
244                                 lastNoteStr = daten
245                                 dialog.noteHistory.append([row[0], row[1], row[2], row[3], daten+"\n"])
246
247                 dialog.vbox.show_all()
248                 dialog.set_size_request(600, 380)
249
250                 if dialog.run() == gtk.RESPONSE_ACCEPT:
251                         print "saving"
252                         self.save_note()
253                         data = dialog.get_selected_row()
254                         if data is not None:
255                                 self._db.speichereSQL(data[2], data[3].split(" <<Tren-ner>> "), rowid = self.noteId)
256                                 logging.info("loading History")
257                                 self._update_noteslist()
258
259                 dialog.destroy()