]> spindle.queued.net Git - midori/commitdiff
Revamp bookmarkbar items based on KatzeArrayAction
authorChristian Dywan <christian@twotoasts.de>
Sun, 26 Oct 2008 21:22:26 +0000 (22:22 +0100)
committerChristian Dywan <christian@twotoasts.de>
Sun, 26 Oct 2008 21:22:26 +0000 (22:22 +0100)
Some refactoring in KatzeArrayAction and the addition
of a function to create arbitrary bookmark tool items
allows us to easily revamp the bookmarkbar so that
it finally reflectls changes to the bookmarks,
including adding and removing items.

katze/katze-arrayaction.c
katze/katze-arrayaction.h
midori/midori-browser.c

index f0287362839681f3e7adf84a07f831ff54ee463a..cc5f45f186f231087d0381e78bc44fd2af9140d0 100644 (file)
@@ -223,22 +223,21 @@ katze_array_action_icon_cb (GdkPixbuf* icon,
 
 static void
 katze_array_action_menu_item_select_cb (GtkWidget*        proxy,
-                                        KatzeArrayAction* array_action)
+                                        KatzeArrayAction* array_action);
+
+static void
+katze_array_action_generate_menu (KatzeArrayAction* array_action,
+                                  KatzeArray*       array,
+                                  GtkWidget*        menu,
+                                  GtkWidget*        proxy)
 {
     guint n, i;
-    GtkWidget* menu;
+    KatzeItem* item;
     GtkWidget* menuitem;
+    GdkPixbuf* icon;
+    GtkWidget* image;
     GtkWidget* submenu;
-    KatzeArray* array;
-    KatzeItem* item;
-    GdkPixbuf* pixbuf;
-    GtkWidget* icon;
-
-    menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy));
-    gtk_container_foreach (GTK_CONTAINER (menu),
-        (GtkCallback)(gtk_widget_destroy), NULL);
 
-    array = g_object_get_data (G_OBJECT (proxy), "KatzeItem");
     n = katze_array_get_length (array);
     if (n > 0)
     for (i = 0; i < n; i++)
