]> spindle.queued.net Git - midori/commitdiff
Show progress in location entry if statusbar is hidden
authorChristian Dywan <christian@twotoasts.de>
Sun, 31 Aug 2008 00:45:13 +0000 (02:45 +0200)
committerChristian Dywan <christian@twotoasts.de>
Sun, 31 Aug 2008 00:45:13 +0000 (02:45 +0200)
AUTHORS
midori/midori-browser.c
midori/midori-locationaction.c
midori/midori-locationaction.h
midori/midori-locationentry.c
midori/midori-locationentry.h

diff --git a/AUTHORS b/AUTHORS
index 2b93c60c9b0e287cf477e16a0b1f40cce310689e..161eb23a8eb491eaa5cb1ff13fa869f41781da6a 100644 (file)
--- a/AUTHORS
+++ b/AUTHORS
@@ -29,3 +29,5 @@ Translations:
 
 Code from other projects:
     GTK+/ GdkPixbuf, Matthias Clasen <mclasen@redhat.com>
+    GTK+/ GtkEntry, Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+    Modified by the GTK+ Team and others 1997-2000
index 3db8f8e69236aab397acffde49aadf0032cc4b4c..78aff86f64b71615f0a2ac1fdfab2b864fe2416a 100644 (file)
@@ -271,9 +271,9 @@ _midori_browser_update_interface (MidoriBrowser* browser)
         gtk_widget_set_sensitive (browser->throbber, FALSE);
         g_object_set (action,
                       "stock-id", GTK_STOCK_REFRESH,
-                      "tooltip", _("Reload the current page"), NULL);
+                      "tooltip", _("Reload the current page"),
+                      "sensitive", web_view != NULL, NULL);
         gtk_widget_hide (browser->progressbar);
-        gtk_action_set_sensitive (action, web_view != NULL);
     }
     else
     {
@@ -282,6 +282,9 @@ _midori_browser_update_interface (MidoriBrowser* browser)
                       "stock-id", GTK_STOCK_STOP,
                       "tooltip", _("Stop loading the current page"), NULL);
         gtk_widget_show (browser->progressbar);
+        if (!GTK_WIDGET_VISIBLE (browser->statusbar))
+            g_object_set (_action_by_name (browser, "Location"), "progress",
+                midori_web_view_get_progress (MIDORI_WEB_VIEW (web_view)), NULL);
     }
     katze_throbber_set_animated (KATZE_THROBBER (browser->throbber), loading);
 
@@ -339,10 +342,15 @@ static void
 _midori_browser_update_progress (MidoriBrowser* browser,
                                  MidoriWebView* web_view)
 {
+    MidoriLocationAction* action;
     gdouble progress;
     gchar* message;
 
+    action = MIDORI_LOCATION_ACTION (_action_by_name (browser, "Location"));
     progress = midori_web_view_get_progress (web_view);
+    /* When we are finished, we don't want to *see* progress anymore */
+    if (midori_web_view_get_load_status (web_view) == MIDORI_LOAD_FINISHED)
+        progress = 0.0;
     if (progress > 0.0)
     {
         gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (browser->progressbar),
@@ -351,12 +359,15 @@ _midori_browser_update_progress (MidoriBrowser* browser,
         gtk_progress_bar_set_text (GTK_PROGRESS_BAR (browser->progressbar),
                                    message);
         g_free (message);
+        if (!GTK_WIDGET_VISIBLE (browser->statusbar))
+            midori_location_action_set_progress (action, progress);
     }
     else
     {
         gtk_progress_bar_pulse (GTK_PROGRESS_BAR (browser->progressbar));
         gtk_progress_bar_set_text (GTK_PROGRESS_BAR (browser->progressbar),
                                    NULL);
+        midori_location_action_set_progress (action, 0.0);
     }
 }
 
@@ -634,7 +645,7 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
         gtk_entry_set_activates_default (GTK_ENTRY (entry_uri), TRUE);
         gtk_entry_set_text (GTK_ENTRY (entry_uri),
                             katze_xbel_bookmark_get_href (bookmark));
-        gtk_box_pack_start (GTK_BOX(hbox), entry_uri, TRUE, TRUE, 0);
+        gtk_box_pack_start (GTK_BOX (hbox), entry_uri, TRUE, TRUE, 0);
         gtk_container_add (GTK_CONTAINER (GTK_DIALOG (dialog)->vbox), hbox);
         gtk_widget_show_all (hbox);
     }
