]> spindle.queued.net Git - midori/commitdiff
Actually handle non web view tabs, and a View Source tab
authorChristian Dywan <christian@twotoasts.de>
Sun, 13 Jul 2008 19:49:57 +0000 (21:49 +0200)
committerChristian Dywan <christian@twotoasts.de>
Sun, 13 Jul 2008 19:49:57 +0000 (21:49 +0200)
midori/midori-browser.c
midori/midori-webview.c
midori/midori-webview.h
midori/sokoke.c
midori/sokoke.h

index 265d297f3cafff60dbec084ce58e570137c30d62..7cddb06cfcabe8ed287b365f6a77e34ea22ecbdb 100644 (file)
@@ -63,10 +63,10 @@ struct _MidoriBrowser
     GtkWidget* statusbar;
     GtkWidget* progressbar;
 
-    gchar* uri;
-    gchar* title;
     gchar* statusbar_text;
     MidoriWebSettings* settings;
+    GList* tab_titles;
+    GList* close_buttons;
 
     KatzeXbelItem* proxy_xbel_folder;
     MidoriWebList* trash;
@@ -145,10 +145,84 @@ _action_set_active (MidoriBrowser* browser,
     gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action), active);
 }
 
+static const gchar*
+_midori_browser_get_tab_uri (MidoriBrowser* browser,
+                             GtkWidget*     widget)
+{
+    const gchar* uri;
+
+    if (MIDORI_IS_WEB_VIEW (widget))
+        return midori_web_view_get_display_uri (MIDORI_WEB_VIEW (widget));
+
+    uri = g_object_get_data (G_OBJECT (widget), "browser-tab-uri");
+    return uri ? uri : "file://";
+}
+
+/* Note: The return value is valid only
+         until the next call to this function */
+static const gchar*
+_midori_browser_get_tab_title (MidoriBrowser* browser,
+                               GtkWidget*     widget)
+{
+    const gchar* uri;
+    static gchar* title = NULL;
+
+    if (MIDORI_IS_WEB_VIEW (widget))
+        return midori_web_view_get_display_title (MIDORI_WEB_VIEW (widget));
+
+    uri = g_object_get_data (G_OBJECT (widget), "browser-tab-uri");
+    if (g_str_has_prefix (uri, "view-source:"))
+    {
+        g_free (title);
+        title = g_strconcat (_("Source"), ": ", uri, NULL);
+        return title;
+    }
+    return "untitled";
+}
+
+static GdkPixbuf*
+_midori_browser_get_tab_icon (MidoriBrowser* browser,
+                              GtkWidget*     widget)
+{
+    const gchar* uri;
+    GdkPixbuf* icon;
+
+    if (MIDORI_IS_WEB_VIEW (widget))
+        return midori_web_view_get_icon (MIDORI_WEB_VIEW (widget));
+
+    uri = g_object_get_data (G_OBJECT (widget), "browser-tab-uri");
+    if (g_str_has_prefix (uri, "view-source:"))
+        icon = gtk_widget_render_icon (widget, GTK_STOCK_EDIT,
+                                       GTK_ICON_SIZE_MENU, NULL);
+    else
+        icon = gtk_widget_render_icon (widget, GTK_STOCK_FILE,
+                                       GTK_ICON_SIZE_MENU, NULL);
+    return icon;
+}
+
+static void
+_midori_browser_open_uri (MidoriBrowser* browser,
+                          const gchar*   uri)
+{
+    GtkWidget* web_view;
+    gint n;
+
+    web_view = midori_browser_get_current_web_view (browser);
+    if (web_view)
+        webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), uri);
+    else
+    {
+        n = midori_browser_add_uri (browser, uri);
+        midori_browser_set_current_page (browser, n);
+    }
+}
+
 static void
 _midori_browser_update_actions (MidoriBrowser* browser)
 {
-    guint n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook));
+    guint n;
+
+    n = gtk_notebook_get_n_pages (GTK_NOTEBOOK (browser->notebook));
     gtk_notebook_set_show_tabs (GTK_NOTEBOOK (browser->notebook), n > 1);
     _action_set_sensitive (browser, "TabClose", n > 1);
     _action_set_sensitive (browser, "TabPrevious", n > 1);
@@ -166,26 +240,31 @@ static void
 _midori_browser_update_interface (MidoriBrowser* browser)
 {
     gboolean loading;
+    GtkWidget* widget;
     GtkWidget* web_view;
-    GdkPixbuf* pixbuf;
-
-    loading = FALSE;
-    web_view = midori_browser_get_current_web_view (browser);
-    if (web_view)
-    {
-        loading = midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
-        _action_set_sensitive (browser, "ZoomNormal",
-            webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view)) != 1.0);
-        _action_set_sensitive (browser, "Back",
-            webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
-        _action_set_sensitive (browser, "Forward",
-            webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
-        _action_set_sensitive (browser, "Reload", !loading);
-        _action_set_sensitive (browser, "Stop", loading);
-        _action_set_sensitive (browser, "Print", TRUE);
-    }
-    else
-        _action_set_sensitive (browser, "Print", FALSE);
+    GdkPixbuf* icon;
+
+    widget = midori_browser_get_current_tab (browser);
+    web_view = widget && MIDORI_IS_WEB_VIEW (widget) ? widget : NULL;
+    loading = web_view != NULL
+        && midori_web_view_is_loading (MIDORI_WEB_VIEW (web_view));
+
+    _action_set_sensitive (browser, "Reload", web_view != NULL && !loading);
+        _action_set_sensitive (browser, "Stop", web_view != NULL && loading);
+    _action_set_sensitive (browser, "Back", web_view != NULL
+        && webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (web_view)));
+    _action_set_sensitive (browser, "Forward", web_view != NULL
+        && webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (web_view)));
+
+    _action_set_sensitive (browser, "Print", web_view != NULL);
+    _action_set_sensitive (browser, "ZoomIn", web_view != NULL);
+    _action_set_sensitive (browser, "ZoomOut", web_view != NULL);
+    _action_set_sensitive (browser, "ZoomNormal", web_view != NULL
+        && webkit_web_view_get_zoom_level (WEBKIT_WEB_VIEW (web_view)) != 1.0);
+    _action_set_sensitive (browser, "SourceView", web_view != NULL);
+    _action_set_sensitive (browser, "FindNext", web_view != NULL);
+    _action_set_sensitive (browser, "FindPrevious", web_view != NULL);
+    /* _action_set_sensitive (browser, "FindQuick", web_view != NULL); */
 
     GtkAction* action = gtk_action_group_get_action (browser->action_group,
                                                      "ReloadStop");
@@ -196,6 +275,7 @@ _midori_browser_update_interface (MidoriBrowser* browser)
                       "stock-id", GTK_STOCK_REFRESH,
                       "tooltip", _("Reload the current page"), NULL);
         gtk_widget_hide (browser->progressbar);
+        gtk_action_set_sensitive (action, web_view != NULL);
     }
     else
     {
@@ -206,15 +286,9 @@ _midori_browser_update_interface (MidoriBrowser* browser)
         gtk_widget_show (browser->progressbar);
     }
     katze_throbber_set_animated (KATZE_THROBBER (browser->throbber), loading);
-    if (web_view && MIDORI_IS_WEB_VIEW (web_view))
-    {
-        pixbuf = midori_web_view_get_icon (MIDORI_WEB_VIEW (web_view));
-        gtk_image_set_from_pixbuf (GTK_IMAGE (browser->location_icon), pixbuf);
-        g_object_unref (pixbuf);
-    }
-    else
-        gtk_image_set_from_stock (GTK_IMAGE (browser->location_icon),
-                                  GTK_STOCK_FILE, GTK_ICON_SIZE_MENU);
+    icon = _midori_browser_get_tab_icon (browser, widget);
+    gtk_image_set_from_pixbuf (GTK_IMAGE (browser->location_icon), icon);
+    g_object_unref (icon);
 }
 
 static GtkWidget*
@@ -419,15 +493,12 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
 
     if (new_bookmark)
     {
-        GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+        GtkWidget* widget = midori_browser_get_current_tab (browser);
         bookmark = katze_xbel_bookmark_new ();
-        if (MIDORI_IS_WEB_VIEW (web_view))
-        {
-            katze_xbel_item_set_title (bookmark,
-                midori_web_view_get_display_title (MIDORI_WEB_VIEW (web_view)));
-            katze_xbel_bookmark_set_href (bookmark,
-                midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view)));
-        }
+        katze_xbel_item_set_title (bookmark,
+            _midori_browser_get_tab_title (browser, widget));
+        katze_xbel_bookmark_set_href (bookmark,
+            _midori_browser_get_tab_uri (browser, widget));
     }
 
     GtkWidget* hbox = gtk_hbox_new (FALSE, 8);
