From 2e0319f6a91a354950a1e7dfff9715dfa24cab45 Mon Sep 17 00:00:00 2001 From: Thomas Perl Date: Mon, 13 Oct 2008 11:54:58 +0000 Subject: [PATCH] Initial support for full-text searching git-svn-id: https://vcs.maemo.org/svn/maemopadplus/trunk/unified@93 5e5308f7-2816-0410-9b18-d3ce14e03fc0 --- src/ui/callbacks.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/ui/callbacks.h | 6 +++++ src/ui/interface.c | 19 ++++++++++++++-- src/ui/interface.h | 23 +++++++++++++++++++ 4 files changed, 112 insertions(+), 2 deletions(-) diff --git a/src/ui/callbacks.c b/src/ui/callbacks.c index bfbb07d..218ae77 100644 --- a/src/ui/callbacks.c +++ b/src/ui/callbacks.c @@ -4025,3 +4025,69 @@ gtk_tree_view_set_model(GTK_TREE_VIEW(mainview->listview), model); g_object_unref(model); gtk_object_set_data(GTK_OBJECT(mainview->listview), "edited", TRUE); } + +gboolean search_foreach(GtkTreeModel *model, GtkTreePath *path, GtkTreeIter* iter, gpointer user_data) +{ + SearchResults *results = (SearchResults*)user_data; + nodeData *data; + int i; + gtk_tree_model_get(model, iter, NODE_DATA, &data, -1); + for (i=0; iindex; i++) { + if (results->ids[i] == data->sql3id) { + gtk_tree_store_set(GTK_TREE_STORE(model), iter, NODE_BGCOLOR, results->main_view->color_highlight, -1); + return FALSE; + } + } + gtk_tree_store_set(GTK_TREE_STORE(model), iter, NODE_BGCOLOR, NULL, -1); + return FALSE; +} + +void callback_search_activate(GtkWidget* widget, gpointer user_data) +{ + MainView* main_view = (MainView*)user_data; + GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(main_view->treeview)); + + sqlite3_stmt *stmt = NULL; + const char *dum; + char *search_str; + + SearchResults *results = g_new(SearchResults, 1); + results->index = 0; + results->current_size = SEARCH_RESULTS_ARRAY_SIZE; + results->ids = g_malloc(sizeof(int)*results->current_size); + results->main_view = main_view; + + /* Save data so our tables reflect the current UI content */ + saveCurrentData(main_view); + + /* Create a search string "%text%" for SQLite's "LIKE" keyword */ + search_str = gtk_entry_get_text(main_view->search_entry); + if (strlen(search_str) > 0) { + sqlite3_prepare(main_view->db, "SELECT nodeid FROM " checklisttable_tmpname " WHERE name LIKE ?1 UNION SELECT nodeid FROM " datatable_tmpname " WHERE name LIKE ?1 OR (bodytype=1 AND bodyblob LIKE ?1)", -1, &stmt, &dum); + + search_str = g_strdup_printf("%%%s%%", search_str); + + if (sqlite3_bind_text(stmt, 1, search_str, -1, SQLITE_TRANSIENT) != SQLITE_OK) { + fprintf(stderr, "Error while binding search string to SQL query\n"); + return; + } + + while (sqlite3_step(stmt) == SQLITE_ROW) { + if (results->index > results->current_size-1) { + results->current_size += SEARCH_RESULTS_ARRAY_SIZE; + results->ids = g_realloc(results->ids, sizeof(int)*results->current_size); + } + results->ids[results->index++] = sqlite3_column_int(stmt, 0); + } + fprintf(stderr, "Search for \"%s\" gave %d results.\n", search_str, results->index); + g_free(search_str); + + sqlite3_finalize(stmt); + } + + gtk_tree_model_foreach(model, search_foreach, results); + + g_free(results->ids); + g_free(results); +} + diff --git a/src/ui/callbacks.h b/src/ui/callbacks.h index 2b76e88..ded8506 100644 --- a/src/ui/callbacks.h +++ b/src/ui/callbacks.h @@ -73,6 +73,12 @@ void callback_edit_copy(GtkAction * action, gpointer data); void callback_edit_paste(GtkAction * action, gpointer data); gint cb_popup(GtkWidget * widget, GdkEvent * event); + +/* + * search entry + */ +void callback_search_activate(GtkWidget* widget, gpointer user_data); + /* * file-> new/open/save */ diff --git a/src/ui/interface.c b/src/ui/interface.c index 2380118..40f114f 100644 --- a/src/ui/interface.c +++ b/src/ui/interface.c @@ -539,6 +539,8 @@ GtkWidget *create_shapemenu(MainView * main) */ static void create_toolbar(MainView * main) { + GtkToolItem * ti; + /* * Create new GTK toolbar */ @@ -671,6 +673,18 @@ static void create_toolbar(MainView * main) gtk_toolbar_insert(GTK_TOOLBAR(main->toolbar), main->redo_tb, -1); g_signal_connect(G_OBJECT(main->redo_tb), "clicked", G_CALLBACK(callback_redo), main); + /* Search entry widget */ + gtk_toolbar_insert(GTK_TOOLBAR(main->toolbar), gtk_separator_tool_item_new(), -1); + ti = gtk_tool_item_new(); + gtk_tool_item_set_expand(ti, TRUE); + main->search_entry = gtk_entry_new(); + g_signal_connect(G_OBJECT(main->search_entry), "activate", G_CALLBACK(callback_search_activate), main); + gtk_container_add(GTK_CONTAINER(ti), main->search_entry); + gtk_toolbar_insert(main->toolbar, ti, -1); + ti = gtk_tool_button_new(gtk_image_new_from_icon_name("qgn_addr_icon_search_service", GTK_ICON_SIZE_SMALL_TOOLBAR), _("Search")); + g_signal_connect(G_OBJECT(ti), "clicked", G_CALLBACK(callback_search_activate), main); + gtk_toolbar_insert(main->toolbar, ti, -1); + /* * Connect signals to buttons */ @@ -757,6 +771,7 @@ void create_textarea(MainView * main) */ void create_treeview(MainView * main) { + main->color_highlight = "#ffff00"; main->scrolledtree = gtk_scrolled_window_new(NULL, NULL); /*#ifdef MAEMOPADPLUS_FINGER_FRIENDLY hildon_helper_set_thumb_scrollbar(main->scrolledtree, TRUE); @@ -764,8 +779,7 @@ void create_treeview(MainView * main) gtk_widget_show(main->scrolledtree); gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(main->scrolledtree), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - GtkTreeStore *tstore = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF, - G_TYPE_POINTER); + GtkTreeStore *tstore = gtk_tree_store_new(N_COLUMNS, G_TYPE_STRING, GDK_TYPE_PIXBUF, G_TYPE_POINTER, G_TYPE_STRING); main->treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(tstore)); g_object_unref(G_OBJECT(tstore)); @@ -778,6 +792,7 @@ void create_treeview(MainView * main) gtk_tree_view_column_pack_start(column, renderer2, FALSE); gtk_tree_view_column_pack_start(column, renderer1, FALSE); + gtk_tree_view_column_add_attribute(column, renderer1, "cell-background", NODE_BGCOLOR); gtk_tree_view_column_add_attribute(column, renderer1, "text", NODE_NAME); gtk_tree_view_column_add_attribute(column, renderer2, "pixbuf", NODE_PIXBUF); diff --git a/src/ui/interface.h b/src/ui/interface.h index 3c611cf..12704ed 100644 --- a/src/ui/interface.h +++ b/src/ui/interface.h @@ -100,6 +100,7 @@ enum NODE_NAME, NODE_PIXBUF, NODE_DATA, + NODE_BGCOLOR, N_COLUMNS }; @@ -133,6 +134,9 @@ struct _nodeData unsigned int flags; }; + + + /* * Struct to include view's information */ @@ -227,6 +231,8 @@ struct _MainView GtkToolItem *shape_tb; GtkWidget *shapemenuitems[4]; + + GtkEntry *search_entry; /* * Textview related @@ -254,6 +260,9 @@ struct _MainView gchar *file_name; gboolean loading; + /* For highlighting searches */ + char* color_highlight; + sqlite3 *db; #ifdef NEW_SEL_LOGIC @@ -264,6 +273,20 @@ struct _MainView gboolean newnodedialog_createchild; }; + +/* Initial size and increment for the search result node ID array */ +#define SEARCH_RESULTS_ARRAY_SIZE 64 + +/* Saves the found node IDs after a search */ +typedef struct _SearchResults SearchResults; +struct _SearchResults { + int *ids; + int current_size; + int index; + MainView *main_view; +}; + + #define datatable_name "nodes" #define datatable_tmpname "tmpnodes" #define datatable_backupname "nodesbackup" -- 2.11.4.GIT