@@ -255,16 +254,16 @@ katze_array_action_menu_item_select_cb (GtkWidget*        proxy,
         menuitem = katze_image_menu_item_new_ellipsized (
             katze_item_get_name (item));
         if (KATZE_IS_ARRAY (item))
-            pixbuf = gtk_widget_render_icon (menuitem,
+            icon = gtk_widget_render_icon (menuitem,
                 GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
         else
-            pixbuf = katze_net_load_icon (array_action->net,
+            icon = katze_net_load_icon (array_action->net,
                 katze_item_get_uri (item),
                 (KatzeNetIconCb)katze_array_action_icon_cb,
                 proxy, g_object_ref (menuitem));
-        icon = gtk_image_new_from_pixbuf (pixbuf);
-        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-        g_object_unref (pixbuf);
+        image = gtk_image_new_from_pixbuf (icon);
+        g_object_unref (icon);
+        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
         g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
         if (KATZE_IS_ARRAY (item))
@@ -288,17 +287,27 @@ katze_array_action_menu_item_select_cb (GtkWidget*        proxy,
     }
 }
 
+static void
+katze_array_action_menu_item_select_cb (GtkWidget*        proxy,
+                                        KatzeArrayAction* array_action)
+{
+    GtkWidget* menu;
+    KatzeArray* array;
+
+    menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (proxy));
+    gtk_container_foreach (GTK_CONTAINER (menu),
+        (GtkCallback)(gtk_widget_destroy), NULL);
+
+    array = g_object_get_data (G_OBJECT (proxy), "KatzeItem");
+    katze_array_action_generate_menu (array_action, array, menu, proxy);
+}
+
 static void
 katze_array_action_proxy_clicked_cb (GtkWidget*        proxy,
                                      KatzeArrayAction* array_action)
 {
-    guint n, i;
     GtkWidget* menu;
-    GtkWidget* menuitem;
-    GtkWidget* submenu;
-    KatzeItem* item;
-    GdkPixbuf* pixbuf;
-    GtkWidget* icon;
+    KatzeArray* array;
 
     if (GTK_IS_MENU_ITEM (proxy))
     {
@@ -311,50 +320,14 @@ katze_array_action_proxy_clicked_cb (GtkWidget*        proxy,
 
     menu = gtk_menu_new ();
 
-    n = katze_array_get_length (array_action->array);
-    if (n > 0)
-    for (i = 0; i < n; i++)
-    {
-        item = katze_array_get_nth_item (array_action->array, i);
-        /* FIXME: The menu item should reflect changes to the item  */
-        if (!KATZE_IS_ARRAY (item) && !katze_item_get_uri (item))
-        {
-            menuitem = gtk_separator_menu_item_new ();
-            gtk_widget_show (menuitem);
-            gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-            continue;
-        }
-        menuitem = katze_image_menu_item_new_ellipsized (
-            katze_item_get_name (item));
-        pixbuf = gtk_widget_render_icon (menuitem,
-            KATZE_IS_ARRAY (item) ? GTK_STOCK_DIRECTORY : GTK_STOCK_FILE,
-            GTK_ICON_SIZE_MENU, NULL);
-        icon = gtk_image_new_from_pixbuf (pixbuf);
-        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon);
-        g_object_unref (pixbuf);
-        gtk_widget_show (menuitem);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-        g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
-        if (KATZE_IS_ARRAY (item))
-        {
-            submenu = gtk_menu_new ();
-            gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
-            g_signal_connect (menuitem, "select",
-                G_CALLBACK (katze_array_action_menu_item_select_cb), array_action);
-        }
-        else
-            g_signal_connect (menuitem, "activate",
-                G_CALLBACK (katze_array_action_menu_item_activate_cb), array_action);
-    }
-    else
-    {
-        menuitem = gtk_image_menu_item_new_with_label (_("Empty"));
-        gtk_widget_set_sensitive (menuitem, FALSE);
-        gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-        gtk_widget_show (menuitem);
-    }
+    array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeArray");
+    if (!array)
+        array = array_action->array;
+    katze_array_action_generate_menu (array_action, array, menu, proxy);
 
-    g_signal_emit (array_action, signals[POPULATE_POPUP], 0, menu);
+    /* populate-popup should only affect the main proxy */
+    if (array == array_action->array)
+        g_signal_emit (array_action, signals[POPULATE_POPUP], 0, menu);
 
     katze_widget_popup (GTK_WIDGET (proxy), GTK_MENU (menu),
                         NULL, KATZE_MENU_POSITION_LEFT);
@@ -378,6 +351,106 @@ katze_array_action_create_tool_item (GtkAction* action)
     return toolitem;
 }
 
+static void
+katze_array_action_item_notify_cb (KatzeItem*   item,
+                                   GParamSpec*  pspec,
+                                   GtkToolItem* toolitem)
+{
+    KatzeArrayAction* array_action;
+    const gchar* property;
+    const gchar* title;
+    const gchar* desc;
+    GdkPixbuf* icon;
+    GtkWidget* image;
+
+    if (!G_IS_PARAM_SPEC_STRING (pspec))
+        return;
+
+    array_action = (KatzeArrayAction*)g_object_get_data (
+        G_OBJECT (toolitem), "KatzeArrayAction");
+    property = g_param_spec_get_name (pspec);
+    if (!strcmp (property, "name"))
+    {
+        title = katze_item_get_name (item);
+        if (title)
+            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+        else
+            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem),
+                katze_item_get_uri (item));
+    }
+    else if (!strcmp (property, "text"))
+    {
+        desc = katze_item_get_text (item);
+        if (desc && *desc)
+            gtk_tool_item_set_tooltip_text (toolitem, desc);
+        else
+            gtk_tool_item_set_tooltip_text (toolitem,
+                katze_item_get_uri (item));
+    }
+    else if (!KATZE_IS_ARRAY (item) && !strcmp (property, "uri"))
+    {
+        icon = katze_net_load_icon (array_action->net, katze_item_get_uri (item),
+            (KatzeNetIconCb)katze_array_action_icon_cb,
+            GTK_WIDGET (toolitem), g_object_ref (toolitem));
+        image = gtk_image_new_from_pixbuf (icon);
+        g_object_unref (icon);
+        gtk_widget_show (image);
+        gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
+    }
+}
+
+GtkToolItem*
+katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
+                                         KatzeItem*        item)
+{
+    const gchar* title;
+    const gchar* uri;
+    const gchar* desc;
+    GtkToolItem* toolitem;
+    GdkPixbuf* icon;
+    GtkWidget* image;
+
+    title = katze_item_get_name (item);
+    uri = katze_item_get_uri (item);
+    desc = katze_item_get_text (item);
+
+    if (!KATZE_IS_ARRAY (item) && !uri)
+        return gtk_separator_tool_item_new ();
+
+    toolitem = gtk_tool_button_new (NULL, NULL);
+    if (KATZE_IS_ARRAY (item))
+        icon = gtk_widget_render_icon (GTK_WIDGET (toolitem),
+            GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
+    else
+        icon = katze_net_load_icon (array_action->net, uri,
+            (KatzeNetIconCb)katze_array_action_icon_cb,
+            GTK_WIDGET (toolitem), g_object_ref (toolitem));
+    image = gtk_image_new_from_pixbuf (icon);
+    g_object_unref (icon);
+    gtk_widget_show (image);
+    gtk_tool_button_set_icon_widget (GTK_TOOL_BUTTON (toolitem), image);
+    if (title)
+        gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
+    else
+        gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), uri);
+    gtk_tool_item_set_is_important (toolitem, TRUE);
+    if (desc && *desc)
+        gtk_tool_item_set_tooltip_text (toolitem, desc);
+    else
+        gtk_tool_item_set_tooltip_text (toolitem, uri);
+    if (KATZE_IS_ARRAY (item))
+    {
+        g_object_set_data (G_OBJECT (toolitem), "KatzeArray", item);
+        g_signal_connect (toolitem, "clicked",
+            G_CALLBACK (katze_array_action_proxy_clicked_cb), array_action);
+    }
+
+    g_object_set_data (G_OBJECT (toolitem), "KatzeArrayAction", array_action);
+    g_signal_connect (item, "notify",
+        G_CALLBACK (katze_array_action_item_notify_cb), toolitem);
+    return toolitem;
+}
+
 static void
 katze_array_action_connect_proxy (GtkAction* action,
                                   GtkWidget* proxy)
