1
2 /*
3 * Osmo - a handy personal organizer
4 *
5 * Copyright (C) 2007-2014 Tomasz Maka <pasp@users.sourceforge.net>
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 as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program 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 this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */
21
22 #include "notes_items.h"
23 #include "i18n.h"
24 #include "options_prefs.h"
25 #include "notes.h"
26 #include "notes_preferences_gui.h"
27 #include "calendar.h"
28 #include "calendar_notes.h"
29 #include "calendar_widget.h"
30 #include "calendar_utils.h"
31 #include "utils.h"
32 #include "utils_gui.h"
33 #include "utils_date.h"
34 #include "stock_icons.h"
35
36 #ifdef NOTES_ENABLED
37
38 #ifdef HAVE_LIBGRINGOTTS
39 #include <libgringotts.h>
40 #endif /* HAVE_LIBGRINGOTTS */
41
42 /*------------------------------------------------------------------------------*/
43
44 gboolean
notes_get_active_state(GUI * appGUI)45 notes_get_active_state (GUI *appGUI) {
46
47 gint b, c;
48
49 gint a = strlen(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->note_name_entry)));
50 if (appGUI->nte->encrypted == FALSE) {
51 return a;
52 }
53 if (appGUI->nte->password_entry != NULL) {
54 b = strlen(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->password_entry)));
55 } else {
56 b = 1;
57 }
58 if (appGUI->nte->spassword_entry != NULL) {
59 c = strlen(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->spassword_entry)));
60 } else {
61 c = 1;
62 }
63
64 return (a && b && c);
65 }
66
67 /*------------------------------------------------------------------------------*/
68
69 void
notes_edit_close_cb(GtkWidget * widget,GdkEvent * event,gpointer user_data)70 notes_edit_close_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) {
71
72 GUI *appGUI = (GUI *)user_data;
73
74 appGUI->nte->password_entry = NULL;
75 appGUI->nte->spassword_entry = NULL;
76
77 gtk_widget_destroy(appGUI->nte->edit_entry_window);
78 }
79
80 /*------------------------------------------------------------------------------*/
81
82 void
button_notes_edit_close_cb(GtkWidget * widget,gpointer data)83 button_notes_edit_close_cb (GtkWidget *widget, gpointer data) {
84
85 notes_edit_close_cb (widget, NULL, data);
86 }
87
88 /*------------------------------------------------------------------------------*/
89
90 void
notes_edit_action_cb(GtkWidget * widget,gpointer data)91 notes_edit_action_cb (GtkWidget *widget, gpointer data) {
92
93 GtkTreePath *path, *sort_path, *filter_path;
94 GtkTreeIter iter;
95 gchar *category;
96 gboolean remember_cursor;
97
98 GUI *appGUI = (GUI *)data;
99
100 gtk_tree_view_get_cursor (GTK_TREE_VIEW (appGUI->nte->notes_list), &sort_path, NULL);
101
102 if (sort_path == NULL) return;
103 filter_path = gtk_tree_model_sort_convert_path_to_child_path (GTK_TREE_MODEL_SORT(appGUI->nte->notes_sort), sort_path);
104 gtk_tree_path_free (sort_path);
105
106 if (filter_path == NULL) return;
107 path = gtk_tree_model_filter_convert_path_to_child_path (GTK_TREE_MODEL_FILTER(appGUI->nte->notes_filter), filter_path);
108 gtk_tree_path_free (filter_path);
109
110 if (path != NULL) {
111
112 category = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(appGUI->nte->category_combobox));
113 remember_cursor = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(appGUI->nte->remember_cursor_checkbutton));
114
115 gtk_tree_model_get_iter (GTK_TREE_MODEL(appGUI->nte->notes_list_store), &iter, path);
116 gtk_list_store_set(appGUI->nte->notes_list_store, &iter,
117 N_COLUMN_NAME, gtk_entry_get_text(GTK_ENTRY(appGUI->nte->note_name_entry)),
118 N_COLUMN_CATEGORY, category, N_COLUMN_REMEMBER_EDITOR_LINE, remember_cursor, -1);
119
120 g_free (category);
121 gtk_tree_path_free (path);
122
123 notes_edit_close_cb (widget, NULL, data);
124
125 if (config.save_data_after_modification) {
126 write_notes_entries (appGUI);
127 }
128 }
129
130 }
131
132 /*------------------------------------------------------------------------------*/
133
134 gint
notes_edit_key_press_cb(GtkWidget * widget,GdkEventKey * event,gpointer data)135 notes_edit_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data) {
136
137 GUI *appGUI = (GUI *)data;
138
139 if (event->keyval == GDK_KEY_Escape) {
140 notes_edit_close_cb (NULL, NULL, appGUI);
141 return TRUE;
142 } else if (event->keyval == GDK_KEY_Return) {
143 notes_edit_action_cb (NULL, appGUI);
144 return TRUE;
145 }
146 return FALSE;
147 }
148
149 /*------------------------------------------------------------------------------*/
150
151 gint
notes_add_entry_changed_cb(GtkEditable * editable,gpointer data)152 notes_add_entry_changed_cb (GtkEditable *editable, gpointer data) {
153
154 GUI *appGUI = (GUI *)data;
155
156 gtk_widget_set_sensitive(appGUI->nte->add_entry_ok_button, notes_get_active_state (appGUI));
157
158 return FALSE;
159 }
160
161 /*------------------------------------------------------------------------------*/
162
163 void
notes_edit_dialog_show(GtkWidget * list,GtkTreeModel * model,GUI * appGUI)164 notes_edit_dialog_show (GtkWidget *list, GtkTreeModel *model, GUI *appGUI)
165 {
166 GtkWidget *vbox1;
167 GtkWidget *hseparator;
168 GtkWidget *hbuttonbox;
169 GtkWidget *cancel_button;
170 GtkWidget *label;
171 GtkWidget *frame;
172 GtkWidget *table;
173
174 GtkTreeIter iter;
175 gchar *category, *name;
176 gchar tmpbuf[BUFFER_SIZE];
177 gboolean remember_cursor;
178
179 appGUI->nte->edit_entry_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
180 gtk_container_set_border_width (GTK_CONTAINER (appGUI->nte->edit_entry_window), 4);
181 gtk_window_set_title (GTK_WINDOW (appGUI->nte->edit_entry_window), _("Edit entry"));
182 gtk_window_set_default_size (GTK_WINDOW (appGUI->nte->edit_entry_window), 400, -1);
183 if (config.fullscreen == FALSE) {
184 gtk_window_set_transient_for (GTK_WINDOW (appGUI->nte->edit_entry_window), GTK_WINDOW (appGUI->main_window));
185 }
186 gtk_window_set_position (GTK_WINDOW (appGUI->nte->edit_entry_window), GTK_WIN_POS_CENTER_ON_PARENT);
187 gtk_window_set_modal (GTK_WINDOW (appGUI->nte->edit_entry_window), TRUE);
188 g_signal_connect (G_OBJECT (appGUI->nte->edit_entry_window), "delete_event",
189 G_CALLBACK (notes_edit_close_cb), appGUI);
190 g_signal_connect (G_OBJECT (appGUI->nte->edit_entry_window), "key_press_event",
191 G_CALLBACK (notes_edit_key_press_cb), appGUI);
192
193 vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
194 gtk_container_add (GTK_CONTAINER (appGUI->nte->edit_entry_window), vbox1);
195
196 table = gtk_grid_new ();
197 gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE, TRUE, 0);
198
199 frame = gtk_frame_new (NULL);
200 gtk_widget_set_hexpand(frame, TRUE);
201 gtk_widget_set_vexpand(frame, TRUE);
202 gtk_grid_attach (GTK_GRID (table), frame, 0, 0, 1, 1);
203 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
204
205 appGUI->nte->note_name_entry = gtk_entry_new ();
206 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->note_name_entry);
207 gtk_widget_set_margin_left(appGUI->nte->note_name_entry, 16);
208 gtk_widget_set_margin_right(appGUI->nte->note_name_entry, 4);
209 gtk_widget_set_margin_top(appGUI->nte->note_name_entry, 4);
210 gtk_widget_set_margin_bottom(appGUI->nte->note_name_entry, 4);
211 gtk_entry_set_invisible_char (GTK_ENTRY (appGUI->nte->note_name_entry), 8226);
212 g_signal_connect (G_OBJECT (appGUI->nte->note_name_entry), "changed",
213 G_CALLBACK (notes_add_entry_changed_cb), appGUI);
214
215 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Note name"));
216 label = gtk_label_new (tmpbuf);
217 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
218 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
219
220 frame = gtk_frame_new (NULL);
221 gtk_grid_attach (GTK_GRID (table), frame, 1, 0, 1, 1);
222 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
223
224 appGUI->nte->category_combobox = gtk_combo_box_text_new ();
225 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->category_combobox);
226 gtk_widget_set_margin_left(appGUI->nte->category_combobox, 16);
227 gtk_widget_set_margin_right(appGUI->nte->category_combobox, 4);
228 gtk_widget_set_margin_top(appGUI->nte->category_combobox, 4);
229 gtk_widget_set_margin_bottom(appGUI->nte->category_combobox, 4);
230 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->nte->category_combobox), NULL, _("None"));
231
232 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Category"));
233 label = gtk_label_new (tmpbuf);
234 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
235 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
236
237 frame = gtk_frame_new (NULL);
238 gtk_box_pack_start (GTK_BOX (vbox1), frame, FALSE, FALSE, 0);
239 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
240
241 appGUI->nte->remember_cursor_checkbutton = gtk_check_button_new_with_mnemonic (_("Remember cursor position"));
242 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->remember_cursor_checkbutton);
243 gtk_widget_set_can_focus (appGUI->nte->remember_cursor_checkbutton, FALSE);
244 gtk_widget_set_margin_left(appGUI->nte->remember_cursor_checkbutton, 16);
245 gtk_widget_set_margin_right(appGUI->nte->remember_cursor_checkbutton, 4);
246 gtk_widget_set_margin_top(appGUI->nte->remember_cursor_checkbutton, 4);
247 gtk_widget_set_margin_bottom(appGUI->nte->remember_cursor_checkbutton, 4);
248
249 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Options"));
250 label = gtk_label_new (tmpbuf);
251 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
252 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
253
254 hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
255 gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 4);
256
257 hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
258 gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox, FALSE, FALSE, 0);
259 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
260 gtk_box_set_spacing (GTK_BOX (hbuttonbox), 4);
261
262 cancel_button = gtk_button_new_with_mnemonic (_("_Cancel"));
263 gtk_widget_set_can_focus (cancel_button, FALSE);
264 gtk_container_add (GTK_CONTAINER (hbuttonbox), cancel_button);
265 g_signal_connect (G_OBJECT (cancel_button), "clicked",
266 G_CALLBACK (button_notes_edit_close_cb), appGUI);
267
268 appGUI->nte->add_entry_ok_button = gtk_button_new_with_mnemonic (_("_OK"));
269 gtk_widget_set_can_focus (appGUI->nte->add_entry_ok_button, FALSE);
270 gtk_container_add (GTK_CONTAINER (hbuttonbox), appGUI->nte->add_entry_ok_button);
271 g_signal_connect (G_OBJECT (appGUI->nte->add_entry_ok_button), "clicked",
272 G_CALLBACK (notes_edit_action_cb), appGUI);
273
274 iter = utl_gui_get_first_selection_iter(appGUI->nte->notes_list_selection, &model);
275 gtk_tree_model_get(model, &iter,
276 N_COLUMN_NAME, &name,
277 N_COLUMN_CATEGORY, &category,
278 N_COLUMN_REMEMBER_EDITOR_LINE, &remember_cursor,
279 -1);
280
281 gtk_entry_set_text(GTK_ENTRY(appGUI->nte->note_name_entry), name);
282
283 utl_gui_create_category_combobox(GTK_COMBO_BOX(appGUI->nte->category_combobox),
284 appGUI->opt->notes_category_store, TRUE);
285
286 gtk_combo_box_set_active(GTK_COMBO_BOX(appGUI->nte->category_combobox), utl_gui_list_store_get_text_index(appGUI->opt->notes_category_store, category));
287
288 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(appGUI->nte->remember_cursor_checkbutton), remember_cursor);
289
290 g_free(category);
291 g_free(name);
292 gtk_widget_show_all(appGUI->nte->edit_entry_window);
293 }
294 /*------------------------------------------------------------------------------*/
295 void
notes_remove(GtkTreeRowReference * ref,GUI * appGUI)296 notes_remove(GtkTreeRowReference *ref, GUI *appGUI) {
297 GtkTreePath *path;
298 GtkTreeIter iter, filter_iter, sort_iter;
299 gchar *filename;
300 GtkTreeModel *model;
301
302 model = gtk_tree_row_reference_get_model(ref);
303 path = gtk_tree_row_reference_get_path(ref);
304 if (path != NULL) {
305 if (gtk_tree_model_get_iter(model, &sort_iter, path)) {
306 gtk_tree_model_get(model, &sort_iter, N_COLUMN_FILENAME, &filename, -1);
307 g_unlink(notes_get_full_filename(filename, appGUI));
308 g_free(filename);
309 gtk_tree_model_sort_convert_iter_to_child_iter(GTK_TREE_MODEL_SORT(model), &filter_iter, &sort_iter);
310 gtk_tree_model_filter_convert_iter_to_child_iter(GTK_TREE_MODEL_FILTER(gtk_tree_model_sort_get_model(GTK_TREE_MODEL_SORT(model))), &iter, &filter_iter);
311 gtk_list_store_remove(appGUI->nte->notes_list_store, &iter);
312 }
313 gtk_tree_path_free(path);
314 }
315 }
316 /*------------------------------------------------------------------------------*/
317
318 void
notes_remove_dialog_show(GUI * appGUI)319 notes_remove_dialog_show (GUI *appGUI) {
320 gint response;
321 gchar tmpbuf[BUFFER_SIZE];
322
323
324 g_snprintf(tmpbuf, BUFFER_SIZE, "%s\n%s\n\n%s", _("Selected note will be removed."),
325 _("No further data recovery will be possible."), _("Are you sure?"));
326
327 response = utl_gui_create_dialog(GTK_MESSAGE_QUESTION, tmpbuf, GTK_WINDOW(appGUI->main_window));
328
329 if (response == GTK_RESPONSE_YES) {
330 utl_gui_foreach_selected(appGUI->nte->notes_list_selection, GTK_TREE_MODEL(appGUI->nte->notes_list_store),
331 (GFunc) notes_remove, appGUI);
332 update_notes_items(appGUI);
333 check_notes_type(appGUI);
334
335 if (config.save_data_after_modification) {
336 write_notes_entries(appGUI);
337 }
338 }
339 }
340
341 /*------------------------------------------------------------------------------*/
342
343 void
notes_add_close_cb(GtkWidget * widget,GdkEvent * event,gpointer user_data)344 notes_add_close_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) {
345
346 GUI *appGUI = (GUI *)user_data;
347
348 #ifdef HAVE_LIBGRINGOTTS
349 appGUI->nte->password_entry = NULL;
350 appGUI->nte->spassword_entry = NULL;
351 #endif /* HAVE_LIBGRINGOTTS */
352
353 gtk_widget_destroy(appGUI->nte->add_entry_window);
354 }
355
356 /*------------------------------------------------------------------------------*/
357
358 void
button_notes_add_close_cb(GtkWidget * widget,gpointer data)359 button_notes_add_close_cb (GtkWidget *widget, gpointer data) {
360
361 notes_add_close_cb (widget, NULL, data);
362 }
363
364 /*------------------------------------------------------------------------------*/
365
366 gint
notes_add_key_press_cb(GtkWidget * widget,GdkEventKey * event,gpointer data)367 notes_add_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data) {
368
369 GUI *appGUI = (GUI *)data;
370
371 if (event->keyval == GDK_KEY_Escape) {
372 notes_add_close_cb (NULL, NULL, appGUI);
373 return TRUE;
374 }
375 return FALSE;
376 }
377
378 /*------------------------------------------------------------------------------*/
379
380 void
notes_add_entry_action_cb(GtkWidget * widget,gpointer data)381 notes_add_entry_action_cb (GtkWidget *widget, gpointer data) {
382
383 gchar *name;
384 gchar *current_filename;
385 gchar *category, *create_date_str;
386 guint32 current_date;
387 GtkTreeIter iter;
388 gint current_time;
389 gboolean remember_cursor;
390
391 #ifdef HAVE_LIBGRINGOTTS
392 gchar *pass = NULL, *spass = NULL;
393 GRG_CTX context;
394 GRG_KEY keyholder;
395 #endif /* HAVE_LIBGRINGOTTS */
396
397 GUI *appGUI = (GUI *)data;
398
399 #ifdef HAVE_LIBGRINGOTTS
400 if (appGUI->nte->encrypted == TRUE) {
401 pass = g_strdup(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->password_entry)));
402 spass = g_strdup(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->spassword_entry)));
403
404 if (g_utf8_collate (pass, spass) != 0) {
405 utl_gui_create_dialog(GTK_MESSAGE_ERROR, _("Passwords do not match!"), GTK_WINDOW(appGUI->main_window));
406 gtk_widget_grab_focus (appGUI->nte->password_entry);
407 g_free(pass);
408 g_free(spass);
409 return;
410 }
411 }
412 #endif /* HAVE_LIBGRINGOTTS */
413
414 name = g_strdup(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->note_name_entry)));
415 category = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(appGUI->nte->category_combobox));
416 remember_cursor = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(appGUI->nte->remember_cursor_checkbutton));
417
418 notes_add_close_cb (NULL, NULL, appGUI);
419
420 current_date = utl_date_get_current_julian ();
421 current_time = utl_time_get_current_seconds ();
422 current_filename = g_strdup (notes_get_new_filename (appGUI));
423
424 #ifdef HAVE_LIBGRINGOTTS
425 if (appGUI->nte->encrypted == TRUE) {
426
427 context = grg_context_initialize_defaults ((unsigned char*) "OSM");
428 keyholder = grg_key_gen ((unsigned char*) pass, -1);
429
430 grg_ctx_set_crypt_algo (context, get_enc_algorithm_value());
431 grg_ctx_set_hash_algo (context, get_enc_hashing_value());
432 grg_ctx_set_comp_algo (context, get_comp_algorithm_value());
433 grg_ctx_set_comp_ratio (context, get_comp_ratio_value());
434
435 grg_encrypt_file (context, keyholder,
436 (unsigned char*) notes_get_full_filename (current_filename, appGUI),
437 (guchar *)"", 0);
438
439 grg_key_free (context, keyholder);
440 grg_context_free (context);
441
442 } else {
443
444 g_file_set_contents (notes_get_full_filename(current_filename, appGUI),
445 "", 0, NULL);
446 }
447 #endif /* HAVE_LIBGRINGOTTS */
448 create_date_str = g_strdup(get_date_time_str (current_date, current_time));
449
450 gtk_list_store_append(appGUI->nte->notes_list_store, &iter);
451 gtk_list_store_set(appGUI->nte->notes_list_store, &iter,
452 N_COLUMN_NAME, name,
453 N_COLUMN_CATEGORY, category,
454 N_COLUMN_LAST_CHANGES_DATE, create_date_str,
455 N_COLUMN_LAST_CHANGES_DATE_JULIAN, current_date,
456 N_COLUMN_LAST_CHANGES_TIME, current_time,
457 N_COLUMN_CREATE_DATE, create_date_str,
458 N_COLUMN_CREATE_DATE_JULIAN, current_date,
459 N_COLUMN_CREATE_TIME, current_time,
460 N_COLUMN_REMEMBER_EDITOR_LINE, remember_cursor,
461 N_COLUMN_EDITOR_LINE, 0,
462 N_COLUMN_FILENAME, current_filename,
463 N_COLUMN_FONTNAME, DEFAULT_NOTE_FONT,
464 -1);
465 g_free (category);
466 g_free (create_date_str);
467
468 update_notes_items(appGUI);
469 check_notes_type (appGUI);
470
471 if (config.save_data_after_modification) {
472 write_notes_entries (appGUI);
473 }
474
475 g_free(current_filename);
476 g_free(name);
477
478 #ifdef HAVE_LIBGRINGOTTS
479 if (appGUI->nte->encrypted == TRUE) {
480 g_free(pass);
481 g_free(spass);
482 }
483 #endif /* HAVE_LIBGRINGOTTS */
484
485 }
486
487 /*------------------------------------------------------------------------------*/
488
489 gint
notes_add_ok_key_press_cb(GtkWidget * widget,GdkEventKey * event,gpointer data)490 notes_add_ok_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data) {
491
492 GUI *appGUI = (GUI *)data;
493
494 if (event->keyval == GDK_KEY_Return && notes_get_active_state (appGUI) == TRUE) {
495 notes_add_entry_action_cb (NULL, appGUI);
496 return TRUE;
497 }
498 return FALSE;
499 }
500
501 /*------------------------------------------------------------------------------*/
502
503 void
note_type_cb(GtkWidget * widget,gpointer user_data)504 note_type_cb (GtkWidget *widget, gpointer user_data) {
505
506 GUI *appGUI = (GUI *) user_data;
507
508 if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (appGUI->nte->note_normal_radiobutton)) == TRUE) {
509 appGUI->nte->encrypted = FALSE;
510 } else {
511 appGUI->nte->encrypted = TRUE;
512 }
513
514 gtk_widget_set_sensitive (appGUI->nte->password_entry, appGUI->nte->encrypted);
515 gtk_widget_set_sensitive (appGUI->nte->spassword_entry, appGUI->nte->encrypted);
516 gtk_widget_set_sensitive(appGUI->nte->add_entry_ok_button, notes_get_active_state (appGUI));
517 }
518
519 /*------------------------------------------------------------------------------*/
520
521 void
notes_add_entry(GUI * appGUI)522 notes_add_entry (GUI *appGUI) {
523
524 GtkWidget *vbox1;
525 GtkWidget *hseparator;
526 GtkWidget *hbuttonbox;
527 GtkWidget *cancel_button;
528 GtkWidget *label;
529 GtkWidget *frame;
530 GtkWidget *table;
531
532 #ifdef HAVE_LIBGRINGOTTS
533 GtkWidget *hbox1;
534 GtkWidget *note_encrypted_radiobutton;
535 GSList *note_normal_radiobutton_group = NULL;
536 #endif /* HAVE_LIBGRINGOTTS */
537
538 gchar tmpbuf[BUFFER_SIZE];
539 gboolean has_next;
540 gchar *category;
541 GtkTreeIter iter;
542
543 appGUI->nte->encrypted = FALSE; /* default mode */
544
545 appGUI->nte->add_entry_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
546 gtk_container_set_border_width (GTK_CONTAINER (appGUI->nte->add_entry_window), 4);
547 gtk_window_set_title (GTK_WINDOW (appGUI->nte->add_entry_window), _("Add note"));
548 gtk_window_set_default_size (GTK_WINDOW(appGUI->nte->add_entry_window), 450, -1);
549 if (config.fullscreen == FALSE) {
550 gtk_window_set_transient_for(GTK_WINDOW(appGUI->nte->add_entry_window), GTK_WINDOW(appGUI->main_window));
551 }
552 gtk_window_set_position(GTK_WINDOW(appGUI->nte->add_entry_window), GTK_WIN_POS_CENTER_ON_PARENT);
553 gtk_window_set_modal(GTK_WINDOW(appGUI->nte->add_entry_window), TRUE);
554 g_signal_connect (G_OBJECT (appGUI->nte->add_entry_window), "delete_event",
555 G_CALLBACK(notes_add_close_cb), appGUI);
556 g_signal_connect (G_OBJECT (appGUI->nte->add_entry_window), "key_press_event",
557 G_CALLBACK (notes_add_key_press_cb), appGUI);
558
559 vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
560 gtk_widget_show (vbox1);
561 gtk_container_add (GTK_CONTAINER (appGUI->nte->add_entry_window), vbox1);
562
563 table = gtk_grid_new ();
564 gtk_widget_show (table);
565 gtk_box_pack_start (GTK_BOX (vbox1), table, FALSE, TRUE, 0);
566
567 frame = gtk_frame_new (NULL);
568 gtk_widget_show (frame);
569 gtk_widget_set_hexpand(frame, TRUE);
570 gtk_widget_set_vexpand(frame, TRUE);
571 gtk_grid_attach (GTK_GRID (table), frame, 0, 0, 1, 1);
572 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
573
574 appGUI->nte->note_name_entry = gtk_entry_new ();
575 gtk_widget_show (appGUI->nte->note_name_entry);
576 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->note_name_entry);
577 gtk_widget_set_margin_left(appGUI->nte->note_name_entry, 16);
578 gtk_widget_set_margin_right(appGUI->nte->note_name_entry, 4);
579 gtk_widget_set_margin_top(appGUI->nte->note_name_entry, 4);
580 gtk_widget_set_margin_bottom(appGUI->nte->note_name_entry, 4);
581 gtk_entry_set_invisible_char (GTK_ENTRY (appGUI->nte->note_name_entry), 8226);
582 g_signal_connect (G_OBJECT (appGUI->nte->note_name_entry), "changed",
583 G_CALLBACK (notes_add_entry_changed_cb), appGUI);
584
585 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Note name"));
586 label = gtk_label_new (tmpbuf);
587 gtk_widget_show (label);
588 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
589 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
590
591 frame = gtk_frame_new (NULL);
592 gtk_widget_show (frame);
593 gtk_grid_attach (GTK_GRID (table), frame, 1, 0, 1, 1);
594 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
595
596 appGUI->nte->category_combobox = gtk_combo_box_text_new ();
597 gtk_widget_show (appGUI->nte->category_combobox);
598 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->category_combobox);
599 gtk_widget_set_margin_left(appGUI->nte->category_combobox, 16);
600 gtk_widget_set_margin_right(appGUI->nte->category_combobox, 4);
601 gtk_widget_set_margin_top(appGUI->nte->category_combobox, 4);
602 gtk_widget_set_margin_bottom(appGUI->nte->category_combobox, 4);
603 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->nte->category_combobox), NULL, _("None"));
604
605 has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(appGUI->opt->notes_category_store), &iter);
606 while (has_next) {
607 gtk_tree_model_get(GTK_TREE_MODEL(appGUI->opt->notes_category_store), &iter, 0, &category, -1);
608 gtk_combo_box_text_append (GTK_COMBO_BOX_TEXT (appGUI->nte->category_combobox), NULL, category);
609 g_free(category);
610 has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL(appGUI->opt->notes_category_store), &iter);
611 }
612
613 gtk_combo_box_set_active (GTK_COMBO_BOX(appGUI->nte->category_combobox),
614 gtk_combo_box_get_active (GTK_COMBO_BOX (appGUI->nte->cf_combobox)));
615
616 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Category"));
617 label = gtk_label_new (tmpbuf);
618 gtk_widget_show (label);
619 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
620 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
621
622 #ifdef HAVE_LIBGRINGOTTS
623
624 frame = gtk_frame_new (NULL);
625 gtk_widget_show (frame);
626 gtk_box_pack_start (GTK_BOX (vbox1), frame, FALSE, FALSE, 0);
627 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
628
629 hbox1 = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
630 gtk_widget_show (hbox1);
631 gtk_container_add (GTK_CONTAINER (frame), hbox1);
632 gtk_widget_set_margin_left(hbox1, 16);
633 gtk_widget_set_margin_right(hbox1, 4);
634 gtk_widget_set_margin_top(hbox1, 4);
635 gtk_widget_set_margin_bottom(hbox1, 4);
636
637 appGUI->nte->note_normal_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Plain"));
638 gtk_widget_show (appGUI->nte->note_normal_radiobutton);
639 g_signal_connect (appGUI->nte->note_normal_radiobutton, "toggled",
640 G_CALLBACK (note_type_cb), appGUI);
641 gtk_widget_set_can_focus(appGUI->nte->note_normal_radiobutton, FALSE);
642 gtk_box_pack_start (GTK_BOX (hbox1), appGUI->nte->note_normal_radiobutton, TRUE, TRUE, 0);
643 gtk_radio_button_set_group (GTK_RADIO_BUTTON (appGUI->nte->note_normal_radiobutton), note_normal_radiobutton_group);
644 note_normal_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (appGUI->nte->note_normal_radiobutton));
645
646 note_encrypted_radiobutton = gtk_radio_button_new_with_mnemonic (NULL, _("Encrypted"));
647 gtk_widget_show (note_encrypted_radiobutton);
648 gtk_widget_set_can_focus(note_encrypted_radiobutton, FALSE);
649 gtk_box_pack_start (GTK_BOX (hbox1), note_encrypted_radiobutton, TRUE, TRUE, 0);
650 gtk_radio_button_set_group (GTK_RADIO_BUTTON (note_encrypted_radiobutton), note_normal_radiobutton_group);
651 note_normal_radiobutton_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (note_encrypted_radiobutton));
652
653 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Note type"));
654 label = gtk_label_new (tmpbuf);
655 gtk_widget_show (label);
656 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
657 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
658
659 frame = gtk_frame_new (NULL);
660 gtk_widget_show (frame);
661 gtk_box_pack_start (GTK_BOX (vbox1), frame, FALSE, FALSE, 0);
662 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
663
664 appGUI->nte->password_entry = gtk_entry_new ();
665 gtk_widget_show (appGUI->nte->password_entry);
666 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->password_entry);
667 gtk_widget_set_margin_left(appGUI->nte->password_entry, 16);
668 gtk_widget_set_margin_right(appGUI->nte->password_entry, 4);
669 gtk_widget_set_margin_top(appGUI->nte->password_entry, 4);
670 gtk_widget_set_margin_bottom(appGUI->nte->password_entry, 4);
671 gtk_entry_set_invisible_char (GTK_ENTRY (appGUI->nte->password_entry), 8226);
672 gtk_entry_set_visibility (GTK_ENTRY (appGUI->nte->password_entry), FALSE);
673 g_signal_connect (G_OBJECT (appGUI->nte->password_entry), "changed",
674 G_CALLBACK (notes_add_entry_changed_cb), appGUI);
675 gtk_widget_set_sensitive (appGUI->nte->password_entry, FALSE);
676
677 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Enter password"));
678 label = gtk_label_new (tmpbuf);
679 gtk_widget_show (label);
680 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
681 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
682
683 frame = gtk_frame_new (NULL);
684 gtk_widget_show (frame);
685 gtk_box_pack_start (GTK_BOX (vbox1), frame, FALSE, FALSE, 0);
686 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
687
688 appGUI->nte->spassword_entry = gtk_entry_new ();
689 gtk_widget_show (appGUI->nte->spassword_entry);
690 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->spassword_entry);
691 gtk_widget_set_margin_left(appGUI->nte->spassword_entry, 16);
692 gtk_widget_set_margin_right(appGUI->nte->spassword_entry, 4);
693 gtk_widget_set_margin_top(appGUI->nte->spassword_entry, 4);
694 gtk_widget_set_margin_bottom(appGUI->nte->spassword_entry, 4);
695 gtk_entry_set_invisible_char (GTK_ENTRY (appGUI->nte->spassword_entry), 8226);
696 gtk_entry_set_visibility (GTK_ENTRY (appGUI->nte->spassword_entry), FALSE);
697 g_signal_connect (G_OBJECT (appGUI->nte->spassword_entry), "changed",
698 G_CALLBACK (notes_add_entry_changed_cb), appGUI);
699 g_signal_connect (G_OBJECT (appGUI->nte->spassword_entry), "key_press_event",
700 G_CALLBACK (notes_add_ok_key_press_cb), appGUI);
701 gtk_widget_set_sensitive (appGUI->nte->spassword_entry, FALSE);
702
703 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Re-enter password"));
704 label = gtk_label_new (tmpbuf);
705 gtk_widget_show (label);
706 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
707 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
708
709 #endif /* HAVE_LIBGRINGOTTS */
710
711 frame = gtk_frame_new (NULL);
712 gtk_widget_show (frame);
713 gtk_box_pack_start (GTK_BOX (vbox1), frame, FALSE, FALSE, 0);
714 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
715
716 appGUI->nte->remember_cursor_checkbutton = gtk_check_button_new_with_mnemonic (_("Remember cursor position"));
717 gtk_widget_set_can_focus(appGUI->nte->remember_cursor_checkbutton, FALSE);
718 gtk_widget_show (appGUI->nte->remember_cursor_checkbutton);
719 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->remember_cursor_checkbutton);
720 gtk_widget_set_margin_left(appGUI->nte->remember_cursor_checkbutton, 16);
721 gtk_widget_set_margin_right(appGUI->nte->remember_cursor_checkbutton, 4);
722 gtk_widget_set_margin_top(appGUI->nte->remember_cursor_checkbutton, 4);
723 gtk_widget_set_margin_bottom(appGUI->nte->remember_cursor_checkbutton, 4);
724
725 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Options"));
726 label = gtk_label_new (tmpbuf);
727 gtk_widget_show (label);
728 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
729 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
730
731 hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
732 gtk_widget_show (hseparator);
733 gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 4);
734
735 hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
736 gtk_widget_show (hbuttonbox);
737 gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox, FALSE, FALSE, 0);
738 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
739 gtk_box_set_spacing (GTK_BOX (hbuttonbox), 4);
740
741 cancel_button = gtk_button_new_with_mnemonic (_("_Cancel"));
742 gtk_widget_set_can_focus(cancel_button, FALSE);
743 gtk_widget_show (cancel_button);
744 gtk_container_add (GTK_CONTAINER (hbuttonbox), cancel_button);
745 g_signal_connect (G_OBJECT (cancel_button), "clicked",
746 G_CALLBACK (button_notes_add_close_cb), appGUI);
747
748 appGUI->nte->add_entry_ok_button = gtk_button_new_with_mnemonic (_("_OK"));
749 gtk_widget_set_can_focus(appGUI->nte->add_entry_ok_button, FALSE);
750 gtk_widget_show (appGUI->nte->add_entry_ok_button);
751 gtk_container_add (GTK_CONTAINER (hbuttonbox), appGUI->nte->add_entry_ok_button);
752 g_signal_connect (G_OBJECT (appGUI->nte->add_entry_ok_button), "clicked",
753 G_CALLBACK (notes_add_entry_action_cb), appGUI);
754 gtk_widget_set_sensitive(appGUI->nte->add_entry_ok_button, FALSE);
755
756 gtk_widget_show (appGUI->nte->add_entry_window);
757
758 }
759
760 /*------------------------------------------------------------------------------*/
761
762 void
notes_enter_password_close_cb(GtkWidget * widget,GdkEvent * event,gpointer user_data)763 notes_enter_password_close_cb (GtkWidget *widget, GdkEvent *event, gpointer user_data) {
764
765 GUI *appGUI = (GUI *)user_data;
766
767 appGUI->nte->password_entry = NULL;
768 appGUI->nte->spassword_entry = NULL;
769
770 gtk_widget_destroy(appGUI->nte->enter_password_window);
771 }
772
773 /*------------------------------------------------------------------------------*/
774
775 void
button_enter_password_close_cb(GtkWidget * widget,gpointer data)776 button_enter_password_close_cb (GtkWidget *widget, gpointer data) {
777
778 notes_enter_password_close_cb (widget, NULL, data);
779 }
780
781 /*------------------------------------------------------------------------------*/
782
783 void
notes_enter_editor_action(GUI * appGUI)784 notes_enter_editor_action (GUI *appGUI) {
785
786 GtkTextBuffer *buffer;
787 gchar *txtnote;
788 gchar *current_filename;
789 GtkTreeIter iter;
790 GtkTreeModel *model;
791
792 iter = utl_gui_get_first_selection_iter(appGUI->nte->notes_list_selection, &model);
793 gtk_tree_model_get(model, &iter, N_COLUMN_FILENAME, ¤t_filename, -1);
794
795 appGUI->nte->filename = g_strdup(current_filename);
796
797 g_file_get_contents(notes_get_full_filename(current_filename, appGUI), &txtnote, NULL, NULL);
798
799 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->nte->editor_textview));
800 utl_gui_text_buffer_set_text_with_tags(buffer, (const gchar *) txtnote, TRUE);
801 notes_show_selector_editor(EDITOR, appGUI);
802 appGUI->nte->buffer_check_modify_enable = TRUE;
803
804 g_free(txtnote);
805 g_free(current_filename);
806 }
807
808 /*------------------------------------------------------------------------------*/
809
810 #ifdef HAVE_LIBGRINGOTTS
811
812 void
notes_enter_password_action_cb(GtkWidget * widget,gpointer data)813 notes_enter_password_action_cb (GtkWidget *widget, gpointer data) {
814
815 gchar *pass, *current_filename;
816 GtkTreeIter iter;
817 GtkTreeModel *model;
818 GtkTextBuffer *buffer;
819 unsigned char *txtnote;
820 long txtlen;
821 gint ret;
822
823 GUI *appGUI = (GUI *) data;
824
825 pass = g_strdup(gtk_entry_get_text(GTK_ENTRY(appGUI->nte->password_entry)));
826
827 notes_enter_password_close_cb(widget, NULL, data);
828
829 iter = utl_gui_get_first_selection_iter(appGUI->nte->notes_list_selection, &model);
830
831 gtk_tree_model_get(GTK_TREE_MODEL(model), &iter, N_COLUMN_FILENAME, ¤t_filename, -1);
832
833 appGUI->nte->filename = g_strdup(notes_get_full_filename(current_filename, appGUI));
834 appGUI->nte->context = grg_context_initialize_defaults((unsigned char*) "OSM");
835 appGUI->nte->keyholder = grg_key_gen((unsigned char*) pass, -1);
836
837 grg_ctx_set_crypt_algo(appGUI->nte->context, get_enc_algorithm_value());
838 grg_ctx_set_hash_algo(appGUI->nte->context, get_enc_hashing_value());
839 grg_ctx_set_comp_algo(appGUI->nte->context, get_comp_algorithm_value());
840 grg_ctx_set_comp_ratio(appGUI->nte->context, get_comp_ratio_value());
841
842 ret = grg_decrypt_file(appGUI->nte->context, appGUI->nte->keyholder,
843 (unsigned char *) appGUI->nte->filename, &txtnote, &txtlen);
844
845 if (ret != GRG_OK) {
846 utl_gui_create_dialog(GTK_MESSAGE_ERROR, _("Incorrect password!"), GTK_WINDOW(appGUI->main_window));
847 g_free(pass);
848 grg_key_free(appGUI->nte->context, appGUI->nte->keyholder);
849 appGUI->nte->keyholder = NULL;
850 grg_context_free(appGUI->nte->context);
851 appGUI->nte->context = NULL;
852 g_free(appGUI->nte->filename);
853 appGUI->nte->filename = NULL;
854 return;
855 } else {
856 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(appGUI->nte->editor_textview));
857 utl_gui_text_buffer_set_text_with_tags(buffer, (const gchar *) txtnote, TRUE);
858 notes_show_selector_editor(EDITOR, appGUI);
859 appGUI->nte->buffer_check_modify_enable = TRUE;
860 }
861
862 if(txtnote) {
863 grg_free(appGUI->nte->context, txtnote, txtlen);
864 }
865
866 g_free(current_filename);
867 g_free(pass);
868 }
869
870
871 /*------------------------------------------------------------------------------*/
872
873 gint
notes_enter_password_key_press_cb(GtkWidget * widget,GdkEventKey * event,gpointer data)874 notes_enter_password_key_press_cb (GtkWidget *widget, GdkEventKey *event, gpointer data) {
875
876 GUI *appGUI = (GUI *)data;
877
878 if (event->keyval == GDK_KEY_Escape) {
879 notes_enter_password_close_cb (NULL, NULL, appGUI);
880 return TRUE;
881 } else if (event->keyval == GDK_KEY_Return) {
882 notes_enter_password_action_cb (NULL, appGUI);
883 return TRUE;
884 }
885 return FALSE;
886 }
887
888 #endif /* HAVE_LIBGRINGOTTS */
889
890 /*------------------------------------------------------------------------------*/
891
892 void
notes_enter_password(GUI * appGUI)893 notes_enter_password (GUI *appGUI) {
894
895 gchar tmpbuf[BUFFER_SIZE];
896
897 GtkTreeIter iter;
898 GtkTreeModel *model;
899 gchar *current_filename;
900
901 #ifdef HAVE_LIBGRINGOTTS
902 GtkWidget *frame;
903 GtkWidget *ok_button;
904 GtkWidget *cancel_button;
905 GtkWidget *label;
906 GtkWidget *vbox1;
907 GtkWidget *hseparator;
908 GtkWidget *hbuttonbox;
909 #endif /* HAVE_LIBGRINGOTTS */
910
911 iter = utl_gui_get_first_selection_iter(appGUI->nte->notes_list_selection, &model);
912 gtk_tree_model_get (model, &iter, N_COLUMN_FILENAME, ¤t_filename, -1);
913
914 #ifndef HAVE_LIBGRINGOTTS
915
916 if (check_if_encrypted (current_filename, appGUI) == TRUE) {
917
918 g_snprintf (tmpbuf, BUFFER_SIZE, "%s\n\n(%s)", _("Cannot open the note."), _("encryption support is disabled"));
919 utl_gui_create_dialog (GTK_MESSAGE_ERROR, tmpbuf, GTK_WINDOW(appGUI->main_window));
920 g_free (current_filename);
921 return;
922
923 } else {
924 appGUI->nte->encrypted = FALSE;
925 appGUI->nte->changed = FALSE;
926 notes_enter_editor_action (appGUI);
927 }
928
929 #else
930
931 if (check_if_encrypted (current_filename, appGUI) == TRUE) {
932
933 appGUI->nte->encrypted = TRUE;
934
935 appGUI->nte->enter_password_window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
936 gtk_container_set_border_width (GTK_CONTAINER (appGUI->nte->enter_password_window), 4);
937 gtk_window_set_title (GTK_WINDOW (appGUI->nte->enter_password_window), _("Authorization"));
938 gtk_window_set_default_size (GTK_WINDOW(appGUI->nte->enter_password_window), 350, -1);
939 if (config.fullscreen == FALSE) {
940 gtk_window_set_transient_for(GTK_WINDOW(appGUI->nte->enter_password_window), GTK_WINDOW(appGUI->main_window));
941 }
942 gtk_window_set_position(GTK_WINDOW(appGUI->nte->enter_password_window), GTK_WIN_POS_CENTER_ON_PARENT);
943 gtk_window_set_modal(GTK_WINDOW(appGUI->nte->enter_password_window), TRUE);
944 g_signal_connect (G_OBJECT (appGUI->nte->enter_password_window), "delete_event",
945 G_CALLBACK(notes_enter_password_close_cb), appGUI);
946 g_signal_connect (G_OBJECT (appGUI->nte->enter_password_window), "key_press_event",
947 G_CALLBACK (notes_enter_password_key_press_cb), appGUI);
948
949 vbox1 = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
950 gtk_widget_show (vbox1);
951 gtk_container_add (GTK_CONTAINER (appGUI->nte->enter_password_window), vbox1);
952
953 frame = gtk_frame_new (NULL);
954 gtk_widget_show (frame);
955 gtk_box_pack_start (GTK_BOX (vbox1), frame, FALSE, FALSE, 0);
956 gtk_frame_set_shadow_type (GTK_FRAME (frame), GTK_SHADOW_NONE);
957
958 appGUI->nte->password_entry = gtk_entry_new ();
959 gtk_widget_show (appGUI->nte->password_entry);
960 gtk_container_add (GTK_CONTAINER (frame), appGUI->nte->password_entry);
961 gtk_widget_set_margin_left(appGUI->nte->password_entry, 16);
962 gtk_widget_set_margin_right(appGUI->nte->password_entry, 4);
963 gtk_widget_set_margin_top(appGUI->nte->password_entry, 4);
964 gtk_widget_set_margin_bottom(appGUI->nte->password_entry, 4);
965 gtk_entry_set_invisible_char (GTK_ENTRY (appGUI->nte->password_entry), 8226);
966 gtk_entry_set_visibility (GTK_ENTRY (appGUI->nte->password_entry), FALSE);
967
968 g_snprintf(tmpbuf, BUFFER_SIZE, "<b>%s:</b>", _("Enter password"));
969 label = gtk_label_new (tmpbuf);
970 gtk_widget_show (label);
971 gtk_frame_set_label_widget (GTK_FRAME (frame), label);
972 gtk_label_set_use_markup (GTK_LABEL (label), TRUE);
973
974 hseparator = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
975 gtk_widget_show (hseparator);
976 gtk_box_pack_start (GTK_BOX (vbox1), hseparator, FALSE, TRUE, 4);
977
978 hbuttonbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
979 gtk_widget_show (hbuttonbox);
980 gtk_box_pack_start (GTK_BOX (vbox1), hbuttonbox, FALSE, FALSE, 0);
981 gtk_button_box_set_layout (GTK_BUTTON_BOX (hbuttonbox), GTK_BUTTONBOX_END);
982 gtk_box_set_spacing (GTK_BOX (hbuttonbox), 4);
983
984 cancel_button = gtk_button_new_with_mnemonic (_("_Cancel"));
985 gtk_widget_set_can_focus(cancel_button, FALSE);
986 gtk_widget_show (cancel_button);
987 gtk_container_add (GTK_CONTAINER (hbuttonbox), cancel_button);
988 g_signal_connect (G_OBJECT (cancel_button), "clicked",
989 G_CALLBACK (button_enter_password_close_cb), appGUI);
990
991 ok_button = gtk_button_new_with_mnemonic (_("_OK"));
992 gtk_widget_set_can_focus(ok_button, FALSE);
993 gtk_widget_show (ok_button);
994 gtk_container_add (GTK_CONTAINER (hbuttonbox), ok_button);
995 g_signal_connect (G_OBJECT (ok_button), "clicked",
996 G_CALLBACK (notes_enter_password_action_cb), appGUI);
997
998 gtk_widget_show (appGUI->nte->enter_password_window);
999
1000 } else {
1001 appGUI->nte->encrypted = FALSE;
1002 appGUI->nte->changed = FALSE;
1003 notes_enter_editor_action (appGUI);
1004 }
1005
1006 #endif /* HAVE_LIBGRINGOTTS */
1007
1008 g_free (current_filename);
1009 }
1010
1011 /*------------------------------------------------------------------------------*/
1012
1013 void
read_notes_entries(GUI * appGUI)1014 read_notes_entries (GUI *appGUI) {
1015
1016 xmlDocPtr doc;
1017 xmlChar *key;
1018 xmlNodePtr node, cnode, category_node, main_node;
1019 GtkTreeIter iter;
1020 gchar *name, *category, *create_date_str, *fontname;
1021 gchar *notes_dir, *str, *dir, *fullpath;
1022 gint last_changes_time, create_time, editor_line;
1023 guint32 last_changes_date_julian, create_date_julian;
1024 gboolean remember_editor_line, editor_readonly;
1025
1026 notes_dir = g_strdup(prefs_get_data_filename(NOTES_DIRNAME, appGUI));
1027 if (g_file_test (notes_dir, G_FILE_TEST_IS_DIR | G_FILE_TEST_EXISTS) == FALSE) {
1028 g_mkdir (notes_dir, 0755);
1029 }
1030 g_free(notes_dir);
1031
1032 if (g_file_test (prefs_get_data_filename(NOTES_ENTRIES_FILENAME, appGUI), G_FILE_TEST_IS_REGULAR) == FALSE)
1033 return;
1034
1035 if((doc = xmlParseFile(prefs_get_data_filename(NOTES_ENTRIES_FILENAME, appGUI)))) {
1036
1037 if(!(node = xmlDocGetRootElement(doc))) {
1038 xmlFreeDoc(doc);
1039 return;
1040 }
1041
1042 if (xmlStrcmp(node->name, (const xmlChar *) NOTES_NAME)) {
1043 xmlFreeDoc(doc);
1044 return;
1045 }
1046
1047 main_node = node->xmlChildrenNode;
1048
1049 while (main_node != NULL) {
1050
1051 if(!xmlStrcmp(main_node->name, (xmlChar *) NOTES_CATEGORY_ENTRIES_NAME)) {
1052
1053 /* read note */
1054 category_node = main_node->xmlChildrenNode;
1055
1056 while (category_node != NULL) {
1057
1058 if ((!xmlStrcmp(category_node->name, (const xmlChar *) "name"))) {
1059 key = xmlNodeListGetString(doc, category_node->xmlChildrenNode, 1);
1060 if (key != NULL) {
1061 gtk_list_store_append(appGUI->opt->notes_category_store, &iter);
1062 gtk_list_store_set(appGUI->opt->notes_category_store, &iter, 0, (gchar *) key, -1);
1063 }
1064 xmlFree(key);
1065 }
1066
1067 category_node = category_node->next;
1068 }
1069 }
1070
1071 /*---------------------------------------------------------------------------------------*/
1072
1073 if(!xmlStrcmp(main_node->name, (xmlChar *) NOTES_ENTRIES_NAME)) {
1074
1075 /* read note */
1076 node = main_node->xmlChildrenNode;
1077
1078 while (node != NULL) {
1079
1080 if(!xmlStrcmp(node->name, (xmlChar *) "entry")) {
1081
1082 cnode = node->xmlChildrenNode;
1083
1084 remember_editor_line = FALSE;
1085 editor_readonly = FALSE;
1086 editor_line = 0;
1087 fontname = NULL;
1088
1089 while (cnode != NULL) {
1090
1091 utl_xml_get_str ("name", &name, cnode);
1092 utl_xml_get_str ("category", &category, cnode);
1093 utl_xml_get_uint ("last_changes_date", &last_changes_date_julian, cnode);
1094 utl_xml_get_int ("last_changes_time", &last_changes_time, cnode);
1095 utl_xml_get_uint ("create_date", &create_date_julian, cnode);
1096 utl_xml_get_int ("create_time", &create_time, cnode);
1097 utl_xml_get_int ("remember_editor_line", &remember_editor_line, cnode);
1098 utl_xml_get_int ("editor_line", &editor_line, cnode);
1099 utl_xml_get_int ("read_only", &editor_readonly, cnode);
1100 utl_xml_get_str ("fontname", &fontname, cnode);
1101
1102 if ((!xmlStrcmp(cnode->name, (const xmlChar *) "filename"))) {
1103 key = xmlNodeListGetString(doc, cnode->xmlChildrenNode, 1);
1104 if (key != NULL) {
1105
1106 str = g_path_get_basename ((gchar *) key);
1107 dir = g_path_get_dirname ((gchar *) key);
1108
1109 if (str && dir) {
1110
1111 if (dir[0] == '.') {
1112 fullpath = g_strdup (notes_get_full_filename (str, appGUI));
1113 } else {
1114 fullpath = (gchar *) key;
1115 }
1116
1117 gtk_list_store_append (appGUI->nte->notes_list_store, &iter);
1118
1119 create_date_str = g_strdup(get_date_time_str (create_date_julian, create_time));
1120
1121 if (fontname == NULL) {
1122 fontname = g_strdup(DEFAULT_NOTE_FONT);
1123 }
1124
1125 gtk_list_store_set (appGUI->nte->notes_list_store, &iter,
1126 N_COLUMN_NAME, name,
1127 N_COLUMN_CATEGORY, category,
1128 N_COLUMN_LAST_CHANGES_DATE, get_date_time_str (last_changes_date_julian, last_changes_time),
1129 N_COLUMN_LAST_CHANGES_DATE_JULIAN, last_changes_date_julian,
1130 N_COLUMN_LAST_CHANGES_TIME, last_changes_time,
1131 N_COLUMN_CREATE_DATE, create_date_str,
1132 N_COLUMN_CREATE_DATE_JULIAN, create_date_julian,
1133 N_COLUMN_CREATE_TIME, create_time,
1134 N_COLUMN_REMEMBER_EDITOR_LINE, remember_editor_line,
1135 N_COLUMN_FONTNAME, fontname,
1136 N_COLUMN_EDITOR_LINE, editor_line,
1137 N_COLUMN_EDITOR_READONLY, editor_readonly, -1);
1138
1139 g_free (create_date_str);
1140
1141 if (dir[0] == '.') {
1142 gtk_list_store_set (appGUI->nte->notes_list_store, &iter,
1143 N_COLUMN_FILENAME, (gchar *)key, -1);
1144 g_free (fullpath);
1145 } else {
1146 gtk_list_store_set (appGUI->nte->notes_list_store, &iter,
1147 N_COLUMN_FILENAME, str, -1);
1148 }
1149
1150 g_free (str);
1151 g_free (dir);
1152 g_free (name);
1153 g_free (fontname);
1154 g_free (category);
1155
1156 fontname = NULL;
1157 }
1158 xmlFree (key);
1159 }
1160 }
1161
1162 cnode = cnode->next;
1163 }
1164
1165 }
1166
1167 node = node->next;
1168 }
1169
1170 }
1171
1172 /*---------------------------------------------------------------------------------------*/
1173
1174 main_node = main_node->next;
1175 }
1176
1177 xmlFree(node);
1178 xmlFreeDoc(doc);
1179
1180 notes_cleanup_files (appGUI);
1181 check_notes_type (appGUI);
1182 }
1183
1184 }
1185
1186 /*------------------------------------------------------------------------------*/
1187
1188 void
write_notes_entries(GUI * appGUI)1189 write_notes_entries (GUI *appGUI) {
1190
1191 xmlDocPtr doc;
1192 xmlNodePtr main_node, node, note_node;
1193 xmlAttrPtr attr;
1194 GtkTreeIter iter;
1195 gchar *category, *name, *note_filename, *note_fontname;
1196 gint last_changes_time, create_time, editor_line;
1197 guint32 last_changes_date_julian, create_date_julian;
1198 gboolean remember_editor_line, editor_readonly, has_next;
1199 xmlChar *escaped;
1200
1201 if ((appGUI->save_status & WRT_NOTES) != 0) return;
1202
1203 appGUI->save_status |= WRT_NOTES;
1204
1205 doc = xmlNewDoc((const xmlChar *) "1.0");
1206 attr = xmlNewDocProp (doc, (const xmlChar *) "encoding", (const xmlChar *) "utf-8");
1207
1208 main_node = xmlNewNode(NULL, (const xmlChar *) NOTES_NAME);
1209 xmlDocSetRootElement(doc, main_node);
1210
1211 node = xmlNewChild(main_node, NULL, (const xmlChar *) NOTES_CATEGORY_ENTRIES_NAME, (xmlChar *) NULL);
1212
1213 has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(appGUI->opt->notes_category_store), &iter);
1214 while (has_next) {
1215
1216 gtk_tree_model_get(GTK_TREE_MODEL(appGUI->opt->notes_category_store), &iter, 0, &category, -1);
1217 escaped = xmlEncodeEntitiesReentrant(doc, (const xmlChar *) category);
1218 xmlNewChild(node, NULL, (const xmlChar *) "name", (xmlChar *) escaped);
1219 g_free(category);
1220 xmlFree (escaped);
1221 has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL(appGUI->opt->notes_category_store), &iter);
1222 }
1223
1224 node = xmlNewChild(main_node, NULL, (const xmlChar *) NOTES_ENTRIES_NAME, (xmlChar *) NULL);
1225
1226 has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (appGUI->nte->notes_list_store), &iter);
1227 while (has_next) {
1228
1229 gtk_tree_model_get (GTK_TREE_MODEL (appGUI->nte->notes_list_store), &iter,
1230 N_COLUMN_NAME, &name,
1231 N_COLUMN_CATEGORY, &category,
1232 N_COLUMN_LAST_CHANGES_DATE_JULIAN, &last_changes_date_julian,
1233 N_COLUMN_LAST_CHANGES_TIME, &last_changes_time,
1234 N_COLUMN_CREATE_DATE_JULIAN, &create_date_julian,
1235 N_COLUMN_CREATE_TIME, &create_time,
1236 N_COLUMN_REMEMBER_EDITOR_LINE, &remember_editor_line,
1237 N_COLUMN_EDITOR_LINE, &editor_line,
1238 N_COLUMN_EDITOR_READONLY, &editor_readonly,
1239 N_COLUMN_FONTNAME, ¬e_fontname,
1240 N_COLUMN_FILENAME, ¬e_filename, -1);
1241
1242 note_node = xmlNewChild (node, NULL, (const xmlChar *) "entry", (xmlChar *) NULL);
1243
1244 utl_xml_put_str ("name", name, note_node);
1245 g_free (name);
1246 utl_xml_put_str ("category", category, note_node);
1247 g_free (category);
1248 utl_xml_put_uint ("last_changes_date", last_changes_date_julian, note_node);
1249 utl_xml_put_int ("last_changes_time", last_changes_time, note_node);
1250 utl_xml_put_uint ("create_date", create_date_julian, note_node);
1251 utl_xml_put_int ("create_time", create_time, note_node);
1252 utl_xml_put_int ("remember_editor_line", remember_editor_line, note_node);
1253 utl_xml_put_int ("editor_line", editor_line, note_node);
1254 utl_xml_put_int ("read_only", editor_readonly, note_node);
1255 utl_xml_put_str ("fontname", note_fontname, note_node);
1256 g_free (note_fontname);
1257 utl_xml_put_str ("filename", note_filename, note_node);
1258 g_free (note_filename);
1259 has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL (appGUI->nte->notes_list_store), &iter);
1260 }
1261
1262 utl_xml_write_doc (prefs_get_data_filename (NOTES_ENTRIES_FILENAME, appGUI), doc);
1263 xmlFreeProp (attr);
1264 xmlFreeDoc (doc);
1265
1266 appGUI->save_status &= ~WRT_NOTES;
1267 }
1268
1269 /*------------------------------------------------------------------------------*/
1270
1271 gchar *
notes_get_new_filename(GUI * appGUI)1272 notes_get_new_filename (GUI *appGUI) {
1273
1274 guint i;
1275 static gchar fullpath[PATH_MAX];
1276
1277 for(i=0; i < 99999999; i++) {
1278 g_snprintf(fullpath, PATH_MAX-1, "%s%c%08d.osm",
1279 prefs_get_data_filename(NOTES_DIRNAME, appGUI), G_DIR_SEPARATOR, i);
1280 if (g_file_test (fullpath, G_FILE_TEST_EXISTS) == FALSE) break;
1281 }
1282
1283 g_snprintf(fullpath, PATH_MAX-1, "%08d.osm", i);
1284
1285 return fullpath;
1286 }
1287
1288 /*------------------------------------------------------------------------------*/
1289
1290 void
notes_cleanup_files(GUI * appGUI)1291 notes_cleanup_files (GUI *appGUI) {
1292
1293 gchar fullpath[PATH_MAX];
1294 GDir *dpath;
1295 gboolean found;
1296 const gchar *item_name;
1297 gchar *note_filename;
1298 GtkTreeIter iter;
1299
1300 g_snprintf(fullpath, PATH_MAX-1, "%s", prefs_get_data_filename(NOTES_DIRNAME, appGUI));
1301 dpath = g_dir_open (fullpath, 0, NULL);
1302
1303 if (dpath != NULL) {
1304
1305 while ((item_name = g_dir_read_name (dpath)) != NULL) {
1306 gboolean has_next;
1307
1308 found = FALSE;
1309
1310 g_snprintf(fullpath, PATH_MAX-1, "%s%c%s",
1311 prefs_get_data_filename(NOTES_DIRNAME, appGUI), G_DIR_SEPARATOR, item_name);
1312
1313 has_next = gtk_tree_model_get_iter_first (GTK_TREE_MODEL(appGUI->nte->notes_list_store), &iter);
1314 while (has_next) {
1315
1316 gtk_tree_model_get(GTK_TREE_MODEL(appGUI->nte->notes_list_store), &iter,
1317 N_COLUMN_FILENAME, ¬e_filename, -1);
1318
1319 if (!strncmp(notes_get_full_filename(note_filename, appGUI), fullpath, PATH_MAX)) {
1320 found = TRUE;
1321 g_free(note_filename);
1322 break;
1323 }
1324
1325 g_free(note_filename);
1326 has_next = gtk_tree_model_iter_next (GTK_TREE_MODEL(appGUI->nte->notes_list_store), &iter);
1327 }
1328
1329 if (found == FALSE) {
1330 g_unlink (fullpath);
1331 }
1332
1333 }
1334
1335 g_dir_close (dpath);
1336 }
1337
1338 }
1339
1340 /*------------------------------------------------------------------------------*/
1341
1342 gchar *
notes_get_full_filename(gchar * filename,GUI * appGUI)1343 notes_get_full_filename (gchar *filename, GUI *appGUI) {
1344
1345 static gchar fullname[PATH_MAX];
1346 gchar *str;
1347
1348 g_snprintf (fullname, PATH_MAX-1, "%s%c%s",
1349 prefs_get_data_filename(NOTES_DIRNAME, appGUI), G_DIR_SEPARATOR, filename);
1350
1351 if (g_file_test (fullname, G_FILE_TEST_IS_REGULAR | G_FILE_TEST_EXISTS) == FALSE) {
1352
1353 str = g_path_get_basename (fullname);
1354
1355 if (str) {
1356 g_snprintf (fullname, PATH_MAX-1, "%s%c%s",
1357 prefs_get_data_filename(NOTES_DIRNAME, appGUI), G_DIR_SEPARATOR, str);
1358 g_free (str);
1359 }
1360 }
1361
1362 return fullname;
1363 }
1364
1365 /*------------------------------------------------------------------------------*/
1366
1367 #endif /* NOTES_ENABLED */
1368
1369