From 3f75dc69e6b08995872f4033942886caf325ab52 Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Fri, 20 Feb 2009 22:43:08 +0100 Subject: [PATCH] Revise bookmark panel, along with a unit test --- panels/midori-bookmarks.c | 147 +++++++++++++++++++++++++--------- tests/bookmarks.c | 161 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 272 insertions(+), 36 deletions(-) create mode 100644 tests/bookmarks.c diff --git a/panels/midori-bookmarks.c b/panels/midori-bookmarks.c index 2f0b728d..e657d6a6 100644 --- a/panels/midori-bookmarks.c +++ b/panels/midori-bookmarks.c @@ -23,6 +23,7 @@ #include #include +#include void midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser, @@ -138,6 +139,8 @@ midori_bookmarks_edit_clicked_cb (GtkWidget* toolitem, midori_browser_edit_bookmark_dialog_new (MIDORI_BROWSER (browser), item, FALSE); } + + g_object_unref (item); } } @@ -161,6 +164,8 @@ midori_bookmarks_delete_clicked_cb (GtkWidget* toolitem, parent = katze_item_get_parent (item); katze_array_remove_item (parent, item); + + g_object_unref (item); } } @@ -171,18 +176,21 @@ midori_bookmarks_cursor_or_row_changed_cb (GtkTreeView* treeview, GtkTreeModel* model; GtkTreeIter iter; KatzeItem* item; - gboolean is_separator; if (!bookmarks->edit) return; if (katze_tree_view_get_selected_iter (treeview, &model, &iter)) { + gboolean is_separator; + gtk_tree_model_get (model, &iter, 0, &item, -1); is_separator = !KATZE_IS_ARRAY (item) && !katze_item_get_uri (item); gtk_widget_set_sensitive (bookmarks->edit, !is_separator); gtk_widget_set_sensitive (bookmarks->delete, TRUE); + + g_object_unref (item); } else { @@ -266,9 +274,10 @@ static void midori_bookmarks_disconnect_folder (MidoriBookmarks* bookmarks, KatzeArray* array) { - guint i, n; + KatzeItem* item; + guint i; - g_assert (KATZE_IS_ARRAY (array)); + g_return_if_fail (KATZE_IS_ARRAY (array)); g_signal_handlers_disconnect_by_func (array, midori_bookmarks_add_item_cb, bookmarks); @@ -277,10 +286,9 @@ midori_bookmarks_disconnect_folder (MidoriBookmarks* bookmarks, g_signal_handlers_disconnect_by_func (array, midori_bookmarks_clear_cb, bookmarks); - n = katze_array_get_length (array); - for (i = 0; i < n; i++) + i = 0; + while ((item = katze_array_get_nth_item (array, i++))) { - KatzeItem* item = katze_array_get_nth_item (bookmarks->array, i); if (KATZE_IS_ARRAY (item)) midori_bookmarks_disconnect_folder (bookmarks, KATZE_ARRAY (item)); g_object_unref (item); @@ -296,8 +304,8 @@ midori_bookmarks_add_item_cb (KatzeArray* array, GtkTreeIter iter; guint i; - g_assert (KATZE_IS_ARRAY (array)); - g_assert (KATZE_IS_ITEM (added_item)); + g_return_if_fail (KATZE_IS_ARRAY (array)); + g_return_if_fail (KATZE_IS_ITEM (added_item)); if (KATZE_IS_ARRAY (added_item)) { @@ -334,41 +342,57 @@ midori_bookmarks_add_item_cb (KatzeArray* array, &child_iter, &iter, G_MAXINT, 0, added_item, -1); break; } + g_object_unref (item); + i++; } } static void -midori_bookmarks_remove_item_cb (KatzeArray* array, - KatzeItem* removed_item, - MidoriBookmarks* bookmarks) +midori_bookmarks_remove_iter (GtkTreeModel* model, + GtkTreeIter* parent, + KatzeItem* removed_item) { - GtkTreeModel* model; guint i; GtkTreeIter iter; - g_assert (KATZE_IS_ARRAY (array)); - g_assert (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)); i = 0; - /* FIXME: Recurse over children of folders, too */ - while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i)) + while (gtk_tree_model_iter_nth_child (model, &iter, parent, i)) { KatzeItem* item; gtk_tree_model_get (model, &iter, 0, &item, -1); + if (item == removed_item) { gtk_tree_store_remove (GTK_TREE_STORE (model), &iter); g_object_unref (item); break; } + + if (KATZE_IS_ARRAY (item)) + midori_bookmarks_remove_iter (model, &iter, removed_item); + + g_object_unref (item); i++; } +} + +static void +midori_bookmarks_remove_item_cb (KatzeArray* array, + KatzeItem* removed_item, + MidoriBookmarks* bookmarks) +{ + GtkTreeModel* model; + + 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); } @@ -379,17 +403,23 @@ midori_bookmarks_clear_cb (KatzeArray* array, GtkTreeView* treeview; GtkTreeStore* store; - g_assert (KATZE_IS_ARRAY (array)); + g_return_if_fail (KATZE_IS_ARRAY (array)); - /* FIXME: Clear folders */ if (array == bookmarks->array) { treeview = GTK_TREE_VIEW (bookmarks->treeview); store = GTK_TREE_STORE (gtk_tree_view_get_model (treeview)); gtk_tree_store_clear (store); } + else + { + KatzeItem* item; + guint i; - midori_bookmarks_disconnect_folder (bookmarks, array); + i = 0; + while ((item = katze_array_get_nth_item (array, i++))) + midori_bookmarks_remove_item_cb (array, item, bookmarks); + } } static void @@ -398,11 +428,11 @@ midori_bookmarks_insert_folder (MidoriBookmarks* bookmarks, GtkTreeIter* parent, KatzeArray* array) { - guint n, i; KatzeItem* item; + guint i; GtkTreeIter iter; - g_assert (KATZE_IS_ARRAY (array)); + g_return_if_fail (KATZE_IS_ARRAY (array)); g_signal_connect (array, "add-item", G_CALLBACK (midori_bookmarks_add_item_cb), bookmarks); @@ -411,12 +441,11 @@ midori_bookmarks_insert_folder (MidoriBookmarks* bookmarks, g_signal_connect (array, "clear", G_CALLBACK (midori_bookmarks_clear_cb), bookmarks); - n = katze_array_get_length (array); - for (i = 0; i < n; i++) + i = 0; + while ((item = katze_array_get_nth_item (array, i++))) { - item = katze_array_get_nth_item (array, i); g_object_ref (item); - gtk_tree_store_insert_with_values (treestore, &iter, parent, n, + gtk_tree_store_insert_with_values (treestore, &iter, parent, i, 0, item, -1); if (KATZE_IS_ARRAY (item)) midori_bookmarks_insert_folder (bookmarks, treestore, @@ -437,7 +466,11 @@ midori_bookmarks_set_app (MidoriBookmarks* bookmarks, model = gtk_tree_view_get_model (GTK_TREE_VIEW (bookmarks->treeview)); gtk_tree_store_clear (GTK_TREE_STORE (model)); } - katze_assign (bookmarks->app, g_object_ref (app)); + katze_assign (bookmarks->app, app); + if (!app) + return; + + g_object_ref (app); bookmarks->array = katze_object_get_object (app, "bookmarks"); if (bookmarks->array) { @@ -508,8 +541,11 @@ midori_bookmarks_treeview_render_icon_cb (GtkTreeViewColumn* column, MIDORI_BOOKMARKS (gtk_widget_get_parent (treeview))->net, katze_item_get_uri (item), NULL, treeview, NULL); g_object_set (renderer, "pixbuf", pixbuf, NULL); + if (pixbuf) g_object_unref (pixbuf); + + g_object_unref (item); } static void @@ -528,6 +564,8 @@ midori_bookmarks_treeview_render_text_cb (GtkTreeViewColumn* column, "text", katze_item_get_name (item), NULL); else g_object_set (renderer, "markup", _("Separator"), NULL); + + g_object_unref (item); } static void @@ -554,6 +592,8 @@ midori_bookmarks_row_activated_cb (GtkTreeView* treeview, browser = gtk_widget_get_toplevel (GTK_WIDGET (bookmarks)); midori_browser_set_current_uri (MIDORI_BROWSER (browser), uri); } + + g_object_unref (item); } } @@ -711,33 +751,65 @@ midori_bookmarks_button_release_event_cb (GtkWidget* widget, { GtkTreeModel* model; GtkTreeIter iter; - KatzeItem* item; - const gchar* uri; - gint n; if (event->button != 2 && event->button != 3) return FALSE; if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (widget), &model, &iter)) { + KatzeItem* item; + gtk_tree_model_get (model, &iter, 0, &item, -1); - uri = katze_item_get_uri (item); + if (event->button == 2) { + const gchar* uri = katze_item_get_uri (item); + if (uri && *uri) { - GtkWidget* browser = gtk_widget_get_toplevel (widget); + GtkWidget* browser; + gint n; + + browser = gtk_widget_get_toplevel (widget); n = midori_browser_add_uri (MIDORI_BROWSER (browser), uri); midori_browser_set_current_page (MIDORI_BROWSER (browser), n); } } else midori_bookmarks_popup (widget, event, item, bookmarks); + + g_object_unref (item); return TRUE; } return FALSE; } +static gboolean +midori_bookmarks_key_release_event_cb (GtkWidget* widget, + GdkEventKey* event, + MidoriBookmarks* bookmarks) +{ + GtkTreeModel* model; + GtkTreeIter iter; + + if (event->keyval != GDK_Delete) + return FALSE; + + if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (widget), &model, &iter)) + { + KatzeItem* item; + KatzeArray* parent; + + gtk_tree_model_get (model, &iter, 0, &item, -1); + parent = katze_item_get_parent (item); + katze_array_remove_item (parent, item); + + g_object_unref (item); + } + + return FALSE; +} + static void midori_bookmarks_popup_menu_cb (GtkWidget* widget, MidoriBookmarks* bookmarks) @@ -750,6 +822,7 @@ midori_bookmarks_popup_menu_cb (GtkWidget* widget, { gtk_tree_model_get (model, &iter, 0, &item, -1); midori_bookmarks_popup (widget, NULL, item, bookmarks); + g_object_unref (item); } } @@ -791,6 +864,8 @@ midori_bookmarks_init (MidoriBookmarks* bookmarks) midori_bookmarks_cursor_or_row_changed_cb, bookmarks, "signal::button-release-event", midori_bookmarks_button_release_event_cb, bookmarks, + "signal::key-release-event", + midori_bookmarks_key_release_event_cb, bookmarks, "signal::popup-menu", midori_bookmarks_popup_menu_cb, bookmarks, NULL); diff --git a/tests/bookmarks.c b/tests/bookmarks.c new file mode 100644 index 00000000..8f759cd0 --- /dev/null +++ b/tests/bookmarks.c @@ -0,0 +1,161 @@ +/* + 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. +*/ + +#if HAVE_CONFIG_H + #include +#endif + +#include "midori.h" +#include "midori-bookmarks.h" + +#if GLIB_CHECK_VERSION(2, 16, 0) + +static void +bookmarks_panel_create (void) +{ + MidoriApp* app; + MidoriBookmarks* bookmarks; + gpointer value; + + app = g_object_new (MIDORI_TYPE_APP, NULL); + + bookmarks = g_object_new (MIDORI_TYPE_BOOKMARKS, NULL); + value = katze_object_get_object (bookmarks, "app"); + g_assert (value == NULL); + gtk_widget_destroy (GTK_WIDGET (bookmarks)); + + bookmarks = g_object_new (MIDORI_TYPE_BOOKMARKS, "app", app, NULL); + value = katze_object_get_object (bookmarks, "app"); + g_assert (value == app); + gtk_widget_destroy (GTK_WIDGET (bookmarks)); + + bookmarks = g_object_new (MIDORI_TYPE_BOOKMARKS, NULL); + g_object_set (bookmarks, "app", app, NULL); + value = katze_object_get_object (bookmarks, "app"); + g_assert (value == app); + gtk_widget_destroy (GTK_WIDGET (bookmarks)); +} + +static KatzeItem* +bookmark_new (const gchar* uri, + const gchar* title) +{ + return g_object_new (KATZE_TYPE_ITEM, "uri", uri, "name", title, NULL); +} + +static KatzeArray* +folder_new (const gchar* title) +{ + KatzeArray* folder; + + folder = katze_array_new (KATZE_TYPE_ARRAY); + g_object_set (folder, "name", title, NULL); + return folder; +} + +static void +bookmarks_panel_fill (void) +{ + MidoriApp* app; + KatzeArray* array; + MidoriBookmarks* bookmarks; + GList* children; + GtkWidget* treeview; + GtkTreeModel* model; + GtkTreeIter iter; + KatzeItem* bookmark; + KatzeArray* folder; + guint n; + gpointer value; + + app = g_object_new (MIDORI_TYPE_APP, NULL); + array = katze_array_new (KATZE_TYPE_ARRAY); + g_object_set (app, "bookmarks", array, NULL); + value = katze_object_get_object (app, "bookmarks"); + g_assert (value == array); + bookmarks = g_object_new (MIDORI_TYPE_BOOKMARKS, "app", app, NULL); + children = gtk_container_get_children (GTK_CONTAINER (bookmarks)); + treeview = g_list_nth_data (children, 0); + g_list_free (children); + g_assert (GTK_IS_TREE_VIEW (treeview)); + model = gtk_tree_view_get_model (GTK_TREE_VIEW (treeview)); + g_assert (GTK_IS_TREE_MODEL (model)); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 0); + bookmark = bookmark_new ("http://www.example.com", "Example"); + katze_array_add_item (array, bookmark); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 1); + katze_array_remove_item (array, bookmark); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 0); + bookmark = bookmark_new ("http://www.example.com", "Example"); + katze_array_add_item (array, bookmark); + folder = folder_new ("Empty"); + katze_array_add_item (array, folder); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 2); + katze_array_remove_item (array, folder); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 1); + folder = folder_new ("Empty"); + katze_array_add_item (array, folder); + folder = folder_new ("Kurioses"); + katze_array_add_item (array, folder); + bookmark = bookmark_new ("http://www.ende.de", "Das Ende"); + katze_array_add_item (folder, bookmark); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 3); + folder = folder_new ("Miscellaneous"); + katze_array_add_item (array, folder); + gtk_tree_model_iter_nth_child (model, &iter, NULL, 3); + n = gtk_tree_model_iter_n_children (model, &iter); + g_assert_cmpint (n, ==, 0); + bookmark = bookmark_new ("http://thesaurus.reference.com/", "Thesaurus"); + katze_array_add_item (folder, bookmark); + n = gtk_tree_model_iter_n_children (model, &iter); + g_assert_cmpint (n, ==, 1); + bookmark = bookmark_new ("http://en.wikipedia.org/", "Wikipedia"); + katze_array_add_item (folder, bookmark); + n = gtk_tree_model_iter_n_children (model, &iter); + g_assert_cmpint (n, ==, 2); + katze_array_remove_item (folder, bookmark); + n = gtk_tree_model_iter_n_children (model, &iter); + g_assert_cmpint (n, ==, 1); + katze_array_remove_item (array, folder); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 3); + katze_array_add_item (array, folder); + /* katze_array_clear (folder); + n = gtk_tree_model_iter_n_children (model, &iter); + g_assert_cmpint (n, ==, 0); */ + katze_array_clear (array); + n = gtk_tree_model_iter_n_children (model, NULL); + g_assert_cmpint (n, ==, 0); +} + +int +main (int argc, + char** argv) +{ + /* libSoup uses threads, therefore if WebKit is built with libSoup + or Midori is using it, we need to initialize threads. */ + if (!g_thread_supported ()) g_thread_init (NULL); + g_test_init (&argc, &argv, NULL); + gtk_init_check (&argc, &argv); + + g_test_add_func ("/bookmarks/panel/create", bookmarks_panel_create); + g_test_add_func ("/bookmarks/panel/fill", bookmarks_panel_fill); + + return g_test_run (); +} + +#endif -- 2.39.5