Bookmarks: Database structure improved

The new format uses bookmarks_v2.db.

We require sqlite 3.6.19 now due to foreign keys.

Fixes: https://bugs.launchpad.net/midori/+bug/836707
This commit is contained in:
Oliver Hanraths 2012-06-16 01:06:58 +02:00 committed by Christian Dywan
parent bc37926516
commit f840f0508c
8 changed files with 524 additions and 151 deletions

View file

@ -434,7 +434,6 @@ midori_history_clear_cb (KatzeArray* array,
static gboolean static gboolean
midori_history_initialize (KatzeArray* array, midori_history_initialize (KatzeArray* array,
const gchar* filename, const gchar* filename,
const gchar* bookmarks_filename,
char** errmsg) char** errmsg)
{ {
sqlite3* db; sqlite3* db;
@ -442,6 +441,9 @@ midori_history_initialize (KatzeArray* array,
sqlite3_stmt* stmt; sqlite3_stmt* stmt;
gint result; gint result;
gchar* sql; gchar* sql;
gchar* bookmarks_filename;
g_return_val_if_fail (errmsg != NULL, FALSE);
if (sqlite3_open (filename, &db) != SQLITE_OK) if (sqlite3_open (filename, &db) != SQLITE_OK)
{ {
@ -493,7 +495,9 @@ midori_history_initialize (KatzeArray* array,
"COMMIT;", "COMMIT;",
NULL, NULL, errmsg); NULL, NULL, errmsg);
bookmarks_filename = build_config_filename ("bookmarks_v2.db");
sql = g_strdup_printf ("ATTACH DATABASE '%s' AS bookmarks", bookmarks_filename); sql = g_strdup_printf ("ATTACH DATABASE '%s' AS bookmarks", bookmarks_filename);
g_free (bookmarks_filename);
sqlite3_exec (db, sql, NULL, NULL, errmsg); sqlite3_exec (db, sql, NULL, NULL, errmsg);
g_free (sql); g_free (sql);
g_object_set_data (G_OBJECT (array), "db", db); g_object_set_data (G_OBJECT (array), "db", db);
@ -1900,9 +1904,7 @@ main (int argc,
gchar** extensions; gchar** extensions;
MidoriWebSettings* settings; MidoriWebSettings* settings;
gchar* config_file; gchar* config_file;
gchar* bookmarks_file;
GKeyFile* speeddial; GKeyFile* speeddial;
gboolean bookmarks_exist;
MidoriStartup load_on_startup; MidoriStartup load_on_startup;
KatzeArray* search_engines; KatzeArray* search_engines;
KatzeArray* bookmarks; KatzeArray* bookmarks;
@ -2347,10 +2349,8 @@ main (int argc,
midori_startup_timer ("Search read: \t%f"); midori_startup_timer ("Search read: \t%f");
bookmarks = katze_array_new (KATZE_TYPE_ARRAY); bookmarks = katze_array_new (KATZE_TYPE_ARRAY);
bookmarks_file = g_build_filename (config, "bookmarks.db", NULL);
bookmarks_exist = g_access (bookmarks_file, F_OK) == 0;
errmsg = NULL; errmsg = NULL;
if ((db = midori_bookmarks_initialize (bookmarks, bookmarks_file, &errmsg)) == NULL) if ((db = midori_bookmarks_initialize (bookmarks, &errmsg)) == NULL)
{ {
g_string_append_printf (error_messages, g_string_append_printf (error_messages,
_("Bookmarks couldn't be loaded: %s\n"), errmsg); _("Bookmarks couldn't be loaded: %s\n"), errmsg);
@ -2396,13 +2396,12 @@ main (int argc,
katze_assign (config_file, g_build_filename (config, "history.db", NULL)); katze_assign (config_file, g_build_filename (config, "history.db", NULL));
errmsg = NULL; errmsg = NULL;
if (!midori_history_initialize (history, config_file, bookmarks_file, &errmsg)) if (!midori_history_initialize (history, config_file, &errmsg))
{ {
g_string_append_printf (error_messages, g_string_append_printf (error_messages,
_("The history couldn't be loaded: %s\n"), errmsg); _("The history couldn't be loaded: %s\n"), errmsg);
errmsg = NULL; errmsg = NULL;
} }
g_free (bookmarks_file);
midori_startup_timer ("History read: \t%f"); midori_startup_timer ("History read: \t%f");
error = NULL; error = NULL;

View file

@ -982,24 +982,26 @@ katze_item_set_value_from_column (sqlite3_stmt* stmt,
item->added = date; item->added = date;
} }
else if (g_str_equal (name, "day") || g_str_equal (name, "app") else if (g_str_equal (name, "day") || g_str_equal (name, "app")
|| g_str_equal (name, "toolbar")) || g_str_equal (name, "toolbar") || g_str_equal (name, "id")
|| g_str_equal (name, "parentid") || g_str_equal (name, "seq")
|| g_str_equal (name, "pos_panel") || g_str_equal (name, "pos_bar"))
{ {
gint value; gint value;
value = sqlite3_column_int64 (stmt, column); value = sqlite3_column_int64 (stmt, column);
katze_item_set_meta_integer (item, name, value); katze_item_set_meta_integer (item, name, value);
} }
else if (g_str_equal (name, "folder"))
{
const unsigned char* folder;
folder = sqlite3_column_text (stmt, column);
katze_item_set_meta_string (item, name, (gchar*)folder);
}
else if (g_str_equal (name, "desc")) else if (g_str_equal (name, "desc"))
{ {
const unsigned char* text; const unsigned char* text;
text = sqlite3_column_text (stmt, column); text = sqlite3_column_text (stmt, column);
item->text = g_strdup ((gchar*)text); item->text = g_strdup ((gchar*)text);
} }
else if (g_str_equal (name, "sql"))
{
const unsigned char* sql;
sql = sqlite3_column_text (stmt, column);
katze_item_set_meta_string (item, name, (gchar*)sql);
}
else else
g_warn_if_reached (); g_warn_if_reached ();
} }
@ -1102,7 +1104,7 @@ midori_array_query_recursive (KatzeArray* bookmarks,
return NULL; return NULL;
sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s " sqlcmd = g_strdup_printf ("SELECT %s FROM bookmarks WHERE %s "
"ORDER BY title DESC", fields, condition); "ORDER BY (uri='') ASC, title DESC", fields, condition);
if (strstr (condition, "%q")) if (strstr (condition, "%q"))
{ {
sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : ""); sqlcmd_value = sqlite3_mprintf (sqlcmd, value ? value : "");
@ -1120,10 +1122,14 @@ midori_array_query_recursive (KatzeArray* bookmarks,
{ {
if (KATZE_ITEM_IS_FOLDER (item)) if (KATZE_ITEM_IS_FOLDER (item))
{ {
gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
katze_item_get_meta_integer (item, "id"));
KatzeArray* subarray = midori_array_query_recursive (bookmarks, KatzeArray* subarray = midori_array_query_recursive (bookmarks,
fields, "folder='%q'", item->name, TRUE); fields, "parentid=%q", parentid, TRUE);
katze_item_set_name (KATZE_ITEM (subarray), item->name); katze_item_set_name (KATZE_ITEM (subarray), item->name);
katze_array_add_item (array, subarray); katze_array_add_item (array, subarray);
g_free (parentid);
} }
} }
g_list_free (list); g_list_free (list);

View file

@ -13,7 +13,9 @@
#include "midori-bookmarks.h" #include "midori-bookmarks.h"
#include "panels/midori-bookmarks.h" #include "panels/midori-bookmarks.h"
#include "midori-array.h" #include "midori-array.h"
#include "sokoke.h"
#include <glib/gstdio.h>
#include <glib/gi18n.h> #include <glib/gi18n.h>
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
@ -29,7 +31,7 @@ midori_bookmarks_add_item_cb (KatzeArray* array,
sqlite3* db) sqlite3* db)
{ {
midori_bookmarks_insert_item_db (db, item, midori_bookmarks_insert_item_db (db, item,
katze_item_get_meta_string (item, "folder")); katze_item_get_meta_integer (item, "parentid"));
} }
void void
@ -40,19 +42,10 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
gchar* sqlcmd; gchar* sqlcmd;
char* errmsg = NULL; char* errmsg = NULL;
if (KATZE_ITEM_IS_BOOKMARK (item))
sqlcmd = sqlite3_mprintf (
"DELETE FROM bookmarks WHERE uri = '%q' "
" AND folder = '%q'",
katze_item_get_uri (item),
katze_str_non_null (katze_item_get_meta_string (item, "folder")));
else sqlcmd = sqlite3_mprintf (
sqlcmd = sqlite3_mprintf ( "DELETE FROM bookmarks WHERE id = %" G_GINT64_FORMAT ";",
"DELETE FROM bookmarks WHERE title = '%q'" katze_item_get_meta_integer (item, "id"));
" AND folder = '%q'",
katze_item_get_name (item),
katze_str_non_null (katze_item_get_meta_string (item, "folder")));
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
{ {
@ -63,20 +56,102 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
sqlite3_free (sqlcmd); sqlite3_free (sqlcmd);
} }
#define _APPEND_TO_SQL_ERRORMSG(custom_errmsg) \
do { \
if (sql_errmsg) \
{ \
g_string_append_printf (errmsg_str, "%s : %s\n", custom_errmsg, sql_errmsg); \
sqlite3_free (sql_errmsg); \
} \
else \
g_string_append (errmsg_str, custom_errmsg); \
} while (0)
gboolean
midori_bookmarks_import_from_old_db (sqlite3* db,
const gchar* oldfile,
gchar** errmsg)
{
gint sql_errcode;
gboolean failure = FALSE;
gchar* sql_errmsg = NULL;
GString* errmsg_str = g_string_new (NULL);
gchar* attach_stmt = sqlite3_mprintf ("ATTACH DATABASE %Q AS old_db;", oldfile);
const gchar* convert_stmts =
"BEGIN TRANSACTION;"
"INSERT INTO main.bookmarks (parentid, title, uri, desc, app, toolbar) "
"SELECT NULL AS parentid, title, uri, desc, app, toolbar "
"FROM old_db.bookmarks;"
"UPDATE main.bookmarks SET parentid = ("
"SELECT id FROM main.bookmarks AS b1 WHERE b1.title = ("
"SELECT folder FROM old_db.bookmarks WHERE title = main.bookmarks.title));"
"COMMIT;";
const gchar* detach_stmt = "DETACH DATABASE old_db;";
*errmsg = NULL;
sql_errcode = sqlite3_exec (db, attach_stmt, NULL, NULL, &sql_errmsg);
sqlite3_free (attach_stmt);
if (sql_errcode != SQLITE_OK)
{
_APPEND_TO_SQL_ERRORMSG (_("failed to ATTACH old db"));
goto convert_failed;
}
if (sqlite3_exec (db, convert_stmts, NULL, NULL, &sql_errmsg) != SQLITE_OK)
{
failure = TRUE;
_APPEND_TO_SQL_ERRORMSG (_("failed to import from old db"));
/* try to get back to previous state */
if (sqlite3_exec (db, "ROLLBACK TRANSACTION;", NULL, NULL, &sql_errmsg) != SQLITE_OK)
_APPEND_TO_SQL_ERRORMSG (_("failed to rollback the transaction"));
}
if (sqlite3_exec (db, detach_stmt, NULL, NULL, &sql_errmsg) != SQLITE_OK)
_APPEND_TO_SQL_ERRORMSG (_("failed to DETACH "));
if (failure)
{
convert_failed:
*errmsg = g_string_free (errmsg_str, FALSE);
g_print ("ERRORR: %s\n", errmsg_str->str);
return FALSE;
}
return TRUE;
}
#undef _APPEND_TO_SQL_ERRORMSG
sqlite3* sqlite3*
midori_bookmarks_initialize (KatzeArray* array, midori_bookmarks_initialize (KatzeArray* array,
const gchar* filename,
char** errmsg) char** errmsg)
{ {
sqlite3* db; sqlite3* db;
gchar* oldfile;
gchar* newfile;
gboolean newfile_did_exist, oldfile_exists;
const gchar* create_stmt;
gchar* sql_errmsg = NULL;
gchar* import_errmsg = NULL;
if (sqlite3_open (filename, &db) != SQLITE_OK) g_return_val_if_fail (errmsg != NULL, NULL);
oldfile = g_build_filename (sokoke_set_config_dir (NULL), "bookmarks.db", NULL);
oldfile_exists = g_access (oldfile, F_OK) == 0;
newfile = g_build_filename (sokoke_set_config_dir (NULL), "bookmarks_v2.db", NULL);
newfile_did_exist = g_access (newfile, F_OK) == 0;
/* sqlite3_open will create the file if it did not exists already */
if (sqlite3_open (newfile, &db) != SQLITE_OK)
{ {
if (errmsg) if (db)
*errmsg = g_strdup_printf (_("Failed to open database: %s\n"), *errmsg = g_strdup_printf (_("failed to open database: %s\n"),
sqlite3_errmsg (db)); sqlite3_errmsg (db));
sqlite3_close (db); else
return NULL; *errmsg = g_strdup (_("failed to open database\n"));
goto init_failed;
} }
#ifdef G_ENABLE_DEBUG #ifdef G_ENABLE_DEBUG
@ -84,17 +159,155 @@ midori_bookmarks_initialize (KatzeArray* array,
sqlite3_trace (db, midori_bookmarks_dbtracer, NULL); sqlite3_trace (db, midori_bookmarks_dbtracer, NULL);
#endif #endif
if (sqlite3_exec (db, create_stmt = /* Table structure */
"CREATE TABLE IF NOT EXISTS " "CREATE TABLE IF NOT EXISTS bookmarks "
"bookmarks (uri text, title text, folder text, " "(id INTEGER PRIMARY KEY AUTOINCREMENT, "
"desc text, app integer, toolbar integer);", "parentid INTEGER DEFAULT NULL, "
NULL, NULL, errmsg) != SQLITE_OK) "title TEXT, uri TEXT, desc TEXT, app INTEGER, toolbar INTEGER, "
"pos_panel INTEGER, pos_bar INTEGER, "
"created DATE DEFAULT CURRENT_TIMESTAMP, "
"last_visit DATE, visit_count INTEGER DEFAULT 0, "
"nick TEXT, "
"FOREIGN KEY(parentid) REFERENCES bookmarks(id) "
"ON DELETE CASCADE); PRAGMA foreign_keys = ON;"
/* trigger: insert panel position */
"CREATE TRIGGER IF NOT EXISTS bookmarkInsertPosPanel "
"AFTER INSERT ON bookmarks FOR EACH ROW "
"BEGIN UPDATE bookmarks SET pos_panel = ("
"SELECT ifnull(MAX(pos_panel),0)+1 FROM bookmarks WHERE "
"(NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) "
"WHERE id = NEW.id; END;"
/* trigger: insert Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkInsertPosBar "
"AFTER INSERT ON bookmarks FOR EACH ROW WHEN NEW.toolbar=1 "
"BEGIN UPDATE bookmarks SET pos_bar = ("
"SELECT ifnull(MAX(pos_bar),0)+1 FROM bookmarks WHERE "
"((NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) AND toolbar=1) "
"WHERE id = NEW.id; END;"
/* trigger: update panel position */
"CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosPanel "
"BEFORE UPDATE OF parentid ON bookmarks FOR EACH ROW "
"WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
"AND NEW.parentid IS NOT OLD.parentid) OR "
"((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
"AND NEW.parentid!=OLD.parentid) "
"BEGIN UPDATE bookmarks SET pos_panel = pos_panel-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_panel > OLD.pos_panel; "
"UPDATE bookmarks SET pos_panel = ("
"SELECT ifnull(MAX(pos_panel),0)+1 FROM bookmarks "
"WHERE (NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) "
"WHERE id = OLD.id; END;"
/* trigger: update Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosBar0 "
"AFTER UPDATE OF parentid, toolbar ON bookmarks FOR EACH ROW "
"WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
"AND NEW.parentid IS NOT OLD.parentid) "
"OR ((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
"AND NEW.parentid!=OLD.parentid) OR (OLD.toolbar=1 AND NEW.toolbar=0) "
"BEGIN UPDATE bookmarks SET pos_bar = NULL WHERE id = NEW.id; "
"UPDATE bookmarks SET pos_bar = pos_bar-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_bar > OLD.pos_bar; END;"
/* trigger: update Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkUpdatePosBar1 "
"BEFORE UPDATE OF parentid, toolbar ON bookmarks FOR EACH ROW "
"WHEN ((NEW.parentid IS NULL OR OLD.parentid IS NULL) "
"AND NEW.parentid IS NOT OLD.parentid) OR "
"((NEW.parentid IS NOT NULL AND OLD.parentid IS NOT NULL) "
"AND NEW.parentid!=OLD.parentid) OR (OLD.toolbar=0 AND NEW.toolbar=1) "
"BEGIN UPDATE bookmarks SET pos_bar = ("
"SELECT ifnull(MAX(pos_bar),0)+1 FROM bookmarks WHERE "
"(NEW.parentid IS NOT NULL AND parentid = NEW.parentid) "
"OR (NEW.parentid IS NULL AND parentid IS NULL)) "
"WHERE id = OLD.id; END;"
/* trigger: delete panel position */
"CREATE TRIGGER IF NOT EXISTS bookmarkDeletePosPanel "
"AFTER DELETE ON bookmarks FOR EACH ROW "
"BEGIN UPDATE bookmarks SET pos_panel = pos_panel-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_panel > OLD.pos_panel; END;"
/* trigger: delete Bookmarkbar position */
"CREATE TRIGGER IF NOT EXISTS bookmarkDeletePosBar "
"AFTER DELETE ON bookmarks FOR EACH ROW WHEN OLD.toolbar=1 "
"BEGIN UPDATE bookmarks SET pos_bar = pos_bar-1 "
"WHERE ((OLD.parentid IS NOT NULL AND parentid = OLD.parentid) "
"OR (OLD.parentid IS NULL AND parentid IS NULL)) AND pos_bar > OLD.pos_bar; END;";
if (newfile_did_exist)
{
/* we are done */
goto init_success;
}
else
{
/* initial creation */
if (sqlite3_exec (db, create_stmt, NULL, NULL, &sql_errmsg) != SQLITE_OK)
{
if (errmsg)
{
if (sql_errmsg)
{
*errmsg = g_strdup_printf (_("could not create bookmarks table: %s\n"), sql_errmsg);
sqlite3_free (sql_errmsg);
}
else
*errmsg = g_strdup (_("could not create bookmarks table"));
}
/* we can as well remove the new file */
g_unlink (newfile);
goto init_failed;
}
}
if (oldfile_exists)
/* import from old db */
if (!midori_bookmarks_import_from_old_db (db, oldfile, &import_errmsg))
{
if (errmsg)
{
if (import_errmsg)
{
*errmsg = g_strdup_printf (_("could not import from old database: %s\n"), import_errmsg);
g_free (import_errmsg);
}
else
*errmsg = g_strdup_printf (_("could not import from old database"));
}
}
init_success:
g_free (newfile);
g_free (oldfile);
g_signal_connect (array, "add-item",
G_CALLBACK (midori_bookmarks_add_item_cb), db);
g_signal_connect (array, "remove-item",
G_CALLBACK (midori_bookmarks_remove_item_cb), db);
return db;
init_failed:
g_free (newfile);
g_free (oldfile);
if (db)
sqlite3_close (db);
return NULL; return NULL;
g_signal_connect (array, "add-item",
G_CALLBACK (midori_bookmarks_add_item_cb), db);
g_signal_connect (array, "remove-item",
G_CALLBACK (midori_bookmarks_remove_item_cb), db);
return db;
} }
void void
@ -112,5 +325,5 @@ midori_bookmarks_import (const gchar* filename,
g_error_free (error); g_error_free (error);
return; return;
} }
midori_bookmarks_import_array_db (db, bookmarks, ""); midori_bookmarks_import_array_db (db, bookmarks, 0);
} }

View file

@ -25,7 +25,6 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
sqlite3* sqlite3*
midori_bookmarks_initialize (KatzeArray* array, midori_bookmarks_initialize (KatzeArray* array,
const gchar* filename,
char** errmsg); char** errmsg);
void void

View file

@ -173,7 +173,11 @@ midori_browser_get_property (GObject* object,
void void
midori_bookmarks_import_array_db (sqlite3* db, midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array, KatzeArray* array,
gchar* folder); gint64 parentid);
gboolean
midori_bookmarks_update_item_db (sqlite3* db,
KatzeItem* item);
void void
midori_browser_open_bookmark (MidoriBrowser* browser, midori_browser_open_bookmark (MidoriBrowser* browser,
@ -659,9 +663,10 @@ midori_view_notify_statusbar_text_cb (GtkWidget* view,
} }
static GtkWidget* static GtkWidget*
midori_bookmark_folder_button_new (KatzeArray* array, midori_bookmark_folder_button_new (KatzeArray* array,
gboolean new_bookmark, gboolean new_bookmark,
const gchar* selected) gint64 selected,
gint64 parentid)
{ {
GtkListStore* model; GtkListStore* model;
GtkWidget* combo; GtkWidget* combo;
@ -670,16 +675,16 @@ midori_bookmark_folder_button_new (KatzeArray* array,
sqlite3* db; sqlite3* db;
sqlite3_stmt* statement; sqlite3_stmt* statement;
gint result; gint result;
const gchar* sqlcmd = "SELECT title from bookmarks where uri=''"; const gchar* sqlcmd = "SELECT title, id FROM bookmarks WHERE uri='' ORDER BY title ASC";
model = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT); model = gtk_list_store_new (3, G_TYPE_STRING, G_TYPE_INT, G_TYPE_INT64);
combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model)); combo = gtk_combo_box_new_with_model (GTK_TREE_MODEL (model));
renderer = gtk_cell_renderer_text_new (); renderer = gtk_cell_renderer_text_new ();
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE); gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo), renderer, TRUE);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "text", 0);
gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "ellipsize", 1); gtk_cell_layout_add_attribute (GTK_CELL_LAYOUT (combo), renderer, "ellipsize", 1);
gtk_list_store_insert_with_values (model, NULL, G_MAXINT, gtk_list_store_insert_with_values (model, NULL, G_MAXINT,
0, _("Toplevel folder"), 1, PANGO_ELLIPSIZE_END, -1); 0, _("Toplevel folder"), 1, PANGO_ELLIPSIZE_END, 2, (gint64)0, -1);
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0); gtk_combo_box_set_active (GTK_COMBO_BOX (combo), 0);
db = g_object_get_data (G_OBJECT (array), "db"); db = g_object_get_data (G_OBJECT (array), "db");
@ -689,34 +694,45 @@ midori_bookmark_folder_button_new (KatzeArray* array,
while ((result = sqlite3_step (statement)) == SQLITE_ROW) while ((result = sqlite3_step (statement)) == SQLITE_ROW)
{ {
const unsigned char* name = sqlite3_column_text (statement, 0); const unsigned char* name = sqlite3_column_text (statement, 0);
gtk_list_store_insert_with_values (model, NULL, G_MAXINT, gint64 id = sqlite3_column_int64 (statement, 1);
0, name, 1, PANGO_ELLIPSIZE_END, -1);
if (!new_bookmark && !g_strcmp0 (selected, (gchar*)name)) /* do not show the folder itself */
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), n); if (id != selected)
n++; {
gtk_list_store_insert_with_values (model, NULL, G_MAXINT,
0, name, 1, PANGO_ELLIPSIZE_END, 2, id, -1);
if (!new_bookmark && id == parentid)
gtk_combo_box_set_active (GTK_COMBO_BOX (combo), n);
n++;
}
} }
if (n < 2) if (n < 2)
gtk_widget_set_sensitive (combo, FALSE); gtk_widget_set_sensitive (combo, FALSE);
return combo; return combo;
} }
static gchar* static gint64
midori_bookmark_folder_button_get_active (GtkWidget* combo) midori_bookmark_folder_button_get_active (GtkWidget* combo)
{ {
gchar* selected = NULL; gint64 id;
GtkTreeIter iter; GtkTreeIter iter;
g_return_val_if_fail (GTK_IS_COMBO_BOX (combo), NULL); g_return_val_if_fail (GTK_IS_COMBO_BOX (combo), 0);
if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter))
{ {
gchar* selected = NULL;
GtkTreeModel* model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo)); GtkTreeModel* model = gtk_combo_box_get_model (GTK_COMBO_BOX (combo));
gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &selected, -1); gtk_tree_model_get (GTK_TREE_MODEL (model), &iter, 0, &selected, 2, &id, -1);
if (g_str_equal (selected, _("Toplevel folder"))) if (g_str_equal (selected, _("Toplevel folder")))
katze_assign (selected, g_strdup ("")); id = 0;
g_free (selected);
} }
return selected; return id;
} }
static void static void
@ -861,7 +877,8 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
gtk_size_group_add_widget (sizegroup, label); gtk_size_group_add_widget (sizegroup, label);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
combo_folder = midori_bookmark_folder_button_new (browser->bookmarks, combo_folder = midori_bookmark_folder_button_new (browser->bookmarks,
new_bookmark, katze_item_get_meta_string (bookmark, "folder")); new_bookmark, katze_item_get_meta_integer (bookmark, "id"),
katze_item_get_meta_integer (bookmark, "parentid"));
gtk_box_pack_start (GTK_BOX (hbox), combo_folder, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), combo_folder, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox); gtk_container_add (GTK_CONTAINER (content_area), hbox);
gtk_widget_show_all (hbox); gtk_widget_show_all (hbox);
@ -912,10 +929,7 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT);
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT) if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_ACCEPT)
{ {
gchar* selected; gint64 selected;
if (!new_bookmark)
katze_array_remove_item (browser->bookmarks, bookmark);
katze_item_set_name (bookmark, katze_item_set_name (bookmark,
gtk_entry_get_text (GTK_ENTRY (entry_title))); gtk_entry_get_text (GTK_ENTRY (entry_title)));
@ -930,13 +944,16 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
} }
selected = midori_bookmark_folder_button_get_active (combo_folder); selected = midori_bookmark_folder_button_get_active (combo_folder);
katze_item_set_meta_string (bookmark, "folder", selected); katze_item_set_meta_integer (bookmark, "parentid", selected);
katze_array_add_item (browser->bookmarks, bookmark);
if (new_bookmark)
katze_array_add_item (browser->bookmarks, bookmark);
else
midori_bookmarks_update_item_db (db, bookmark);
if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_toolbar))) if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check_toolbar)))
if (!gtk_widget_get_visible (browser->bookmarkbar)) if (!gtk_widget_get_visible (browser->bookmarkbar))
_action_set_active (browser, "Bookmarkbar", TRUE); _action_set_active (browser, "Bookmarkbar", TRUE);
g_free (selected);
return_status = TRUE; return_status = TRUE;
} }
if (gtk_widget_get_visible (browser->bookmarkbar)) if (gtk_widget_get_visible (browser->bookmarkbar))
@ -3041,14 +3058,35 @@ _action_bookmarks_populate_folder (GtkAction* action,
KatzeArray* folder, KatzeArray* folder,
MidoriBrowser* browser) MidoriBrowser* browser)
{ {
const gchar* folder_name; gint64 id;
KatzeArray* bookmarks; KatzeArray* bookmarks;
GtkWidget* menuitem; GtkWidget* menuitem;
folder_name = katze_item_get_name (KATZE_ITEM (folder)); id = katze_item_get_meta_integer (KATZE_ITEM (folder), "id");
if (!(bookmarks = midori_array_query (browser->bookmarks,
"uri, title, app, folder", "folder = '%q'", folder_name))) if (id == -1)
return FALSE; {
if (!(bookmarks = midori_array_query (browser->bookmarks,
"id, title, parentid, uri, app, pos_panel, pos_bar", "parentid is NULL", NULL)))
{
g_warning ("midori_array_query returned NULL)");
return FALSE;
}
}
else
{
gchar *parentid = g_strdup_printf ("%" G_GINT64_FORMAT, id);
if (!(bookmarks = midori_array_query (browser->bookmarks,
"id, title, parentid, uri, app, pos_panel, pos_bar", "parentid = %q", parentid)))
{
g_warning ("midori_array_query returned NULL (id='%s')", parentid);
g_free (parentid);
return FALSE;
}
g_free (parentid);
}
/* Clear items from dummy array here */ /* Clear items from dummy array here */
gtk_container_foreach (GTK_CONTAINER (menu), gtk_container_foreach (GTK_CONTAINER (menu),
@ -4365,7 +4403,7 @@ _action_bookmarks_import_activate (GtkAction* action,
gtk_size_group_add_widget (sizegroup, label); gtk_size_group_add_widget (sizegroup, label);
gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
combobox_folder = midori_bookmark_folder_button_new (browser->bookmarks, combobox_folder = midori_bookmark_folder_button_new (browser->bookmarks,
FALSE, NULL); FALSE, 0, 0);
gtk_box_pack_start (GTK_BOX (hbox), combobox_folder, TRUE, TRUE, 0); gtk_box_pack_start (GTK_BOX (hbox), combobox_folder, TRUE, TRUE, 0);
gtk_container_add (GTK_CONTAINER (content_area), hbox); gtk_container_add (GTK_CONTAINER (content_area), hbox);
gtk_widget_show_all (hbox); gtk_widget_show_all (hbox);
@ -4375,7 +4413,7 @@ _action_bookmarks_import_activate (GtkAction* action,
{ {
GtkTreeIter iter; GtkTreeIter iter;
gchar* path = NULL; gchar* path = NULL;
gchar* selected = NULL; gint64 selected;
GError* error; GError* error;
sqlite3* db = g_object_get_data (G_OBJECT (browser->bookmarks), "db"); sqlite3* db = g_object_get_data (G_OBJECT (browser->bookmarks), "db");
@ -4408,7 +4446,6 @@ _action_bookmarks_import_activate (GtkAction* action,
midori_bookmarks_import_array_db (db, bookmarks, selected); midori_bookmarks_import_array_db (db, bookmarks, selected);
katze_array_update (browser->bookmarks); katze_array_update (browser->bookmarks);
g_object_unref (bookmarks); g_object_unref (bookmarks);
g_free (selected);
g_free (path); g_free (path);
} }
else else
@ -4465,7 +4502,7 @@ wrong_format:
error = NULL; error = NULL;
bookmarks = midori_array_query_recursive (browser->bookmarks, bookmarks = midori_array_query_recursive (browser->bookmarks,
"*", "folder='%q'", "", TRUE); "*", "parentid IS NULL", NULL, TRUE);
if (!midori_array_to_file (bookmarks, path, format, &error)) if (!midori_array_to_file (bookmarks, path, format, &error))
{ {
sokoke_message_dialog (GTK_MESSAGE_ERROR, sokoke_message_dialog (GTK_MESSAGE_ERROR,
@ -7044,9 +7081,10 @@ midori_bookmarkbar_populate (MidoriBrowser* browser)
gtk_separator_tool_item_new (), -1); gtk_separator_tool_item_new (), -1);
array = midori_array_query (browser->bookmarks, array = midori_array_query (browser->bookmarks,
"uri, title, desc, app, folder, toolbar", "toolbar = 1", NULL); "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "toolbar = 1", NULL);
if (!array) if (!array)
{ {
g_warning ("midori_array_query returned NULL");
_action_set_sensitive (browser, "BookmarkAdd", FALSE); _action_set_sensitive (browser, "BookmarkAdd", FALSE);
_action_set_sensitive (browser, "BookmarkFolderAdd", FALSE); _action_set_sensitive (browser, "BookmarkFolderAdd", FALSE);
return; return;
@ -7058,10 +7096,22 @@ midori_bookmarkbar_populate (MidoriBrowser* browser)
midori_bookmarkbar_insert_item (browser->bookmarkbar, item); midori_bookmarkbar_insert_item (browser->bookmarkbar, item);
else else
{ {
gint64 id = katze_item_get_meta_integer (item, "id");
gchar* parentid = g_strdup_printf ("%" G_GINT64_FORMAT, id);
KatzeArray* subfolder = midori_array_query (browser->bookmarks, KatzeArray* subfolder = midori_array_query (browser->bookmarks,
"uri, title, desc, app", "folder = '%q' AND uri != ''", katze_item_get_name (item)); "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q AND uri != ''",
katze_item_set_name (KATZE_ITEM (subfolder), katze_item_get_name (item)); parentid);
midori_bookmarkbar_insert_item (browser->bookmarkbar, KATZE_ITEM (subfolder));
if (subfolder)
{
katze_item_set_name (KATZE_ITEM (subfolder), katze_item_get_name (item));
katze_item_set_meta_integer (KATZE_ITEM (subfolder), "id", id);
midori_bookmarkbar_insert_item (browser->bookmarkbar, KATZE_ITEM (subfolder));
}
else
g_warning ("midori_array_query returned NULL (id='%s')", parentid);
g_free (parentid);
} }
} }
_action_set_sensitive (browser, "BookmarkAdd", TRUE); _action_set_sensitive (browser, "BookmarkAdd", TRUE);

View file

@ -120,66 +120,87 @@ midori_bookmarks_get_stock_id (MidoriViewable* viewable)
return STOCK_BOOKMARKS; return STOCK_BOOKMARKS;
} }
/* TODO: Function never used */
void void
midori_bookmarks_export_array_db (sqlite3* db, midori_bookmarks_export_array_db (sqlite3* db,
KatzeArray* array, KatzeArray* array,
const gchar* folder) gint64 parentid)
{ {
KatzeArray* root_array; KatzeArray* root_array;
KatzeArray* subarray; KatzeArray* subarray;
KatzeItem* item; KatzeItem* item;
GList* list; GList* list;
gchar* parent_id;
if (!(root_array = midori_array_query (array, "*", "folder='%q'", folder))) parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
if (!(root_array = midori_array_query (array, "*", "parentid = %q", parent_id)))
{
g_free (parent_id);
return; return;
}
KATZE_ARRAY_FOREACH_ITEM_L (item, root_array, list) KATZE_ARRAY_FOREACH_ITEM_L (item, root_array, list)
{ {
if (KATZE_ITEM_IS_FOLDER (item)) if (KATZE_ITEM_IS_FOLDER (item))
{ {
subarray = katze_array_new (KATZE_TYPE_ARRAY); subarray = katze_array_new (KATZE_TYPE_ARRAY);
katze_item_set_name (KATZE_ITEM (subarray), katze_item_get_name (item)); katze_item_set_name (KATZE_ITEM (subarray), katze_item_get_name (item));
midori_bookmarks_export_array_db (db, subarray, katze_item_get_name (item)); midori_bookmarks_export_array_db (db, subarray,
katze_item_get_meta_integer (item, "parentid"));
katze_array_add_item (array, subarray); katze_array_add_item (array, subarray);
} }
else else
katze_array_add_item (array, item); katze_array_add_item (array, item);
} }
g_free (parent_id);
g_list_free (list); g_list_free (list);
} }
void void
midori_bookmarks_import_array_db (sqlite3* db, midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array, KatzeArray* array,
const gchar* folder) gint64 parentid)
{ {
GList* list; GList* list;
KatzeItem* item; KatzeItem* item;
gint64 id;
if (!db) if (!db)
return; return;
KATZE_ARRAY_FOREACH_ITEM_L (item, array, list) KATZE_ARRAY_FOREACH_ITEM_L (item, array, list)
{ {
id = midori_bookmarks_insert_item_db (db, item, parentid);
if (KATZE_IS_ARRAY (item)) if (KATZE_IS_ARRAY (item))
midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), folder); midori_bookmarks_import_array_db (db, KATZE_ARRAY (item), id);
midori_bookmarks_insert_item_db (db, item, folder);
} }
g_list_free (list); g_list_free (list);
} }
static KatzeArray* static KatzeArray*
midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks, midori_bookmarks_read_from_db (MidoriBookmarks* bookmarks,
const gchar* folder, gint64 parentid,
const gchar* keyword) const gchar* keyword)
{ {
KatzeArray* array; KatzeArray* array;
if (keyword && *keyword) if (keyword && *keyword)
array = midori_array_query (bookmarks->array, array = midori_array_query (bookmarks->array,
"uri, title, desc, app, toolbar, folder", "title LIKE '%%%q%%'", keyword); "id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "title LIKE '%%%q%%'", keyword);
else else
array = midori_array_query (bookmarks->array, {
"uri, title, desc, app, toolbar, folder", "folder = '%q'", folder); if (parentid > 0)
{
gchar* parent_id = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
array = midori_array_query (bookmarks->array,
"id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid = %q", parent_id);
g_free (parent_id);
}
else
array = midori_array_query (bookmarks->array,
"id, parentid, title, uri, desc, app, toolbar, pos_panel, pos_bar", "parentid IS NULL", NULL);
}
return array ? array : katze_array_new (KATZE_TYPE_ITEM); return array ? array : katze_array_new (KATZE_TYPE_ITEM);
} }
@ -187,7 +208,7 @@ static void
midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks, midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
GtkTreeStore* model, GtkTreeStore* model,
GtkTreeIter* parent, GtkTreeIter* parent,
const gchar* folder, gint64 parentid,
const gchar* keyword) const gchar* keyword)
{ {
KatzeArray* array; KatzeArray* array;
@ -195,7 +216,7 @@ midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
KatzeItem* item; KatzeItem* item;
GtkTreeIter child; GtkTreeIter child;
array = midori_bookmarks_read_from_db (bookmarks, folder, keyword); array = midori_bookmarks_read_from_db (bookmarks, parentid, keyword);
katze_bookmark_populate_tree_view (array, model, parent); katze_bookmark_populate_tree_view (array, model, parent);
/* Remove invisible dummy row */ /* Remove invisible dummy row */
last = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), parent); last = gtk_tree_model_iter_n_children (GTK_TREE_MODEL (model), parent);
@ -209,23 +230,30 @@ midori_bookmarks_read_from_db_to_model (MidoriBookmarks* bookmarks,
g_object_unref (item); g_object_unref (item);
} }
void gint64
midori_bookmarks_insert_item_db (sqlite3* db, midori_bookmarks_insert_item_db (sqlite3* db,
KatzeItem* item, KatzeItem* item,
const gchar* folder) gint64 parentid)
{ {
gchar* sqlcmd; gchar* sqlcmd;
char* errmsg = NULL; char* errmsg = NULL;
KatzeItem* old_parent; KatzeItem* old_parent;
const gchar* parent; gchar* new_parentid;
gchar* id = NULL;
const gchar* uri = NULL; const gchar* uri = NULL;
const gchar* desc = NULL; const gchar* desc = NULL;
gint64 seq = 0;
/* Bookmarks must have a name, import may produce invalid items */ /* Bookmarks must have a name, import may produce invalid items */
g_return_if_fail (katze_item_get_name (item)); g_return_val_if_fail (katze_item_get_name (item), seq);
if (!db) if (!db)
return; return seq;
if (katze_item_get_meta_integer (item, "id") > 0)
id = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer(item, "id"));
else
id = g_strdup_printf ("NULL");
if (KATZE_ITEM_IS_BOOKMARK (item)) if (KATZE_ITEM_IS_BOOKMARK (item))
uri = katze_item_get_uri (item); uri = katze_item_get_uri (item);
@ -235,30 +263,57 @@ midori_bookmarks_insert_item_db (sqlite3* db,
/* Use folder, otherwise fallback to parent folder */ /* Use folder, otherwise fallback to parent folder */
old_parent = katze_item_get_parent (item); old_parent = katze_item_get_parent (item);
if (folder && *folder) if (parentid > 0)
parent = folder; new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, parentid);
else if (old_parent && katze_item_get_name (old_parent)) else if (old_parent && katze_item_get_meta_integer (old_parent, "id") > 0)
parent = katze_item_get_name (old_parent); new_parentid = g_strdup_printf ("%" G_GINT64_FORMAT, katze_item_get_meta_integer (old_parent, "id"));
else else
parent = ""; new_parentid = g_strdup_printf ("NULL");
sqlcmd = sqlite3_mprintf ( sqlcmd = sqlite3_mprintf (
"INSERT into bookmarks (uri, title, desc, folder, toolbar, app) values" "INSERT INTO bookmarks (id, parentid, title, uri, desc, toolbar, app) "
" ('%q', '%q', '%q', '%q', %d, %d)", "VALUES (%q, %q, '%q', '%q', '%q', %d, %d)",
uri ? uri : "", id,
new_parentid,
katze_item_get_name (item), katze_item_get_name (item),
desc ? desc : "", katze_str_non_null (uri),
parent, katze_str_non_null (desc),
katze_item_get_meta_boolean (item, "toolbar"), katze_item_get_meta_boolean (item, "toolbar"),
katze_item_get_meta_boolean (item, "app")); katze_item_get_meta_boolean (item, "app"));
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK) if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) == SQLITE_OK)
{
/* Get insert id */
if (g_str_equal (id, "NULL"))
{
KatzeArray* seq_array;
sqlite3_free (sqlcmd);
sqlcmd = sqlite3_mprintf (
"SELECT seq FROM sqlite_sequence WHERE name = 'bookmarks'");
seq_array = katze_array_from_sqlite (db, sqlcmd);
if (katze_array_get_nth_item (seq_array, 0))
{
KatzeItem* seq_item = katze_array_get_nth_item (seq_array, 0);
seq = katze_item_get_meta_integer (seq_item, "seq");
katze_item_set_meta_integer (item, "id", seq);
}
g_object_unref (seq_array);
}
}
else
{ {
g_printerr (_("Failed to add bookmark item: %s\n"), errmsg); g_printerr (_("Failed to add bookmark item: %s\n"), errmsg);
sqlite3_free (errmsg); sqlite3_free (errmsg);
} }
sqlite3_free (sqlcmd); sqlite3_free (sqlcmd);
g_free (new_parentid);
g_free (id);
return seq;
} }
static void static void
@ -268,15 +323,9 @@ midori_bookmarks_add_item_cb (KatzeArray* array,
{ {
GtkTreeModel* model; GtkTreeModel* model;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
if (!g_strcmp0 (katze_item_get_meta_string (item, "folder"), "")) gtk_tree_store_clear (GTK_TREE_STORE (model));
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), midori_bookmarks_read_from_db_to_model (bookmarks,
NULL, NULL, G_MAXINT, 0, item, -1); GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
else
{
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks,
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter);
}
} }
static void static void
@ -287,7 +336,7 @@ midori_bookmarks_remove_item_cb (KatzeArray* array,
GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
gtk_tree_store_clear (GTK_TREE_STORE (model)); gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks, midori_bookmarks_read_from_db_to_model (bookmarks,
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter); GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
} }
static void static void
@ -297,7 +346,7 @@ midori_bookmarks_update_cb (KatzeArray* array,
GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); GtkTreeModel* model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview));
gtk_tree_store_clear (GTK_TREE_STORE (model)); gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks, midori_bookmarks_read_from_db_to_model (bookmarks,
GTK_TREE_STORE (model), NULL, NULL, bookmarks->filter); GTK_TREE_STORE (model), NULL, 0, bookmarks->filter);
} }
@ -310,7 +359,7 @@ midori_bookmarks_row_changed_cb (GtkTreeModel* model,
KatzeItem* item; KatzeItem* item;
GtkTreeIter parent; GtkTreeIter parent;
KatzeItem* new_parent = NULL; KatzeItem* new_parent = NULL;
const gchar* parent_name; gint64 parentid;
gtk_tree_model_get (model, iter, 0, &item, -1); gtk_tree_model_get (model, iter, 0, &item, -1);
@ -320,15 +369,15 @@ midori_bookmarks_row_changed_cb (GtkTreeModel* model,
/* Bookmarks must not be moved into non-folder items */ /* Bookmarks must not be moved into non-folder items */
if (!KATZE_ITEM_IS_FOLDER (new_parent)) if (!KATZE_ITEM_IS_FOLDER (new_parent))
parent_name = ""; parentid = 0;
else else
parent_name = katze_item_get_name (new_parent); parentid = katze_item_get_meta_integer (new_parent, "id");
} }
else else
parent_name = ""; parentid = 0;
katze_array_remove_item (bookmarks->array, item); katze_array_remove_item (bookmarks->array, item);
katze_item_set_meta_string (item, "folder", parent_name); katze_item_set_meta_integer (item, "parentid", parentid);
katze_array_add_item (bookmarks->array, item); katze_array_add_item (bookmarks->array, item);
g_object_unref (item); g_object_unref (item);
@ -359,14 +408,24 @@ midori_bookmarks_edit_clicked_cb (GtkWidget* toolitem,
{ {
KatzeItem* item; KatzeItem* item;
MidoriBrowser* browser; MidoriBrowser* browser;
gint64 parentid;
gtk_tree_model_get (model, &iter, 0, &item, -1); gtk_tree_model_get (model, &iter, 0, &item, -1);
g_assert (!KATZE_ITEM_IS_SEPARATOR (item)); g_assert (!KATZE_ITEM_IS_SEPARATOR (item));
browser = midori_browser_get_for_widget (bookmarks->treeview); browser = midori_browser_get_for_widget (bookmarks->treeview);
parentid = katze_item_get_meta_integer (item, "parentid");
midori_browser_edit_bookmark_dialog_new ( midori_browser_edit_bookmark_dialog_new (
browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL); browser, item, FALSE, KATZE_ITEM_IS_FOLDER (item), NULL);
if (katze_item_get_meta_integer (item, "parentid") != parentid)
{
gtk_tree_store_clear (GTK_TREE_STORE (model));
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model),
NULL, 0, NULL);
}
g_object_unref (item); g_object_unref (item);
} }
} }
@ -382,6 +441,47 @@ midori_bookmarks_toolbar_update (MidoriBookmarks *bookmarks)
gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected); gtk_widget_set_sensitive (GTK_WIDGET (bookmarks->edit), selected);
} }
gboolean
midori_bookmarks_update_item_db (sqlite3* db,
KatzeItem* item)
{
gchar* sqlcmd;
char* errmsg = NULL;
gchar* parentid;
gboolean updated;
if (katze_item_get_meta_integer (item, "parentid") > 0)
parentid = g_strdup_printf ("%" G_GINT64_FORMAT,
katze_item_get_meta_integer (item, "parentid"));
else
parentid = g_strdup_printf ("NULL");
sqlcmd = sqlite3_mprintf (
"UPDATE bookmarks SET "
"parentid=%q, title='%q', uri='%q', desc='%q', toolbar=%d, app=%d "
"WHERE id = %" G_GINT64_FORMAT ";",
parentid,
katze_item_get_name (item),
katze_str_non_null (katze_item_get_uri (item)),
katze_str_non_null (katze_item_get_meta_string (item, "desc")),
katze_item_get_meta_boolean (item, "toolbar"),
katze_item_get_meta_boolean (item, "app"),
katze_item_get_meta_integer (item, "id"));
updated = TRUE;
if (sqlite3_exec (db, sqlcmd, NULL, NULL, &errmsg) != SQLITE_OK)
{
updated = FALSE;
g_printerr (_("Failed to update bookmark : %s\n"), errmsg);
sqlite3_free (errmsg);
}
sqlite3_free (sqlcmd);
g_free (parentid);
return updated;
}
static void static void
midori_bookmarks_delete_clicked_cb (GtkWidget* toolitem, midori_bookmarks_delete_clicked_cb (GtkWidget* toolitem,
MidoriBookmarks* bookmarks) MidoriBookmarks* bookmarks)
@ -496,8 +596,8 @@ midori_bookmarks_set_app (MidoriBookmarks* bookmarks,
g_object_ref (app); g_object_ref (app);
bookmarks->array = katze_object_get_object (app, "bookmarks"); bookmarks->array = katze_object_get_object (app, "bookmarks");
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, "", NULL); midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), NULL, 0, NULL);
g_signal_connect (bookmarks->array, "add-item", g_signal_connect_after (bookmarks->array, "add-item",
G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks); G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks);
g_signal_connect (bookmarks->array, "remove-item", g_signal_connect (bookmarks->array, "remove-item",
G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks); G_CALLBACK (midori_bookmarks_remove_item_cb), bookmarks);
@ -687,7 +787,9 @@ midori_bookmarks_open_in_tab_activate_cb (GtkWidget* menuitem,
KatzeItem* child; KatzeItem* child;
KatzeArray* array; KatzeArray* array;
array = midori_bookmarks_read_from_db (bookmarks, katze_item_get_name (item), NULL); array = midori_bookmarks_read_from_db (bookmarks,
katze_item_get_meta_integer (item, "parentid"), NULL);
g_return_if_fail (KATZE_IS_ARRAY (array)); g_return_if_fail (KATZE_IS_ARRAY (array));
KATZE_ARRAY_FOREACH_ITEM (child, array) KATZE_ARRAY_FOREACH_ITEM (child, array)
{ {
@ -843,7 +945,7 @@ midori_bookmarks_row_expanded_cb (GtkTreeView* treeview,
model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview));
gtk_tree_model_get (model, iter, 0, &item, -1); gtk_tree_model_get (model, iter, 0, &item, -1);
midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model), midori_bookmarks_read_from_db_to_model (bookmarks, GTK_TREE_STORE (model),
iter, katze_item_get_name (item), NULL); iter, katze_item_get_meta_integer (item, "id"), NULL);
g_object_unref (item); g_object_unref (item);
} }
@ -885,7 +987,7 @@ midori_bookmarks_filter_timeout_cb (gpointer data)
gtk_tree_store_clear (treestore); gtk_tree_store_clear (treestore);
midori_bookmarks_read_from_db_to_model (bookmarks, midori_bookmarks_read_from_db_to_model (bookmarks,
treestore, NULL, NULL, bookmarks->filter); treestore, NULL, 0, bookmarks->filter);
return FALSE; return FALSE;
} }