index b4e9ee22fee007c1dcff7fe374a8ba7e0fa7bd00..062ffbd0cd7b84f85bc8e05596d1322e87730898 100644 (file)
@@ -14,6 +14,8 @@
 
 #include "katze-array.h"
 
+#include <gtk/gtk.h>
+
 G_BEGIN_DECLS
 
 #define KATZE_TYPE_ARRAY_ACTION \
@@ -42,6 +44,10 @@ void
 katze_array_action_set_array            (KatzeArrayAction* array_action,
                                          KatzeArray*       array);
 
+GtkToolItem*
+katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
+                                         KatzeItem*        item);
+
 G_END_DECLS
 
 #endif /* __KATZE_ARRAY_ACTION_H__ */
index 08f99fdfae83e0add954c53fe96b6713a33a701e..0df54628058ca6f52c39f05ad97bbeb461eacf46 100644 (file)
@@ -2443,46 +2443,6 @@ midori_browser_bookmarks_item_render_text_cb (GtkTreeViewColumn* column,
         g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL);
 }
 
-static void
-_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
-                                      KatzeArray*    array,
-                                      GtkWidget*     menu);
-
-static void
-midori_browser_bookmark_menu_folder_activate_cb (GtkWidget*     menuitem,
-                                                 MidoriBrowser* browser)
-{
-    GtkWidget* menu;
-    KatzeArray* array;
-
-    menu = gtk_menu_item_get_submenu (GTK_MENU_ITEM (menuitem));
-    gtk_container_foreach (GTK_CONTAINER (menu), (GtkCallback) gtk_widget_destroy, NULL);
-    array = (KatzeArray*)g_object_get_data (G_OBJECT (menuitem), "KatzeArray");
-    _midori_browser_create_bookmark_menu (browser, array, menu);
-    /* Remove all menuitems when the menu is hidden.
-       FIXME: We really *want* the line below, but it won't work like that
-       g_signal_connect_after (menu, "hide", G_CALLBACK (gtk_container_foreach), gtk_widget_destroy); */
-    gtk_widget_show (menuitem);
-}
-
-static void
-midori_browser_bookmarkbar_folder_activate_cb (GtkToolItem*   toolitem,
-                                               MidoriBrowser* browser)
-{
-    GtkWidget* menu;
-    KatzeArray* array;
-
-    menu = gtk_menu_new ();
-    array = (KatzeArray*)g_object_get_data (G_OBJECT (toolitem), "KatzeArray");
-    _midori_browser_create_bookmark_menu (browser, array, menu);
-    /* Remove all menuitems when the menu is hidden.
-       FIXME: We really *should* run the line below, but it won't work like that
-       g_signal_connect (menu, "hide", G_CALLBACK (gtk_container_foreach),
-                         gtk_widget_destroy); */
-    sokoke_widget_popup (GTK_WIDGET (toolitem), GTK_MENU (menu),
-                        NULL, SOKOKE_MENU_POSITION_LEFT);
-}
-
 static void
 midori_browser_menu_bookmarks_item_activate_cb (GtkWidget*     widget,
                                                 MidoriBrowser* browser)