@@ -595,9 +666,9 @@ midori_web_view_populate_popup_cb (GtkWidget*     web_view,
 }
 
 static gboolean
-midori_web_view_leave_notify_event_cb (GtkWidget*        web_view,
-                                       GdkEventCrossing* event,
-                                       MidoriBrowser*    browser)
+midori_browser_tab_leave_notify_event_cb (GtkWidget*        widget,
+                                          GdkEventCrossing* event,
+                                          MidoriBrowser*    browser)
 {
     _midori_browser_set_statusbar_text (browser, NULL);
     return TRUE;
@@ -620,49 +691,101 @@ midori_web_view_new_window_cb (GtkWidget*     web_view,
     g_signal_emit (browser, signals[NEW_WINDOW], 0, uri);
 }
 
-static void
-midori_web_view_close_cb (GtkWidget*     web_view,
-                          MidoriBrowser* browser)
+static gboolean
+midori_browser_tab_destroy_cb (GtkWidget*     widget,
+                               MidoriBrowser* browser)
 {
-    if (browser->proxy_xbel_folder)
+    KatzeXbelItem* xbel_item;
+    const gchar* uri;
+
+    if (browser->proxy_xbel_folder && MIDORI_IS_WEB_VIEW (widget))
     {
-        KatzeXbelItem* xbel_item = midori_web_view_get_proxy_xbel_item (
-            MIDORI_WEB_VIEW (web_view));
-        const gchar* uri = katze_xbel_bookmark_get_href (xbel_item);
+        xbel_item = midori_web_view_get_proxy_xbel_item (
+            MIDORI_WEB_VIEW (widget));
+        uri = katze_xbel_bookmark_get_href (xbel_item);
         if (browser->trash && uri && *uri)
             midori_web_list_add_item (browser->trash, xbel_item);
         katze_xbel_folder_remove_item (browser->proxy_xbel_folder, xbel_item);
         katze_xbel_item_unref (xbel_item);
     }
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
+    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
     guint n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), scrolled);
     gtk_notebook_remove_page (GTK_NOTEBOOK (browser->notebook), n);
 
     _midori_browser_update_actions (browser);
+    return FALSE;
 }
 
-static gboolean
-midori_web_view_destroy_cb (GtkWidget*     widget,
-                            MidoriBrowser* browser)
+static void
+midori_browser_window_menu_item_activate_cb (GtkWidget* menuitem,
+                                             GtkWidget* widget)
 {
-    _midori_browser_update_actions (browser);
-    return FALSE;
+    MidoriBrowser* browser;
+    GtkWidget* scrolled;
+    guint n;
+
+    g_return_if_fail (GTK_IS_WIDGET (widget));
+
+    browser = MIDORI_BROWSER (gtk_widget_get_toplevel (widget));
+    g_return_if_fail (MIDORI_IS_BROWSER (browser));
+
+    scrolled = _midori_browser_scrolled_for_child (browser, widget);
+    n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), scrolled);
+    gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
 }
 
 static void
-midori_browser_window_menu_item_activate_cb (GtkWidget* widget,
-                                             GtkWidget* web_view)
+_update_label_size (GtkWidget* label,
+                    gint       size)
 {
-    MidoriBrowser* browser = MIDORI_BROWSER (gtk_widget_get_toplevel (web_view));
-    if (!browser)
+    gint width, height;
+
+    if (size > -1)
     {
-        g_warning ("Orphaned web view");
-        return;
+        sokoke_widget_get_text_size (label, "M", &width, &height);
+        gtk_widget_set_size_request (label, width * size, -1);
+        gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_END);
+    }
+    else
+    {
+        gtk_widget_set_size_request (label, -1, -1);
+        gtk_label_set_ellipsize (GTK_LABEL (label), PANGO_ELLIPSIZE_NONE);
     }
+}
 
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, web_view);
-    guint n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), scrolled);
-    gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
+static gboolean
+midori_browser_tab_label_button_release_event (GtkWidget*      tab_label,
+                                               GdkEventButton* event,
+                                               GtkWidget*      widget)
+{
+    if (event->button == 2)
+    {
+        /* Close the widget on middle click */
+        gtk_widget_destroy (widget);
+        return TRUE;
+    }
+
+    return FALSE;
+}
+
+static void
+midori_browser_tab_close_style_set (GtkWidget* tab_close,
+                                    GtkStyle*  previous_style)
+{
+    GtkSettings* gtk_settings;
+    gint width, height;
+
+    gtk_settings = gtk_widget_get_settings (tab_close);
+    gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_BUTTON,
+                                       &width, &height);
+    gtk_widget_set_size_request (tab_close, width + 2, height + 2);
+}
+
+static void
+midori_browser_tab_close_clicked (GtkWidget* tab_close,
+                                  GtkWidget* widget)
+{
+    gtk_widget_destroy (widget);
 }
 
 static gint
@@ -672,9 +795,17 @@ _midori_browser_add_tab (MidoriBrowser* browser,
     GtkWidget* scrolled;
     GtkWidget* child;
     GObjectClass* gobject_class;
-    GtkWidget* label;
+    GdkPixbuf* icon;
+    GtkWidget* tab_icon;
+    const gchar* title;
+    GtkWidget* tab_title;
     GtkWidget* menuitem;
     KatzeXbelItem* xbel_item;
+    GtkWidget* event_box;
+    GtkWidget* hbox;
+    GtkWidget* close_button;
+    GtkRcStyle* rcstyle;
+    GtkWidget* image;
     guint n;
 
     scrolled = gtk_scrolled_window_new (NULL, NULL);
@@ -694,11 +825,10 @@ _midori_browser_add_tab (MidoriBrowser* browser,
     gtk_container_add (GTK_CONTAINER (scrolled), child);
     gtk_widget_show (scrolled);
 
-    label = NULL;
-     menuitem = NULL;
     if (MIDORI_IS_WEB_VIEW (widget))
     {
-        label = midori_web_view_get_proxy_tab_label (MIDORI_WEB_VIEW (widget));
+        tab_icon = midori_web_view_get_proxy_tab_icon (MIDORI_WEB_VIEW (widget));
+        tab_title = midori_web_view_get_proxy_tab_title (MIDORI_WEB_VIEW (widget));
         menuitem = midori_web_view_get_proxy_menu_item (MIDORI_WEB_VIEW (widget));
 
         if (browser->proxy_xbel_folder)
@@ -732,38 +862,93 @@ _midori_browser_add_tab (MidoriBrowser* browser,
                           midori_web_view_element_motion_cb, browser,
                           "signal::console-message",
                           midori_web_view_console_message_cb, browser,
-                          "signal::close",
-                          midori_web_view_close_cb, browser,
                           "signal::new-tab",
                           midori_web_view_new_tab_cb, browser,
                           "signal::new-window",
                           midori_web_view_new_window_cb, browser,
                           "signal::populate-popup",
                           midori_web_view_populate_popup_cb, browser,
-                          "signal::leave-notify-event",
-                          midori_web_view_leave_notify_event_cb, browser,
-                          "signal::destroy",
-                          midori_web_view_destroy_cb, browser,
                           NULL);
     }
-
-    if (menuitem)
+    else
     {
-        gtk_widget_show (menuitem);
-        g_signal_connect (menuitem, "activate",
-            G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
-        gtk_menu_shell_append (GTK_MENU_SHELL (browser->menu_window), menuitem);
+        icon = _midori_browser_get_tab_icon (browser, widget);
+        tab_icon = gtk_image_new_from_pixbuf (icon);
+        title = _midori_browser_get_tab_title (browser, widget);
+        tab_title = gtk_label_new (title);
+        menuitem = gtk_image_menu_item_new_with_label (title);
+        gtk_image_menu_item_set_image (GTK_IMAGE_MENU_ITEM (menuitem),
+            gtk_image_new_from_pixbuf (icon));
+        g_object_unref (icon);
+
+        if (browser->proxy_xbel_folder)
+        {
+            xbel_item = katze_xbel_bookmark_new ();
+            katze_xbel_item_set_title (xbel_item, title);
+            katze_xbel_bookmark_set_href (xbel_item,
+                _midori_browser_get_tab_uri (browser, widget));
+            katze_xbel_folder_append_item (browser->proxy_xbel_folder,
+                                           xbel_item);
+        }
     }
+    browser->tab_titles = g_list_prepend (browser->tab_titles, tab_title);
+
+    g_signal_connect (widget, "leave-notify-event",
+        G_CALLBACK (midori_browser_tab_leave_notify_event_cb), browser);
+
+    event_box = gtk_event_box_new ();
+    gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
+    hbox = gtk_hbox_new (FALSE, 1);
+    gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
+    gtk_box_pack_start (GTK_BOX (hbox), tab_icon, FALSE, FALSE, 0);
+    gtk_misc_set_alignment (GTK_MISC (tab_title), 0.0, 0.5);
+    /* TODO: make the tab initially look "unvisited" until it's focused */
+    gtk_box_pack_start (GTK_BOX (hbox), tab_title, FALSE, TRUE, 0);
+    _update_label_size (tab_title,
+        sokoke_object_get_int (browser->settings, "tab-label-size"));
+
+    close_button = gtk_button_new ();
+    gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
+    gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
+    rcstyle = gtk_rc_style_new ();
+    rcstyle->xthickness = rcstyle->ythickness = 0;
+    gtk_widget_modify_style(close_button, rcstyle);
+    image = gtk_image_new_from_stock (GTK_STOCK_CLOSE, GTK_ICON_SIZE_MENU);
+    gtk_button_set_image (GTK_BUTTON (close_button), image);
+    gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
+    gtk_widget_show_all (GTK_WIDGET (event_box));
+    if (!sokoke_object_get_boolean (browser->settings, "close-buttons-on-tabs"))
+        gtk_widget_hide (close_button);
+    browser->close_buttons = g_list_prepend (browser->close_buttons, close_button);
+
+    g_signal_connect (event_box, "button-release-event",
+        G_CALLBACK (midori_browser_tab_label_button_release_event), widget);
+    g_signal_connect (close_button, "style-set",
+        G_CALLBACK (midori_browser_tab_close_style_set), NULL);
+    g_signal_connect (close_button, "clicked",
+        G_CALLBACK (midori_browser_tab_close_clicked), widget);
 
     n = gtk_notebook_get_current_page (GTK_NOTEBOOK (browser->notebook));
     gtk_notebook_insert_page (GTK_NOTEBOOK (browser->notebook), scrolled,
-                              label, n + 1);
+                              event_box, n + 1);
     #if GTK_CHECK_VERSION(2, 10, 0)
     gtk_notebook_set_tab_reorderable (GTK_NOTEBOOK (browser->notebook),
                                       scrolled, TRUE);
     gtk_notebook_set_tab_detachable (GTK_NOTEBOOK (browser->notebook),
                                      scrolled, TRUE);
     #endif
+
+    gtk_widget_show (menuitem);
+    g_signal_connect (menuitem, "activate",
+        G_CALLBACK (midori_browser_window_menu_item_activate_cb), scrolled);
+    gtk_menu_shell_append (GTK_MENU_SHELL (browser->menu_window), menuitem);
+
+    /* We want the tab to be removed if the widget is destroyed */
+    g_signal_connect_swapped (widget, "destroy",
+        G_CALLBACK (gtk_widget_destroy), menuitem);
+    g_signal_connect (widget, "destroy",
+        G_CALLBACK (midori_browser_tab_destroy_cb), browser);
+
     _midori_browser_update_actions (browser);
 
     n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), scrolled);
