diff --git a/src/main.c b/src/main.c index af61136..d358c17 100644 --- a/src/main.c +++ b/src/main.c @@ -13,7 +13,7 @@ int main(int argc, char *argv[]) mainWindow = mainWindow_new(); gtk_widget_show(mainWindow->mainWindow); - mdiary_scan_to_store(argv[1], mainWindow->entryListStore); + mdiary_scan_to_store(argv[1], mainWindow->entryListStore, mainWindow->completionListStore); mainWindow_set_meta_information(mainWindow, mdiary_get_time_earliest(), mdiary_get_time_latest(), FALSE); gtk_main(); diff --git a/src/mainwindow.c b/src/mainwindow.c index 891f8e3..91eeab9 100644 --- a/src/mainwindow.c +++ b/src/mainwindow.c @@ -269,6 +269,31 @@ static void mainWindow_configure_treeView(struct mainWindow *mainWindow) gtk_tree_sortable_set_sort_column_id(sortable, COL_DATE_TEXT, GTK_SORT_DESCENDING); } +static void mainWindow_configure_entry_completion(struct mainWindow *mainWindow) +{ + GtkCellRenderer *renderer; + GtkTreeSortable *sortable; + GtkTreeModelSort *sorted; + GtkTreeModel *model; + GtkTreeIter iter; + + mainWindow->completionListStore = gtk_list_store_new(1, G_TYPE_STRING); + sorted = GTK_TREE_MODEL_SORT(gtk_tree_model_sort_new_with_model( + GTK_TREE_MODEL(mainWindow->completionListStore))); + model = GTK_TREE_MODEL(sorted); + + /* TODO: Unref mainWindow->completionListStore and filtered, sorted and model? */ + + sortable = GTK_TREE_SORTABLE(sorted); + + renderer = gtk_cell_renderer_text_new(); + + gtk_entry_completion_set_model(mainWindow->searchEntryCompletion, model); + gtk_entry_completion_set_text_column(mainWindow->searchEntryCompletion, 0); + + gtk_tree_sortable_set_sort_column_id(sortable, 0, GTK_SORT_ASCENDING); +} + /** * @brief mainWindow_connect_signals connects are g signals * @param mainWindow struct mainWindow * @@ -405,6 +430,8 @@ struct mainWindow *mainWindow_new() mainWindow->entryListView = GTK_TREE_VIEW(gtk_builder_get_object(builder, "entryListView")); mainWindow->entryListSelection = GTK_TREE_SELECTION(gtk_builder_get_object(builder, "entryListSelection")); mainWindow->textBuffer = GTK_TEXT_BUFFER(gtk_builder_get_object(builder, "entryTextBuffer")); + mainWindow->searchEntryCompletion = GTK_ENTRY_COMPLETION(gtk_builder_get_object(builder, + "searchEntryCompletion")); mainWindow->buttonOtherWorkspace = GTK_WIDGET(gtk_builder_get_object(builder, "buttonOtherWorkspace")); mainWindow->workspaceSearch = GTK_WIDGET(gtk_builder_get_object(builder, "searchWorkspace")); @@ -428,6 +455,7 @@ struct mainWindow *mainWindow_new() mainWindow_configure_workspaceTreeView(mainWindow); mainWindow_init_to_default(mainWindow); mainWindow_clearSearch(NULL, mainWindow); + mainWindow_configure_entry_completion(mainWindow); return mainWindow; } diff --git a/src/mainwindow.h b/src/mainwindow.h index 443c08a..7a08f39 100644 --- a/src/mainwindow.h +++ b/src/mainwindow.h @@ -23,7 +23,9 @@ struct mainWindow { GtkTreeView *entryListView; GtkTreeSelection *entryListSelection; GtkTextBuffer *textBuffer; + GtkEntryCompletion *searchEntryCompletion; + GtkListStore *completionListStore; GtkListStore *entryListStore; GtkWidget *selectedDateEntry; GtkTreeModelFilter *entryListFiltered; diff --git a/src/mdiary.c b/src/mdiary.c index 50ce4c8..efba467 100644 --- a/src/mdiary.c +++ b/src/mdiary.c @@ -217,7 +217,7 @@ static GList *mdiary_add_tags_from_string(gchar *string) return ret; } -static void mdiary_add_file_to_store(gchar *filename, GtkListStore *entryListStore) +static void mdiary_add_file_to_store(gchar *filename, GtkListStore *entryListStore, GtkListStore *autoCompletion) { GFile *file; GError *err = NULL; @@ -302,6 +302,7 @@ static void mdiary_add_file_to_store(gchar *filename, GtkListStore *entryListSto } mdiary_add_entry_to_store(entryListStore, + autoCompletion, title, datetime, tagList, @@ -322,7 +323,10 @@ static void mdiary_add_file_to_store(gchar *filename, GtkListStore *entryListSto g_object_unref(file); } -static void mdiary_recurse_and_collect(gchar *base_dir, GtkListStore *entryListStore, guint max_level) +static void mdiary_recurse_and_collect(gchar *base_dir, + GtkListStore *entryListStore, + GtkListStore *autoCompletion, + guint max_level) { GError *error; GDir *dir = g_dir_open(base_dir, 0, &error); @@ -340,10 +344,10 @@ static void mdiary_recurse_and_collect(gchar *base_dir, GtkListStore *entryListS regex = g_regex_new("\\.md$", G_REGEX_CASELESS, 0, NULL); if (g_regex_match(regex, fullPath, 0, &match_info) && g_match_info_matches(match_info)) - mdiary_add_file_to_store(fullPath, entryListStore); + mdiary_add_file_to_store(fullPath, entryListStore, autoCompletion); g_regex_unref(regex); } else if (g_file_test(fullPath, G_FILE_TEST_IS_DIR) && max_level) { - mdiary_recurse_and_collect(fullPath, entryListStore, max_level--); + mdiary_recurse_and_collect(fullPath, entryListStore, autoCompletion, max_level--); } g_free(fullPath); } @@ -356,11 +360,11 @@ static void mdiary_recurse_and_collect(gchar *base_dir, GtkListStore *entryListS * @param base_dir The base directory to start scanning in * @param entryListStore Target GtkListStore */ -void mdiary_scan_to_store(gchar *base_dir, GtkListStore *entryListStore) +void mdiary_scan_to_store(gchar *base_dir, GtkListStore *entryListStore, GtkListStore *autoCompletion) { time_earliest = G_MAXINT64; time_latest = 0; - mdiary_recurse_and_collect(base_dir, entryListStore, 5); + mdiary_recurse_and_collect(base_dir, entryListStore, autoCompletion, 5); } /** @@ -407,6 +411,31 @@ static gchar *mdiary_taglist_to_string(GList *list) return ret; } +struct tag_compare_struct { + gchar *text; + gboolean result; +}; + + +gboolean mdiary_test_duplicate(GtkTreeModel *model, + GtkTreePath *path, + GtkTreeIter *iter, + gpointer data) { + gchar *temp = NULL; + gboolean ret = FALSE; + struct tag_compare_struct *tag_compare_struct = (struct tag_compare_struct *)data; + + gtk_tree_model_get(model, iter, 0, &temp, -1); + if (!g_strcmp0(temp, tag_compare_struct->text)) { + ret = TRUE; + tag_compare_struct->result = TRUE; + } + + g_free(temp); + + return ret; +} + /** * @brief mdiary_add_entry_to_store adds the specified entry to the store. All params are copied. * @param entryListStore target store @@ -416,6 +445,7 @@ static gchar *mdiary_taglist_to_string(GList *list) * @param text Entry MD text (with header) */ void mdiary_add_entry_to_store(GtkListStore *entryListStore, + GtkListStore *autoCompletion, gchar *title, GDateTime *datetime, GList *tags, @@ -428,6 +458,9 @@ void mdiary_add_entry_to_store(GtkListStore *entryListStore, gchar *date_text; gchar *taglistString; + GList *l; + struct tag_compare_struct tag_compare_struct = { .text = "", .result = FALSE }; + datetime_copy = g_date_time_add(datetime, 0); date_text = g_date_time_format(datetime_copy, "%A, %e %B %Y %R"); taglist_copy = g_list_copy_deep(tags, (GCopyFunc) g_strdup, NULL); @@ -444,4 +477,15 @@ void mdiary_add_entry_to_store(GtkListStore *entryListStore, COL_TEXT, text, /* Automatically strdupd */ -1); g_free(date_text); + + for (l = tags; l != NULL; l = l->next) { + tag_compare_struct.text = l->data; + gtk_tree_model_foreach(GTK_TREE_MODEL(autoCompletion), mdiary_test_duplicate, &tag_compare_struct); + if (!tag_compare_struct.result) { + gtk_list_store_append(autoCompletion, &iter); + gtk_list_store_set(autoCompletion, &iter, + 0, l->data, + -1); + } + } } diff --git a/src/mdiary.h b/src/mdiary.h index 0bfb548..944e5b5 100644 --- a/src/mdiary.h +++ b/src/mdiary.h @@ -16,9 +16,9 @@ enum { COL_COUNT }; -void mdiary_scan_to_store(gchar *base_dir, - GtkListStore *entryListStore); +void mdiary_scan_to_store(gchar *base_dir, GtkListStore *entryListStore, GtkListStore *autoCompletion); void mdiary_add_entry_to_store(GtkListStore *entryListStore, + GtkListStore *autoCompletion, gchar *title, GDateTime *datetime, GList *tags,