@@ -2505,13 +2465,16 @@ midori_browser_bookmarkbar_item_button_press_event_cb (GtkWidget*      toolitem,
 
     if (event->button == 2)
     {
-        g_object_get (browser->settings, "open-tabs-in-the-background",
-            &open_in_background, NULL);
         item = (KatzeItem*)g_object_get_data (G_OBJECT (toolitem), "KatzeItem");
-        n = midori_browser_add_uri (browser, katze_item_get_uri (item));
-        if (!open_in_background)
-            midori_browser_set_current_page (browser, n);
-        return TRUE;
+        if (katze_item_get_uri (item))
+        {
+            g_object_get (browser->settings, "open-tabs-in-the-background",
+                &open_in_background, NULL);
+            n = midori_browser_add_uri (browser, katze_item_get_uri (item));
+            if (!open_in_background)
+                midori_browser_set_current_page (browser, n);
+            return TRUE;
+        }
     }
     else if (event->button == 3)
     {
@@ -2522,64 +2485,6 @@ midori_browser_bookmarkbar_item_button_press_event_cb (GtkWidget*      toolitem,
     return FALSE;
 }
 
-static void
-_midori_browser_create_bookmark_menu (MidoriBrowser* browser,
-                                      KatzeArray*    array,
-                                      GtkWidget*     menu)
-{
-    guint i, n;
-    KatzeItem* item;
-    const gchar* title;
-    GtkWidget* menuitem;
-    GtkWidget* submenu;
-    GtkWidget* image;
-    GdkPixbuf* icon;
-
-    n = katze_array_get_length (array);
-    for (i = 0; i < n; i++)
-    {
-        item = katze_array_get_nth_item (array, i);
-        title = katze_item_get_name (item);
-
-        if (KATZE_IS_ARRAY (item))
-        {
-            /* FIXME: what about the "folded" status */
-            menuitem = sokoke_image_menu_item_new_ellipsized (title);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
-                gtk_image_new_from_stock (GTK_STOCK_DIRECTORY,
-                                          GTK_ICON_SIZE_MENU));
-            submenu = gtk_menu_new ();
-            gtk_menu_item_set_submenu (GTK_MENU_ITEM (menuitem), submenu);
-            g_signal_connect (menuitem, "activate",
-                G_CALLBACK (midori_browser_bookmark_menu_folder_activate_cb),
-                browser);
-            g_object_set_data (G_OBJECT (menuitem), "KatzeArray", item);
-        }
-        else if (katze_item_get_uri (item))
-        {
-            menuitem = sokoke_image_menu_item_new_ellipsized (title);
-            image = gtk_image_new ();
-            /* FIXME: Implement icon_cb */
-            icon = katze_net_load_icon (browser->net,
-                katze_item_get_uri (item),
-                NULL /*(KatzeNetIconCb)midori_browser_bookmark_icon_cb*/,
-                GTK_WIDGET (browser), NULL /*g_object_ref (image)*/);
-            gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);
-            g_object_unref (icon);
-            gtk_widget_show (image);
-            gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
-            g_signal_connect (menuitem, "activate",
-                G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
-                browser);
-            g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
-        }
-        else
-            menuitem = gtk_separator_menu_item_new ();
-         gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
-         gtk_widget_show (menuitem);
-    }
-}
-
 static void
 _action_bookmark_add_activate (GtkAction*     action,
                                MidoriBrowser* browser)
@@ -4193,20 +4098,61 @@ midori_browser_settings_notify (MidoriWebSettings* web_settings,
     g_value_unset (&value);
 }
 
