Revamp bookmarkbar items based on KatzeArrayAction

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.
This commit is contained in:
Christian Dywan 2008-10-26 22:22:26 +01:00
parent 7a7353e6fd
commit 23e784922e
3 changed files with 207 additions and 221 deletions

View file

@ -223,22 +223,21 @@ katze_array_action_icon_cb (GdkPixbuf* icon,
static void static void
katze_array_action_menu_item_select_cb (GtkWidget* proxy, 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; guint n, i;
GtkWidget* menu;
GtkWidget* menuitem;
GtkWidget* submenu;
KatzeArray* array;
KatzeItem* item; KatzeItem* item;
GdkPixbuf* pixbuf; GtkWidget* menuitem;
GtkWidget* icon; GdkPixbuf* icon;
GtkWidget* image;
GtkWidget* submenu;
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); n = katze_array_get_length (array);
if (n > 0) if (n > 0)
for (i = 0; i < n; i++) 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 ( menuitem = katze_image_menu_item_new_ellipsized (
katze_item_get_name (item)); katze_item_get_name (item));
if (KATZE_IS_ARRAY (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); GTK_STOCK_DIRECTORY, GTK_ICON_SIZE_MENU, NULL);
else else
pixbuf = katze_net_load_icon (array_action->net, icon = katze_net_load_icon (array_action->net,
katze_item_get_uri (item), katze_item_get_uri (item),
(KatzeNetIconCb)katze_array_action_icon_cb, (KatzeNetIconCb)katze_array_action_icon_cb,
proxy, g_object_ref (menuitem)); proxy, g_object_ref (menuitem));
icon = gtk_image_new_from_pixbuf (pixbuf); image = gtk_image_new_from_pixbuf (icon);
gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon); g_object_unref (icon);
g_object_unref (pixbuf); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), image);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item); g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
if (KATZE_IS_ARRAY (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 static void
katze_array_action_proxy_clicked_cb (GtkWidget* proxy, katze_array_action_proxy_clicked_cb (GtkWidget* proxy,
KatzeArrayAction* array_action) KatzeArrayAction* array_action)
{ {
guint n, i;
GtkWidget* menu; GtkWidget* menu;
GtkWidget* menuitem; KatzeArray* array;
GtkWidget* submenu;
KatzeItem* item;
GdkPixbuf* pixbuf;
GtkWidget* icon;
if (GTK_IS_MENU_ITEM (proxy)) if (GTK_IS_MENU_ITEM (proxy))
{ {
@ -311,50 +320,14 @@ katze_array_action_proxy_clicked_cb (GtkWidget* proxy,
menu = gtk_menu_new (); menu = gtk_menu_new ();
n = katze_array_get_length (array_action->array); array = (KatzeArray*)g_object_get_data (G_OBJECT (proxy), "KatzeArray");
if (n > 0) if (!array)
for (i = 0; i < n; i++) array = array_action->array;
{ katze_array_action_generate_menu (array_action, array, menu, proxy);
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);
}
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), katze_widget_popup (GTK_WIDGET (proxy), GTK_MENU (menu),
NULL, KATZE_MENU_POSITION_LEFT); NULL, KATZE_MENU_POSITION_LEFT);
@ -378,6 +351,106 @@ katze_array_action_create_tool_item (GtkAction* action)
return toolitem; 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 static void
katze_array_action_connect_proxy (GtkAction* action, katze_array_action_connect_proxy (GtkAction* action,
GtkWidget* proxy) GtkWidget* proxy)

View file

@ -14,6 +14,8 @@
#include "katze-array.h" #include "katze-array.h"
#include <gtk/gtk.h>
G_BEGIN_DECLS G_BEGIN_DECLS
#define KATZE_TYPE_ARRAY_ACTION \ #define KATZE_TYPE_ARRAY_ACTION \
@ -42,6 +44,10 @@ void
katze_array_action_set_array (KatzeArrayAction* array_action, katze_array_action_set_array (KatzeArrayAction* array_action,
KatzeArray* array); KatzeArray* array);
GtkToolItem*
katze_array_action_create_tool_item_for (KatzeArrayAction* array_action,
KatzeItem* item);
G_END_DECLS G_END_DECLS
#endif /* __KATZE_ARRAY_ACTION_H__ */ #endif /* __KATZE_ARRAY_ACTION_H__ */

View file

@ -2443,46 +2443,6 @@ midori_browser_bookmarks_item_render_text_cb (GtkTreeViewColumn* column,
g_object_set (renderer, "markup", _("<i>Separator</i>"), NULL); 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 static void
midori_browser_menu_bookmarks_item_activate_cb (GtkWidget* widget, midori_browser_menu_bookmarks_item_activate_cb (GtkWidget* widget,
MidoriBrowser* browser) MidoriBrowser* browser)
@ -2505,13 +2465,16 @@ midori_browser_bookmarkbar_item_button_press_event_cb (GtkWidget* toolitem,
if (event->button == 2) 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"); item = (KatzeItem*)g_object_get_data (G_OBJECT (toolitem), "KatzeItem");
n = midori_browser_add_uri (browser, katze_item_get_uri (item)); if (katze_item_get_uri (item))
if (!open_in_background) {
midori_browser_set_current_page (browser, n); g_object_get (browser->settings, "open-tabs-in-the-background",
return TRUE; &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) else if (event->button == 3)
{ {
@ -2522,64 +2485,6 @@ midori_browser_bookmarkbar_item_button_press_event_cb (GtkWidget* toolitem,
return FALSE; 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 static void
_action_bookmark_add_activate (GtkAction* action, _action_bookmark_add_activate (GtkAction* action,
MidoriBrowser* browser) MidoriBrowser* browser)
@ -4193,20 +4098,61 @@ midori_browser_settings_notify (MidoriWebSettings* web_settings,
g_value_unset (&value); 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 static void
midori_browser_load_bookmarks (MidoriBrowser* browser) midori_browser_load_bookmarks (MidoriBrowser* browser)
{ {
guint i, n; guint i, n;
KatzeItem* item; KatzeItem* item;
const gchar* title;
const gchar* desc;
GtkWidget* image;
GdkPixbuf* icon;
GtkToolItem* toolitem;
GtkTreeModel* treestore; GtkTreeModel* treestore;
// FIXME: Clear bookmarks menu
// FIXME: Clear bookmarkbar
// FIXME: Clear bookmark panel // FIXME: Clear bookmark panel
_action_set_sensitive (browser, "BookmarkAdd", FALSE); _action_set_sensitive (browser, "BookmarkAdd", FALSE);
@ -4218,51 +4164,12 @@ midori_browser_load_bookmarks (MidoriBrowser* browser)
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
item = katze_array_get_nth_item (browser->bookmarks, i); item = katze_array_get_nth_item (browser->bookmarks, i);
title = katze_item_get_name (item); browser_bookmarks_add_item_cb (browser->bookmarks, item, browser);
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);
} }
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)); treestore = gtk_tree_view_get_model (GTK_TREE_VIEW (browser->panel_bookmarks));
_tree_store_insert_folder (GTK_TREE_STORE (treestore), _tree_store_insert_folder (GTK_TREE_STORE (treestore),