@@ -1138,7 +1323,9 @@ _action_open_activate (GtkAction*     action,
     static gchar* last_dir = NULL;
     gchar* uri = NULL;
     gboolean folder_set = FALSE;
-    GtkWidget* dialog = gtk_file_chooser_dialog_new (
+    GtkWidget* dialog;
+
+    dialog = gtk_file_chooser_dialog_new (
         ("Open file"), GTK_WINDOW (browser),
         GTK_FILE_CHOOSER_ACTION_OPEN,
         GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
@@ -1148,10 +1335,8 @@ _action_open_activate (GtkAction*     action,
      gtk_window_set_transient_for (GTK_WINDOW (dialog), GTK_WINDOW (browser));
 
      /* base the start folder on the current web view's uri if it is local */
-     GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-     if (web_view)
-         g_object_get (web_view, "uri", &uri, NULL);
-     if (uri)
+     GtkWidget* widget = midori_browser_get_current_tab (browser);
+     if ((uri = (gchar*)_midori_browser_get_tab_uri (browser, widget)))
      {
          gchar* filename = g_filename_from_uri (uri, NULL, NULL);
          if (filename)
@@ -1166,7 +1351,6 @@ _action_open_activate (GtkAction*     action,
              g_free (dirname);
              g_free (filename);
          }
-         g_free (uri);
      }
 
      if (!folder_set && last_dir && *last_dir)
@@ -1176,7 +1360,7 @@ _action_open_activate (GtkAction*     action,
      {
          uri = gtk_file_chooser_get_uri (GTK_FILE_CHOOSER (dialog));
          gchar* folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog));
-         g_object_set (web_view, "uri", uri, NULL);
+         _midori_browser_open_uri (browser, uri);
 
          g_free (last_dir);
          last_dir = folder;
@@ -1190,8 +1374,7 @@ _action_tab_close_activate (GtkAction*     action,
                             MidoriBrowser* browser)
 {
     GtkWidget* widget = midori_browser_get_current_tab (browser);
-    GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
-    gtk_widget_destroy (scrolled);
+    gtk_widget_destroy (widget);
 }
 
 static void
@@ -1223,7 +1406,7 @@ _action_edit_activate (GtkAction*     action,
 {
     GtkWidget* widget = gtk_window_get_focus (GTK_WINDOW (browser));
     gboolean can_cut = FALSE, can_copy = FALSE, can_paste = FALSE;
-    gboolean has_selection;
+    gboolean has_selection, can_select_all = FALSE;
 
     if (WEBKIT_IS_WEB_VIEW (widget))
     {
@@ -1231,6 +1414,7 @@ _action_edit_activate (GtkAction*     action,
         can_cut = webkit_web_view_can_cut_clipboard (web_view);
         can_copy = webkit_web_view_can_copy_clipboard (web_view);
         can_paste = webkit_web_view_can_paste_clipboard (web_view);
+        can_select_all = TRUE;
     }
     else if (GTK_IS_EDITABLE (widget))
     {
@@ -1239,13 +1423,24 @@ _action_edit_activate (GtkAction*     action,
         can_cut = has_selection && gtk_editable_get_editable (editable);
         can_copy = has_selection;
         can_paste = gtk_editable_get_editable (editable);
+        can_select_all = TRUE;
+    }
+    else if (GTK_IS_TEXT_VIEW (widget))
+    {
+        GtkTextView* text_view = GTK_TEXT_VIEW (widget);
+        GtkTextBuffer* buffer = gtk_text_view_get_buffer (text_view);
+        has_selection = gtk_text_buffer_get_has_selection (buffer);
+        can_cut = gtk_text_view_get_editable (text_view);
+        can_copy = has_selection;
+        can_paste = gtk_text_view_get_editable (text_view) && has_selection;
+        can_select_all = TRUE;
     }
 
     _action_set_sensitive (browser, "Cut", can_cut);
     _action_set_sensitive (browser, "Copy", can_copy);
     _action_set_sensitive (browser, "Paste", can_paste);
     _action_set_sensitive (browser, "Delete", can_cut);
-    _action_set_sensitive (browser, "SelectAll", FALSE);
+    _action_set_sensitive (browser, "SelectAll", can_select_all);
 }
 
 static void
@@ -1284,8 +1479,11 @@ _action_delete_activate (GtkAction*     action,
     {
         if (WEBKIT_IS_WEB_VIEW (widget))
             webkit_web_view_delete_selection (WEBKIT_WEB_VIEW (widget));
-        else if (GTK_IS_EDITABLE(widget))
+        else if (GTK_IS_EDITABLE (widget))
             gtk_editable_delete_selection (GTK_EDITABLE (widget));
+        else if (GTK_IS_TEXT_VIEW (widget))
+            gtk_text_buffer_delete_selection (
+                gtk_text_view_get_buffer (GTK_TEXT_VIEW (widget)), TRUE, FALSE);
     }
 }
 
@@ -1299,18 +1497,60 @@ _action_select_all_activate (GtkAction*     action,
         if (GTK_IS_EDITABLE (widget))
             gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
         else
-            g_signal_emit_by_name (widget, "select-all");
+            g_signal_emit_by_name (widget, "select-all", TRUE);
     }
 }
 
+static void
+_midori_browser_tab_unmark_text_matches (MidoriBrowser* browser,
+                                         GtkWidget*     widget)
+{
+    if (WEBKIT_IS_WEB_VIEW (widget))
+        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (widget));
+}
+
+static gboolean
+_midori_browser_tab_search_text (MidoriBrowser* browser,
+                                 GtkWidget*     widget,
+                                 const gchar*   text,
+                                 gboolean       case_sensitive,
+                                 gboolean       forward)
+{
+    if (WEBKIT_IS_WEB_VIEW (widget))
+        return webkit_web_view_search_text (WEBKIT_WEB_VIEW (widget),
+            text, case_sensitive, forward, TRUE);
+    return FALSE;
+}
+
+static void
+_midori_browser_tab_mark_text_matches (MidoriBrowser* browser,
+                                       GtkWidget*     widget,
+                                       const gchar*   text,
+                                       gboolean       case_sensitive)
+{
+    if (WEBKIT_IS_WEB_VIEW (widget))
+        webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (widget),
+            text, case_sensitive, 0);
+}
+
+static void
+_midori_browser_tab_set_highlight_text_matches (MidoriBrowser* browser,
+                                                GtkWidget*     widget,
+                                                gboolean       highlight)
+{
+    if (WEBKIT_IS_WEB_VIEW (widget))
+        webkit_web_view_set_highlight_text_matches (
+            WEBKIT_WEB_VIEW (widget), highlight);
+}
+
 static void
 _action_find_activate(GtkAction*     action,
                       MidoriBrowser* browser)
 {
     if (GTK_WIDGET_VISIBLE (browser->find))
     {
-        GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
+        GtkWidget* widget = midori_browser_get_current_tab (browser);
+        _midori_browser_tab_unmark_text_matches (browser, widget);
         gtk_toggle_tool_button_set_active (
             GTK_TOGGLE_TOOL_BUTTON (browser->find_highlight), FALSE);
         gtk_widget_hide (browser->find);
@@ -1334,11 +1574,11 @@ _midori_browser_find (MidoriBrowser* browser,
     const gchar* text = gtk_entry_get_text (GTK_ENTRY (browser->find_text));
     const gboolean case_sensitive = gtk_toggle_tool_button_get_active (
         GTK_TOGGLE_TOOL_BUTTON(browser->find_case));
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    GtkWidget* widget = midori_browser_get_current_tab (browser);
     if (GTK_WIDGET_VISIBLE (browser->find))
-        webkit_web_view_unmark_text_matches (WEBKIT_WEB_VIEW (web_view));
-    gboolean found = webkit_web_view_search_text (WEBKIT_WEB_VIEW (web_view),
-        text, case_sensitive, forward, TRUE);
+        _midori_browser_tab_unmark_text_matches (browser, widget);
+    gboolean found = _midori_browser_tab_search_text (browser, widget,
+        text, case_sensitive, forward);
     if (GTK_WIDGET_VISIBLE (browser->find))
     {
         GtkWidget* icon;
@@ -1348,12 +1588,12 @@ _midori_browser_find (MidoriBrowser* browser,
             icon = gtk_image_new_from_stock (GTK_STOCK_STOP, GTK_ICON_SIZE_MENU);
         sexy_icon_entry_set_icon (SEXY_ICON_ENTRY (browser->find_text),
             SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (icon));
-        webkit_web_view_mark_text_matches (WEBKIT_WEB_VIEW (web_view), text,
-                                           case_sensitive, 0);
+        _midori_browser_tab_mark_text_matches (browser, widget,
+                                               text, case_sensitive);
         const gboolean highlight = gtk_toggle_tool_button_get_active (
             GTK_TOGGLE_TOOL_BUTTON (browser->find_highlight));
-        webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
-                                                    highlight);
+        _midori_browser_tab_set_highlight_text_matches (browser, widget,
+                                                        highlight);
     }
 }
 
@@ -1375,10 +1615,10 @@ static void
 _find_highlight_toggled (GtkToggleToolButton* toolitem,
                          MidoriBrowser*       browser)
 {
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
+    GtkWidget* widget = midori_browser_get_current_tab (browser);
     const gboolean highlight = gtk_toggle_tool_button_get_active (toolitem);
-    webkit_web_view_set_highlight_text_matches (WEBKIT_WEB_VIEW (web_view),
-                                                highlight);
+    _midori_browser_tab_set_highlight_text_matches (browser, widget,
+                                                    highlight);
 }
 
 static void
@@ -1550,15 +1790,53 @@ _action_zoom_normal_activate (GtkAction*     action,
         webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (web_view), 1.0);
 }
 
-/*static void
+static void
 _action_source_view_activate (GtkAction*     action,
                               MidoriBrowser* browser)
 {
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    gchar* source = webkit_web_view_copy_source (WEBKIT_WEB_VIEW (web_view));
-    webkit_web_view_load_html_string (WEBKIT_WEB_VIEW (web_view), source, "");
-    g_free (source);
-}*/
+    GtkWidget* web_view;
+    const gchar* uri;
+    GFile* file;
+    gchar* contents;
+    gchar* tag;
+    gchar* contents_utf8;
+    GtkTextBuffer* buffer;
+    GtkWidget* text_view;
+    gint n;
+
+    web_view = midori_browser_get_current_web_view (browser);
+    if (!(web_view && MIDORI_IS_WEB_VIEW (web_view)))
+        return;
+
+    uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+    file = g_file_new_for_uri (uri);
+    contents = NULL;
+    g_file_load_contents (file, NULL, &contents, NULL, &tag, NULL);
+    g_object_unref (file);
+    if (contents && !g_utf8_validate (contents, -1, NULL))
+    {
+        contents_utf8 = g_convert (contents, -1, "UTF-8", "ISO-8859-1",
+                                   NULL, NULL, NULL);
+        g_free (contents);
+    }
+    else
+        contents_utf8 = contents;
+
+    buffer = gtk_text_buffer_new (NULL);
+    if (contents_utf8)
+        gtk_text_buffer_set_text (buffer, contents_utf8, -1);
+    text_view = gtk_text_view_new_with_buffer (buffer);
+    gtk_text_view_set_editable (GTK_TEXT_VIEW (text_view), FALSE);
+    g_object_set_data (G_OBJECT (text_view), "browser-tab-uri",
+        g_strconcat ("view-source:", uri, NULL));
+    gtk_widget_show (text_view);
+    n = midori_browser_add_tab (browser, text_view);
+    midori_browser_set_current_page (browser, n);
+
+    g_object_unref (buffer);
+    g_free (contents_utf8);
+    g_free (tag);
+}
 
 static void
 _action_fullscreen_activate (GtkAction*     action,
@@ -1593,9 +1871,8 @@ _action_homepage_activate (GtkAction*     action,
 {
     gchar* homepage;
 
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
     g_object_get (browser->settings, "homepage", &homepage, NULL);
-    g_object_set (web_view, "uri", homepage, NULL);
+    _midori_browser_open_uri (browser, homepage);
     g_free (homepage);
 }
 
@@ -1627,18 +1904,16 @@ midori_browser_location_key_press_event_cb (GtkWidget*     widget,
                Completion should be generated from history, that is
                the uri as well as the title. */
             sokoke_entry_append_completion (GTK_ENTRY (widget), uri);
-            GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-            g_object_set (web_view, "uri", new_uri, NULL);
+            _midori_browser_open_uri (browser, new_uri);
             g_free (new_uri);
-            gtk_widget_grab_focus (web_view);
+            gtk_widget_grab_focus (midori_browser_get_current_tab (browser));
         }
         return TRUE;
     }
     case GDK_Escape:
     {
-        GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-        const gchar* uri = midori_web_view_get_display_uri (
-            MIDORI_WEB_VIEW (web_view));
+        const gchar* uri = _midori_browser_get_tab_uri (
+            browser, midori_browser_get_current_tab (browser));
         gtk_entry_set_text (GTK_ENTRY (widget), uri);
         return TRUE;
     }
@@ -1712,9 +1987,8 @@ midori_panel_bookmarks_row_activated_cb (GtkTreeView*       treeview,
         gtk_tree_model_get (model, &iter, 0, &item, -1);
         if (katze_xbel_item_is_bookmark (item))
         {
-            GtkWidget* web_view = midori_browser_get_current_web_view (browser);
             const gchar* uri = katze_xbel_bookmark_get_href (item);
-            g_object_set (web_view, "uri", uri, NULL);
+            _midori_browser_open_uri (browser, uri);
         }
     }
 }
@@ -1930,9 +2204,8 @@ midori_browser_menu_bookmarks_item_activate_cb (GtkWidget*     widget,
 {
     KatzeXbelItem* item = (KatzeXbelItem*)g_object_get_data (G_OBJECT (widget),
                                                              "KatzeXbelItem");
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    g_object_set (web_view, "uri", katze_xbel_bookmark_get_href (item), NULL);
-    gtk_widget_grab_focus (web_view);
+    _midori_browser_open_uri (browser, katze_xbel_bookmark_get_href (item));
+    gtk_widget_grab_focus (midori_browser_get_current_tab (browser));
 }
 
 static void
@@ -2084,8 +2357,8 @@ static void
 _action_open_in_panel_activate (GtkAction*     action,
                                 MidoriBrowser* browser)
 {
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+    GtkWidget* widget = midori_browser_get_current_tab (browser);
+    const gchar* uri = _midori_browser_get_tab_uri (browser, widget);
     /* FIXME: Don't assign the uri here, update it properly while navigating */
     g_object_set (browser->settings, "last-pageholder-uri", uri, NULL);
     gint n = midori_panel_page_num (MIDORI_PANEL (browser->panel),
@@ -2114,18 +2387,22 @@ midori_panel_close_cb (MidoriPanel*   panel,
 }
 
 static void
-gtk_notebook_switch_page_cb (GtkWidget*       widget,
+gtk_notebook_switch_page_cb (GtkWidget*       notebook,
                              GtkNotebookPage* page,
                              guint            page_num,
                              MidoriBrowser*   browser)
 {
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    const gchar* uri = midori_web_view_get_display_uri (MIDORI_WEB_VIEW (web_view));
+    GtkWidget* widget;
+    const gchar* uri;
+    const gchar* title;
+    gchar* window_title;
+
+    widget = midori_browser_get_current_tab (browser);
+    uri = _midori_browser_get_tab_uri (browser, widget);
     gtk_entry_set_text (GTK_ENTRY (browser->location), uri);
-    const gchar* title = midori_web_view_get_display_title (
-        MIDORI_WEB_VIEW (web_view));
-    gchar* window_title = g_strconcat (title, " - ",
-                                       g_get_application_name (), NULL);
+    title = _midori_browser_get_tab_title (browser, widget);
+    window_title = g_strconcat (title, " - ",
+                                g_get_application_name (), NULL);
     gtk_window_set_title (GTK_WINDOW (browser), window_title);
     g_free (window_title);
     _midori_browser_set_statusbar_text (browser, NULL);
@@ -2356,8 +2633,8 @@ static const GtkActionEntry entries[] = {
    NULL, "<Ctrl>0",
    N_("Reset the zoom level"), G_CALLBACK (_action_zoom_normal_activate) },
  { "SourceView", NULL,
-   N_("View Source"), "",
-   N_("View the source code of the page"), /*G_CALLBACK (_action_source_view_activate)*/ },
+   N_("View _Source"), "",
+   N_("View the source code of the page"), G_CALLBACK (_action_source_view_activate) },
  { "SelectionSourceView", NULL,
     N_("View Selection Source"), "",
     N_("View the source code of the selection"), NULL/*G_CALLBACK (_action_selection_source_view_activate)*/ },
@@ -2692,8 +2969,7 @@ midori_browser_search_activate_cb (GtkWidget*     widget,
     else
         search = g_strconcat (url, " ", keywords, NULL);
     sokoke_entry_append_completion (GTK_ENTRY (widget), keywords);
-    GtkWidget* web_view = midori_browser_get_current_web_view (browser);
-    webkit_web_view_open (WEBKIT_WEB_VIEW (web_view), search);
+    _midori_browser_open_uri (browser, search);
     g_free (search);
     g_free (location_entry_search);
 }
@@ -3067,20 +3343,24 @@ midori_browser_init (MidoriBrowser* browser)
     GtkWidget* icon = gtk_image_new_from_stock (GTK_STOCK_FIND,
                                                 GTK_ICON_SIZE_MENU);
     sexy_icon_entry_set_icon (SEXY_ICON_ENTRY(browser->find_text),
-                              SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE(icon));
-    sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY(browser->find_text));
+                              SEXY_ICON_ENTRY_PRIMARY, GTK_IMAGE (icon));
+    sexy_icon_entry_add_clear_button (SEXY_ICON_ENTRY (browser->find_text));
     g_signal_connect (browser->find_text, "activate",
         G_CALLBACK (_action_find_next_activate), browser);
     toolitem = gtk_tool_item_new ();
     gtk_container_add (GTK_CONTAINER (toolitem), browser->find_text);
     gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
     gtk_toolbar_insert (GTK_TOOLBAR(browser->find), toolitem, -1);
-    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_BACK);
+    toolitem = (GtkToolItem*)gtk_action_create_tool_item
+        (_action_by_name (browser, "FindPrevious"));
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), NULL);
     gtk_tool_item_set_is_important (toolitem, TRUE);
     g_signal_connect (toolitem, "clicked",
         G_CALLBACK (_action_find_previous_activate), browser);
     gtk_toolbar_insert (GTK_TOOLBAR (browser->find), toolitem, -1);
-    toolitem = gtk_tool_button_new_from_stock (GTK_STOCK_GO_FORWARD);
+    toolitem = (GtkToolItem*)gtk_action_create_tool_item
+        (_action_by_name (browser, "FindNext"));
+    gtk_tool_button_set_label (GTK_TOOL_BUTTON (toolitem), NULL);
     gtk_tool_item_set_is_important (toolitem, TRUE);
     g_signal_connect (toolitem, "clicked",
         G_CALLBACK (_action_find_next_activate), browser);
@@ -3136,6 +3416,9 @@ midori_browser_init (MidoriBrowser* browser)
     _action_set_sensitive (browser, "ZoomIn", FALSE);
     _action_set_sensitive (browser, "ZoomOut", FALSE);
     #endif
+
+    browser->tab_titles = NULL;
+    browser->close_buttons = NULL;
 }
 
 static void
@@ -3143,9 +3426,9 @@ midori_browser_finalize (GObject* object)
 {
     MidoriBrowser* browser = MIDORI_BROWSER (object);
 
-    g_free (browser->uri);
-    g_free (browser->title);
     g_free (browser->statusbar_text);
+    g_list_free (browser->tab_titles);
+    g_list_free (browser->close_buttons);
 
     if (browser->proxy_xbel_folder)
         katze_xbel_item_unref (browser->proxy_xbel_folder);
@@ -3204,6 +3487,10 @@ _midori_browser_update_settings (MidoriBrowser* browser)
     MidoriToolbarStyle toolbar_style;
     gint last_web_search;
     gchar* last_pageholder_uri;
+    gint tab_label_size;
+    gboolean close_buttons_on_tabs;
+
+    guint i, n;
 
     g_object_get (browser->settings,
                   "remember-last-window-size", &remember_last_window_size,
@@ -3223,6 +3510,8 @@ _midori_browser_update_settings (MidoriBrowser* browser)
                   "toolbar-style", &toolbar_style,
                   "last-web-search", &last_web_search,
                   "last-pageholder-uri", &last_pageholder_uri,
+                  "tab-label-size", &tab_label_size,
+                  "close-buttons-on-tabs", &close_buttons_on_tabs,
                   NULL);
 
     GdkScreen* screen = gtk_window_get_screen (GTK_WINDOW (browser));
@@ -3268,6 +3557,16 @@ _midori_browser_update_settings (MidoriBrowser* browser)
     sokoke_widget_set_visible (browser->search, show_web_search);
     sokoke_widget_set_visible (browser->button_trash, show_trash);
 
+    /* We assume that tab_titles has the same length as close_buttons */
+    n = g_list_length (browser->tab_titles);
+    for (i = 0; i < n; i++)
+    {
+        _update_label_size (g_list_nth_data (browser->tab_titles, i),
+                            tab_label_size);
+        sokoke_widget_set_visible (g_list_nth_data (browser->close_buttons, i),
+                                   close_buttons_on_tabs);
+    }
+
     g_free (last_pageholder_uri);
 }
 
@@ -3276,9 +3575,12 @@ midori_browser_settings_notify (MidoriWebSettings* web_settings,
                                 GParamSpec*        pspec,
                                 MidoriBrowser*     browser)
 {
-    const gchar* name = g_intern_string (pspec->name);
+    const gchar* name;
     GValue value = {0, };
+    guint i;
+    guint n;
 
+    name = g_intern_string (pspec->name);
     g_value_init (&value, pspec->value_type);
     g_object_get_property (G_OBJECT (browser->settings), name, &value);
 
@@ -3300,6 +3602,20 @@ midori_browser_settings_notify (MidoriWebSettings* web_settings,
     else if (name == g_intern_string ("show-trash"))
         sokoke_widget_set_visible (browser->button_trash,
             g_value_get_boolean (&value));
+    else if (name == g_intern_string ("tab-label-size"))
+    {
+        n = g_list_length (browser->tab_titles);
+        for (i = 0; i < n; i++)
+            _update_label_size (g_list_nth_data (browser->tab_titles, i),
+                                g_value_get_int (&value));
+    }
+    else if (name == g_intern_string ("close-buttons-on-tabs"))
+    {
+        n = g_list_length (browser->close_buttons);
+        for (i = 0; i < n; i++)
+            sokoke_widget_set_visible (g_list_nth_data (browser->close_buttons, i),
+                                       g_value_get_boolean (&value));
+    }
     else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
                                              name))
          g_warning (_("Unexpected setting '%s'"), name);
@@ -3542,9 +3858,7 @@ midori_browser_set_current_page (MidoriBrowser* browser,
     gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
     GtkWidget* scrolled = gtk_notebook_get_nth_page (GTK_NOTEBOOK (browser->notebook), n);
     GtkWidget* widget = _midori_browser_child_for_scrolled (browser, scrolled);
-    if (widget && MIDORI_IS_WEB_VIEW (widget)
-        && !strcmp (midori_web_view_get_display_uri (
-        MIDORI_WEB_VIEW (widget)), ""))
+    if (widget && !strcmp (_midori_browser_get_tab_uri (browser, widget), ""))
         gtk_widget_grab_focus (browser->location);
     else
         gtk_widget_grab_focus (widget);
@@ -3584,9 +3898,7 @@ midori_browser_set_current_tab (MidoriBrowser* browser,
     GtkWidget* scrolled = _midori_browser_scrolled_for_child (browser, widget);
     gint n = gtk_notebook_page_num (GTK_NOTEBOOK (browser->notebook), scrolled);
     gtk_notebook_set_current_page (GTK_NOTEBOOK (browser->notebook), n);
-    if (widget && MIDORI_IS_WEB_VIEW (widget)
-        && !strcmp (midori_web_view_get_display_uri (
-        MIDORI_WEB_VIEW (widget)), ""))
+    if (widget && !strcmp (_midori_browser_get_tab_uri (browser, widget), ""))
         gtk_widget_grab_focus (browser->location);
     else
         gtk_widget_grab_focus (widget);
index cb56c3d5583f5e37536a6196374710b5ceded816..b99d4e366857107d5c57e7f92dee185b989e87b7 100644 (file)
@@ -29,9 +29,6 @@ struct _MidoriWebView
 {
     WebKitWebView parent_instance;
 
-    GtkWidget* tab_icon;
-    GtkWidget* tab_label;
-    GtkWidget* tab_close;
     gchar* uri;
     gchar* title;
     gboolean is_loading;
@@ -39,14 +36,13 @@ struct _MidoriWebView
     gchar* statusbar_text;
     gchar* link_uri;
 
-    gint tab_label_size;
-    gboolean close_button;
     gboolean middle_click_opens_selection;
     MidoriWebSettings* settings;
 
-    GtkWidget* proxy_menu_item;
-    GtkWidget* proxy_tab_label;
-    KatzeXbelItem* proxy_xbel_item;
+    GtkWidget* menu_item;
+    GtkWidget* tab_icon;
+    GtkWidget* tab_title;
+    KatzeXbelItem* xbel_item;
 };
 
 G_DEFINE_TYPE (MidoriWebView, midori_web_view, WEBKIT_TYPE_WEB_VIEW)
@@ -68,7 +64,6 @@ enum {
     PROGRESS_DONE,
     LOAD_DONE,
     ELEMENT_MOTION,
-    CLOSE,
     NEW_TAB,
     NEW_WINDOW,
 
@@ -150,16 +145,6 @@ midori_web_view_class_init (MidoriWebViewClass* class)
         G_TYPE_NONE, 1,
         G_TYPE_STRING);
 
-    signals[CLOSE] = g_signal_new (
-        "close",
-        G_TYPE_FROM_CLASS (class),
-        (GSignalFlags)(G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION),
-        G_STRUCT_OFFSET (MidoriWebViewClass, close),
-        0,
-        NULL,
-        g_cclosure_marshal_VOID__VOID,
-        G_TYPE_NONE, 0);
-
     signals[NEW_TAB] = g_signal_new (
         "new-tab",
         G_TYPE_FROM_CLASS (class),
@@ -235,10 +220,10 @@ _midori_web_view_set_uri (MidoriWebView* web_view,
                           const gchar*   uri)
 {
     katze_assign (web_view->uri, g_strdup (uri));
-    if (web_view->proxy_xbel_item)
+    if (web_view->xbel_item)
     {
         const gchar* uri = midori_web_view_get_display_uri (web_view);
-        katze_xbel_bookmark_set_href (web_view->proxy_xbel_item, uri);
+        katze_xbel_bookmark_set_href (web_view->xbel_item, uri);
     }
     g_object_set (web_view, "title", NULL, NULL);
 }
@@ -504,36 +489,10 @@ webkit_web_view_populate_popup_cb (GtkWidget*     web_view,
     }
 }
 
-static void
-_midori_web_view_update_tab_label_size (MidoriWebView* web_view)
-{
-    if (web_view->tab_label)
-    {
-        if (web_view->tab_label_size > -1)
-        {
-            gint width, height;
-            sokoke_widget_get_text_size (web_view->tab_label, "M",
-                                         &width, &height);
-            gtk_widget_set_size_request (web_view->tab_label,
-                                         width * web_view->tab_label_size, -1);
-            gtk_label_set_ellipsize (GTK_LABEL (web_view->tab_label),
-                                     PANGO_ELLIPSIZE_END);
-        }
-        else
-        {
-            gtk_widget_set_size_request (web_view->tab_label, -1, -1);
-            gtk_label_set_ellipsize (GTK_LABEL (web_view->tab_label),
-                                     PANGO_ELLIPSIZE_NONE);
-        }
-    }
-}
-
 static void
 _midori_web_view_update_settings (MidoriWebView* web_view)
 {
     g_object_get (G_OBJECT (web_view->settings),
-                  "tab-label-size", &web_view->tab_label_size,
-                  "close-buttons-on-tabs", &web_view->close_button,
                   "middle-click-opens-selection", &web_view->middle_click_opens_selection,
                   NULL);
 }
@@ -548,18 +507,7 @@ midori_web_view_settings_notify (MidoriWebSettings* web_settings,
     g_value_init (&value, pspec->value_type);
     g_object_get_property (G_OBJECT (web_view->settings), name, &value);
 
-    if (name == g_intern_string ("tab-label-size"))
-    {
-        web_view->tab_label_size = g_value_get_int (&value);
-        _midori_web_view_update_tab_label_size (web_view);
-    }
-    else if (name == g_intern_string ("close-buttons-on-tabs"))
-    {
-        web_view->close_button = g_value_get_boolean (&value);
-        if (web_view->tab_close)
-            sokoke_widget_set_visible (web_view->tab_close, web_view->close_button);
-    }
-    else if (name == g_intern_string ("middle-click-opens-selection"))
+    if (name == g_intern_string ("middle-click-opens-selection"))
         web_view->middle_click_opens_selection = g_value_get_boolean (&value);
     else if (!g_object_class_find_property (G_OBJECT_GET_CLASS (web_settings),
                                              name))
@@ -626,10 +574,8 @@ midori_web_view_finalize (GObject* object)
     g_free (web_view->statusbar_text);
     g_free (web_view->link_uri);
 
-    if (web_view->proxy_menu_item)
-        gtk_widget_destroy (web_view->proxy_menu_item);
-    if (web_view->proxy_xbel_item)
-        katze_xbel_item_unref (web_view->proxy_xbel_item);
+    if (web_view->xbel_item)
+        katze_xbel_item_unref (web_view->xbel_item);
 
     if (web_view->settings)
     {
@@ -665,16 +611,16 @@ midori_web_view_set_property (GObject*      object,
     case PROP_TITLE:
         katze_assign (web_view->title, g_value_dup_string (value));
         const gchar* title = midori_web_view_get_display_title (web_view);
-        if (web_view->tab_label)
+        if (web_view->tab_title)
         {
-            gtk_label_set_text (GTK_LABEL (web_view->tab_label), title);
-            gtk_widget_set_tooltip_text (web_view->tab_label, title);
+            gtk_label_set_text (GTK_LABEL (web_view->tab_title), title);
+            gtk_widget_set_tooltip_text (web_view->tab_title, title);
         }
-        if (web_view->proxy_menu_item)
+        if (web_view->menu_item)
             gtk_label_set_text (GTK_LABEL (gtk_bin_get_child (GTK_BIN (
-                                web_view->proxy_menu_item))), title);
-        if (web_view->proxy_xbel_item)
-            katze_xbel_item_set_title (web_view->proxy_xbel_item, title);
+                                web_view->menu_item))), title);
+        if (web_view->xbel_item)
+            katze_xbel_item_set_title (web_view->xbel_item, title);
         break;
     case PROP_SETTINGS:
         g_signal_handlers_disconnect_by_func (web_view->settings,
@@ -774,7 +720,7 @@ midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
 
     g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), FALSE);
 
-    if (!web_view->proxy_menu_item)
+    if (!web_view->menu_item)
     {
         title = midori_web_view_get_display_title (web_view);
         menu_item = gtk_image_menu_item_new_with_label (title);
@@ -783,9 +729,9 @@ midori_web_view_get_proxy_menu_item (MidoriWebView* web_view)
             gtk_image_new_from_pixbuf (icon));
         g_object_unref (icon);
 
-        web_view->proxy_menu_item = menu_item;
+        web_view->menu_item = menu_item;
     }
-    return web_view->proxy_menu_item;
+    return web_view->menu_item;
 }
 
 /**
@@ -816,115 +762,43 @@ midori_web_view_get_proxy_tab_icon (MidoriWebView* web_view)
         katze_throbber_set_static_pixbuf (KATZE_THROBBER (web_view->tab_icon),
                                           icon);
         g_object_unref (icon);
-    }
-    return web_view->tab_icon;
-}
 
-static gboolean
-midori_web_view_tab_label_button_release_event (GtkWidget* tab_label,
-                                                GdkEventButton* event,
-                                                MidoriWebView* web_view)
-{
-    if (event->button == 2)
-    {
-        /* Close the web view on middle click */
-        g_signal_emit (web_view, signals[CLOSE], 0);
-        return TRUE;
+        g_signal_connect (web_view->tab_icon, "destroy",
+                          G_CALLBACK (gtk_widget_destroyed),
+                          &web_view->tab_icon);
     }