@@ -661,7 +672,7 @@ midori_browser_edit_bookmark_dialog_new (MidoriBrowser* browser,
         katze_xbel_item_set_title (bookmark,
             gtk_entry_get_text (GTK_ENTRY (entry_title)));
         katze_xbel_item_set_desc (bookmark,
-            gtk_entry_get_text(GTK_ENTRY(entry_desc)));
+            gtk_entry_get_text (GTK_ENTRY (entry_desc)));
         if (katze_xbel_item_is_bookmark (bookmark))
             katze_xbel_bookmark_set_href (bookmark,
                 gtk_entry_get_text (GTK_ENTRY (entry_uri)));
@@ -1582,8 +1593,8 @@ _midori_browser_tab_set_highlight_text_matches (MidoriBrowser* browser,
 }
 
 static void
-_action_find_activate(GtkAction*     action,
-                      MidoriBrowser* browser)
+_action_find_activate (GtkAction*     action,
+                       MidoriBrowser* browser)
 {
     if (GTK_WIDGET_VISIBLE (browser->find))
     {
@@ -1609,7 +1620,7 @@ _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));
+        GTK_TOGGLE_TOOL_BUTTON (browser->find_case));
     GtkWidget* widget = midori_browser_get_current_tab (browser);
     if (GTK_WIDGET_VISIBLE (browser->find))
         _midori_browser_tab_unmark_text_matches (browser, widget);
@@ -1772,6 +1783,9 @@ _action_statusbar_activate (GtkToggleAction* action,
     gboolean active = gtk_toggle_action_get_active (action);
     g_object_set (browser->settings, "show-statusbar", active, NULL);
     sokoke_widget_set_visible (browser->statusbar, active);
+    if (active)
+        g_object_set (_action_by_name (browser, "Location"),
+                      "progress", 0.0, NULL);
 }
 
 static void
@@ -3237,8 +3251,8 @@ midori_browser_init (MidoriBrowser* browser)
     browser->menubar = gtk_ui_manager_get_widget (ui_manager, "/menubar");
     GtkWidget* menuitem = gtk_menu_item_new ();
     gtk_widget_show (menuitem);
-    browser->throbber = katze_throbber_new();
-    gtk_widget_show(browser->throbber);
+    browser->throbber = katze_throbber_new ();
+    gtk_widget_show (browser->throbber);
     gtk_container_add (GTK_CONTAINER (menuitem), browser->throbber);
     gtk_widget_set_sensitive (menuitem, FALSE);
     gtk_menu_item_set_right_justified (GTK_MENU_ITEM (menuitem), TRUE);
index d8d285ac636856e783ce1d0388aee8b69970bfb7..503740b8a425dee47d30f012f00b2d61aa576916 100644 (file)
@@ -23,6 +23,7 @@ struct _MidoriLocationAction
     GtkAction parent_instance;
 
     gchar* uri;
+    gdouble progress;
 };
 
 struct _MidoriLocationActionClass
@@ -36,6 +37,7 @@ enum
 {
     PROP_0,
 
+    PROP_PROGRESS,
     PROP_SECONDARY_ICON
 };
 
@@ -138,11 +140,20 @@ midori_location_action_class_init (MidoriLocationActionClass* class)
     action_class->connect_proxy = midori_location_action_connect_proxy;
     action_class->disconnect_proxy = midori_location_action_disconnect_proxy;
 
