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, &current_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, &current_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, &current_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, &note_fontname,
1240 		                    N_COLUMN_FILENAME, &note_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, &note_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