]> spindle.queued.net Git - midori/commitdiff
Revise bookmark panel, along with a unit test
authorChristian Dywan <christian@twotoasts.de>
Fri, 20 Feb 2009 21:43:08 +0000 (22:43 +0100)
committerChristian Dywan <christian@twotoasts.de>
Fri, 20 Feb 2009 21:43:08 +0000 (22:43 +0100)
panels/midori-bookmarks.c
tests/bookmarks.c [new file with mode: 0644]

index 2f0b728d1f786f65bac50c1155d87389eeed6498..e657d6a6d3b0939b630a2f62dc891c7a8fdf79ba 100644 (file)
@@ -23,6 +23,7 @@
 #include <string.h>
 
 #include <katze/katze.h>
+#include <gdk/gdkkeysyms.h>
 
 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", _("<i>Separator</i>"), 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 (file)
index 0000000..8f759cd
--- /dev/null
@@ -0,0 +1,161 @@
+/*
+ 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.
+*/
+
+#if HAVE_CONFIG_H
+    #include <config.h>
+#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