892 lines
26 KiB
C
892 lines
26 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 = katze_item_get_text (item);
|
|
if (!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 (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_assert (KATZE_IS_ARRAY (item));
|
|
g_assert (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,
|
|
FeedPanel* panel)
|
|
{
|
|
GtkTreeModel* model;
|
|
GtkTreeIter iter;
|
|
guint i;
|
|
|
|
g_assert (KATZE_IS_ARRAY (feed));
|
|
g_assert (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
|
|
{
|
|
date = katze_item_get_added (item);
|
|
if (date)
|
|
{
|
|
time_t date_t;
|
|
const struct tm* tm;
|
|
static gchar date_format[512];
|
|
const gchar* puri;
|
|
KatzeItem* parent;
|
|
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);
|
|
parent = katze_item_get_parent (item);
|
|
g_assert (KATZE_IS_ARRAY (parent));
|
|
puri = katze_item_get_uri (parent);
|
|
/* 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);
|
|
}
|
|
}
|
|
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);
|
|
if (text)
|
|
{
|
|
webkit_web_view_load_html_string (
|
|
WEBKIT_WEB_VIEW (panel->webview), 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);
|
|
}
|
|
|