-
-    return FALSE;
-}
-
-static void
-midori_web_view_tab_close_style_set (GtkWidget*     tab_close,
-                                     GtkStyle*      previous_style,
-                                     MidoriWebView* web_view)
-{
-    GtkSettings* gtk_settings = gtk_widget_get_settings (tab_close);
-    gint width, height;
-    gtk_icon_size_lookup_for_settings (gtk_settings, GTK_ICON_SIZE_BUTTON,
-                                       &width, &height);
-    gtk_widget_set_size_request (tab_close, width + 2, height + 2);
-}
-
-static void
-midori_web_view_tab_close_clicked (GtkWidget*     tab_close,
-                                   MidoriWebView* web_view)
-{
-    g_signal_emit (web_view, signals[CLOSE], 0);
+    return web_view->tab_icon;
 }
 
 /**
- * midori_web_view_get_proxy_tab_label:
+ * midori_web_view_get_proxy_tab_title:
  * @web_view: a #MidoriWebView
  *
- * Retrieves a proxy tab label that is typically used as the label
+ * Retrieves a proxy tab title that is typically used as the label
  * of a #GtkNotebook page.
  *
- * The label is created on the first call and will be updated to
- * reflect changes to the icon and title automatically.
- *
- * The icon embedded in the label will reflect the loading status
- * of the web view.
+ * The title is created on the first call and will be updated to
+ * reflect changes automatically.
  *
- * Note: This fails if a proxy tab icon has been created already.
- *
- * Return value: the proxy #GtkEventBox
+ * Return value: the proxy #GtkLabel
  **/
 GtkWidget*
