midori/extensions/feed-panel/feed-panel.c
Dale Whittaker ec44108653 Improve title and URI display in the feed panel
We strip HTML from "title" elements when required now. And we
always try to show at least the URI for feeds in the WebKit view.
And we fallback to using the URI in the treeview if the title/
description is empty.
2009-05-09 14:08:06 +02:00

900 lines
27 KiB
C

/*
Copyright (C) 2009 Dale Whittaker <dayul@users.sf.net>
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.
*/
#include "feed-panel.h"
#include <midori/midori.h>
#include <midori/sokoke.h>
#include <time.h>
#if HAVE_CONFIG_H
#include <config.h>
#endif
#define STOCK_FEED_PANEL "feed-panel"
struct _FeedPanel
{
GtkVBox parent_instance;
GtkWidget* toolbar;
GtkWidget* treeview;
GtkWidget* webview;
GtkWidget* delete;
GdkPixbuf* pixbuf;
KatzeNet* net;
};
struct _FeedPanelClass
{
GtkVBoxClass parent_class;
};
static void
feed_panel_viewable_iface_init (MidoriViewableIface* iface);
static void
feed_panel_insert_item (FeedPanel* panel,
GtkTreeStore* treestore,
GtkTreeIter* parent,
KatzeItem* item);
static void
feed_panel_disconnect_feed (FeedPanel* panel,
KatzeArray* feed);
G_DEFINE_TYPE_WITH_CODE (FeedPanel, feed_panel, GTK_TYPE_VBOX,
G_IMPLEMENT_INTERFACE (MIDORI_TYPE_VIEWABLE,
feed_panel_viewable_iface_init));
enum
{
ADD_FEED,
REMOVE_FEED,
LAST_SIGNAL
};
static guint signals[LAST_SIGNAL];
static void
feed_panel_treeview_render_icon_cb (GtkTreeViewColumn* column,
GtkCellRenderer* renderer,
GtkTreeModel* model,
GtkTreeIter* iter,
FeedPanel* panel)
{
GdkPixbuf* pixbuf;
KatzeItem* item;
KatzeItem* pitem;
const gchar* uri;
gtk_tree_model_get (model, iter, 0, &item, -1);
g_assert (KATZE_IS_ITEM (item));
if (!KATZE_IS_ARRAY (item))
{
pitem = katze_item_get_parent (item);
g_assert (KATZE_IS_ITEM (pitem));
}
else
pitem = item;
uri = katze_item_get_uri (pitem);
if (uri)
{
pixbuf = katze_net_load_icon (panel->net, uri, NULL, NULL, NULL);
if (!pixbuf)
pixbuf = panel->pixbuf;
}
else
{
pixbuf = gtk_widget_render_icon (panel->treeview,
GTK_STOCK_DIALOG_ERROR, GTK_ICON_SIZE_MENU, NULL);
}
g_object_set (renderer, "pixbuf", pixbuf, NULL);
if (pixbuf != panel->pixbuf)
g_object_unref (pixbuf);
}
static void
feed_panel_treeview_render_text_cb (GtkTreeViewColumn* column,
GtkCellRenderer* renderer,
GtkTreeModel* model,
GtkTreeIter* iter,
GtkWidget* treeview)
{
KatzeItem* item;
const gchar* title;
gtk_tree_model_get (model, iter, 0, &item, -1);
g_assert (KATZE_IS_ITEM (item));
title = katze_item_get_name (item);
if (!title || !*title || g_str_equal (title, " "))
title = katze_item_get_text (item);
if (!title || !*title || g_str_equal (title, " "))
title = katze_item_get_uri (item);
g_object_set (renderer, "text", title, NULL);
g_object_unref (item);
}
static void
feed_panel_add_item_cb (KatzeArray* parent,
KatzeItem* child,
FeedPanel* panel)
{
GtkTreeModel* model;
GtkTreeIter iter;
GtkTreeIter child_iter;
KatzeItem* item;
gint i;
g_return_if_fail (FEED_IS_PANEL (panel));
g_return_if_fail (KATZE_IS_ARRAY (parent));
g_return_if_fail (KATZE_IS_ITEM (child));
model = gtk_tree_view_get_model (GTK_TREE_VIEW (panel->treeview));
if (katze_item_get_parent (KATZE_ITEM (parent)))
{
if (KATZE_IS_ARRAY (child))
{
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &child_iter,
NULL, G_MAXINT, 0, child, -1);
}
else
{
i = 0;
while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i++))
{
gtk_tree_model_get (model, &iter, 0, &item, -1);
if (item == KATZE_ITEM (parent))
{
gtk_tree_store_insert_with_values (GTK_TREE_STORE (model), &child_iter,
&iter, 0, 0, child, -1);
g_object_unref (child);
g_object_unref (item);
break;
}
g_object_unref (item);
}
}
}
feed_panel_insert_item (panel, GTK_TREE_STORE (model), &child_iter, child);
}
static void
feed_panel_remove_iter (GtkTreeModel* model,
KatzeItem* removed_item)
{
guint i;
GtkTreeIter iter;
i = 0;
while (gtk_tree_model_iter_nth_child (model, &iter, NULL, 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;
}
g_object_unref (item);
i++;
}
}
static void
feed_panel_remove_item_cb (KatzeArray* item,
KatzeItem* child,
FeedPanel* panel)
{
GtkTreeModel* model;
KatzeItem* pitem;
g_return_if_fail (FEED_IS_PANEL (panel));
g_return_if_fail (KATZE_IS_ARRAY (item));
g_return_if_fail (KATZE_IS_ITEM (child));
if (KATZE_IS_ARRAY (child))
feed_panel_disconnect_feed (panel, KATZE_ARRAY (child));
if (!katze_item_get_parent (KATZE_ITEM (item)))
{
gint n;
n = katze_array_get_length (KATZE_ARRAY (child));
g_assert (n == 1);
pitem = katze_array_get_nth_item (KATZE_ARRAY (child), 0);
}
else
pitem = child;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (panel->treeview));
feed_panel_remove_iter (model, pitem);
g_object_unref (pitem);
}
static void
feed_panel_move_item_cb (KatzeArray* feed,
KatzeItem* child,
gint position,
FeedPanel* panel)
{
GtkTreeModel* model;
GtkTreeIter iter;
guint i;
g_return_if_fail (FEED_IS_PANEL (panel));
g_return_if_fail (KATZE_IS_ARRAY (feed));
g_return_if_fail (KATZE_IS_ITEM (child));
model = gtk_tree_view_get_model (GTK_TREE_VIEW (panel->treeview));
i = 0;
while (gtk_tree_model_iter_nth_child (model, &iter, NULL, i))
{
KatzeItem* item;
gtk_tree_model_get (model, &iter, 0, &item, -1);
if (item == child)
{
gtk_tree_store_move_after (GTK_TREE_STORE (model), &iter, NULL);
g_object_unref (item);
break;
}
g_object_unref (item);
i++;
}
}
static void
feed_panel_disconnect_feed (FeedPanel* panel,
KatzeArray* feed)
{
KatzeItem* item;
guint i;
g_return_if_fail (KATZE_IS_ARRAY (feed));
g_signal_handlers_disconnect_by_func (feed,
feed_panel_add_item_cb, panel);
g_signal_handlers_disconnect_by_func (feed,
feed_panel_remove_item_cb, panel);
g_signal_handlers_disconnect_by_func (feed,
feed_panel_move_item_cb, panel);
i = 0;
while ((item = katze_array_get_nth_item (feed, i++)))
{
if (KATZE_IS_ARRAY (item))
feed_panel_disconnect_feed (panel, KATZE_ARRAY (item));
g_object_unref (item);
}
}
static void
feed_panel_insert_item (FeedPanel* panel,
GtkTreeStore* treestore,
GtkTreeIter* parent,
KatzeItem* item)
{
g_return_if_fail (KATZE_IS_ITEM (item));
if (KATZE_IS_ARRAY (item))
{
g_signal_connect_after (item, "add-item",
G_CALLBACK (feed_panel_add_item_cb), panel);
g_signal_connect_after (item, "move-item",
G_CALLBACK (feed_panel_move_item_cb), panel);
if (!parent)
{
g_signal_connect (item, "remove-item",
G_CALLBACK (feed_panel_remove_item_cb), panel);
}
}
}
static void
feed_panel_row_activated_cb (GtkTreeView* treeview,
GtkTreePath* path,
GtkTreeViewColumn* column,
FeedPanel* panel)
{
GtkTreeModel* model;
GtkTreeIter iter;
KatzeItem* item;
const gchar* uri;
model = gtk_tree_view_get_model (treeview);
if (gtk_tree_model_get_iter (model, &iter, path))
{
gtk_tree_model_get (model, &iter, 0, &item, -1);
uri = katze_item_get_uri (item);
if (uri && *uri)
{
MidoriWebSettings* settings;
MidoriBrowser* browser;
gint n;
browser = midori_browser_get_for_widget (GTK_WIDGET (panel));
n = midori_browser_add_item (browser, item);
settings = katze_object_get_object (browser, "settings");
if (!katze_object_get_boolean (settings, "open-tabs-in-the-background"))
midori_browser_set_current_page (browser, n);
g_object_unref (settings);
}
g_object_unref (item);
}
}
static void
feed_panel_cursor_or_row_changed_cb (GtkTreeView* treeview,
FeedPanel* panel)
{
GtkTreeModel* model;
GtkTreeIter iter;
KatzeItem* item;
gboolean sensitive = FALSE;
if (katze_tree_view_get_selected_iter (treeview, &model, &iter))
{
const gchar* uri;
const gchar* text;
gtk_tree_model_get (model, &iter, 0, &item, -1);
uri = katze_item_get_uri (item);
if (KATZE_IS_ARRAY (item))
{
gint64 date;
text = NULL;
if (!uri)
text = g_strdup (katze_item_get_text (KATZE_ITEM (item)));
else
{
KatzeItem* parent;
const gchar* puri;
parent = katze_item_get_parent (item);
g_assert (KATZE_IS_ARRAY (parent));
date = katze_item_get_added (item);
puri = katze_item_get_uri (parent);
if (date)
{
time_t date_t;
const struct tm* tm;
static gchar date_format[512];
gchar* last_updated;
date_t = (time_t)date;
tm = localtime (&date_t);
/* Some gcc versions complain about "%c" for no reason */
strftime (date_format, sizeof (date_format), "%c", tm);
/* i18n: The local date a feed was last updated */
last_updated = g_strdup_printf (C_("Feed", "Last updated: %s."),
date_format);
text = g_strdup_printf (
"<html><head><title>feed</title></head>"
"<body><h3>%s</h3><p />%s</body></html>",
puri, last_updated);
g_free (last_updated);
}
else
{
text = g_strdup_printf (
"<html><head><title>feed</title></head>"
"<body><h3>%s</h3></body></html>", puri);
}
}
webkit_web_view_load_html_string (
WEBKIT_WEB_VIEW (panel->webview), text ? text : "", uri);
g_free ((gchar*) text);
sensitive = TRUE;
}
else
{
text = katze_item_get_text (item);
webkit_web_view_load_html_string (
WEBKIT_WEB_VIEW (panel->webview), text ? text : "", uri);
}
g_object_unref (item);
}
if (GTK_IS_WIDGET (panel->delete))
gtk_widget_set_sensitive (panel->delete, sensitive);
}
static void
feed_panel_popup_item (GtkWidget* menu,
const gchar* stock_id,
const gchar* label,
KatzeItem* item,
gpointer callback,
FeedPanel* panel)
{
const gchar* uri;
GtkWidget* menuitem;
uri = katze_item_get_uri (item);
menuitem = gtk_image_menu_item_new_from_stock (stock_id, NULL);
if (label)
gtk_label_set_text_with_mnemonic (GTK_LABEL (gtk_bin_get_child (
GTK_BIN (menuitem))), label);
g_object_set_data (G_OBJECT (menuitem), "KatzeItem", item);
g_signal_connect (menuitem, "activate", G_CALLBACK (callback), panel);
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menuitem);
gtk_widget_show (menuitem);
}
static void
feed_panel_open_activate_cb (GtkWidget* menuitem,
FeedPanel* panel)
{
KatzeItem* item;
const gchar* uri;
item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
uri = katze_item_get_uri (item);
if (uri && *uri)
{
MidoriBrowser* browser;
browser = midori_browser_get_for_widget (GTK_WIDGET (panel));
midori_browser_set_current_uri (browser, uri);
}
}
static void
feed_panel_open_in_tab_activate_cb (GtkWidget* menuitem,
FeedPanel* panel)
{
KatzeItem* item;
const gchar* uri;
guint n;
item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
if ((uri = katze_item_get_uri (item)) && *uri)
{
MidoriWebSettings* settings;
MidoriBrowser* browser;
browser = midori_browser_get_for_widget (GTK_WIDGET (panel));
n = midori_browser_add_item (browser, item);
settings = katze_object_get_object (browser, "settings");
if (!katze_object_get_boolean (settings, "open-tabs-in-the-background"))
midori_browser_set_current_page (browser, n);
g_object_unref (settings);
}
}
static void
feed_panel_open_in_window_activate_cb (GtkWidget* menuitem,
FeedPanel* panel)
{
KatzeItem* item;
const gchar* uri;
item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
uri = katze_item_get_uri (item);
if (uri && *uri)
{
MidoriBrowser* browser;
browser = midori_browser_get_for_widget (GTK_WIDGET (panel));
g_signal_emit_by_name (browser, "new-window", uri);
}
}
static void
feed_panel_delete_activate_cb (GtkWidget* menuitem,
FeedPanel* panel)
{
KatzeItem* item;
g_return_if_fail (FEED_IS_PANEL (panel));
item = (KatzeItem*)g_object_get_data (G_OBJECT (menuitem), "KatzeItem");
g_signal_emit (panel, signals[REMOVE_FEED], 0, item);
}
static void
feed_panel_popup (GtkWidget* widget,
GdkEventButton* event,
KatzeItem* item,
FeedPanel* panel)
{
GtkWidget* menu;
menu = gtk_menu_new ();
if (!KATZE_IS_ARRAY (item))
{
feed_panel_popup_item (menu, GTK_STOCK_OPEN, NULL,
item, feed_panel_open_activate_cb, panel);
feed_panel_popup_item (menu, STOCK_TAB_NEW, _("Open in New _Tab"),
item, feed_panel_open_in_tab_activate_cb, panel);
feed_panel_popup_item (menu, STOCK_WINDOW_NEW, _("Open in New _Window"),
item, feed_panel_open_in_window_activate_cb, panel);
}
else
{
feed_panel_popup_item (menu, GTK_STOCK_DELETE, NULL,
item, feed_panel_delete_activate_cb, panel);
}
sokoke_widget_popup (widget, GTK_MENU (menu),
event, SOKOKE_MENU_POSITION_CURSOR);
}
static gboolean
feed_panel_button_release_event_cb (GtkWidget* widget,
GdkEventButton* event,
FeedPanel* panel)
{
GtkTreeModel* model;
GtkTreeIter iter;
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);
if (event->button == 2)
{
const gchar* uri = katze_item_get_uri (item);
if (uri && *uri)
{
MidoriWebSettings* settings;
MidoriBrowser* browser;
gint n;
browser = midori_browser_get_for_widget (GTK_WIDGET (panel));
n = midori_browser_add_item (browser, item);
settings = katze_object_get_object (browser, "settings");
if (!katze_object_get_boolean (settings, "open-tabs-in-the-background"))
midori_browser_set_current_page (browser, n);
g_object_unref (settings);
}
}
else
feed_panel_popup (widget, event, item, panel);
g_object_unref (item);
return TRUE;
}
return FALSE;
}
static void
feed_panel_popup_menu_cb (GtkWidget* widget,
FeedPanel* panel)
{
GtkTreeModel* model;
GtkTreeIter iter;
KatzeItem* item;
if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (widget), &model, &iter))
{
gtk_tree_model_get (model, &iter, 0, &item, -1);
feed_panel_popup (widget, NULL, item, panel);
g_object_unref (item);
}
}
void
feed_panel_add_feeds (FeedPanel* panel,
KatzeItem* feed)
{
GtkTreeModel* model;
model = gtk_tree_view_get_model (GTK_TREE_VIEW (panel->treeview));
g_assert (GTK_IS_TREE_MODEL (model));
feed_panel_insert_item (panel, GTK_TREE_STORE (model), NULL, feed);
}
static gboolean
webview_button_press_event_cb (GtkWidget* widget,
GdkEventButton* event)
{
/* Disable the popup menu */
return (event->button == 3);
}
static gboolean
webview_navigation_request_cb (WebKitWebView* web_view,
WebKitWebFrame* frame,
WebKitNetworkRequest* request,
WebKitWebNavigationAction* navigation_action,
WebKitWebPolicyDecision* policy_decision,
FeedPanel* panel)
{
if (webkit_web_navigation_action_get_reason (navigation_action) ==
WEBKIT_WEB_NAVIGATION_REASON_LINK_CLICKED)
{
MidoriBrowser* browser;
const gchar* uri;
gint n;
browser = midori_browser_get_for_widget (GTK_WIDGET (panel));
uri = webkit_network_request_get_uri (request);
n = midori_browser_add_uri (browser, uri);
midori_browser_set_current_page (browser, n);
}
return TRUE;
}
static const gchar*
feed_panel_get_label (MidoriViewable* viewable)
{
return _("Feeds");
}
static const gchar*
feed_panel_get_stock_id (MidoriViewable* viewable)
{
return STOCK_FEED_PANEL;
}
static void
feed_panel_add_clicked_cb (GtkWidget* toolitem,
FeedPanel* panel)
{
g_return_if_fail (FEED_IS_PANEL (panel));
g_signal_emit (panel, signals[ADD_FEED], 0);
}
static void
feed_panel_delete_clicked_cb (GtkWidget* toolitem,
FeedPanel* panel)
{
GtkTreeModel* model;
GtkTreeIter iter;
g_return_if_fail (FEED_IS_PANEL (panel));
if (katze_tree_view_get_selected_iter (GTK_TREE_VIEW (panel->treeview),
&model, &iter))
{
KatzeItem* item;
gtk_tree_model_get (model, &iter, 0, &item, -1);
g_signal_emit (panel, signals[REMOVE_FEED], 0, item);
g_object_unref (item);
}
}
static GtkWidget*
feed_panel_get_toolbar (MidoriViewable* viewable)
{
FeedPanel* panel = FEED_PANEL (viewable);
if (!panel->toolbar)
{
GtkWidget* toolbar;
GtkToolItem* toolitem;
toolbar = gtk_toolbar_new ();
gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_BOTH_HORIZ);
gtk_toolbar_set_icon_size (GTK_TOOLBAR (toolbar), GTK_ICON_SIZE_BUTTON);
panel->toolbar = toolbar;
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_ADD);
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), _("Add new feed"));
gtk_tool_item_set_is_important (toolitem, TRUE);
g_signal_connect (toolitem, "clicked",
G_CALLBACK (feed_panel_add_clicked_cb), panel);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
gtk_widget_show (GTK_WIDGET (toolitem));
toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_DELETE);
gtk_widget_set_tooltip_text (GTK_WIDGET (toolitem), _("Delete feed"));
g_signal_connect (toolitem, "clicked",
G_CALLBACK (feed_panel_delete_clicked_cb), panel);
gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
gtk_widget_show (GTK_WIDGET (toolitem));
panel->delete = GTK_WIDGET (toolitem);;
feed_panel_cursor_or_row_changed_cb (
GTK_TREE_VIEW (panel->treeview), panel);
g_signal_connect (panel->delete, "destroy",
G_CALLBACK (gtk_widget_destroyed), &panel->delete);
}
return panel->toolbar;
}
static void
feed_panel_finalize (GObject* object)
{
FeedPanel* panel = FEED_PANEL (object);
g_object_unref (panel->pixbuf);
g_object_unref (panel->net);
}
static void
feed_panel_viewable_iface_init (MidoriViewableIface* iface)
{
iface->get_stock_id = feed_panel_get_stock_id;
iface->get_label = feed_panel_get_label;
iface->get_toolbar = feed_panel_get_toolbar;
}
static void
feed_panel_class_init (FeedPanelClass* class)
{
GObjectClass* gobject_class;
signals[ADD_FEED] = g_signal_new (
"add-feed",
G_TYPE_FROM_CLASS (class),
(GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
0,
0,
NULL,
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0);
signals[REMOVE_FEED] = g_signal_new (
"remove-feed",
G_TYPE_FROM_CLASS (class),
(GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
0,
0,
NULL,
g_cclosure_marshal_VOID__POINTER,
G_TYPE_NONE, 1,
G_TYPE_POINTER);
gobject_class = G_OBJECT_CLASS (class);
gobject_class->finalize = feed_panel_finalize;
}
static void
feed_panel_init (FeedPanel* panel)
{
GtkTreeStore* model;
GtkWidget* treewin;
GtkWidget* treeview;
GtkWidget* webview;
GtkWidget* paned;
GtkTreeViewColumn* column;
GtkCellRenderer* renderer_pixbuf;
GtkCellRenderer* renderer_text;
GtkIconFactory *factory;
GtkIconSource *icon_source;
GtkIconSet *icon_set;
WebKitWebSettings* settings;
PangoFontDescription* font_desc;
const gchar* family;
gint size;
GtkStockItem items[] =
{
{ STOCK_FEED_PANEL, N_("_Feeds"), 0, 0, NULL }
};
factory = gtk_icon_factory_new ();
gtk_stock_add (items, G_N_ELEMENTS (items));
icon_set = gtk_icon_set_new ();
icon_source = gtk_icon_source_new ();
gtk_icon_source_set_icon_name (icon_source, STOCK_NEWS_FEED);
gtk_icon_set_add_source (icon_set, icon_source);
gtk_icon_source_free (icon_source);
gtk_icon_factory_add (factory, STOCK_FEED_PANEL, icon_set);
gtk_icon_set_unref (icon_set);
gtk_icon_factory_add_default (factory);
g_object_unref (factory);
panel->net = katze_net_new ();
model = gtk_tree_store_new (1, KATZE_TYPE_ITEM);
treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
panel->treeview = treeview;
gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (treeview), FALSE);
column = gtk_tree_view_column_new ();
renderer_pixbuf = gtk_cell_renderer_pixbuf_new ();
gtk_tree_view_column_pack_start (column, renderer_pixbuf, FALSE);
gtk_tree_view_column_set_cell_data_func (column, renderer_pixbuf,
(GtkTreeCellDataFunc)feed_panel_treeview_render_icon_cb,
panel, NULL);
renderer_text = gtk_cell_renderer_text_new ();
gtk_tree_view_column_pack_start (column, renderer_text, FALSE);
gtk_tree_view_column_set_cell_data_func (column, renderer_text,
(GtkTreeCellDataFunc)feed_panel_treeview_render_text_cb,
treeview, NULL);
gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column);
g_object_unref (model);
g_object_connect (treeview,
"signal::row-activated",
feed_panel_row_activated_cb, panel,
"signal::cursor-changed",
feed_panel_cursor_or_row_changed_cb, panel,
"signal::columns-changed",
feed_panel_cursor_or_row_changed_cb, panel,
"signal::button-release-event",
feed_panel_button_release_event_cb, panel,
"signal::popup-menu",
feed_panel_popup_menu_cb, panel,
NULL);
gtk_widget_show (treeview);
webview = webkit_web_view_new ();
font_desc = treeview->style->font_desc;
family = pango_font_description_get_family (font_desc);
size = pango_font_description_get_size (font_desc) / PANGO_SCALE;
settings = webkit_web_settings_new ();
g_object_set (settings, "default-font-family", family,
"default-font-size", size, NULL);
g_object_set (webview, "settings", settings, NULL);
gtk_widget_set_size_request (webview, -1, 50);
g_object_connect (webview,
"signal::navigation-policy-decision-requested",
webview_navigation_request_cb, panel,
"signal::button-press-event",
webview_button_press_event_cb, NULL,
"signal::button-release-event",
webview_button_press_event_cb, NULL,
NULL);
panel->webview = webview;
treewin = gtk_scrolled_window_new (NULL, NULL);
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (treewin),
GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (treewin),
GTK_SHADOW_IN);
gtk_container_add (GTK_CONTAINER (treewin), treeview);
gtk_widget_show (treewin);
paned = gtk_vpaned_new ();
gtk_paned_pack1 (GTK_PANED (paned), treewin, TRUE, FALSE);
gtk_paned_pack2 (GTK_PANED (paned), webview, TRUE, FALSE);
gtk_box_pack_start (GTK_BOX (panel), paned, TRUE, TRUE, 0);
gtk_widget_show (webview);
gtk_widget_show (paned);
panel->pixbuf = gtk_widget_render_icon (treeview,
STOCK_NEWS_FEED, GTK_ICON_SIZE_MENU, NULL);
}
GtkWidget*
feed_panel_new (void)
{
FeedPanel* panel = g_object_new (FEED_TYPE_PANEL, NULL);
return GTK_WIDGET (panel);
}