[evince/outline_search_improvements: 4/8] Improve Outline context menu




commit de57f326ffc96d2805976901091c4c7331b6aa87
Author: Nelson Benítez León <nbenitezl gmail com>
Date:   Wed Jun 22 17:55:16 2022 +0100

    Improve Outline context menu
    
    By:
     - Adding a new "Search in Outline" menu item,
       which will make that existant feature to be
       discoverable by:
          - Giving focus to the search text entry and
            clearing the text in it.
          - Make text entry wider, because by default
            it's small to just show page numbers.
    
     - Update the menu sensitivity to only update when
       right clicking on a selected path.
    
    Part of issue #1555

 libmisc/ev-page-action-widget.c | 30 ++++++++++++++++++++---
 libmisc/ev-page-action-widget.h |  2 ++
 shell/ev-sidebar-links.c        | 40 ++++++++++++++++++++++++++++---
 shell/ev-window.c               | 53 +++++++++++++++++++++++++++++++++++++----
 shell/ev-window.h               |  1 +
 5 files changed, 115 insertions(+), 11 deletions(-)
---
diff --git a/libmisc/ev-page-action-widget.c b/libmisc/ev-page-action-widget.c
index e5c26901a..39152d087 100644
--- a/libmisc/ev-page-action-widget.c
+++ b/libmisc/ev-page-action-widget.c
@@ -28,6 +28,8 @@
 #include <evince-document.h>
 #include "ev-page-action-widget.h"
 
+#define COMPLETION_RESULTS_WIDTH 50
+
 /* Widget we pass back */
 static void  ev_page_action_widget_init       (EvPageActionWidget      *action_widget);
 static void  ev_page_action_widget_class_init (EvPageActionWidgetClass *action_widget);
@@ -51,6 +53,7 @@ struct _EvPageActionWidget
        gulong notify_document_signal_id;
        GtkTreeModel *filter_model;
        GtkTreeModel *model;
+       GtkEntryCompletion *completion;
 };
 
 static guint widget_signals[WIDGET_N_SIGNALS] = {0, };
@@ -203,6 +206,8 @@ focus_out_cb (EvPageActionWidget *action_widget)
 {
         ev_page_action_widget_set_current_page (action_widget,
                                                 ev_document_model_get_page (action_widget->doc_model));
+        g_object_set (action_widget->entry, "xalign", 1.0, NULL);
+        ev_page_action_widget_update_max_width (action_widget);
         return FALSE;
 }
 
@@ -339,6 +344,8 @@ ev_page_action_widget_finalize (GObject *object)
                action_widget->doc_model = NULL;
        }
 
+       g_clear_object (&action_widget->completion);
+
         ev_page_action_widget_set_document (action_widget, NULL);
 
        G_OBJECT_CLASS (ev_page_action_widget_parent_class)->finalize (object);