+static void
+browser_bookmarks_add_item_cb (KatzeArray*    array,
+                               KatzeItem*     item,
+                               MidoriBrowser* browser)
+{
+    GtkToolItem* toolitem;
+
+    toolitem = katze_array_action_create_tool_item_for (
+        KATZE_ARRAY_ACTION (_action_by_name (browser, "Bookmarks")), item);
+
+    g_object_set_data (G_OBJECT (toolitem), "KatzeItem", item);
+    if (!KATZE_IS_ARRAY (item) && katze_item_get_uri (item))
+        g_signal_connect (toolitem, "clicked",
+            G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
+            browser);
+    if (KATZE_IS_ARRAY (item) || katze_item_get_uri (item))
+    {
+        g_signal_connect (gtk_bin_get_child (GTK_BIN (toolitem)),
+            "button-press-event",
+            G_CALLBACK (midori_browser_bookmarkbar_item_button_press_event_cb),
+            browser);
+        g_object_set_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (toolitem))),
+            "KatzeItem", item);
+    }
+    gtk_widget_show (GTK_WIDGET (toolitem));
+    gtk_toolbar_insert (GTK_TOOLBAR (browser->bookmarkbar), toolitem, -1);
+}
+
+static void
+browser_bookmarks_remove_item_cb (KatzeArray*    array,
+                                  KatzeItem*     removed_item,
+                                  MidoriBrowser* browser)
+{
+    GList* children;
+    GtkWidget* toolitem;
+    KatzeItem* item;
+
+    children = gtk_container_get_children (GTK_CONTAINER (browser->bookmarkbar));
+    while (children != NULL)
+    {
+        toolitem = GTK_WIDGET (children->data);
+        item = (KatzeItem*)g_object_get_data (G_OBJECT (toolitem), "KatzeItem");
+        if (item == removed_item)
+            gtk_widget_destroy (toolitem);
+        children = g_list_next (children);
+    }
+}
+
 static void
 midori_browser_load_bookmarks (MidoriBrowser* browser)
 {
     guint i, n;
     KatzeItem* item;
-    const gchar* title;
-    const gchar* desc;
-    GtkWidget* image;
-    GdkPixbuf* icon;
-    GtkToolItem* toolitem;
     GtkTreeModel* treestore;
 
-    // FIXME: Clear bookmarks menu
-    // FIXME: Clear bookmarkbar
     // FIXME: Clear bookmark panel
 
     _action_set_sensitive (browser, "BookmarkAdd", FALSE);
@@ -4218,51 +4164,12 @@ midori_browser_load_bookmarks (MidoriBrowser* browser)
     for (i = 0; i < n; i++)
     {
         item = katze_array_get_nth_item (browser->bookmarks, i);
-        title = katze_item_get_name (item);
-        desc = katze_item_get_text (item);
-
-        if (KATZE_IS_ARRAY (item))
-        {
-            toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DIRECTORY);
-            gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), title);
-            gtk_tool_item_set_is_important (toolitem, TRUE);
-            g_signal_connect (toolitem, "clicked",
-                G_CALLBACK (midori_browser_bookmarkbar_folder_activate_cb),
-                browser);
-            if (desc && *desc)
-                gtk_tool_item_set_tooltip_text (toolitem, desc);
-            g_object_set_data (G_OBJECT (toolitem), "KatzeArray", item);
-        }
-        else if (katze_item_get_uri (item))
-        {
-            image = gtk_image_new ();
-            /* FIXME: Implement icon_cb */
-            icon = katze_net_load_icon (browser->net,
-                katze_item_get_uri (item),
-                NULL /*(KatzeNetIconCb)midori_browser_bookmark_icon_cb*/,
-                GTK_WIDGET (browser), NULL /*g_object_ref (image)*/);
-            gtk_image_set_from_pixbuf (GTK_IMAGE (image), icon);
-            g_object_unref (icon);
-            toolitem = gtk_tool_button_new (image, title);
-            gtk_tool_item_set_is_important (toolitem, TRUE);
-            g_signal_connect (toolitem, "clicked",
-                G_CALLBACK (midori_browser_menu_bookmarks_item_activate_cb),
-                browser);
-            g_signal_connect (gtk_bin_get_child (GTK_BIN (toolitem)),
-                "button-press-event",
-                G_CALLBACK (midori_browser_bookmarkbar_item_button_press_event_cb),
-                browser);
-            if (desc && *desc)
-                gtk_tool_item_set_tooltip_text (toolitem, desc);
-            g_object_set_data (G_OBJECT (toolitem), "KatzeItem", item);
-            g_object_set_data (G_OBJECT (gtk_bin_get_child (GTK_BIN (toolitem))),
-                "KatzeItem", item);
-        }
-        else
-            toolitem = gtk_separator_tool_item_new ();
-        gtk_toolbar_insert (GTK_TOOLBAR (browser->bookmarkbar), toolitem, -1);
+        browser_bookmarks_add_item_cb (browser->bookmarks, item, browser);
     }
-    sokoke_container_show_children (GTK_CONTAINER (browser->bookmarkbar));
+    g_signal_connect (browser->bookmarks, "add-item",
+        G_CALLBACK (browser_bookmarks_add_item_cb), browser);
+    g_signal_connect (browser->bookmarks, "remove-item",
+        G_CALLBACK (browser_bookmarks_remove_item_cb), browser);
 
     treestore = gtk_tree_view_get_model (GTK_TREE_VIEW (browser->panel_bookmarks));
     _tree_store_insert_folder (GTK_TREE_STORE (treestore),