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
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
+++ /dev/null
-/*
- Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
-
- 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;
-}
+++ /dev/null
-/*
- Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
-
- 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 <gtk/gtk.h>
-
-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__ */
#include "midori-stock.h"
#include "midori-view.h"
#include "midori-viewable.h"
-#include "midori-bookmark-store.h"
#include "sokoke.h"
#include <katze/katze.h>
#include <gdk/gdkkeysyms.h>
+#include "config.h"
+#if HAVE_SQLITE
+ #include <sqlite3.h>
+#endif
+
void
midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
KatzeItem* bookmark,
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)
{
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,
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);
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)
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
}
}
+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)
{
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 ();
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);
{
MidoriBookmarks* bookmarks = MIDORI_BOOKMARKS (object);
- midori_bookmarks_disconnect_folder (bookmarks, bookmarks->array);
if (bookmarks->app)
g_object_unref (bookmarks->app);
}