@@ -564,6 +571,8 @@ ev_page_action_widget_update_links_model (EvPageActionWidget *proxy, GtkTreeMode
        filter_model = get_filter_model_from_model (model);
 
        completion = gtk_entry_completion_new ();
+       g_clear_object (&proxy->completion);
+       proxy->completion = completion;
        g_object_set (G_OBJECT (completion),
                      "popup-set-width", FALSE,
                      "model", filter_model,
@@ -578,7 +587,7 @@ ev_page_action_widget_update_links_model (EvPageActionWidget *proxy, GtkTreeMode
        renderer = (GtkCellRenderer *)
                g_object_new (GTK_TYPE_CELL_RENDERER_TEXT,
                              "ellipsize", PANGO_ELLIPSIZE_END,
-                             "width_chars", 30,
+                             "width_chars", COMPLETION_RESULTS_WIDTH,
                              NULL);
        gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (completion), renderer, TRUE);
        gtk_cell_layout_set_cell_data_func (GTK_CELL_LAYOUT (completion),
@@ -586,8 +595,6 @@ ev_page_action_widget_update_links_model (EvPageActionWidget *proxy, GtkTreeMode
                                            (GtkCellLayoutDataFunc) display_completion_text,
                                            proxy, NULL);
        gtk_entry_set_completion (GTK_ENTRY (proxy->entry), completion);
-
-       g_object_unref (completion);
 }
 
 void
@@ -596,3 +603,20 @@ ev_page_action_widget_grab_focus (EvPageActionWidget *proxy)
        gtk_widget_grab_focus (proxy->entry);
 }
 
+void
+ev_page_action_widget_clear (EvPageActionWidget *proxy)
+{
+       gtk_entry_set_text (GTK_ENTRY (proxy->entry), "");
+}
+
+/* Sets width of the text entry, width will be restablished
+ * to default one on focus_out event. This function is used
+ * when searching the Outline, so the user has more space
+ * to write the search term. */
+void
+ev_page_action_widget_set_temporary_entry_width (EvPageActionWidget *proxy, gint width)
+{
+       gtk_entry_set_width_chars (GTK_ENTRY (proxy->entry), width);
+       /* xalign will also be restablished on focus_out */
+       g_object_set (proxy->entry, "xalign", 0., NULL);
+}
diff --git a/libmisc/ev-page-action-widget.h b/libmisc/ev-page-action-widget.h
index 23a94144d..f50055d25 100644
--- a/libmisc/ev-page-action-widget.h
+++ b/libmisc/ev-page-action-widget.h
@@ -48,5 +48,7 @@ void ev_page_action_widget_update_links_model (EvPageActionWidget *proxy,
 void ev_page_action_widget_set_model          (EvPageActionWidget *action_widget,
                                               EvDocumentModel    *doc_model);
 void ev_page_action_widget_grab_focus         (EvPageActionWidget *proxy);
+void ev_page_action_widget_clear              (EvPageActionWidget *proxy);
+void ev_page_action_widget_set_temporary_entry_width (EvPageActionWidget *proxy, gint width);
 
 G_END_DECLS
diff --git a/shell/ev-sidebar-links.c b/shell/ev-sidebar-links.c
index 758f82faa..15f54fe32 100644
--- a/shell/ev-sidebar-links.c
+++ b/shell/ev-sidebar-links.c
@@ -284,6 +284,17 @@ create_loading_model (void)
        return retval;
 }
 
+static void
+search_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
+{
+       GtkWidget *window;
+
+       window = gtk_widget_get_toplevel (GTK_WIDGET (sidebar));
+       if (EV_IS_WINDOW (window)) {
+               ev_window_start_page_selector_search (EV_WINDOW (window));
+       }
+}
+
 static void
 print_section_cb (GtkWidget *menuitem, EvSidebarLinks *sidebar)
 {
@@ -348,6 +359,12 @@ build_popup_menu (EvSidebarLinks *sidebar)
        GtkWidget *item;
 
        menu = gtk_menu_new ();
+       item = gtk_menu_item_new_with_mnemonic(_("Search in the outline…"));
+       gtk_widget_show (item);
+       gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
+       g_signal_connect (item, "activate",
+                         G_CALLBACK (search_section_cb), sidebar);
+
        item = gtk_menu_item_new_with_mnemonic(_("Print…"));
        gtk_widget_show (item);
        gtk_menu_shell_append (GTK_MENU_SHELL (menu), item);
@@ -430,7 +447,10 @@ check_menu_sensitivity (GtkTreeView *treeview,
                }
        }
 
-       if (is_list)
+       if (!selected_path)
+               gtk_widget_set_sensitive (menu_item_expand_under, FALSE);
+
+       if (is_list || !selected_path)
                return;
 
        /* Enable 'Expand under this' only when 'this' element has grandchildren */
@@ -470,6 +490,20 @@ check_menu_sensitivity (GtkTreeView *treeview,
 
 }
 
+static gboolean
+path_is_selected (GtkTreeView *treeview,
+                 GtkTreePath *path)
+{
+       GtkTreeModel *model;
+       GtkTreeSelection *selection;
+       GtkTreeIter iter;
+
+       model = gtk_tree_view_get_model (treeview);
+       selection = gtk_tree_view_get_selection (treeview);
+       return gtk_tree_model_get_iter (model, &iter, path) &&
+              gtk_tree_selection_iter_is_selected (selection, &iter);
+}
+
 static gboolean
 button_press_cb (GtkWidget *treeview,
                  GdkEventButton *event,
@@ -490,8 +524,8 @@ button_press_cb (GtkWidget *treeview,
                                                   event->y,
                                                   &path,
                                                   NULL, NULL, NULL)) {
-                       gtk_tree_view_set_cursor (GTK_TREE_VIEW (treeview),
-                                                 path, NULL, FALSE);
+                       if (! path_is_selected (GTK_TREE_VIEW (treeview), path))
+                               path = NULL;
                        check_menu_sensitivity (GTK_TREE_VIEW (treeview), path, sidebar);
                        gtk_menu_popup_at_pointer (menu,
                                                   (GdkEvent *) event);
diff --git a/shell/ev-window.c b/shell/ev-window.c
index bed494e0c..0c8f71ba0 100644
--- a/shell/ev-window.c
+++ b/shell/ev-window.c
@@ -4231,15 +4231,16 @@ ev_window_cmd_about (GSimpleAction *action,
 }
 
 static void
-ev_window_cmd_focus_page_selector (GSimpleAction *action,
-                                  GVariant      *parameter,
-                                  gpointer       user_data)
+ev_window_focus_page_selector (EvWindow *window)
 {
-       EvWindow *window = user_data;
-       EvWindowPrivate *priv = GET_PRIVATE (window);
+       EvWindowPrivate *priv;
        GtkWidget *page_selector;
        EvToolbar *toolbar;
 
+       g_return_if_fail (EV_IS_WINDOW (window));
+
+       priv = GET_PRIVATE (window);
+
        update_chrome_flag (window, EV_CHROME_RAISE_TOOLBAR, TRUE);
        update_chrome_visibility (window);
 
@@ -4248,6 +4249,48 @@ ev_window_cmd_focus_page_selector (GSimpleAction *action,
        ev_page_action_widget_grab_focus (EV_PAGE_ACTION_WIDGET (page_selector));
 }
 
+/**
+ * ev_window_start_page_selector_search:
+ * @ev_window: The instance of the #EvWindow.
+ *
+ * Prepares page_selector text entry for searching the Outline,
+ * basically this:
+ *    - Gives focus to the page selector entry
+ *    - Clears the text in it.
+ *    - Makes the text entry wider.
+ *
+ * All these changes will be restablished once the search
+ * it's finished by means of the entry focus_out event.
+ */
+void
+ev_window_start_page_selector_search (EvWindow *window)
+{
+       EvWindowPrivate *priv;
+       GtkWidget *page_selector;
+       EvPageActionWidget *action_widget;
+
+       g_return_if_fail (EV_IS_WINDOW (window));
+
+       priv = GET_PRIVATE (window);
+
+       page_selector = ev_toolbar_get_page_selector (EV_TOOLBAR (priv->toolbar));
+       action_widget = EV_PAGE_ACTION_WIDGET (page_selector);
+       if (!action_widget)
+               return;
+
+       ev_window_focus_page_selector (window);
+       ev_page_action_widget_clear (action_widget);
+       ev_page_action_widget_set_temporary_entry_width (action_widget, 15);
+}
+
+static void
+ev_window_cmd_focus_page_selector (GSimpleAction *action,
+                                  GVariant      *parameter,
+                                  gpointer       user_data)
+{
+       ev_window_focus_page_selector (EV_WINDOW (user_data));
+}
+
 static void
 ev_window_cmd_scroll_forward (GSimpleAction *action,
                              GVariant      *parameter,
diff --git a/shell/ev-window.h b/shell/ev-window.h
index 50edb11e0..a2b9c60ae 100644
--- a/shell/ev-window.h
+++ b/shell/ev-window.h
@@ -102,5 +102,6 @@ GtkWidget      *ev_window_get_sidebar                        (EvWindow       *ev_window);
 GtkWidget      *ev_window_get_find_sidebar              (EvWindow       *ev_window);
 void            ev_window_set_divider_position          (EvWindow       *ev_window,
                                                          gint            sidebar_width);
+void            ev_window_start_page_selector_search     (EvWindow       *window);
 
 G_END_DECLS


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]