-midori_web_view_get_proxy_tab_label (MidoriWebView* web_view)
+midori_web_view_get_proxy_tab_title (MidoriWebView* web_view)
 {
-    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
+    const gchar* title;
 
-    GtkWidget* proxy_tab_icon = web_view->tab_icon;
-    g_return_val_if_fail (!proxy_tab_icon, NULL);
+    g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
 
-    if (!web_view->proxy_tab_label)
+    if (!web_view->tab_title)
     {
-        web_view->tab_icon = midori_web_view_get_proxy_tab_icon (web_view);
+        title = midori_web_view_get_display_title (web_view);
+        web_view->tab_title = gtk_label_new (title);
 
-        GtkWidget* event_box = gtk_event_box_new ();
-        gtk_event_box_set_visible_window (GTK_EVENT_BOX (event_box), FALSE);
-        GtkWidget* hbox = gtk_hbox_new (FALSE, 1);
-        gtk_container_add (GTK_CONTAINER (event_box), GTK_WIDGET (hbox));
-        gtk_box_pack_start (GTK_BOX (hbox), web_view->tab_icon, FALSE, FALSE, 0);
-        const gchar* title = midori_web_view_get_display_title (web_view);
-        web_view->tab_label = gtk_label_new (title);
-        gtk_misc_set_alignment (GTK_MISC (web_view->tab_label), 0.0, 0.5);
-        /* TODO: make the tab initially look "unvisited" until it's focused */
-        gtk_box_pack_start (GTK_BOX (hbox), web_view->tab_label, FALSE, TRUE, 0);
-        web_view->proxy_tab_label = event_box;
-        _midori_web_view_update_tab_label_size (web_view);
-
-        GtkWidget* close_button = gtk_button_new ();
-        gtk_button_set_relief (GTK_BUTTON (close_button), GTK_RELIEF_NONE);
-        gtk_button_set_focus_on_click (GTK_BUTTON (close_button), FALSE);
-        GtkRcStyle* rcstyle = gtk_rc_style_new ();
-        rcstyle->xthickness = rcstyle->ythickness = 0;
-        gtk_widget_modify_style(close_button, rcstyle);
-        GtkWidget* image = gtk_image_new_from_stock (GTK_STOCK_CLOSE,
-                                                     GTK_ICON_SIZE_MENU);
-        gtk_button_set_image (GTK_BUTTON(close_button), image);
-        gtk_box_pack_end (GTK_BOX (hbox), close_button, FALSE, FALSE, 0);
-        gtk_widget_show_all (GTK_WIDGET (event_box));
-        if (!web_view->close_button)
-            gtk_widget_hide (close_button);
-        web_view->tab_close = close_button;
-
-        g_signal_connect (web_view->proxy_tab_label, "button-release-event",
-                          G_CALLBACK (midori_web_view_tab_label_button_release_event),
-                          web_view);
-        g_signal_connect (web_view->tab_icon, "destroy",
+        g_signal_connect (web_view->tab_title, "destroy",
                           G_CALLBACK (gtk_widget_destroyed),
-                          &web_view->tab_icon);
-        g_signal_connect (web_view->tab_close, "style-set",
-                          G_CALLBACK (midori_web_view_tab_close_style_set),
-                          web_view);
-        g_signal_connect (web_view->tab_close, "clicked",
-                          G_CALLBACK (midori_web_view_tab_close_clicked),
-                          web_view);
+                          &web_view->tab_title);
     }
-    return web_view->proxy_tab_label;
+    return web_view->tab_title;
 }
 
 /**
@@ -945,17 +819,20 @@ midori_web_view_get_proxy_tab_label (MidoriWebView* web_view)
 KatzeXbelItem*
 midori_web_view_get_proxy_xbel_item (MidoriWebView* web_view)
 {
+    const gchar* uri;
+    const gchar* title;
+
     g_return_val_if_fail (MIDORI_IS_WEB_VIEW (web_view), NULL);
 
-    if (!web_view->proxy_xbel_item)
+    if (!web_view->xbel_item)
     {
-        web_view->proxy_xbel_item = katze_xbel_bookmark_new ();
-        const gchar* uri = midori_web_view_get_display_uri (web_view);
-        katze_xbel_bookmark_set_href (web_view->proxy_xbel_item, uri);
-        const gchar* title = midori_web_view_get_display_title (web_view);
-        katze_xbel_item_set_title (web_view->proxy_xbel_item, title);
+        web_view->xbel_item = katze_xbel_bookmark_new ();
+        uri = midori_web_view_get_display_uri (web_view);
+        katze_xbel_bookmark_set_href (web_view->xbel_item, uri);
+        title = midori_web_view_get_display_title (web_view);
+        katze_xbel_item_set_title (web_view->xbel_item, title);
     }
-    return web_view->proxy_xbel_item;
+    return web_view->xbel_item;
 }
 
 /**
index 91491a89d6a58f43ee45ea26b32c9c09fe00f70c..52e32ddeac7c846e8f8f760bcead68ffd14eb6d9 100644 (file)
@@ -79,7 +79,10 @@ GtkWidget*
 midori_web_view_get_proxy_menu_item    (MidoriWebView*     web_view);
 
 GtkWidget*
-midori_web_view_get_proxy_tab_label    (MidoriWebView*     web_view);
+midori_web_view_get_proxy_tab_icon     (MidoriWebView*     web_view);
+
+GtkWidget*
+midori_web_view_get_proxy_tab_title    (MidoriWebView*     web_view);
 
 KatzeXbelItem*
 midori_web_view_get_proxy_xbel_item    (MidoriWebView*     web_view);
index 49896e2a45dc0de98f46e583b0d7d9b183975f74..e267eed1343442f4ad96f51463f0fc4104edc1f7 100644 (file)
@@ -503,10 +503,12 @@ sokoke_web_icon (const gchar* icon,
         else
         {
             gint width, height;
-            gtk_icon_size_lookup (size, &width, &height);
             if (gtk_widget_has_screen (widget))
             {
                 GdkScreen* screen = gtk_widget_get_screen (widget);
+                gtk_icon_size_lookup_for_settings (
+                    gtk_settings_get_for_screen (screen),
+                    size, &width, &height);
                 pixbuf = gtk_icon_theme_load_icon (
                     gtk_icon_theme_get_for_screen (screen), icon,
                     MAX (width, height), GTK_ICON_LOOKUP_USE_BUILTIN, NULL);
@@ -519,3 +521,31 @@ sokoke_web_icon (const gchar* icon,
         pixbuf = gtk_widget_render_icon (widget, GTK_STOCK_FIND, size, NULL);
     return pixbuf;
 }
+
+gint
+sokoke_object_get_int (gpointer     object,
+                       const gchar* property)
+{
+    gint value;
+
+    g_return_val_if_fail (object != NULL, FALSE);
+    g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
+    /* FIXME: Check value type */
+
+    g_object_get (object, property, &value, NULL);
+    return value;
+}
+
+gboolean
+sokoke_object_get_boolean (gpointer     object,
+                           const gchar* property)
+{
+    gboolean value;
+
+    g_return_val_if_fail (object != NULL, FALSE);
+    g_return_val_if_fail (G_IS_OBJECT (object), FALSE);
+    /* FIXME: Check value type */
+
+    g_object_get (object, property, &value, NULL);
+    return value;
+}
index a2b14afc53ba782668b78a80544b15ebf977994f..c4cbbce0348f2bebf8e00ee8cc38e2896d5ab3f3 100644 (file)
 #define GTK_ICON_SIZE_SMALL_TOOLBAR GTK_ICON_SIZE_BUTTON
 
 gchar*
