]> spindle.queued.net Git - midori/commitdiff
Implement Transfers sidepanel
authorChristian Dywan <christian@twotoasts.de>
Sun, 22 Mar 2009 14:25:57 +0000 (15:25 +0100)
committerChristian Dywan <christian@twotoasts.de>
Sun, 22 Mar 2009 14:25:57 +0000 (15:25 +0100)
midori/main.c
panels/midori-transfers.c [new file with mode: 0644]
panels/midori-transfers.h [new file with mode: 0644]
po/POTFILES.in

index b063b7479e35a9c80ec22ade6b51678d580ceec3..eccf89e270023af304a9f62cedf20c4195e20f34 100644 (file)
@@ -25,6 +25,7 @@
 #include "midori-panel.h"
 #include "midori-preferences.h"
 #include "midori-plugins.h"
+#include "midori-transfers.h"
 #include "midori-view.h"
 #include "midori-websettings.h"
 
@@ -1213,11 +1214,10 @@ midori_app_add_browser_cb (MidoriApp*     app,
     midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
 
     /* Transfers */
-    #if 0
-    addon = midori_view_new (net);
+    #if WEBKIT_CHECK_VERSION (1, 1, 3)
+    addon = g_object_new (MIDORI_TYPE_TRANSFERS, "app", app, NULL);
     gtk_widget_show (addon);
-    midori_panel_append_widget (MIDORI_PANEL (panel), addon,
-                                STOCK_TRANSFERS, _("Transfers"), NULL);
+    midori_panel_append_page (MIDORI_PANEL (panel), MIDORI_VIEWABLE (addon));
     #endif
 
     /* Console */
diff --git a/panels/midori-transfers.c b/panels/midori-transfers.c
new file mode 100644 (file)
index 0000000..43434a0
--- /dev/null
@@ -0,0 +1,417 @@
+/*
+ Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
+
+ 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 "midori-transfers.h"
+
+#include "midori-app.h"
+#include "midori-browser.h"
+#include "midori-stock.h"
+#include "midori-view.h"
+
+#include "sokoke.h"
+#include "compat.h"
+#include <glib/gi18n.h>
+
+struct _MidoriTransfers
+{
+    GtkVBox parent_instance;
+
+    GtkWidget* toolbar;
+    GtkWidget* treeview;
+    MidoriApp* app;
+};
+
+struct _MidoriTransfersClass
+{
+    GtkVBoxClass parent_class;
+};
+
+static void
+midori_transfers_viewable_iface_init (MidoriViewableIface* iface);
+
+G_DEFINE_TYPE_WITH_CODE (MidoriTransfers, midori_transfers, GTK_TYPE_VBOX,
+                         G_IMPLEMENT_INTERFACE (MIDORI_TYPE_VIEWABLE,
+                             midori_transfers_viewable_iface_init));
+
+enum
+{
+    PROP_0,
+
+    PROP_APP
+};
+
+static void
+midori_transfers_set_property (GObject*      object,
+                               guint         prop_id,
+                               const GValue* value,
+                               GParamSpec*   pspec);
+
+static void
+midori_transfers_get_property (GObject*    object,
+                               guint       prop_id,
+                               GValue*     value,
+                               GParamSpec* pspec);
+
+static void
+midori_transfers_class_init (MidoriTransfersClass* class)
+{
+    GObjectClass* gobject_class;
+    GParamFlags flags;
+
+    gobject_class = G_OBJECT_CLASS (class);
+    gobject_class->set_property = midori_transfers_set_property;
+    gobject_class->get_property = midori_transfers_get_property;
+
+    flags = G_PARAM_READWRITE | G_PARAM_CONSTRUCT;
+
+    g_object_class_install_property (gobject_class,
+                                     PROP_APP,
+                                     g_param_spec_object (
+                                     "app",
+                                     "App",
+                                     "The app",
+                                     MIDORI_TYPE_APP,
+                                     flags));
+}
+
+static const gchar*
+midori_transfers_get_label (MidoriViewable* viewable)
+{
+    return _("Transfers");
+}
+
+static const gchar*
+midori_transfers_get_stock_id (MidoriViewable* viewable)
+{
+    return STOCK_TRANSFERS;
+}
+
+static void
+midori_transfers_button_clear_clicked_cb (GtkToolItem*    toolitem,
+                                         MidoriTransfers* transfers)
+{
+    GtkTreeModel* model = gtk_tree_view_get_model (
+        GTK_TREE_VIEW (transfers->treeview));
+    /* FIXME: Clear only finished and cancelled downloads */
+    gtk_tree_store_clear (GTK_TREE_STORE (model));
+}
+
+static GtkWidget*
+midori_transfers_get_toolbar (MidoriViewable* transfers)
+{
+    if (!MIDORI_TRANSFERS (transfers)->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);
+        toolitem = gtk_tool_item_new ();
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        toolitem = gtk_separator_tool_item_new ();
+        gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (toolitem),
+                                          FALSE);
+        gtk_tool_item_set_expand (toolitem, TRUE);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_CLEAR);
+        gtk_tool_item_set_is_important (toolitem, TRUE);
+        g_signal_connect (toolitem, "clicked",
+            G_CALLBACK (midori_transfers_button_clear_clicked_cb), transfers);
+        gtk_toolbar_insert (GTK_TOOLBAR (toolbar), toolitem, -1);
+        gtk_widget_show (GTK_WIDGET (toolitem));
+        MIDORI_TRANSFERS (transfers)->toolbar = toolbar;
+    }
+
+    return MIDORI_TRANSFERS (transfers)->toolbar;
+}
+
+static void
+midori_transfers_viewable_iface_init (MidoriViewableIface* iface)
+{
+    iface->get_stock_id = midori_transfers_get_stock_id;
+    iface->get_label = midori_transfers_get_label;
+    iface->get_toolbar = midori_transfers_get_toolbar;
+}
+
+#if WEBKIT_CHECK_VERSION (1, 1, 3)
+static void
+midori_transfers_download_notify_progress_cb (WebKitDownload*  download,
+                                              GParamSpec*      pspec,
+                                              MidoriTransfers* transfers)
+{
+    /* FIXME: Update only the appropriate row */
+    gtk_widget_queue_draw (transfers->treeview);
+}
+
+static void
+midori_transfers_download_notify_status_cb (WebKitDownload*  download,
+                                            GParamSpec*      pspec,
+                                            MidoriTransfers* transfers)
+{
+    /* FIXME: Update only the appropriate row */
+    gtk_widget_queue_draw (transfers->treeview);
+}
+
+static void
+midori_transfers_browser_add_download_cb (MidoriBrowser*   browser,
+                                          WebKitDownload*  download,
+                                          MidoriTransfers* transfers)
+{
+    GtkTreeView* treeview;
+    GtkTreeModel* model;
+
+    treeview = GTK_TREE_VIEW (transfers->treeview);
+    model = gtk_tree_view_get_model (treeview);
+    gtk_tree_store_insert_with_values (GTK_TREE_STORE (model),
+                                       NULL, NULL, G_MAXINT,
+                                       0, NULL, 1, download, -1);
+    g_signal_connect (download, "notify::progress",
+        G_CALLBACK (midori_transfers_download_notify_progress_cb), transfers);
+    g_signal_connect (download, "notify::status",
+        G_CALLBACK (midori_transfers_download_notify_status_cb), transfers);
+}
+#endif
+
+static void
+midori_transfers_set_property (GObject*      object,
+                               guint         prop_id,
+                               const GValue* value,
+                               GParamSpec*   pspec)
+{
+    MidoriTransfers* transfers = MIDORI_TRANSFERS (object);
+
+    switch (prop_id)
+    {
+    case PROP_APP:
+        transfers->app = g_value_get_object (value);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_transfers_get_property (GObject*    object,
+                               guint       prop_id,
+                               GValue*     value,
+                               GParamSpec* pspec)
+{
+    MidoriTransfers* transfers = MIDORI_TRANSFERS (object);
+
+    switch (prop_id)
+    {
+    case PROP_APP:
+        g_value_set_object (value, transfers->app);
+        break;
+    default:
+        G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+        break;
+    }
+}
+
+static void
+midori_transfers_treeview_render_icon_cb (GtkTreeViewColumn* column,
+                                          GtkCellRenderer*   renderer,
+                                          GtkTreeModel*      model,
+                                          GtkTreeIter*       iter,
+                                          GtkWidget*         treeview)
+{
+    g_object_set (renderer, "stock-id", STOCK_TRANSFER,
+                  "stock-size", GTK_ICON_SIZE_DND,
+                  "xpad", 1, "ypad", 12, NULL);
+}
+
+static void
+midori_transfers_treeview_render_text_cb (GtkTreeViewColumn* column,
+                                          GtkCellRenderer*   renderer,
+                                          GtkTreeModel*      model,
+                                          GtkTreeIter*       iter,
+                                          GtkWidget*         treeview)
+{
+    #if WEBKIT_CHECK_VERSION (1, 1, 3)
+    WebKitDownload* download;
+    gchar* current;
+    gchar* total;
+    gchar* size_text;
+    gchar* text;
+    gdouble progress;
+
+    gtk_tree_model_get (model, iter, 1, &download, -1);
+
+    /* FIXME: Ellipsize filename */
+    current = g_format_size_for_display (webkit_download_get_current_size (download));
+    total = g_format_size_for_display (webkit_download_get_total_size (download));
+    size_text = g_strdup_printf (_("%s of %s"), current, total);
+    g_free (current);
+    g_free (total);
+    text = g_strdup_printf ("%s\n%s",
+        webkit_download_get_suggested_filename (download), size_text);
+    g_free (size_text);
+    /* Avoid a bug in WebKit */
+    if (webkit_download_get_status (download) != WEBKIT_DOWNLOAD_STATUS_CREATED)
+        progress = webkit_download_get_progress (download);
+    else
+        progress = 0.0;
+    g_object_set (renderer, "text", text,
+                  "value", (gint)(progress * 100),
+                  "xpad", 1, "ypad", 6, NULL);
+    g_free (text);
+    g_object_unref (download);
+    #endif
+}
+
+static void
+midori_transfers_treeview_render_button_cb (GtkTreeViewColumn* column,
+                                            GtkCellRenderer*   renderer,
+                                            GtkTreeModel*      model,
+                                            GtkTreeIter*       iter,
+                                            GtkWidget*         treeview)
+{
+    #if WEBKIT_CHECK_VERSION (1, 1, 3)
+    WebKitDownload* download;
+    const gchar* stock_id;
+
+    gtk_tree_model_get (model, iter, 1, &download, -1);
+
+    switch (webkit_download_get_status (download))
+    {
+        case WEBKIT_DOWNLOAD_STATUS_STARTED:
+            stock_id = GTK_STOCK_CANCEL;
+            break;
+        case WEBKIT_DOWNLOAD_STATUS_FINISHED:
+            stock_id = GTK_STOCK_OPEN;
+            break;
+        default:
+            stock_id = GTK_STOCK_CLEAR;
+    }
+    g_object_set (renderer, "stock-id", stock_id,
+                  "stock-size", GTK_ICON_SIZE_MENU, NULL);
+
+    g_object_unref (download);
+    #endif
+}
+
+static void
+midori_transfers_treeview_row_activated_cb (GtkTreeView*       treeview,
+                                            GtkTreePath*       path,
+                                            GtkTreeViewColumn* column,
+                                            MidoriTransfers*   transfers)
+{
+    GtkTreeModel* model = gtk_tree_view_get_model (treeview);
+    GtkTreeIter iter;
+    if (gtk_tree_model_get_iter (model, &iter, path))
+    {
+        #if WEBKIT_CHECK_VERSION (1, 1, 3)
+        WebKitDownload* download;
+
+        gtk_tree_model_get (model, &iter, 1, &download, -1);
+
+        switch (webkit_download_get_status (download))
+        {
+            case WEBKIT_DOWNLOAD_STATUS_STARTED:
+                webkit_download_cancel (download);
+                break;
+            case WEBKIT_DOWNLOAD_STATUS_FINISHED:
+            {
+                const gchar* uri;
+                gboolean success;
+
+                uri = webkit_download_get_destination_uri (download);
+                success = gtk_show_uri (gtk_widget_get_screen (GTK_WIDGET (
+                    treeview)), uri, gtk_get_current_event_time (), NULL);
+                if (!success)
+                {
+                    gchar* command = g_strconcat ("exo-open ", uri, NULL);
+                    success = g_spawn_command_line_async (command, NULL);
+                    g_free (command);
+                }
+                break;
+            }
+            case WEBKIT_DOWNLOAD_STATUS_CANCELLED:
+                /* FIXME: Remove this item from the model */
+            default:
+                break;
+        }
+        g_object_unref (download);
+        #endif
+    }
+}
+
+static void
+midori_transfers_hierarchy_changed_cb (MidoriTransfers* transfers,
+                                       GtkWidget*       old_parent)
+{
+    #if WEBKIT_CHECK_VERSION (1, 1, 3)
+    GtkWidget* browser = gtk_widget_get_toplevel (GTK_WIDGET (transfers));
+    if (GTK_WIDGET_TOPLEVEL (browser))
+        g_signal_connect (browser, "add-download",
+            G_CALLBACK (midori_transfers_browser_add_download_cb), transfers);
+    #endif
+}
+
+static void
+midori_transfers_init (MidoriTransfers* transfers)
+{
+    /* Create the treeview */
+    GtkTreeViewColumn* column;
+    GtkCellRenderer* renderer_pixbuf;
+    GtkCellRenderer* renderer_text;
+    GtkTreeStore* treestore = gtk_tree_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_OBJECT);
+    transfers->treeview = gtk_tree_view_new_with_model (GTK_TREE_MODEL (treestore));
+    gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (transfers->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)midori_transfers_treeview_render_icon_cb,
+        transfers->treeview, NULL);
+    renderer_text = gtk_cell_renderer_progress_new ();
+    gtk_tree_view_column_pack_start (column, renderer_text, TRUE);
+    gtk_tree_view_column_set_cell_data_func (column, renderer_text,
+        (GtkTreeCellDataFunc)midori_transfers_treeview_render_text_cb,
+        transfers->treeview, NULL);
+    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)midori_transfers_treeview_render_button_cb,
+        transfers->treeview, NULL);
+    gtk_tree_view_append_column (GTK_TREE_VIEW (transfers->treeview), column);
+    g_object_unref (treestore);
+    g_signal_connect (transfers->treeview, "row-activated",
+                      G_CALLBACK (midori_transfers_treeview_row_activated_cb),
+                      transfers);
+    gtk_widget_show (transfers->treeview);
+    gtk_box_pack_start (GTK_BOX (transfers), transfers->treeview, TRUE, TRUE, 0);
+
+    g_signal_connect (transfers, "hierarchy-changed",
+        G_CALLBACK (midori_transfers_hierarchy_changed_cb), NULL);
+}
+
+/**
+ * midori_transfers_new:
+ *
+ * Creates a new empty transfers.
+ *
+ * Return value: a new #MidoriTransfers
+ *
+ * Since 0.1.5
+ **/
+GtkWidget*
+midori_transfers_new (void)
+{
+    MidoriTransfers* transfers = g_object_new (MIDORI_TYPE_TRANSFERS, NULL);
+
+    return GTK_WIDGET (transfers);
+}
diff --git a/panels/midori-transfers.h b/panels/midori-transfers.h
new file mode 100644 (file)
index 0000000..9778711
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ Copyright (C) 2009 Christian Dywan <christian@twotoasts.de>
+
+ 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.
+*/
+
+#ifndef __MIDORI_TRANSFERS_H__
+#define __MIDORI_TRANSFERS_H__
+
+#include <gtk/gtk.h>
+
+#include <katze/katze.h>
+
+#include "midori-viewable.h"
+
+G_BEGIN_DECLS
+
+#define MIDORI_TYPE_TRANSFERS \
+    (midori_transfers_get_type ())
+#define MIDORI_TRANSFERS(obj) \
+    (G_TYPE_CHECK_INSTANCE_CAST ((obj), MIDORI_TYPE_TRANSFERS, MidoriTransfers))
+#define MIDORI_TRANSFERS_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_CAST ((klass), MIDORI_TYPE_TRANSFERS, MidoriTransfersClass))
+#define MIDORI_IS_TRANSFERS(obj) \
+    (G_TYPE_CHECK_INSTANCE_TYPE ((obj), MIDORI_TYPE_TRANSFERS))
+#define MIDORI_IS_TRANSFERS_CLASS(klass) \
+    (G_TYPE_CHECK_CLASS_TYPE ((klass), MIDORI_TYPE_TRANSFERS))
+#define MIDORI_TRANSFERS_GET_CLASS(obj) \
+    (G_TYPE_INSTANCE_GET_CLASS ((obj), MIDORI_TYPE_TRANSFERS, MidoriTransfersClass))
+
+typedef struct _MidoriTransfers                MidoriTransfers;
+typedef struct _MidoriTransfersClass           MidoriTransfersClass;
+
+GType
+midori_transfers_get_type               (void);
+
+GtkWidget*
+midori_transfers_new                    (void);
+
+G_END_DECLS
+
+#endif /* __MIDORI_TRANSFERS_H__ */
index de85f0982622aeaf07fc49ef5b6927bb731ecf6f..2840e97a7c06a831e003d86291cacf741032bc3a 100644 (file)
@@ -17,6 +17,7 @@ panels/midori-console.c
 panels/midori-extensions.c
 panels/midori-history.c
 panels/midori-plugins.c
+panels/midori-transfers.c
 katze/katze-http-auth.c
 katze/katze-throbber.c
 katze/katze-utils.c