From e971c12c0b7b5365bf8187e0d6e57c2af17af091 Mon Sep 17 00:00:00 2001 From: Christian Dywan Date: Sat, 2 Aug 2008 04:25:05 +0200 Subject: [PATCH] Show news feeds in a menu if the icon is clicked --- midori/midori-browser.c | 106 +++++++++++++++++++++++++++++----- midori/midori-locationentry.c | 20 +------ midori/midori-webview.c | 36 ++++++++++-- midori/midori-webview.h | 4 ++ 4 files changed, 127 insertions(+), 39 deletions(-) diff --git a/midori/midori-browser.c b/midori/midori-browser.c index 32522158..c25ddfce 100644 --- a/midori/midori-browser.c +++ b/midori/midori-browser.c @@ -24,6 +24,7 @@ #include "midori-searchentry.h" #include "midori-locationentry.h" #include "compat.h" +#include "gjs.h" #if GLIB_CHECK_VERSION (2, 16, 0) #include @@ -289,10 +290,16 @@ _midori_browser_update_interface (MidoriBrowser* browser) gtk_widget_show (browser->progressbar); } katze_throbber_set_animated (KATZE_THROBBER (browser->throbber), loading); - /* FIXME show news feed icon if feeds are available */ - /* gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY ( + + /* FIXME: This won't work due to a bug in GtkIconEntry */ + /* if (web_view && midori_web_view_get_news_feeds (MIDORI_WEB_VIEW (web_view))) + gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY ( gtk_bin_get_child (GTK_BIN (browser->location))), - GTK_ICON_ENTRY_SECONDARY, NULL); */ + GTK_ICON_ENTRY_SECONDARY, browser->stock_news_feed); + else + gtk_icon_entry_set_icon_from_pixbuf (GTK_ICON_ENTRY ( + gtk_bin_get_child (GTK_BIN (browser->location))), + GTK_ICON_ENTRY_SECONDARY, NULL);*/ } static GtkWidget* @@ -1696,7 +1703,7 @@ midori_browser_menu_trash_activate_cb (GtkWidget* widget, GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FILE, GTK_ICON_SIZE_MENU); gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem), icon); - 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), "KatzeXbelItem", item); g_signal_connect (menuitem, "activate", G_CALLBACK (midori_browser_menu_trash_item_activate_cb), browser); @@ -2423,7 +2430,7 @@ _action_about_activate (GtkAction* action, "version", PACKAGE_VERSION, "comments", _("A lightweight web browser."), "copyright", "Copyright © 2007-2008 Christian Dywan", - "website", "http://software.twotoasts.de", + "website", "http://www.twotoasts.de", "authors", credits_authors, "documenters", credits_documenters, "artists", credits_artists, @@ -2443,6 +2450,72 @@ midori_browser_location_changed_cb (GtkWidget* widget, FIXME: If we want this feature, this is the wrong approach */ } +static void +midori_browser_menu_feed_item_activate_cb (GtkWidget* widget, + MidoriBrowser* browser) +{ + const gchar* uri; + + uri = g_object_get_data (G_OBJECT (widget), "uri"); + _midori_browser_open_uri (browser, uri); +} + +static void +midori_browser_location_icon_released_cb (GtkWidget* widget, + gint icon_pos, + gint button, + MidoriBrowser* browser) +{ + MidoriWebView* web_view; + MidoriWebList* news_feeds; + GtkWidget* menu; + guint n, i; + GjsValue* feed; + const gchar* uri; + const gchar* title; + GtkWidget* menuitem; + + if (icon_pos == GTK_ICON_ENTRY_SECONDARY) + { + web_view = (MidoriWebView*)midori_browser_get_current_web_view (browser); + if (web_view) + { + news_feeds = midori_web_view_get_news_feeds (web_view); + n = news_feeds ? midori_web_list_get_length (news_feeds) : 0; + if (n) + { + menu = gtk_menu_new (); + for (i = 0; i < n; i++) + { + if (!(feed = midori_web_list_get_nth_item (news_feeds, i))) + continue; + + uri = gjs_value_get_attribute_string (feed, "href"); + if (gjs_value_has_attribute (feed, "title")) + title = gjs_value_get_attribute_string (feed, "title"); + else + title = uri; + if (!*title) + title = uri; + menuitem = gtk_image_menu_item_new_with_label (title); + /* FIXME: Get the real icon */ + gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM ( + menuitem), gtk_image_new_from_stock (STOCK_NEWS_FEED, + GTK_ICON_SIZE_MENU)); + gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem); + g_object_set_data (G_OBJECT (menuitem), "uri", (gchar*)uri); + g_signal_connect (menuitem, "activate", + G_CALLBACK (midori_browser_menu_feed_item_activate_cb), + browser); + gtk_widget_show (menuitem); + } + sokoke_widget_popup (widget, GTK_MENU (menu), NULL, + SOKOKE_MENU_POSITION_CURSOR); + } + } + } +} + static void _action_panel_activate (GtkToggleAction* action, MidoriBrowser* browser) @@ -3160,7 +3233,7 @@ midori_browser_init (MidoriBrowser* browser) gtk_ui_manager_get_accel_group (ui_manager)); GError* error = NULL; - if (!gtk_ui_manager_add_ui_from_string(ui_manager, ui_markup, -1, &error)) + if (!gtk_ui_manager_add_ui_from_string (ui_manager, ui_markup, -1, &error)) { /* TODO: Should this be a message dialog? When does this happen? */ g_message ("User interface couldn't be created: %s", error->message); @@ -3173,8 +3246,8 @@ midori_browser_init (MidoriBrowser* browser) guint i; for (i = 0; i < entries_n; i++) { - action = gtk_action_group_get_action(browser->action_group, - entries[i].name); + action = gtk_action_group_get_action (browser->action_group, + entries[i].name); gtk_action_set_sensitive (action, entries[i].callback || !entries[i].tooltip); } @@ -3242,13 +3315,6 @@ midori_browser_init (MidoriBrowser* browser) /* Location */ browser->location = midori_location_entry_new (); - /* FIXME: Due to a bug in GtkIconEntry we need to set an initial icon */ - gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY ( - gtk_bin_get_child (GTK_BIN (browser->location))), - GTK_ICON_ENTRY_SECONDARY, browser->stock_news_feed); - gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY ( - gtk_bin_get_child (GTK_BIN (browser->location))), - GTK_ICON_ENTRY_SECONDARY, TRUE); /* FIXME: sokoke_entry_setup_completion (GTK_ENTRY (browser->location)); */ g_object_connect (browser->location, "signal::active-changed", @@ -3261,6 +3327,16 @@ midori_browser_init (MidoriBrowser* browser) "signal::changed", midori_browser_location_changed_cb, browser, NULL); + /* FIXME: Due to a bug in GtkIconEntry we need to set an initial icon */ + gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY ( + gtk_bin_get_child (GTK_BIN (browser->location))), + GTK_ICON_ENTRY_SECONDARY, browser->stock_news_feed); + gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY ( + gtk_bin_get_child (GTK_BIN (browser->location))), + GTK_ICON_ENTRY_SECONDARY, TRUE); + g_signal_connect (gtk_bin_get_child (GTK_BIN (browser->location)), + "icon-released", G_CALLBACK (midori_browser_location_icon_released_cb), + browser); GtkToolItem* toolitem = gtk_tool_item_new (); gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE); GtkWidget* align = gtk_alignment_new (0, 0.5, 1, 0.1); diff --git a/midori/midori-locationentry.c b/midori/midori-locationentry.c index 5fde078f..d9b84dfd 100644 --- a/midori/midori-locationentry.c +++ b/midori/midori-locationentry.c @@ -35,13 +35,6 @@ enum static guint signals[LAST_SIGNAL]; - -static void -entry_icon_released (GtkIconEntry* entry, - gint icon_pos, - gint button, - gpointer user_data); - static gboolean entry_key_press_event (GtkWidget* widget, GdkEventKey* event, @@ -80,14 +73,13 @@ midori_location_entry_init (MidoriLocationEntry* location_entry) entry = gtk_icon_entry_new (); gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry), GTK_ICON_ENTRY_PRIMARY, DEFAULT_ICON); - g_signal_connect (entry, "icon_released", G_CALLBACK (entry_icon_released), NULL); g_signal_connect (entry, "key-press-event", G_CALLBACK (entry_key_press_event), location_entry); gtk_widget_show (entry); gtk_container_add (GTK_CONTAINER (location_entry), entry); store = gtk_list_store_new (N_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING); - g_object_set (G_OBJECT (location_entry), "model", GTK_TREE_MODEL (store), NULL); + g_object_set (G_OBJECT (location_entry), "model", store, NULL); g_object_unref(store); gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (location_entry), URI_COL); @@ -130,16 +122,6 @@ entry_key_press_event (GtkWidget* widget, return FALSE; } -static void -entry_icon_released (GtkIconEntry* entry, - gint icon_pos, - gint button, - gpointer user_data) -{ - if (icon_pos == GTK_ICON_ENTRY_SECONDARY) - /* FIXME Show available news feeds */; -} - static void midori_location_entry_active_changed (GtkComboBox* combo_box, gpointer user_data) diff --git a/midori/midori-webview.c b/midori/midori-webview.c index 1c79d386..ffb341cf 100644 --- a/midori/midori-webview.c +++ b/midori/midori-webview.c @@ -38,6 +38,7 @@ struct _MidoriWebView MidoriLoadStatus load_status; gchar* statusbar_text; gchar* link_uri; + MidoriWebList* news_feeds; MidoriWebSettings* settings; @@ -479,10 +480,13 @@ gjs_value_links_foreach_cb (GjsValue* link, if (!strcmp (type, "application/rss+xml") || !strcmp (type, "application/x.atom+xml") || !strcmp (type, "application/atom+xml")) + { + midori_web_list_add_item (web_view->news_feeds, link); g_signal_emit (web_view, signals[NEWS_FEED_READY], 0, gjs_value_get_attribute_string (link, "href"), type, gjs_value_has_attribute (link, "title") ? gjs_value_get_attribute_string (link, "title") : NULL); + } } if (gjs_value_has_attribute (link, "rel")) { @@ -522,6 +526,7 @@ webkit_web_frame_load_done (WebKitWebFrame* web_frame, value = gjs_value_new (webkit_web_frame_get_global_context (web_frame), NULL); document = gjs_value_get_by_name (value, "document"); links = gjs_value_get_elements_by_tag_name (document, "link"); + midori_web_list_clear (web_view->news_feeds); gjs_value_foreach (links, (GjsCallback)gjs_value_links_foreach_cb, web_view); g_object_unref (links); g_object_unref (document); @@ -663,8 +668,8 @@ midori_web_view_menu_download_activate_cb (GtkWidget* widget, } static void -webkit_web_view_populate_popup_cb (GtkWidget* web_view, - GtkWidget* menu) +webkit_web_view_populate_popup_cb (GtkWidget* web_view, + GtkWidget* menu) { const gchar* uri; GtkWidget* menuitem; @@ -747,6 +752,7 @@ midori_web_view_init (MidoriWebView* web_view) GTK_STOCK_FILE, GTK_ICON_SIZE_MENU, NULL); web_view->progress = 0.0; web_view->load_status = MIDORI_LOAD_FINISHED; + web_view->news_feeds = midori_web_list_new (); web_view->settings = midori_web_settings_new (); g_object_set (web_view, "WebKitWebView::settings", web_view->settings, NULL); @@ -799,13 +805,14 @@ midori_web_view_finalize (GObject* object) g_free (web_view->title); g_free (web_view->statusbar_text); g_free (web_view->link_uri); - - if (web_view->xbel_item) - katze_xbel_item_unref (web_view->xbel_item); + g_object_unref (web_view->news_feeds); if (web_view->settings) g_object_unref (web_view->settings); + if (web_view->xbel_item) + katze_xbel_item_unref (web_view->xbel_item); + G_OBJECT_CLASS (midori_web_view_parent_class)->finalize (object); } @@ -1138,3 +1145,22 @@ midori_web_view_get_link_uri (MidoriWebView* web_view) return web_view->link_uri; } + +/** + * midori_web_view_get_news_feeds: + * @web_view: a #MidoriWebView + * + * Retrieves a list of news feeds for the current page + * or %NULL if there are no feeds at all. + * + * Return value: a #MidoriWebList, or %NULL + **/ +MidoriWebList* +midori_web_view_get_news_feeds (MidoriWebView* web_view) +{ + g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL); + + if (!midori_web_list_is_empty (web_view->news_feeds)) + return web_view->news_feeds; + return NULL; +} diff --git a/midori/midori-webview.h b/midori/midori-webview.h index d6e5b825..c8662114 100644 --- a/midori/midori-webview.h +++ b/midori/midori-webview.h @@ -13,6 +13,7 @@ #define __MIDORI_WEB_VIEW_H__ #include "midori-websettings.h" +#include "midori-weblist.h" #include #include @@ -114,6 +115,9 @@ midori_web_view_get_display_title (MidoriWebView* web_view); const gchar* midori_web_view_get_link_uri (MidoriWebView* web_view); +MidoriWebList* +midori_web_view_get_news_feeds (MidoriWebView* web_view); + G_END_DECLS #endif /* __MIDORI_WEB_VIEW_H__ */