View file

@ -40,15 +40,19 @@ midori_bookmarks_get_type (void);
GtkWidget* GtkWidget*
midori_bookmarks_new (void); midori_bookmarks_new (void);
void gint64
midori_bookmarks_insert_item_db (sqlite3* db, midori_bookmarks_insert_item_db (sqlite3* db,
KatzeItem* item, KatzeItem* item,
const gchar* folder); gint64 parentid);
void void
midori_bookmarks_import_array_db (sqlite3* db, midori_bookmarks_import_array_db (sqlite3* db,
KatzeArray* array, KatzeArray* array,
const gchar* folder); gint64 parentid);
gboolean
midori_bookmarks_update_item_db (sqlite3* db,
KatzeItem* item);
G_END_DECLS G_END_DECLS

View file

@ -268,7 +268,7 @@ def configure (conf):
if check_version (conf.env['LIBSOUP_VERSION'], 2, 37, 1): if check_version (conf.env['LIBSOUP_VERSION'], 2, 37, 1):
conf.define ('HAVE_LIBSOUP_2_37_1', 1) conf.define ('HAVE_LIBSOUP_2_37_1', 1)
check_pkg ('libxml-2.0', '2.6') check_pkg ('libxml-2.0', '2.6')
check_pkg ('sqlite3', '3.0', True, var='SQLITE') check_pkg ('sqlite3', '3.6.19', True, var='SQLITE')
if option_enabled ('hildon'): if option_enabled ('hildon'):
if check_pkg ('hildon-1', mandatory=False, var='HILDON'): if check_pkg ('hildon-1', mandatory=False, var='HILDON'):