+    g_object_class_install_property (gobject_class,
+                                     PROP_PROGRESS,
+                                     g_param_spec_double (
+                                     "progress",
+                                     _("Progress"),
+                                     _("The current progress of the action"),
+                                     0.0, 1.0, 0.0,
+                                     G_PARAM_WRITABLE));
+
     g_object_class_install_property (gobject_class,
                                      PROP_SECONDARY_ICON,
                                      g_param_spec_string (
                                      "secondary-icon",
-                                     "Secondary",
+                                     _("Secondary"),
                                      _("The stock ID of the secondary icon"),
                                      NULL,
                                      G_PARAM_WRITABLE));
@@ -152,6 +163,7 @@ static void
 midori_location_action_init (MidoriLocationAction* location_action)
 {
     location_action->uri = NULL;
+    location_action->progress = 0.0;
 }
 
 static void
@@ -174,6 +186,12 @@ midori_location_action_set_property (GObject*      object,
 
     switch (prop_id)
     {
+    case PROP_PROGRESS:
+    {
+        midori_location_action_set_progress (location_action,
+            g_value_get_double (value));
+        break;
+    }
     case PROP_SECONDARY_ICON:
     {
         midori_location_action_set_secondary_icon (location_action,
@@ -223,6 +241,8 @@ midori_location_action_create_tool_item (GtkAction* action)
     toolitem = GTK_WIDGET (gtk_tool_item_new ());
     gtk_tool_item_set_expand (GTK_TOOL_ITEM (toolitem), TRUE);
     entry = midori_location_entry_new ();
+    midori_location_entry_set_progress (MIDORI_LOCATION_ENTRY (entry),
+        MIDORI_LOCATION_ACTION (action)->progress);
     gtk_icon_entry_set_icon_highlight (GTK_ICON_ENTRY (
         gtk_bin_get_child (GTK_BIN (entry))),
         GTK_ICON_ENTRY_SECONDARY, TRUE);
@@ -355,7 +375,6 @@ midori_location_action_set_uri (MidoriLocationAction* location_action,
     g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
     g_return_if_fail (uri != NULL);
 
-
     katze_assign (location_action->uri, g_strdup (uri));
 
     proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
@@ -478,6 +497,42 @@ midori_location_action_set_title_for_uri (MidoriLocationAction* location_action,
     while ((proxies = g_slist_next (proxies)));
 }
 
+gdouble
+midori_location_action_get_progress (MidoriLocationAction* location_action)
+{
+    g_return_val_if_fail (MIDORI_IS_LOCATION_ACTION (location_action), 0.0);
+
+    return location_action->progress;
+}
+
+void
+midori_location_action_set_progress (MidoriLocationAction* location_action,
+                                     gdouble               progress)
+{
+    GSList* proxies;
+    GtkWidget* alignment;
+    GtkWidget* entry;
+
+    g_return_if_fail (MIDORI_IS_LOCATION_ACTION (location_action));
+
+    location_action->progress = CLAMP (progress, 0.0, 1.0);
+
+    proxies = gtk_action_get_proxies (GTK_ACTION (location_action));
+    if (!proxies)
+        return;
+
+    do
+    if (GTK_IS_TOOL_ITEM (proxies->data))
+    {
+        alignment = gtk_bin_get_child (GTK_BIN (proxies->data));
+        entry = gtk_bin_get_child (GTK_BIN (alignment));
+
+        midori_location_entry_set_progress (MIDORI_LOCATION_ENTRY (entry),
+                                            location_action->progress);
+    }
+    while ((proxies = g_slist_next (proxies)));
+}
+
 void
 midori_location_action_set_secondary_icon (MidoriLocationAction* location_action,
                                            const gchar*          stock_id)
index 5310c4d11eaa4d86b1f571b1db88ce1d47039ede..c6d1e2cd9891a446eb52088af725b0c3a1cb17d4 100644 (file)
@@ -53,6 +53,13 @@ midori_location_action_set_title_for_uri  (MidoriLocationAction* location_action
                                            const gchar*          title,
                                            const gchar*          text);
 
+gdouble
+midori_location_action_get_progress       (MidoriLocationAction* location_action);
+
+void
+midori_location_action_set_progress       (MidoriLocationAction* location_action,
+                                           gdouble               progress);
+
 void
 midori_location_action_set_secondary_icon (MidoriLocationAction* location_action,
                                            const gchar*          stock_id);
index 24508505c11d6b56ac2c7cf77484e088084566b1..70466eaf9b23f7fdc11bd508878c6cdc8d847c8e 100644 (file)
@@ -20,6 +20,8 @@
 struct _MidoriLocationEntry
 {
     GtkComboBoxEntry parent_instance;
+
+    gdouble progress;
 };
 
 struct _MidoriLocationEntryClass
@@ -68,6 +70,263 @@ midori_location_entry_class_init (MidoriLocationEntryClass* class)
                                             G_TYPE_INT);
 }
 
+#define HAVE_ENTRY_PROGRESS GTK_CHECK_VERSION (2, 10, 0)
+
+#ifdef HAVE_ENTRY_PROGRESS
+
+/* GTK+/ GtkEntry internal helper function
+   Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+   Modified by the GTK+ Team and others 1997-2000
+   Copied from Gtk+ 2.13, whitespace adjusted */
+static void
+gtk_entry_get_pixel_ranges (GtkEntry  *entry,
+                            gint     **ranges,
+                            gint      *n_ranges)
+{
+  gint start_char, end_char;
+
+  if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_char, &end_char))
+    {
+      PangoLayout *layout = gtk_entry_get_layout (entry);
+      PangoLayoutLine *line = pango_layout_get_lines (layout)->data;
+      const char *text = pango_layout_get_text (layout);
+      gint start_index = g_utf8_offset_to_pointer (text, start_char) - text;
+      gint end_index = g_utf8_offset_to_pointer (text, end_char) - text;
+      gint real_n_ranges, i;
+
+      pango_layout_line_get_x_ranges (line, start_index, end_index, ranges, &real_n_ranges);
+
+      if (ranges)
+        {
+          gint *r = *ranges;
+
+          for (i = 0; i < real_n_ranges; ++i)
+            {
+              r[2 * i + 1] = (r[2 * i + 1] - r[2 * i]) / PANGO_SCALE;
+              r[2 * i] = r[2 * i] / PANGO_SCALE;
+            }
+        }
+
+      if (n_ranges)
+        *n_ranges = real_n_ranges;
+    }
+  else
+    {
+      if (n_ranges)
+        *n_ranges = 0;
+      if (ranges)
+        *ranges = NULL;
+    }
+}
+
+/* GTK+/ GtkEntry internal helper function
+   Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+   Modified by the GTK+ Team and others 1997-2000
+   Copied from Gtk+ 2.13, whitespace adjusted
+   Code adjusted to not rely on internal qdata */
+static void
+_gtk_entry_effective_inner_border (GtkEntry  *entry,
+                                   GtkBorder *border)
+{
+  static const GtkBorder default_inner_border = { 2, 2, 2, 2 };
+  GtkBorder *tmp_border;
+
+  tmp_border = (GtkBorder*) gtk_entry_get_inner_border (entry);
+
+  if (tmp_border)
+    {
+      *border = *tmp_border;
+      return;
+    }
+
+  gtk_widget_style_get (GTK_WIDGET (entry), "inner-border", &tmp_border, NULL);
+
+  if (tmp_border)
+    {
+      *border = *tmp_border;
+      gtk_border_free (tmp_border);
+      return;
+    }
+
+  *border = default_inner_border;
+}
+
+/* GTK+/ GtkEntry internal helper function
+   Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+   Modified by the GTK+ Team and others 1997-2000
+   Copied from Gtk+ 2.13, whitespace adjusted */
+static void
+get_layout_position (GtkEntry *entry,
+                     gint     *x,
+                     gint     *y)
+{
+  PangoLayout *layout;
+  PangoRectangle logical_rect;
+  gint area_width, area_height;
+  GtkBorder inner_border;
+  gint y_pos;
+  PangoLayoutLine *line;
+
+  layout = gtk_entry_get_layout (entry);
+
+  GTK_ENTRY_CLASS (G_OBJECT_GET_CLASS (entry))->get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
+  _gtk_entry_effective_inner_border (entry, &inner_border);
+
+  area_height = PANGO_SCALE * (area_height - inner_border.top - inner_border.bottom);
+
+  line = pango_layout_get_lines (layout)->data;
+  pango_layout_line_get_extents (line, NULL, &logical_rect);
+
+  /* Align primarily for locale's ascent/descent */
+  y_pos = ((area_height - entry->ascent - entry->descent) / 2 +
+           entry->ascent + logical_rect.y);
+
+  /* Now see if we need to adjust to fit in actual drawn string */
+  if (logical_rect.height > area_height)
+    y_pos = (area_height - logical_rect.height) / 2;
+  else if (y_pos < 0)
+    y_pos = 0;
+  else if (y_pos + logical_rect.height > area_height)
+    y_pos = area_height - logical_rect.height;
+
+  y_pos = inner_border.top + y_pos / PANGO_SCALE;
+
+  if (x)
+    *x = inner_border.left - entry->scroll_offset;
+
+  if (y)
+    *y = y_pos;
+}
+
+/* GTK+/ GtkEntry internal helper function
+   Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+   Modified by the GTK+ Team and others 1997-2000
+   Copied from Gtk+ 2.13, whitespace adjusted
+   Code adjusted to not rely on internal _gtk_entry_ensure_layout */
+static void
+gtk_entry_draw_text (GtkEntry *entry)
+{
+  GtkWidget *widget;
+
+  if (!entry->visible && entry->invisible_char == 0)
+    return;
+
+  if (GTK_WIDGET_DRAWABLE (entry))
+    {
+      PangoLayout *layout = gtk_entry_get_layout (entry);
+      cairo_t *cr;
+      gint x, y;
+      gint start_pos, end_pos;
+
+      widget = GTK_WIDGET (entry);
+
+      get_layout_position (entry, &x, &y);
+
+      cr = gdk_cairo_create (entry->text_area);
+
+      cairo_move_to (cr, x, y);
+      gdk_cairo_set_source_color (cr, &widget->style->text [widget->state]);
+      pango_cairo_show_layout (cr, layout);
+
+      if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos))
+        {
+          gint *ranges;
+          gint n_ranges, i;
+          PangoRectangle logical_rect;
+          GdkColor *selection_color, *text_color;
+          GtkBorder inner_border;
+
+          pango_layout_get_pixel_extents (layout, NULL, &logical_rect);
+          gtk_entry_get_pixel_ranges (entry, &ranges, &n_ranges);
+
+          if (GTK_WIDGET_HAS_FOCUS (entry))
+            {
+              selection_color = &widget->style->base [GTK_STATE_SELECTED];
+              text_color = &widget->style->text [GTK_STATE_SELECTED];
+            }
+          else
+            {
+              selection_color = &widget->style->base [GTK_STATE_ACTIVE];
+              text_color = &widget->style->text [GTK_STATE_ACTIVE];
+            }
+
+          _gtk_entry_effective_inner_border (entry, &inner_border);
+
+          for (i = 0; i < n_ranges; ++i)
+            cairo_rectangle (cr,
+                             inner_border.left - entry->scroll_offset + ranges[2 * i],
+                             y,
+                             ranges[2 * i + 1],
+                             logical_rect.height);
+
+          cairo_clip (cr);
+
+          gdk_cairo_set_source_color (cr, selection_color);
+          cairo_paint (cr);
+
+          cairo_move_to (cr, x, y);
+          gdk_cairo_set_source_color (cr, text_color);
+          pango_cairo_show_layout (cr, layout);
+
+          g_free (ranges);
+        }
+
+      cairo_destroy (cr);
+    }
+}
+
+static gboolean
+entry_expose_event (GtkWidget*           entry,
+                    GdkEventExpose*      event,
+                    MidoriLocationEntry* location_entry)
+{
+  GdkWindow* text_area;
+  gint width, height;
+
+  text_area = GTK_ENTRY (entry)->text_area;
+
+  gdk_drawable_get_size (text_area, &width, &height);
+
+  if (location_entry->progress > 0.0/* && location_entry->progress < 1.0*/)
+  {
+      gtk_paint_box (entry->style, text_area,
+                     GTK_STATE_SELECTED, GTK_SHADOW_OUT,
+                     &event->area, entry, "bar",
+                     0, 0, location_entry->progress * width, height);
+      gtk_entry_draw_text (GTK_ENTRY (entry));
+  }
+  return FALSE;
+}
+
+#endif
+
+gdouble
+midori_location_entry_get_progress (MidoriLocationEntry* location_entry)
+{
+    g_return_val_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry), 0.0);
+
+    return location_entry->progress;
+}
+
+void
+midori_location_entry_set_progress (MidoriLocationEntry* location_entry,
+                                    gdouble              progress)
+{
+    #ifdef HAVE_ENTRY_PROGRESS
+    GtkWidget* child;
+    #endif
+
+    g_return_if_fail (MIDORI_IS_LOCATION_ENTRY (location_entry));
+
+    location_entry->progress = CLAMP (progress, 0.0, 1.0);
+
+    #ifdef HAVE_ENTRY_PROGRESS
+    child = gtk_bin_get_child (GTK_BIN (location_entry));
+    if (GTK_ENTRY (child)->text_area)
+        gdk_window_invalidate_rect (GTK_ENTRY (child)->text_area, NULL, FALSE);
+    #endif
+}
+
 static void
 midori_location_entry_init (MidoriLocationEntry* location_entry)
 {
@@ -81,16 +340,22 @@ midori_location_entry_init (MidoriLocationEntry* location_entry)
                          "widget_class \"*MidoriLocationEntry\" "
                          "style \"midori-location-entry-style\"\n");
 