-sokoke_magic_uri               (const gchar*   uri,
-                                MidoriWebList* search_engines);
+sokoke_magic_uri                    (const gchar*    uri,
+                                     MidoriWebList*  search_engines);
 
 void
-sokoke_entry_setup_completion  (GtkEntry* entry);
+sokoke_entry_setup_completion       (GtkEntry*       entry);
 
 void
-sokoke_entry_append_completion (GtkEntry*    entry,
-                                const gchar* text);
+sokoke_entry_append_completion      (GtkEntry*       entry,
+                                     const gchar*    text);
 
 typedef enum {
     SOKOKE_MENU_POSITION_CURSOR = 0,
@@ -37,81 +37,91 @@ typedef enum {
 } SokokeMenuPos;
 
 void
-sokoke_combo_box_add_strings (GtkComboBox* combobox,
-                              const gchar* label_first, ...);
+sokoke_combo_box_add_strings        (GtkComboBox*    combobox,
+                                     const gchar*    label_first,
+                                     ...);
 
 void
-sokoke_widget_set_visible (GtkWidget* widget,
-                           gboolean   visible);
+sokoke_widget_set_visible           (GtkWidget*      widget,
+                                     gboolean        visible);
 
 void
-sokoke_container_show_children (GtkContainer* container);
+sokoke_container_show_children      (GtkContainer*   container);
 
 void
-sokoke_widget_popup (GtkWidget*      widget,
-                     GtkMenu*        menu,
-                     GdkEventButton* event,
-                     SokokeMenuPos   pos);
+sokoke_widget_popup                 (GtkWidget*      widget,
+                                     GtkMenu*        menu,
+                                     GdkEventButton* event,
+                                     SokokeMenuPos   pos);
 
 GtkWidget*
-sokoke_xfce_header_new (const gchar* icon,
-                        const gchar* title);
+sokoke_xfce_header_new              (const gchar*    icon,
+                                     const gchar*    title);
 
 GtkWidget*
-sokoke_superuser_warning_new (void);
+sokoke_superuser_warning_new        (void);
 
 GtkWidget*
-sokoke_hig_frame_new (const gchar* title);
+sokoke_hig_frame_new                (const gchar*    title);
 
 void
-sokoke_widget_set_pango_font_style (GtkWidget* widget,
-                                    PangoStyle style);
+sokoke_widget_set_pango_font_style  (GtkWidget*      widget,
+                                     PangoStyle      style);
 
 void
-sokoke_entry_set_default_text(GtkEntry*, const gchar*);
+sokoke_entry_set_default_text       (GtkEntry*       entry,
+                                     const gchar*    default_text);
 
 gchar*
-sokoke_key_file_get_string_default (GKeyFile*    key_file,
-                                    const gchar* group,
-                                    const gchar* key,
-                                    const gchar* default_value,
-                                    GError**     error);
+sokoke_key_file_get_string_default  (GKeyFile*       key_file,
+                                     const gchar*    group,
+                                     const gchar*    key,
+                                     const gchar*    default_value,
+                                     GError**        error);
 
 gint
-sokoke_key_file_get_integer_default (GKeyFile*    key_file,
-                                     const gchar* group,
-                                     const gchar* key,
-                                     const gint   default_value,
-                                     GError**     error);
+sokoke_key_file_get_integer_default  (GKeyFile*      key_file,
+                                      const gchar*   group,
+                                      const gchar*   key,
+                                      const gint     default_value,
+                                      GError**       error);
 
 gdouble
-sokoke_key_file_get_double_default (GKeyFile*    key_file,
-                                    const gchar* group,
-                                    const gchar* key,
-                                    gdouble      default_value,
-                                    GError**     error);
+sokoke_key_file_get_double_default   (GKeyFile*      key_file,
+                                      const gchar*   group,
+                                      const gchar*   key,
+                                      gdouble        default_value,
+                                      GError**       error);
 
 gboolean
-sokoke_key_file_get_boolean_default (GKeyFile*    key_file,
-                                     const gchar* group,
-                                     const gchar* key,
-                                     gboolean     default_value,
-                                     GError**     error);
+sokoke_key_file_get_boolean_default  (GKeyFile*      key_file,
+                                      const gchar*   group,
+                                      const gchar*   key,
+                                      gboolean       default_value,
+                                      GError**       error);
 
 gboolean
-sokoke_key_file_save_to_file (GKeyFile*    key_file,
-                              const gchar* filename,
-                              GError**     error);
+sokoke_key_file_save_to_file         (GKeyFile*      key_file,
+                                      const gchar*   filename,
+                                      GError**       error);
 
 void
-sokoke_widget_get_text_size (GtkWidget*   widget,
-                             const gchar* text,
-                             gint*        width,
-                             gint*        height);
+sokoke_widget_get_text_size          (GtkWidget*     widget,
+                                      const gchar*   text,
+                                      gint*          width,
+                                      gint*          height);
 
 GdkPixbuf*
-sokoke_web_icon                      (const gchar* icon,
-                                      GtkIconSize  size,
-                                      GtkWidget*   widget);
+sokoke_web_icon                      (const gchar*   icon,
+                                      GtkIconSize    size,
+                                      GtkWidget*     widget);
+
+gint
+sokoke_object_get_int                (gpointer       object,
+                                      const gchar*   property);
+
+gboolean
+sokoke_object_get_boolean            (gpointer       object,
+                                      const gchar*   property);
 
 #endif /* !__SOKOKE_H__ */