diff --git a/glade/mainWindow.glade b/glade/mainWindow.glade
index 52821f4..d11e5c0 100644
--- a/glade/mainWindow.glade
+++ b/glade/mainWindow.glade
@@ -8,6 +8,11 @@
False
changes-prevent-symbolic.symbolic
+
diff --git a/src/mainwindow.c b/src/mainwindow.c
index 9e23f63..99b2ccd 100644
--- a/src/mainwindow.c
+++ b/src/mainwindow.c
@@ -250,6 +250,8 @@ static void mainWindow_configure_treeView(struct mainWindow *mainWindow)
G_TYPE_POINTER,
G_TYPE_STRING,
G_TYPE_STRING,
+ G_TYPE_STRING,
+ G_TYPE_STRING,
G_TYPE_STRING);
mainWindow->entryListFiltered = GTK_TREE_MODEL_FILTER(gtk_tree_model_filter_new(
GTK_TREE_MODEL(mainWindow->entryListStore),
@@ -425,6 +427,10 @@ static void mainWindow_connect_signals(struct mainWindow *mainWindow)
"clicked",
(GCallback) mainWindow_decrypt_gpg_clicked,
mainWindow);
+ g_signal_connect(mainWindow->buttonUpdateGpg,
+ "clicked",
+ (GCallback) mainWindow_update_gpg_clicked,
+ mainWindow);
g_signal_connect(mainWindow->summaryEventBox,
"button-press-event",
@@ -655,6 +661,7 @@ struct mainWindow *mainWindow_new()
mainWindow->labelDateToDate = GTK_WIDGET(gtk_builder_get_object(builder, "label_date_to_date"));
mainWindow->buttonNew = GTK_WIDGET(gtk_builder_get_object(builder, "buttonNew"));
mainWindow->buttonDecrypt = GTK_WIDGET(gtk_builder_get_object(builder, "buttonDecrypt"));
+ mainWindow->buttonUpdateGpg = GTK_WIDGET(gtk_builder_get_object(builder, "buttonUpdateGpg"));
mainWindow->stackRenderMode = GTK_WIDGET(gtk_builder_get_object(builder, "stackRenderMode"));
mainWindow->entryListView = GTK_TREE_VIEW(gtk_builder_get_object(builder, "entryListView"));
mainWindow->entryListSelection = GTK_TREE_SELECTION(gtk_builder_get_object(builder, "entryListSelection"));
@@ -854,6 +861,23 @@ static void mainWindow_set_text(struct mainWindow *mainWindow, gchar *text, gcha
}
}
+/**
+ * @brief mainWindow_getTempFile returns the path to the temporary file (may not exist) for the entry generated from its UUID
+ * @param uuid the UUID
+ * @return the full path th
+ */
+gchar *mainWindow_getTempFile(gchar *uuid)
+{
+ GString *tempfile = NULL;
+ gchar *str = NULL;
+
+ tempfile = g_string_new("");
+ g_string_printf(tempfile, "/tmp/%s.mdiary", uuid);
+ str = tempfile->str;
+ g_string_free(tempfile, false);
+ return str;
+}
+
/**
* @brief mainWindow_entrySelected is the callback when the user selects a diary entry.
* @param widget N/A
@@ -870,6 +894,7 @@ void mainWindow_entrySelected(GtkWidget *widget, gpointer user_data)
gchar *title;
gchar *summary;
gchar *temp;
+ gchar *tempfile;
selection = gtk_tree_view_get_selection(mainWindow->entryListView);
if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
@@ -887,6 +912,14 @@ void mainWindow_entrySelected(GtkWidget *widget, gpointer user_data)
g_free(title);
g_free(summary);
g_free(temp);
+
+ /* Check for GPG update */
+ gtk_tree_model_get(model, &iter, COL_UUID, &temp, -1);
+ tempfile = mainWindow_getTempFile(temp);
+ gtk_widget_set_visible(mainWindow->buttonUpdateGpg,
+ (g_file_test(tempfile, G_FILE_TEST_EXISTS)));
+ g_free(tempfile);
+ g_free(temp);
} else {
mainWindow_set_text(mainWindow, "", "");
gtk_label_set_text(GTK_LABEL(mainWindow->labelSummary), "Please select an entry in the list above.");
@@ -904,7 +937,7 @@ void mainWindow_openExternalEditor(gchar *path)
GAppInfo *info;
GList *files = NULL;
- g_info("Opening entry in external editor.");
+ g_warning("Opening entry %s in external editor.", path);
file = g_file_new_for_path(path);
info = g_file_query_default_handler(file, NULL, NULL);
files = g_list_append(files, (gpointer) file);
@@ -926,12 +959,54 @@ void mainWindow_entryActivated(GtkWidget *widget, GtkTreePath *path, GtkTreeView
GtkTreeIter iter;
GtkTreeView *treeview = (GtkTreeView*) widget;
gchar *name;
+ gchar *ext;
+ gchar *tempfile;
+ gchar *uuid;
+ gchar *content;
+ FILE *fd;
model = gtk_tree_view_get_model(treeview);
if (gtk_tree_model_get_iter(model, &iter, path)) {
gtk_tree_model_get(model, &iter, COL_URL, &name, -1);
- mainWindow_openExternalEditor(name);
+ if (!name)
+ return;
+
+ ext = strrchr(name, '.');
+ if (!strcmp(ext, ".gpg")) { /* Encrypted file -> Create decrypted copy in /tmp */
+ gtk_tree_model_get(model, &iter, COL_UUID, &uuid, -1);
+ if (uuid) {
+ tempfile = mainWindow_getTempFile(uuid);
+ fd = fopen(tempfile, "r");
+ if (false) {
+ g_warning("Decryption target already exists. Leaving as is and opening.");
+ fclose(fd);
+ } else {
+ fd = fopen(tempfile, "w");
+ if (fd) {
+ gtk_tree_model_get(model, &iter, COL_HEADER, &content, -1);
+ fputs(content, fd);
+ fputs("\n", fd);
+ g_free(content);
+
+ gtk_tree_model_get(model, &iter, COL_TEXT, &content, -1);
+ fputs(content, fd);
+ g_free(content);
+
+ fclose(fd);
+ } else {
+ g_error("Could not open decryption target.");
+ }
+ }
+
+ mainWindow_openExternalEditor(tempfile);
+ g_free(tempfile);
+ g_free(uuid);
+ }
+ } else { /* Regular file -> Open directly */
+ mainWindow_openExternalEditor(name);
+ }
+
g_free(name);
}
}
@@ -1283,6 +1358,17 @@ void mainWindow_decrypt_gpg_clicked(GtkWidget *widget, gpointer user_data)
}
}
+void mainWindow_update_gpg_clicked(GtkWidget *widget, gpointer user_data)
+{
+ struct mainWindow *mainWindow = (struct mainWindow *)user_data;
+ gtk_widget_set_visible(mainWindow->buttonUpdateGpg, false);
+ g_print("Not yet implemented.");
+
+ // Delete .bak if exists
+ // Move existing GPG to .bak
+ // encrypt tmp/uuid file to
+}
+
/**
* @brief mainWindow_toggleSummaryWrap toggles line-wrapping and ellipsize on the summary
* @param widget
diff --git a/src/mainwindow.h b/src/mainwindow.h
index 6c46d29..853abea 100644
--- a/src/mainwindow.h
+++ b/src/mainwindow.h
@@ -47,6 +47,7 @@ struct mainWindow {
GtkWidget *labelDateToDate;
GtkWidget *buttonNew;
GtkWidget *buttonDecrypt;
+ GtkWidget *buttonUpdateGpg;
GtkWidget *webkitView;
GtkWidget *webkitScrollArea;
GtkWidget *stackRenderMode;
@@ -122,6 +123,7 @@ void mainWindow_add_recent_workspace(struct mainWindow *mainWindow, gchar *path,
void mainWindow_switch_workspace(struct mainWindow *mainWindow, gchar *path, gboolean gpg_enabled);
void mainWindow_new_entry_clicked(GtkWidget *widget, gpointer user_data);
void mainWindow_decrypt_gpg_clicked(GtkWidget *widget, gpointer user_data);
+void mainWindow_update_gpg_clicked(GtkWidget *widget, gpointer user_data);
void mainWindow_renderer_set(struct mainWindow *mainWindow, enum renderer_mode state);
void mainWindow_settings_show(struct mainWindow *mainWindow);
gboolean mainWindow_toggleSummaryWrap(GtkWidget *widget, GdkEvent *event, gpointer user_data);
diff --git a/src/mdiary.c b/src/mdiary.c
index 5fe10aa..ad33c17 100644
--- a/src/mdiary.c
+++ b/src/mdiary.c
@@ -261,6 +261,7 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
GList *tagList = NULL;
gchar *summary = NULL;
GString *text = NULL;
+ GString *header = NULL;
guint header_state = 0;
GList *l;
@@ -284,6 +285,13 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
while (line = (content ? mdiary_get_line_from_string(&content_ptr) :
g_data_input_stream_read_line(G_DATA_INPUT_STREAM(dstream), NULL, NULL, NULL))) {
if (header_state == 0) {
+ if (header) {
+ header = g_string_append(header, "\n");
+ header = g_string_append(header, line);
+ } else {
+ header = g_string_new(line);
+ }
+
if (!datetime) {
datetime = mdiary_get_date_from_string_ext(line, "Date: ", "");
if (datetime)
@@ -331,6 +339,10 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
g_warning("PARSER: Could not find any text in file!\n");
text = g_string_new("No content found.");
}
+ if (!header) {
+ g_warning("PARSER: Could not find any header in file!\n");
+ text = g_string_new("No header found.");
+ }
if (!summary) {
g_warning("PARSER: Could not detect summary in file!\n");
summary = g_strdup("No summary found.");
@@ -354,6 +366,7 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
tagList,
summary,
text->str,
+ header->str,
filename);
if (g_date_time_to_unix(datetime) > mdiary_scanner->time_latest)
@@ -368,7 +381,8 @@ static void mdiary_add_file_to_store(struct mdiary_scanner *mdiary_scanner,
}
g_list_free_full(tagList, *g_free);
- g_string_free(text, 0);
+ g_string_free(text, 1);
+ g_string_free(header, 1);
g_free(summary);
g_free(title);
g_date_time_unref(datetime);
@@ -578,6 +592,7 @@ void mdiary_add_entry_to_store(GtkListStore *entryListStore,
GList *tags,
gchar *summary,
gchar *text,
+ gchar *header,
gchar *file_url)
{
GtkTreeIter iter;
@@ -585,6 +600,7 @@ void mdiary_add_entry_to_store(GtkListStore *entryListStore,
GList *taglist_copy;
gchar *date_text;
gchar *taglistString;
+ gchar *uuid;
GList *l;
struct tag_compare_struct tag_compare_struct = { .text = "", .result = FALSE };
@@ -593,6 +609,7 @@ void mdiary_add_entry_to_store(GtkListStore *entryListStore,
date_text = g_date_time_format(datetime_copy, "%A, %e %B %Y %R");
taglist_copy = g_list_copy_deep(tags, (GCopyFunc) g_strdup, NULL);
taglistString = mdiary_taglist_to_string(taglist_copy);
+ uuid = g_compute_checksum_for_data(G_CHECKSUM_SHA256, (guchar *) file_url, strlen(file_url));
gtk_list_store_append(entryListStore, &iter);
gtk_list_store_set(entryListStore, &iter,
@@ -603,9 +620,12 @@ void mdiary_add_entry_to_store(GtkListStore *entryListStore,
COL_TAGLIST, taglist_copy, /* TODO: Verify that the duplication worked! */
COL_SUMMARY, summary, /* Automatically strdupd */
COL_TEXT, text, /* Automatically strdupd */
+ COL_HEADER, header, /* Automatically strdupd */
COL_URL, file_url, /* Automatically strdupd */
+ COL_UUID, uuid, /* Automatically strdupd */
-1);
g_free(date_text);
+ g_free(uuid);
for (l = tags; l != NULL; l = l->next) {
tag_compare_struct.text = l->data;
diff --git a/src/mdiary.h b/src/mdiary.h
index 558e527..01594f9 100644
--- a/src/mdiary.h
+++ b/src/mdiary.h
@@ -16,7 +16,9 @@ enum {
COL_TAGLIST, /* GList of the tags */
COL_SUMMARY, /* Summary of the entry */
COL_TEXT, /* Raw text from the file */
+ COL_HEADER, /* Raw header from the file */
COL_URL, /* Path to the file */
+ COL_UUID, /* UUID of the file */
COL_COUNT
};
@@ -42,6 +44,7 @@ void mdiary_add_entry_to_store(GtkListStore *entryListStore,
GList *tags,
gchar *summary,
gchar *text,
+ gchar *header,
gchar *file_url);
GDateTime *mdiary_get_date_from_string_ext(gchar *string, gchar *prefix, gchar *suffix);
GDateTime *mdiary_get_date_from_string(gchar *string);