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