From 87ac3ae563dd99778537661d6abc708b2db6f737 Mon Sep 17 00:00:00 2001 From: Alexander Butenko Date: Sat, 12 Jun 2010 22:54:11 -0400 Subject: [PATCH] Initial sqlite read support We go back to GtkTreeStore rather than a custom class. --- midori/main.c | 49 +++++++---- panels/midori-bookmark-store.c | 110 ----------------------- panels/midori-bookmark-store.h | 44 ---------- panels/midori-bookmarks.c | 155 ++++++++++++++++++++++++--------- 4 files changed, 150 insertions(+), 208 deletions(-) delete mode 100644 panels/midori-bookmark-store.c delete mode 100644 panels/midori-bookmark-store.h diff --git a/midori/main.c b/midori/main.c index 91e5c5be..dce2085d 100644 --- a/midori/main.c +++ b/midori/main.c @@ -428,6 +428,30 @@ midori_history_terminate (sqlite3* db, g_free (sqlcmd); sqlite3_close (db); } + +static sqlite3* +midori_bookmarks_initialize (KatzeArray* array, + const gchar* filename, + char** errmsg) +{ + sqlite3* db; + + if (sqlite3_open (filename, &db) != SQLITE_OK) + { + if (errmsg) + *errmsg = g_strdup_printf (_("Failed to open database: %s\n"), + sqlite3_errmsg (db)); + sqlite3_close (db); + return NULL; + } + + if (sqlite3_exec (db, + "CREATE TABLE IF NOT EXISTS " + "bookmarks (uri text, title text, folder text, type integer);", + NULL, NULL, errmsg) != SQLITE_OK) + return NULL; + return db; +} #endif static void @@ -1924,24 +1948,19 @@ main (int argc, midori_startup_timer ("Search read: \t%f"); bookmarks = katze_array_new (KATZE_TYPE_ARRAY); - #if HAVE_LIBXML - katze_assign (config_file, build_config_filename (BOOKMARK_FILE)); - error = NULL; - if (!midori_array_from_file (bookmarks, config_file, "xbel", &error)) + #if HAVE_SQLITE + katze_assign (config_file, build_config_filename ("bookmarks.db")); + errmsg = NULL; + if ((db = midori_bookmarks_initialize (bookmarks, config_file, &errmsg)) == NULL) { - if (error->code == G_FILE_ERROR_NOENT) - { - katze_assign (config_file, - sokoke_find_config_filename (NULL, "bookmarks.xbel")); - midori_array_from_file (bookmarks, config_file, "xbel", NULL); - } - else - g_string_append_printf (error_messages, - _("The bookmarks couldn't be loaded: %s\n"), error->message); - g_error_free (error); + g_string_append_printf (error_messages, + _("Bookmarks couldn't be loaded: %s\n"), errmsg); + g_free (errmsg); } + else + g_object_set_data (G_OBJECT (bookmarks), "db", db); #endif - midori_startup_timer ("Bkmarks read: \t%f"); + midori_startup_timer ("Bookmarks read: \t%f"); _session = katze_array_new (KATZE_TYPE_ITEM); #if HAVE_LIBXML diff --git a/panels/midori-bookmark-store.c b/panels/midori-bookmark-store.c deleted file mode 100644 index b8e03f23..00000000 --- a/panels/midori-bookmark-store.c +++ /dev/null @@ -1,110 +0,0 @@ -/* - Copyright (C) 2009 Christian Dywan - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - See the file COPYING for the full license text. -*/ - -#include "midori-bookmark-store.h" - -struct _MidoriBookmarkStore -{ - GtkTreeStore parent_instance; -}; - -struct _MidoriBookmarkStoreClass -{ - GtkTreeStoreClass parent_class; -}; - -static void -midori_bookmark_store_drag_source_iface_init (GtkTreeDragSourceIface* iface); - -static void -midori_bookmark_store_drag_dest_iface_init (GtkTreeDragDestIface* iface); - -G_DEFINE_TYPE_WITH_CODE (MidoriBookmarkStore, midori_bookmark_store, GTK_TYPE_TREE_STORE, - G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_SOURCE, - midori_bookmark_store_drag_source_iface_init) - G_IMPLEMENT_INTERFACE (GTK_TYPE_TREE_DRAG_DEST, - midori_bookmark_store_drag_dest_iface_init)); - -static void -midori_bookmark_store_finalize (GObject* object); - -static void -midori_bookmark_store_class_init (MidoriBookmarkStoreClass* class) -{ - GObjectClass* gobject_class; - - gobject_class = G_OBJECT_CLASS (class); - gobject_class->finalize = midori_bookmark_store_finalize; -} - -static void -midori_bookmark_store_init (MidoriBookmarkStore* bookmark_store) -{ - /* Nothing to do */ -} - -static void -midori_bookmark_store_finalize (GObject* object) -{ - /* Nothing to do */ -} - -static void -midori_bookmark_store_drag_source_iface_init (GtkTreeDragSourceIface* iface) -{ - /*iface->row_draggable = real_gtk_tree_store_row_draggable; - iface->drag_data_delete = gtk_tree_store_drag_data_delete; - iface->drag_data_get = gtk_tree_store_drag_data_get;*/ -} - -static void -midori_bookmark_store_drag_dest_iface_init (GtkTreeDragDestIface* iface) -{ - /*iface->drag_data_received = gtk_tree_store_drag_data_received; - iface->row_drop_possible = gtk_tree_store_row_drop_possible;*/ -} - -/** - * midori_bookmark_store_new: - * - * Creates a new empty bookmark_store. - * - * Return value: a new #MidoriBookmarkStore - * - * Since: 0.1.8 - **/ -GtkTreeStore* -midori_bookmark_store_new (gint n_columns, - ...) -{ - GtkTreeStore* treestore; - va_list args; - gint i; - GType* types; - - g_return_val_if_fail (n_columns > 0, NULL); - - treestore = g_object_new (MIDORI_TYPE_BOOKMARK_STORE, NULL); - - va_start (args, n_columns); - - types = g_new (GType, n_columns); - for (i = 0; i < n_columns; i++) - { - GType type = va_arg (args, GType); - types[i] = type; - } - va_end (args); - - gtk_tree_store_set_column_types (treestore, i, types); - - return treestore; -} diff --git a/panels/midori-bookmark-store.h b/panels/midori-bookmark-store.h deleted file mode 100644 index ee6a3d54..00000000 --- a/panels/midori-bookmark-store.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - Copyright (C) 2009 Christian Dywan - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Lesser General Public - License as published by the Free Software Foundation; either - version 2.1 of the License, or (at your option) any later version. - - See the file COPYING for the full license text. -*/ - -#ifndef __MIDORI_BOOKMARK_STORE_H__ -#define __MIDORI_BOOKMARK_STORE_H__ - -#include - -G_BEGIN_DECLS - -#define MIDORI_TYPE_BOOKMARK_STORE \ - (midori_bookmark_store_get_type ()) -#define MIDORI_BOOKMARK_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_BOOKMARK_STORE, MidoriBookmarkStore)) -#define MIDORI_BOOKMARK_STORE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_BOOKMARK_STORE, MidoriBookmarkStoreClass)) -#define MIDORI_IS_BOOKMARK_STORE(obj) \ - (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_BOOKMARK_STORE)) -#define MIDORI_IS_BOOKMARK_STORE_CLASS(klass) \ - (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_BOOKMARK_STORE)) -#define MIDORI_BOOKMARK_STORE_GET_CLASS(obj) \ - (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_BOOKMARK_STORE, MidoriBookmarkStoreClass)) - -typedef struct _MidoriBookmarkStore MidoriBookmarkStore; -typedef struct _MidoriBookmarkStoreClass MidoriBookmarkStoreClass; - -GType -midori_bookmark_store_get_type (void); - -GtkTreeStore* -midori_bookmark_store_new (gint n_columns, - ...); - -G_END_DECLS - -#endif /* __MIDORI_BOOKMARK_STORE_H__ */ diff --git a/panels/midori-bookmarks.c b/panels/midori-bookmarks.c index 2a901f01..fdc7080d 100644 --- a/panels/midori-bookmarks.c +++ b/panels/midori-bookmarks.c @@ -16,7 +16,6 @@ #include "midori-stock.h" #include "midori-view.h" #include "midori-viewable.h" -#include "midori-bookmark-store.h" #include "sokoke.h" @@ -26,6 +25,11 @@ #include #include +#include "config.h" +#if HAVE_SQLITE + #include +#endif + void midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, KatzeItem* bookmark, @@ -117,6 +121,74 @@ midori_bookmarks_get_stock_id (MidoriViewable* viewable) return STOCK_BOOKMARKS; } +#if HAVE_SQLITE +static gboolean +midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks, + GtkTreeStore* model, + GtkTreeIter* parent, + const gchar* folder) +{ + sqlite3* db; + sqlite3_stmt* statement; + gint result; + const gchar* sqlcmd; + + GtkTreeIter iter; + GtkTreeIter root_iter; + + db = g_object_get_data (G_OBJECT (bookmarks->array), "db"); + + sqlcmd = "SELECT uri, title, type from bookmarks where folder = ?" + " ORDER BY type, title ASC"; + result = sqlite3_prepare_v2 (db, sqlcmd, -1, &statement, NULL); + sqlite3_bind_text (statement, 1, g_strdup(folder), -1, g_free); + + if (result != SQLITE_OK) + return FALSE; + + while ((result = sqlite3_step (statement)) == SQLITE_ROW) + { + gint type; + KatzeItem* item; + const unsigned char* uri; + const unsigned char* title; + + uri = sqlite3_column_text (statement, 0); + title = sqlite3_column_text (statement, 1); + type = sqlite3_column_int64 (statement, 2); + + item = katze_item_new (); + katze_item_set_uri (item, (gchar*)uri); + katze_item_set_name (item, (gchar*)title); + + /* type 0 -- folder, 1 -- entry */ + if (type == 0) + { + gtk_tree_store_insert_with_values (model, &root_iter, parent, + 0, 0, item, -1); + /* That's an invisible dummy, so we always have an expander */ + gtk_tree_store_insert_with_values (model, &iter, &root_iter, + 0, 0, NULL, -1); + } + else + { + if (!uri) + continue; + + gtk_tree_store_insert_with_values (model, NULL, parent, + 0, 0, item, -1); + } + } + + if (result != SQLITE_DONE) + g_print (_("Failed to execute database statement: %s\n"), + sqlite3_errmsg (db)); + + sqlite3_finalize (statement); + return FALSE; +} +#endif + static void midori_bookmarks_add_clicked_cb (GtkWidget* toolitem) { @@ -298,31 +370,6 @@ static void midori_bookmarks_clear_cb (KatzeArray* array, MidoriBookmarks* bookmarks); -static void -midori_bookmarks_disconnect_folder (MidoriBookmarks* bookmarks, - KatzeArray* array) -{ - KatzeItem* item; - guint i; - - g_return_if_fail (KATZE_IS_ARRAY (array)); - - g_signal_handlers_disconnect_by_func (array, - midori_bookmarks_add_item_cb, bookmarks); - g_signal_handlers_disconnect_by_func (array, - midori_bookmarks_remove_item_cb, bookmarks); - g_signal_handlers_disconnect_by_func (array, - midori_bookmarks_clear_cb, bookmarks); - - i = 0; - while ((item = katze_array_get_nth_item (array, i++))) - { - if (KATZE_IS_ARRAY (item)) - midori_bookmarks_disconnect_folder (bookmarks, KATZE_ARRAY (item)); - g_object_unref (item); - } -} - static void midori_bookmarks_add_item_cb (KatzeArray* array, KatzeItem* added_item, @@ -416,9 +463,6 @@ midori_bookmarks_remove_item_cb (KatzeArray* array, g_return_if_fail (KATZE_IS_ARRAY (array)); g_return_if_fail (KATZE_IS_ITEM (removed_item)); - if (KATZE_IS_ARRAY (removed_item)) - midori_bookmarks_disconnect_folder (bookmarks, KATZE_ARRAY (removed_item)); - model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); midori_bookmarks_remove_iter (model, NULL, removed_item); g_object_unref (removed_item); @@ -489,10 +533,12 @@ midori_bookmarks_set_app (MidoriBookmarks* bookmarks, if (bookmarks->array) { - midori_bookmarks_disconnect_folder (bookmarks, bookmarks->array); g_object_unref (bookmarks->array); model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); gtk_tree_store_clear (GTK_TREE_STORE (model)); + #if HAVE_SQLITE + midori_bookmarks_read_from_db (bookmarks, GTK_TREE_STORE (model), NULL, ""); + #endif } katze_assign (bookmarks->app, app); if (!app) @@ -500,13 +546,6 @@ midori_bookmarks_set_app (MidoriBookmarks* bookmarks, g_object_ref (app); bookmarks->array = katze_object_get_object (app, "bookmarks"); - if (bookmarks->array) - { - /* FIXME: Dereference the app on finalization */ - model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); - midori_bookmarks_insert_folder (bookmarks, GTK_TREE_STORE (model), - NULL, g_object_ref (bookmarks->array)); - } } static void @@ -880,6 +919,41 @@ midori_bookmarks_popup_menu_cb (GtkWidget* widget, } } +static void +midori_bookmarks_row_expanded_cb (GtkTreeView* treeview, + GtkTreeIter* iter, + GtkTreePath* path, + MidoriBookmarks* bookmarks) +{ + GtkTreeModel* model; + KatzeItem* item; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); + gtk_tree_model_get (model, iter, 0, &item, -1); + midori_bookmarks_read_from_db (bookmarks, GTK_TREE_STORE (model), + iter, katze_item_get_name (item)); + g_object_unref (item); +} + +static void +midori_bookmarks_row_collapsed_cb (GtkTreeView *treeview, + GtkTreeIter *parent, + GtkTreePath *path, + gpointer user_data) +{ + GtkTreeModel* model; + GtkTreeStore* treestore; + GtkTreeIter child; + + model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); + treestore = GTK_TREE_STORE (model); + while (gtk_tree_model_iter_nth_child (model, &child, parent, 0)) + gtk_tree_store_remove (treestore, &child); + /* That's an invisible dummy, so we always have an expander */ + gtk_tree_store_insert_with_values (treestore, &child, parent, + 0, 0, NULL, -1); +} + static void midori_bookmarks_init (MidoriBookmarks* bookmarks) { @@ -890,7 +964,7 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks) GtkCellRenderer* renderer_text; /* Create the treeview */ - model = midori_bookmark_store_new (1, KATZE_TYPE_ITEM); + model = gtk_tree_store_new (1, KATZE_TYPE_ITEM); treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model)); gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE); column = gtk_tree_view_column_new (); @@ -919,6 +993,10 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks) midori_bookmarks_key_release_event_cb, bookmarks, "signal::popup-menu", midori_bookmarks_popup_menu_cb, bookmarks, + "signal::row-expanded", + midori_bookmarks_row_expanded_cb, bookmarks, + "signal::row-collapsed", + midori_bookmarks_row_collapsed_cb, bookmarks, NULL); gtk_widget_show (treeview); gtk_box_pack_start (GTK_BOX (bookmarks), treeview, TRUE, TRUE, 0); @@ -930,7 +1008,6 @@ midori_bookmarks_finalize (GObject* object) { MidoriBookmarks* bookmarks = MIDORI_BOOKMARKS (object); - midori_bookmarks_disconnect_folder (bookmarks, bookmarks->array); if (bookmarks->app) g_object_unref (bookmarks->app); }