Minor cleanups and the hiding of the history box on zoom
[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                 self._historyBox = gtk.HBox(homogeneous = False, spacing = 0)
85
86                 self._historyStatusLabel = gtk.Label("Test")
87                 self._historyStatusLabel.set_alignment(0.0, 0.5)
88                 self._historyBox.pack_start(self._historyStatusLabel, expand = True, fill = True, padding = 3)
89
90                 button = gtk.Button(_("History"))
91                 button.connect("clicked", self._on_show_history, None)
92                 self._historyBox.pack_start(button, expand = True, fill = True, padding = 3)
93
94                 vbox.pack_start(self._historyBox, 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 show_history_area(self, visible):
110                 if visible:
111                         self._historyBox.show()
112                 else:
113                         self._historyBox.hide()
114
115         def load_notes(self, data = None):
116                 logging.info("load_notes params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
117                 self._noteslist.clear_items()
118                 self._noteslist.append_item(_("new Note"), "new")
119
120                 self._categoryName = self._topBox.get_category()
121                 search = self._topBox.get_search_pattern()
122                 notes = self._db.searchNotes(search, self._categoryName)
123
124                 if notes is not None:
125                         for note in notes:
126                                 noteid, category, noteText = note
127                                 title = self._get_title(noteText)
128                                 self._noteslist.append_item(title, noteid)
129
130                 self.noteId = -1
131                 self._pos = -1
132                 self._noteBodyView.get_buffer().set_text("")
133
134         def save_note(self, widget = None, data = None, data2 = None):
135                 logging.info("save_note params: pos:"+str(self._pos)+" noteid:"+str(self.noteId))
136                 #print "params:", data, data2
137                 buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
138                 if buf is None or len(buf) == 0:
139                         return
140
141                 if buf == self._noteBody:
142                         return
143
144                 logging.info("Saving note: "+buf)
145                 if self._pos == -1 or self.noteId == -1:
146                         self._pos = -1
147                         self.noteId = str(uuid.uuid4())
148                         self._db.save_note(self.noteId, buf, self._categoryName)
149                         self._noteslist.append_item(self._get_title(buf), self.noteId)
150                         self._pos = self._noteslist.select_last_item()
151                 else:
152                         self._db.save_note(self.noteId, buf, self._categoryName)
153
154                 self._topBox.define_this_category()
155
156         def _get_title(self, buf):
157                 """
158                 @returns the title of the current note
159                 """
160                 eol = buf.find("\n")
161                 if -1 == eol:
162                         eol = len(buf)
163                 title = buf[:eol]
164                 return title
165
166         def _set_focus(self):
167                 self._noteBodyView.grab_focus()
168                 return False
169
170         def _update_noteslist(self, data = None, data2 = None):
171                 if self._pos != -1:
172                         self.save_note()
173
174                 try:
175                         (pos, key, value) = self._noteslist.get_selection_data()
176                         if (pos == -1):
177                                 return
178                 except StandardError:
179                         if data != "new":
180                                 return
181                         key = None
182
183                 if key == "new" or data == "new":
184                         #both methods supported click add note or new note (first one disabled)
185                         self.noteId = str(uuid.uuid4())
186                         self._db.save_note(self.noteId, "", self._categoryName)
187                         self._pos = -1
188                         self._noteslist.append_item("", self.noteId)
189                         self._noteBodyView.get_buffer().set_text("")
190                         self._pos = self._noteslist.select_last_item()
191                 else:
192                         self._pos = pos
193                         self.noteId, pcdatum, self._categoryName, self._noteBody = self._db.loadNote(key)
194                         self._historyStatusLabel.set_text(time.strftime(_("Last change: %d.%m.%y %H:%M"), time.localtime(pcdatum)))
195                         buf = self._noteBodyView.get_buffer()
196                         buf.set_text(self._noteBody)
197
198                 gobject.timeout_add(200, self._set_focus)
199
200         def _on_note_changed(self, widget = None, data = None):
201                 if self._pos == -1 or self.noteId == -1:
202                         return
203
204                 buf = self._noteBodyView.get_buffer().get_text(self._noteBodyView.get_buffer().get_start_iter(), self._noteBodyView.get_buffer().get_end_iter())
205
206                 title = self._get_title(buf)
207                 value, key = self._noteslist.get_item(self._pos)
208
209                 if value != title:
210                         self._noteslist.change_item(self._pos, title, self.noteId)
211
212         def _on_add_note(self, widget = None, data = None):
213                 self._update_noteslist("new")
214
215         def _on_delete_note(self, widget = None, data = None):
216                 if (self.noteId == -1):
217                         return
218                 mbox = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_WARNING, gtk.BUTTONS_YES_NO, _("Really delete?"))
219                 response = mbox.run()
220                 mbox.hide()
221                 mbox.destroy()
222                 if response == gtk.RESPONSE_YES:
223                         self._db.delNote(self.noteId)
224                         self.noteId = -1
225                         self._noteslist.remove_item(self._pos)
226                         self._pos = -1
227                         self._noteBodyView.get_buffer().set_text("")
228
229         def _on_show_history(self, widget = None, data = None, label = None):
230                 if self.noteId == -1:
231                         mbox =  gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("No note selected."))
232                         response = mbox.run()
233                         mbox.hide()
234                         mbox.destroy()
235                         return
236
237                 rows = self._db.getNoteHistory(self.noteId)
238
239                 import libhistory
240                 dialog = libhistory.Dialog()
241
242                 lastNoteStr = ""
243                 for row in rows:
244                         daten = row[4][1]
245                         if daten != "" and lastNoteStr != daten:
246                                 lastNoteStr = daten
247                                 dialog.noteHistory.append([row[0], row[1], row[2], row[3], daten+"\n"])
248
249                 dialog.vbox.show_all()
250                 dialog.set_size_request(600, 380)
251
252                 if dialog.run() == gtk.RESPONSE_ACCEPT:
253                         print "saving"
254                         self.save_note()
255                         data = dialog.get_selected_row()
256                         if data is not None:
257                                 self._db.speichereSQL(data[2], data[3].split(" <<Tren-ner>> "), rowid = self.noteId)
258                                 logging.info("loading History")
259                                 self._update_noteslist()
260
261                 dialog.destroy()