+    location_entry->progress = 0.0;
+
     entry = gtk_icon_entry_new ();
     gtk_icon_entry_set_icon_from_stock (GTK_ICON_ENTRY (entry), GTK_ICON_ENTRY_PRIMARY, DEFAULT_ICON);
     g_signal_connect (entry, "key-press-event", G_CALLBACK (entry_key_press_event), location_entry);
+    #ifdef HAVE_ENTRY_PROGRESS
+    g_signal_connect_after (entry, "expose-event",
+        G_CALLBACK (entry_expose_event), location_entry);
+    #endif
 
     gtk_widget_show (entry);
     gtk_container_add (GTK_CONTAINER (location_entry), entry);
 
     store = gtk_list_store_new (N_COLS, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_STRING);
     g_object_set (G_OBJECT (location_entry), "model", store, NULL);
-    g_object_unref(store);
+    g_object_unref (store);
 
     gtk_combo_box_entry_set_text_column (GTK_COMBO_BOX_ENTRY (location_entry), URI_COL);
     gtk_cell_layout_clear (GTK_CELL_LAYOUT (location_entry));
index d6421b47f51c4f99757ed9f1b0fa293b113ecb55..53f8a6fc3d122ebb0624f2cb5ac7c6f41dcdd48e 100644 (file)
@@ -63,6 +63,13 @@ void
 midori_location_entry_add_item          (MidoriLocationEntry* location_entry,
                                          MidoriLocationEntryItem* item);
 
+gdouble
+midori_location_entry_get_progress      (MidoriLocationEntry* location_entry);
+
+void
+midori_location_entry_set_progress      (MidoriLocationEntry* location_entry,
+                                         gdouble              progress);
+
 G_END_DECLS
 
 #endif /* __MIDORI_LOCATION_ENTRY_H__ */