[gimp/nielsdg/help-browser-dialog-gtk-actions] plug-ins: clean up the patch !519 as per review.



commit 784f166815ec6607a82fdc82cf3fa5e6d1eef91a
Author: Jehan <jehan girinstud io>
Date:   Fri Mar 25 14:45:22 2022 +0100

    plug-ins: clean up the patch !519 as per review.
    
    Some coding style fixes, also one warning fix, and a lot of shuffling
    around to reorganize the code. Basically removing the prototype listing
    at the file start is a big error. This file is huge and without a
    minimum of organization, it's a huge mess to understand what's what.
    
    Basically a class file must always start by the class_init(), then the
    init(), then the various object methods (constructed() or finalize() if
    any, etc.), and possibly other parent classes' implementations. These
    are the entry points, it's normal to start here (not from leaf
    functions!).
    Then we get the public functions which are other entry points (calls
    from other parts of the code). And only after, private functions such as
    signal or action callbacks, and utilities at the very end.
    
    This requires a well organized prototype listing, which works as a menu,
    and prevents the implementation order to depend on call order (this gets
    us completely random order and imply usually that top functions are the
    less important ones, such as utilities, just how it was before this
    commit).
    
    Anyway I'm not sure why I spent time on this because we deprecated this
    plug-in, but if we still want to push nice updates (like MR !519), we
    should at least do it well and clean. Also it's a good first example for
    plug-in rewrite in modern no-GtkAction code.

 plug-ins/help-browser/dialog.c | 1148 ++++++++++++++++++++++------------------
 1 file changed, 646 insertions(+), 502 deletions(-)
---
diff --git a/plug-ins/help-browser/dialog.c b/plug-ins/help-browser/dialog.c
index 5500590134..c40f6d8a86 100644
--- a/plug-ins/help-browser/dialog.c
+++ b/plug-ins/help-browser/dialog.c
@@ -58,53 +58,503 @@ typedef struct
   double   zoom;
 } DialogData;
 
-struct _GimpHelpBrowserDialog {
-  GtkApplicationWindow parent_instance;
-
-  GHashTable *uri_hash_table; /* (char*) → (GtkTreeIter) */
-
-  GtkWidget  *webview;
-  GtkWidget  *paned;
-  GtkWidget  *sidebar;
-  GtkWidget  *searchbar;
-  GtkWidget  *search_entry;
-  GtkWidget  *tree_view;
-  GtkWidget  *button_prev;
-  GtkWidget  *button_next;
-  GdkCursor  *busy_cursor;
-
-  GMenuModel *popup_menu_model;
-  GMenuModel *copy_popup_menu_model;
+struct _GimpHelpBrowserDialog
+{
+  GtkApplicationWindow  parent_instance;
+
+  GHashTable           *uri_hash_table; /* (char*) → (GtkTreeIter) */
+
+  GtkWidget            *webview;
+  GtkWidget            *paned;
+  GtkWidget            *sidebar;
+  GtkWidget            *searchbar;
+  GtkWidget            *search_entry;
+  GtkWidget            *tree_view;
+  GtkWidget            *button_prev;
+  GtkWidget            *button_next;
+  GdkCursor            *busy_cursor;
+
+  GMenuModel           *popup_menu_model;
+  GMenuModel           *copy_popup_menu_model;
 };
 
 G_DEFINE_TYPE (GimpHelpBrowserDialog, gimp_help_browser_dialog, GTK_TYPE_APPLICATION_WINDOW)
 
+
+static void        gimp_help_browser_dialog_finalize (GObject                  *object);
+
+/* Actions. */
+
+static void        back_action                       (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        step_action                       (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        forward_action                    (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        reload_action                     (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        stop_action                       (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        home_action                       (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        find_action                       (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        find_again_action                 (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        search_next_action                (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        search_previous_action            (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        copy_location_action              (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        copy_selection_action             (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        show_index_change_state           (GSimpleAction            *action,
+                                                      GVariant                 *new_state,
+                                                      gpointer                  user_data);
+static void        zoom_in_action                    (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        zoom_out_action                   (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        load_uri_action                   (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+static void        close_action                      (GSimpleAction            *action,
+                                                      GVariant                 *parameter,
+                                                      gpointer                  user_data);
+
+/* Callbacks. */
+
+static void        webview_realize                   (GtkWidget                *webview,
+                                                      gpointer                  user_data);
+static void        webview_unrealize                 (GtkWidget                *widget,
+                                                      gpointer                  user_data);
+static void        do_popup_menu                     (GimpHelpBrowserDialog    *self,
+                                                      GtkWidget                *webview,
+                                                      GdkEvent                 *event);
+static gboolean    webview_popup_menu                (GtkWidget                *webview,
+                                                      gpointer                  user_data);
+static gboolean    webview_button_press              (GtkWidget                *webview,
+                                                      GdkEventButton           *event,
+                                                      gpointer                  user_data);
+static gboolean    webview_key_press                 (GtkWidget                *widget,
+                                                      GdkEventKey              *event,
+                                                      gpointer                  user_data);
+static void        webview_title_changed             (WebKitWebView            *webview,
+                                                      GParamSpec               *pspec,
+                                                      gpointer                  user_data);
+static void        select_index                      (GimpHelpBrowserDialog    *self,
+                                                      const char               *uri);
+static gboolean    webview_decide_policy             (WebKitWebView            *webview,
+                                                      WebKitPolicyDecision     *decision,
+                                                      WebKitPolicyDecisionType  decision_type,
+                                                      gpointer                  user_data);
+static gboolean    webview_load_failed               (WebKitWebView            *webview,
+                                                      WebKitLoadEvent           load_event,
+                                                      char                     *failing_uri,
+                                                      GError                   *error,
+                                                      gpointer                  user_data);
+static void        webview_load_changed              (WebKitWebView            *webview,
+                                                      WebKitLoadEvent           event,
+                                                      gpointer                  user_data);
+static void        row_activated                     (GtkTreeView              *tree_view,
+                                                      GtkTreePath              *path,
+                                                      GtkTreeViewColumn        *column,
+                                                      gpointer                  user_data);
+static void        search_close_clicked              (GtkWidget                *button,
+                                                      gpointer                  user_data);
+static void        search_entry_changed              (GtkWidget                *search_entry,
+                                                      gpointer                  user_data);
+static gboolean    search_entry_key_press            (GtkWidget                *search_entry,
+                                                      GdkEventKey              *event,
+                                                      gpointer                  user_data);
+static void        dialog_unmap                      (GtkWidget                *window,
+                                                      gpointer                  user_data);
+
+/* Utilities. */
+
+static void        search                            (GimpHelpBrowserDialog    *self,
+                                                      const char               *text);
+
+static GtkWidget * build_menu                        (const GList              *items,
+                                                      gboolean                  back);
+
+static void        update_actions                    (GimpHelpBrowserDialog    *self);
+
+static void        add_tool_button                   (GtkWidget                *toolbar,
+                                                      const char               *action,
+                                                      const char               *icon,
+                                                      const char               *label,
+                                                      const char               *tooltip);
+static GtkWidget * build_searchbar                   (GimpHelpBrowserDialog    *self);
+
+static void        browser_dialog_make_index_foreach (const gchar              *help_id,
+                                                      GimpHelpItem             *item,
+                                                      GimpHelpLocale           *locale);
+static gint        help_item_compare                 (gconstpointer             a,
+                                                      gconstpointer             b);
+static void        add_child                         (GimpHelpBrowserDialog    *self,
+                                                      GtkTreeStore             *store,
+                                                      GimpHelpDomain           *domain,
+                                                      GimpHelpLocale           *locale,
+                                                      GtkTreeIter              *parent,
+                                                      GimpHelpItem             *item,
+                                                      int                       depth);
+
+
+static const GActionEntry ACTIONS[] =
+{
+  { "back",            back_action },
+  { "forward",         forward_action },
+  { "step",            step_action, "i" },
+  { "reload",          reload_action },
+  { "stop",            stop_action },
+  { "home",            home_action },
+  { "load-uri",        load_uri_action, "s" },
+  { "copy-location",   copy_location_action },
+  { "copy-selection",  copy_selection_action },
+  { "zoom-in",         zoom_in_action },
+  { "zoom-out",        zoom_out_action },
+  { "find",            find_action },
+  { "find-again",      find_again_action },
+  { "search-next",     search_next_action },
+  { "search-previous", search_previous_action },
+  { "close",           close_action },
+  { "show-index",      NULL, NULL, "true", show_index_change_state },
+};
+
+
 static void
-search (GimpHelpBrowserDialog *self,
-        const char            *text)
+gimp_help_browser_dialog_class_init (GimpHelpBrowserDialogClass *klass)
 {
-  WebKitFindController *find_controller;
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-  find_controller = webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (self->webview));
-  if (text)
+  object_class->finalize = gimp_help_browser_dialog_finalize;
+}
+
+static void
+gimp_help_browser_dialog_init (GimpHelpBrowserDialog *self)
+{
+  GtkWindow   *window = GTK_WINDOW (self);
+  GtkWidget   *vbox;
+  GtkWidget   *toolbar;
+  GtkBuilder  *builder;
+  GtkToolItem *item;
+  GtkWidget   *main_vbox;
+  WebKitSettings *settings;
+
+  /*  the dialog window  */
+  gtk_window_set_title (GTK_WINDOW (window), _("GIMP Help Browser"));
+  gtk_window_set_icon_name (GTK_WINDOW (window), GIMP_ICON_HELP_USER_MANUAL);
+
+  g_action_map_add_action_entries (G_ACTION_MAP (self),
+                                   ACTIONS, G_N_ELEMENTS (ACTIONS),
+                                   self);
+
+  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_widget_show (vbox);
+
+  /* Toolbar */
+  toolbar = gtk_toolbar_new ();
+
+  add_tool_button (toolbar, "win.reload", GIMP_ICON_VIEW_REFRESH, _("_Reload"), _("Reload current page"));
+  add_tool_button (toolbar, "win.stop", GIMP_ICON_PROCESS_STOP, _("_Stop"), _("Stop loading this page"));
+  add_tool_button (toolbar, "win.home", GIMP_ICON_GO_HOME, NULL, _("Go to the index page"));
+  item = gtk_separator_tool_item_new ();
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
+  gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE);
+  gtk_tool_item_set_expand (item, TRUE);
+  gtk_widget_show (GTK_WIDGET (item));
+  add_tool_button (toolbar, "win.load-uri('https://docs.gimp.org')", GIMP_ICON_HELP_USER_MANUAL, 
"docs.gimp.org", _("Visit the GIMP documentation website"));
+
+  item = gtk_menu_tool_button_new (gtk_image_new_from_icon_name (GIMP_ICON_GO_NEXT, GTK_ICON_SIZE_BUTTON), 
NULL);
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0);
+  gtk_widget_show (GTK_WIDGET (item));
+  gtk_actionable_set_action_name (GTK_ACTIONABLE (item), "win.forward");
+  self->button_next = GTK_WIDGET (item);
+
+  item = gtk_menu_tool_button_new (gtk_image_new_from_icon_name (GIMP_ICON_GO_PREVIOUS, 
GTK_ICON_SIZE_BUTTON), NULL);
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0);
+  gtk_widget_show (GTK_WIDGET (item));
+  gtk_actionable_set_action_name (GTK_ACTIONABLE (item), "win.back");
+  self->button_prev = GTK_WIDGET (item);
+
+  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
+  gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
+  gtk_widget_show (toolbar);
+
+  /* Context menu */
+  builder = gtk_builder_new_from_string (
+      "<interface>"
+        "<menu id=\"help_browser_popup_menu\">"
+          "<section>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">_Back</attribute>"
+              "<attribute name=\"action\">win.back</attribute>"
+            "</item>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">_Previous</attribute>"
+              "<attribute name=\"action\">win.forward</attribute>"
+            "</item>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">_Reload</attribute>"
+              "<attribute name=\"action\">win.reload</attribute>"
+            "</item>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">_Stop</attribute>"
+              "<attribute name=\"action\">win.stop</attribute>"
+            "</item>"
+          "</section>"
+          "<section>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">_Home</attribute>"
+              "<attribute name=\"action\">win.home</attribute>"
+            "</item>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">C_opy location</attribute>"
+              "<attribute name=\"action\">win.copy-location</attribute>"
+            "</item>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">S_how index</attribute>"
+              "<attribute name=\"action\">win.show-index</attribute>"
+            "</item>"
+          "</section>"
+          "<section>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">Find</attribute>"
+              "<attribute name=\"action\">win.find</attribute>"
+            "</item>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">Find _Again</attribute>"
+              "<attribute name=\"action\">win.find-again</attribute>"
+            "</item>"
+          "</section>"
+          "<section>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">Zoom in</attribute>"
+              "<attribute name=\"action\">win.zoom-in</attribute>"
+            "</item>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">Zoom out</attribute>"
+              "<attribute name=\"action\">win.zoom-out</attribute>"
+            "</item>"
+          "</section>"
+          "<section>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">Close</attribute>"
+              "<attribute name=\"action\">win.close</attribute>"
+            "</item>"
+          "</section>"
+        "</menu>"
+        "<menu id=\"help_browser_copy_popup_menu\">"
+          "<section>"
+            "<item>"
+              "<attribute name=\"label\" translatable=\"yes\">Copy selection</attribute>"
+              "<attribute name=\"action\">win.copy-selection</attribute>"
+            "</item>"
+          "</section>"
+        "</menu>"
+      "</interface>",
+      -1);
+  self->popup_menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, "help_browser_popup_menu"));
+  g_object_ref (self->popup_menu_model);
+  self->copy_popup_menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, 
"help_browser_copy_popup_menu"));
+  g_object_ref (self->copy_popup_menu_model);
+  g_object_unref (builder);
+
+  /*  the horizontal paned  */
+  self->paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
+  gtk_box_pack_start (GTK_BOX (vbox), self->paned, TRUE, TRUE, 0);
+  gtk_widget_show (self->paned);
+
+  self->sidebar = gtk_scrolled_window_new (NULL, NULL);
+  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->sidebar),
+                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
+  gtk_paned_add1 (GTK_PANED (self->paned), self->sidebar);
+
+  self->tree_view = gtk_tree_view_new ();
+  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->tree_view), FALSE);
+  gtk_container_add (GTK_CONTAINER (self->sidebar), self->tree_view);
+  gtk_widget_show (self->tree_view);
+
+  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (self->tree_view), -1,
+                                               NULL,
+                                               gtk_cell_renderer_text_new (),
+                                               "text", 1,
+                                               NULL);
+
+  g_signal_connect (self->tree_view, "row-activated",
+                    G_CALLBACK (row_activated),
+                    self);
+
+  /*  HTML webview  */
+  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
+  gtk_widget_show (main_vbox);
+  gtk_paned_pack2 (GTK_PANED (self->paned), main_vbox, TRUE, TRUE);
+
+  settings = webkit_settings_new_with_settings ("default-charset", "utf-8",
+                                                NULL);
+  self->webview = webkit_web_view_new_with_settings (settings);
+  g_object_unref (settings);
+
+  gtk_widget_set_size_request (self->webview, 300, 200);
+  gtk_widget_show (self->webview);
+
+  gtk_box_pack_start (GTK_BOX (main_vbox), self->webview, TRUE, TRUE, 0);
+
+  g_signal_connect (self->webview, "realize",
+                    G_CALLBACK (webview_realize),
+                    self);
+  g_signal_connect (self->webview, "unrealize",
+                    G_CALLBACK (webview_unrealize),
+                    self);
+  g_signal_connect (self->webview, "popup-menu",
+                    G_CALLBACK (webview_popup_menu),
+                    self);
+  g_signal_connect (self->webview, "button-press-event",
+                    G_CALLBACK (webview_button_press),
+                    self);
+  g_signal_connect (self->webview, "key-press-event",
+                    G_CALLBACK (webview_key_press),
+                    self);
+  g_signal_connect (self->webview, "notify::title",
+                    G_CALLBACK (webview_title_changed),
+                    self);
+  g_signal_connect (self->webview, "load-changed",
+                    G_CALLBACK (webview_load_changed),
+                    self);
+  g_signal_connect (self->webview, "load-failed",
+                    G_CALLBACK (webview_load_failed),
+                    self);
+  g_signal_connect (self->webview, "decide-policy",
+                    G_CALLBACK (webview_decide_policy),
+                    self);
+
+  gtk_widget_grab_focus (self->webview);
+
+  g_signal_connect (window, "unmap",
+                    G_CALLBACK (dialog_unmap),
+                    self);
+
+  update_actions (self);
+
+  /* Searchbar */
+  self->searchbar = build_searchbar (self);
+  gtk_box_pack_start (GTK_BOX (main_vbox), self->searchbar, FALSE, FALSE, 0);
+}
+
+static void
+gimp_help_browser_dialog_finalize (GObject *object)
+{
+  GimpHelpBrowserDialog *self = GIMP_HELP_BROWSER_DIALOG (object);
+
+  g_clear_pointer (&self->uri_hash_table, g_hash_table_unref);
+  g_clear_object (&self->popup_menu_model);
+  g_clear_object (&self->copy_popup_menu_model);
+
+  G_OBJECT_CLASS (gimp_help_browser_dialog_parent_class)->finalize (object);
+}
+
+/* Public functions. */
+
+GimpHelpBrowserDialog *
+gimp_help_browser_dialog_new (const gchar *plug_in_binary, GApplication *app)
+{
+  GimpHelpBrowserDialog *window;
+  DialogData             data = { 720, 560, 240, TRUE, 1.0 };
+
+  gimp_ui_init (plug_in_binary);
+
+  gimp_get_data (GIMP_HELP_BROWSER_DIALOG_DATA, &data);
+
+  window = g_object_new (GIMP_TYPE_HELP_BROWSER_DIALOG,
+                         "application", app,
+                         "role", plug_in_binary,
+                         "default-width", data.width,
+                         "default-height", data.height,
+                         NULL);
+  gtk_paned_set_position (GTK_PANED (window->paned), data.paned_position);
+  if (data.show_index)
+    gtk_widget_show (window->sidebar);
+  webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (window->webview), data.zoom);
+
+  return window;
+}
+
+void
+gimp_help_browser_dialog_load (GimpHelpBrowserDialog *self,
+                               const char            *uri)
+{
+  g_return_if_fail (uri && *uri);
+
+  webkit_web_view_load_uri (WEBKIT_WEB_VIEW (self->webview), uri);
+
+  select_index (self, uri);
+
+  gtk_window_present (GTK_WINDOW (gtk_widget_get_toplevel (self->webview)));
+}
+
+void
+gimp_help_browser_dialog_make_index (GimpHelpBrowserDialog *self,
+                                     GimpHelpDomain        *domain,
+                                     GimpHelpLocale        *locale)
+{
+  GtkTreeStore *store;
+  GList        *list;
+
+  if (! locale->toplevel_items)
     {
-      const char *prev_text =
-        webkit_find_controller_get_search_text (find_controller);
+      g_hash_table_foreach (locale->help_id_mapping,
+                            (GHFunc) browser_dialog_make_index_foreach,
+                            locale);
 
-      /* The previous search, if any, may need to be canceled. */
-      if (prev_text && strcmp (text, prev_text) != 0)
-        webkit_find_controller_search_finish (find_controller);
+      locale->toplevel_items = g_list_sort (locale->toplevel_items,
+                                            help_item_compare);
+    }
 
-      webkit_find_controller_search (find_controller,
-                                     text,
-                                     WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
-                                     WEBKIT_FIND_OPTIONS_WRAP_AROUND,
-                                     G_MAXUINT);
+  store = gtk_tree_store_new (2,
+                              G_TYPE_POINTER,
+                              G_TYPE_STRING);
+
+  g_object_set_data (G_OBJECT (store), "domain", domain);
+  g_object_set_data (G_OBJECT (store), "locale", locale);
+
+  if (self->uri_hash_table)
+    g_hash_table_unref (self->uri_hash_table);
+
+  self->uri_hash_table = g_hash_table_new_full (g_str_hash,
+                                                g_str_equal,
+                                                (GDestroyNotify) g_free,
+                                                (GDestroyNotify) gtk_tree_iter_free);
+
+  for (list = locale->toplevel_items; list; list = g_list_next (list))
+    {
+      GimpHelpItem *item = list->data;
+
+      add_child (self, store, domain, locale, NULL, item, 0);
     }
-  else
-    webkit_find_controller_search_finish (find_controller);
+
+  gtk_tree_view_set_model (GTK_TREE_VIEW (self->tree_view), GTK_TREE_MODEL (store));
+  g_object_unref (store);
 }
 
+/* Private functions. */
+
 static void
 back_action (GSimpleAction *action,
              GVariant      *parameter,
@@ -322,133 +772,21 @@ load_uri_action (GSimpleAction *action,
                  GVariant      *parameter,
                  gpointer       user_data)
 {
-  GimpHelpBrowserDialog *self = GIMP_HELP_BROWSER_DIALOG (user_data);
-  const char *uri;
-
-  uri = g_variant_get_string (parameter, NULL);
-  gimp_help_browser_dialog_load (self, uri);
-}
-
-static void
-close_action (GSimpleAction *action,
-              GVariant      *parameter,
-              gpointer       user_data)
-{
-  GimpHelpBrowserDialog *self = GIMP_HELP_BROWSER_DIALOG (user_data);
-
-  gtk_widget_destroy (GTK_WIDGET (self));
-}
-
-static const GActionEntry ACTIONS[] =
-{
-  { "back", back_action },
-  { "forward", forward_action },
-  { "step", step_action, "i" },
-  { "reload", reload_action },
-  { "stop", stop_action },
-  { "home", home_action },
-  { "load-uri", load_uri_action, "s" },
-  { "copy-location", copy_location_action },
-  { "copy-selection", copy_selection_action },
-  { "zoom-in", zoom_in_action },
-  { "zoom-out", zoom_out_action },
-  { "find", find_action },
-  { "find-again", find_again_action },
-  { "search-next", search_next_action },
-  { "search-previous", search_previous_action },
-  { "close", close_action },
-  { "show-index", NULL, NULL, "true", show_index_change_state },
-};
-
-static GtkWidget *
-build_menu (const GList *items,
-            gboolean     back)
-{
-  GMenu       *menu;
-  const GList *iter;
-  int          steps;
-
-  if (!items)
-    return NULL;
-
-  menu = g_menu_new ();
-
-  /* Go over every item in the back_fw list and add it to the menu */
-  for (iter = items, steps = 1; iter; iter = g_list_next (iter), steps++)
-    {
-      WebKitBackForwardListItem *item = iter->data;
-      const char                *title;
-      char                      *action;
-
-      title = webkit_back_forward_list_item_get_title (item);
-      if (title == NULL)
-        continue;
-
-      action = g_strdup_printf ("steps(%d)", steps);
-      g_menu_insert (menu, steps - 1, title, action);
-      g_free (action);
-    }
-
-  return gtk_menu_new_from_model (G_MENU_MODEL (menu));
-}
-
-static void
-update_actions (GimpHelpBrowserDialog *self)
-{
-  GActionMap            *action_map = G_ACTION_MAP (self);
-  GAction               *action;
-  WebKitBackForwardList *back_forward_list;
-
-  back_forward_list =
-    webkit_web_view_get_back_forward_list (WEBKIT_WEB_VIEW (self->webview));
-
-  /*  update the back button and its menu  */
-  action = g_action_map_lookup_action (action_map, "back");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
-                               webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (self->webview)));
-
-  if (back_forward_list)
-    {
-      const GList *list;
-
-      list = webkit_back_forward_list_get_back_list_with_limit (back_forward_list,
-                                                                12);
-      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_prev),
-                                     build_menu (list, TRUE));
-    }
-  else
-    {
-      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_prev), NULL);
-    }
-
-  /*  update the forward button and its menu  */
-  action = g_action_map_lookup_action (action_map, "forward");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
-                               webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (self->webview)));
-
-  if (back_forward_list)
-    {
-      const GList *list;
-
-      list = webkit_back_forward_list_get_forward_list_with_limit (back_forward_list,
-                                                                   12);
-      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_next),
-                                     build_menu (list, FALSE));
-    }
-  else
-    {
-      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_next), NULL);
-    }
+  GimpHelpBrowserDialog *self = GIMP_HELP_BROWSER_DIALOG (user_data);
+  const char *uri;
 
-  /*  update the copy-location action  */
-  action = g_action_map_lookup_action (action_map, "copy-location");
-  g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
-                               webkit_web_view_get_uri (WEBKIT_WEB_VIEW (self->webview)) != NULL);
+  uri = g_variant_get_string (parameter, NULL);
+  gimp_help_browser_dialog_load (self, uri);
+}
 
-  /*  update the show-index action  */
-  action = g_action_map_lookup_action (action_map, "show-index");
-  g_simple_action_set_state (G_SIMPLE_ACTION (action),
-                             g_variant_new_boolean (gtk_widget_get_visible (self->sidebar)));
+static void
+close_action (GSimpleAction *action,
+              GVariant      *parameter,
+              gpointer       user_data)
+{
+  GimpHelpBrowserDialog *self = GIMP_HELP_BROWSER_DIALOG (user_data);
+
+  gtk_widget_destroy (GTK_WIDGET (self));
 }
 
 static void
@@ -747,347 +1085,197 @@ dialog_unmap (GtkWidget *window,
 }
 
 static void
-add_tool_button (GtkWidget  *toolbar,
-                 const char *action,
-                 const char *icon,
-                 const char *label,
-                 const char *tooltip)
-{
-  GtkWidget *tool_icon;
-  GtkToolItem *tool_button;
-
-  tool_icon = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
-  gtk_widget_show (GTK_WIDGET (tool_icon));
-  tool_button = gtk_tool_button_new (tool_icon, label);
-  gtk_widget_show (GTK_WIDGET (tool_button));
-  gtk_tool_item_set_tooltip_text (tool_button, tooltip);
-  gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (tool_button), action);
-
-  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tool_button, -1);
-}
-
-static GtkWidget *
-build_searchbar (GimpHelpBrowserDialog *self)
+search (GimpHelpBrowserDialog *self,
+        const char            *text)
 {
-  GtkWidget *button;
-  GtkWidget *hbox;
-  GtkWidget *label;
-
-  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
-
-  label = gtk_label_new (_("Find:"));
-  gtk_widget_show (label);
-  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
-
-  self->search_entry = gtk_entry_new ();
-  gtk_widget_show (self->search_entry);
-  gtk_box_pack_start (GTK_BOX (hbox), self->search_entry, TRUE, TRUE, 0);
-
-  g_signal_connect (self->search_entry, "changed",
-                    G_CALLBACK (search_entry_changed),
-                    self);
-
-  g_signal_connect (self->search_entry, "key-press-event",
-                    G_CALLBACK (search_entry_key_press),
-                    self);
-
-  button = gtk_button_new_with_mnemonic (C_("search", "_Previous"));
-  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-  gtk_button_set_image (GTK_BUTTON (button),
-                        gtk_image_new_from_icon_name (GIMP_ICON_GO_PREVIOUS,
-                                                      GTK_ICON_SIZE_BUTTON));
-  gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.search-previous");
-  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-  gtk_widget_show (button);
-
-  button = gtk_button_new_with_mnemonic (C_("search", "_Next"));
-  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-  gtk_button_set_image (GTK_BUTTON (button),
-                        gtk_image_new_from_icon_name (GIMP_ICON_GO_NEXT,
-                                                      GTK_ICON_SIZE_BUTTON));
-  gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.search-next");
-  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-  gtk_widget_show (button);
+  WebKitFindController *find_controller;
 
-  button = gtk_button_new_with_mnemonic (C_("search", "_Close"));
-  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
-  gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
-  gtk_widget_show (button);
+  find_controller = webkit_web_view_get_find_controller (WEBKIT_WEB_VIEW (self->webview));
+  if (text)
+    {
+      const char *prev_text =
+        webkit_find_controller_get_search_text (find_controller);
 
-  g_signal_connect (button, "clicked",
-                    G_CALLBACK (search_close_clicked),
-                    self);
+      /* The previous search, if any, may need to be canceled. */
+      if (prev_text && strcmp (text, prev_text) != 0)
+        webkit_find_controller_search_finish (find_controller);
 
-  return hbox;
+      webkit_find_controller_search (find_controller,
+                                     text,
+                                     WEBKIT_FIND_OPTIONS_CASE_INSENSITIVE |
+                                     WEBKIT_FIND_OPTIONS_WRAP_AROUND,
+                                     G_MAXUINT);
+    }
+  else
+    {
+      webkit_find_controller_search_finish (find_controller);
+    }
 }
 
-static void
-gimp_help_browser_dialog_init (GimpHelpBrowserDialog *self)
+static GtkWidget *
+build_menu (const GList *items,
+            gboolean     back)
 {
-  GtkWindow   *window = GTK_WINDOW (self);
-  GtkWidget   *vbox;
-  GtkWidget   *toolbar;
-  GtkBuilder  *builder;
-  GtkToolItem *item;
-  GtkWidget   *main_vbox;
-  WebKitSettings *settings;
-
-  /*  the dialog window  */
-  gtk_window_set_title (GTK_WINDOW (window), _("GIMP Help Browser"));
-  gtk_window_set_icon_name (GTK_WINDOW (window), GIMP_ICON_HELP_USER_MANUAL);
-
-  g_action_map_add_action_entries (G_ACTION_MAP (self),
-                                   ACTIONS, G_N_ELEMENTS (ACTIONS),
-                                   self);
-
-  vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 2);
-  gtk_container_add (GTK_CONTAINER (window), vbox);
-  gtk_widget_show (vbox);
-
-  /* Toolbar */
-  toolbar = gtk_toolbar_new ();
-
-  add_tool_button (toolbar, "win.reload", GIMP_ICON_VIEW_REFRESH, _("_Reload"), _("Reload current page"));
-  add_tool_button (toolbar, "win.stop", GIMP_ICON_PROCESS_STOP, _("_Stop"), _("Stop loading this page"));
-  add_tool_button (toolbar, "win.home", GIMP_ICON_GO_HOME, NULL, _("Go to the index page"));
-  item = gtk_separator_tool_item_new ();
-  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, -1);
-  gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (item), FALSE);
-  gtk_tool_item_set_expand (item, TRUE);
-  gtk_widget_show (GTK_WIDGET (item));
-  add_tool_button (toolbar, "win.load-uri('https://docs.gimp.org')", GIMP_ICON_HELP_USER_MANUAL, 
"docs.gimp.org", _("Visit the GIMP documentation website"));
-
-  item = gtk_menu_tool_button_new (gtk_image_new_from_icon_name (GIMP_ICON_GO_NEXT, GTK_ICON_SIZE_BUTTON), 
NULL);
-  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0);
-  gtk_widget_show (GTK_WIDGET (item));
-  gtk_actionable_set_action_name (GTK_ACTIONABLE (item), "win.forward");
-  self->button_next = GTK_WIDGET (item);
-
-  item = gtk_menu_tool_button_new (gtk_image_new_from_icon_name (GIMP_ICON_GO_PREVIOUS, 
GTK_ICON_SIZE_BUTTON), NULL);
-  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), item, 0);
-  gtk_widget_show (GTK_WIDGET (item));
-  gtk_actionable_set_action_name (GTK_ACTIONABLE (item), "win.back");
-  self->button_prev = GTK_WIDGET (item);
+  GMenu       *menu;
+  const GList *iter;
+  int          steps;
 
-  gtk_toolbar_set_style (GTK_TOOLBAR (toolbar), GTK_TOOLBAR_ICONS);
-  gtk_box_pack_start (GTK_BOX (vbox), toolbar, FALSE, FALSE, 0);
-  gtk_widget_show (toolbar);
+  if (!items)
+    return NULL;
 
-  /* Context menu */
-  builder = gtk_builder_new_from_string (
-      "<interface>"
-        "<menu id=\"help_browser_popup_menu\">"
-          "<section>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">_Back</attribute>"
-              "<attribute name=\"action\">win.back</attribute>"
-            "</item>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">_Previous</attribute>"
-              "<attribute name=\"action\">win.forward</attribute>"
-            "</item>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">_Reload</attribute>"
-              "<attribute name=\"action\">win.reload</attribute>"
-            "</item>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">_Stop</attribute>"
-              "<attribute name=\"action\">win.stop</attribute>"
-            "</item>"
-          "</section>"
-          "<section>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">_Home</attribute>"
-              "<attribute name=\"action\">win.home</attribute>"
-            "</item>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">C_opy location</attribute>"
-              "<attribute name=\"action\">win.copy-location</attribute>"
-            "</item>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">S_how index</attribute>"
-              "<attribute name=\"action\">win.show-index</attribute>"
-            "</item>"
-          "</section>"
-          "<section>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">Find</attribute>"
-              "<attribute name=\"action\">win.find</attribute>"
-            "</item>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">Find _Again</attribute>"
-              "<attribute name=\"action\">win.find-again</attribute>"
-            "</item>"
-          "</section>"
-          "<section>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">Zoom in</attribute>"
-              "<attribute name=\"action\">win.zoom-in</attribute>"
-            "</item>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">Zoom out</attribute>"
-              "<attribute name=\"action\">win.zoom-out</attribute>"
-            "</item>"
-          "</section>"
-          "<section>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">Close</attribute>"
-              "<attribute name=\"action\">win.close</attribute>"
-            "</item>"
-          "</section>"
-        "</menu>"
-        "<menu id=\"help_browser_copy_popup_menu\">"
-          "<section>"
-            "<item>"
-              "<attribute name=\"label\" translatable=\"yes\">Copy selection</attribute>"
-              "<attribute name=\"action\">win.copy-selection</attribute>"
-            "</item>"
-          "</section>"
-        "</menu>"
-      "</interface>",
-      -1);
-  self->popup_menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, "help_browser_popup_menu"));
-  g_object_ref (self->popup_menu_model);
-  self->copy_popup_menu_model = G_MENU_MODEL (gtk_builder_get_object (builder, 
"help_browser_copy_popup_menu"));
-  g_object_ref (self->copy_popup_menu_model);
-  g_object_unref (builder);
+  menu = g_menu_new ();
 
-  /*  the horizontal paned  */
-  self->paned = gtk_paned_new (GTK_ORIENTATION_HORIZONTAL);
-  gtk_box_pack_start (GTK_BOX (vbox), self->paned, TRUE, TRUE, 0);
-  gtk_widget_show (self->paned);
+  /* Go over every item in the back_fw list and add it to the menu */
+  for (iter = items, steps = 1; iter; iter = g_list_next (iter), steps++)
+    {
+      WebKitBackForwardListItem *item = iter->data;
+      const char                *title;
+      char                      *action;
 
-  self->sidebar = gtk_scrolled_window_new (NULL, NULL);
-  gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (self->sidebar),
-                                  GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
-  gtk_paned_add1 (GTK_PANED (self->paned), self->sidebar);
+      title = webkit_back_forward_list_item_get_title (item);
+      if (title == NULL)
+        continue;
 
-  self->tree_view = gtk_tree_view_new ();
-  gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (self->tree_view), FALSE);
-  gtk_container_add (GTK_CONTAINER (self->sidebar), self->tree_view);
-  gtk_widget_show (self->tree_view);
+      action = g_strdup_printf ("steps(%d)", steps);
+      g_menu_insert (menu, steps - 1, title, action);
+      g_free (action);
+    }
 
-  gtk_tree_view_insert_column_with_attributes (GTK_TREE_VIEW (self->tree_view), -1,
-                                               NULL,
-                                               gtk_cell_renderer_text_new (),
-                                               "text", 1,
-                                               NULL);
+  return gtk_menu_new_from_model (G_MENU_MODEL (menu));
+}
 
-  g_signal_connect (self->tree_view, "row-activated",
-                    G_CALLBACK (row_activated),
-                    self);
+static void
+update_actions (GimpHelpBrowserDialog *self)
+{
+  GActionMap            *action_map = G_ACTION_MAP (self);
+  GAction               *action;
+  WebKitBackForwardList *back_forward_list;
 
-  /*  HTML webview  */
-  main_vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
-  gtk_widget_show (main_vbox);
-  gtk_paned_pack2 (GTK_PANED (self->paned), main_vbox, TRUE, TRUE);
+  back_forward_list =
+    webkit_web_view_get_back_forward_list (WEBKIT_WEB_VIEW (self->webview));
 
-  settings = webkit_settings_new_with_settings ("default-charset", "utf-8",
-                                                NULL);
-  self->webview = webkit_web_view_new_with_settings (settings);
-  g_object_unref (settings);
+  /*  update the back button and its menu  */
+  action = g_action_map_lookup_action (action_map, "back");
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+                               webkit_web_view_can_go_back (WEBKIT_WEB_VIEW (self->webview)));
 
-  gtk_widget_set_size_request (self->webview, 300, 200);
-  gtk_widget_show (self->webview);
+  if (back_forward_list)
+    {
+      const GList *list;
 
-  gtk_box_pack_start (GTK_BOX (main_vbox), self->webview, TRUE, TRUE, 0);
+      list = webkit_back_forward_list_get_back_list_with_limit (back_forward_list,
+                                                                12);
+      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_prev),
+                                     build_menu (list, TRUE));
+    }
+  else
+    {
+      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_prev), NULL);
+    }
 
-  g_signal_connect (self->webview, "realize",
-                    G_CALLBACK (webview_realize),
-                    self);
-  g_signal_connect (self->webview, "unrealize",
-                    G_CALLBACK (webview_unrealize),
-                    self);
-  g_signal_connect (self->webview, "popup-menu",
-                    G_CALLBACK (webview_popup_menu),
-                    self);
-  g_signal_connect (self->webview, "button-press-event",
-                    G_CALLBACK (webview_button_press),
-                    self);
-  g_signal_connect (self->webview, "key-press-event",
-                    G_CALLBACK (webview_key_press),
-                    self);
-  g_signal_connect (self->webview, "notify::title",
-                    G_CALLBACK (webview_title_changed),
-                    self);
-  g_signal_connect (self->webview, "load-changed",
-                    G_CALLBACK (webview_load_changed),
-                    self);
-  g_signal_connect (self->webview, "load-failed",
-                    G_CALLBACK (webview_load_failed),
-                    self);
-  g_signal_connect (self->webview, "decide-policy",
-                    G_CALLBACK (webview_decide_policy),
-                    self);
+  /*  update the forward button and its menu  */
+  action = g_action_map_lookup_action (action_map, "forward");
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+                               webkit_web_view_can_go_forward (WEBKIT_WEB_VIEW (self->webview)));
 
-  gtk_widget_grab_focus (self->webview);
+  if (back_forward_list)
+    {
+      const GList *list;
 
-  g_signal_connect (window, "unmap",
-                    G_CALLBACK (dialog_unmap),
-                    self);
+      list = webkit_back_forward_list_get_forward_list_with_limit (back_forward_list,
+                                                                   12);
+      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_next),
+                                     build_menu (list, FALSE));
+    }
+  else
+    {
+      gtk_menu_tool_button_set_menu (GTK_MENU_TOOL_BUTTON (self->button_next), NULL);
+    }
 
-  update_actions (self);
+  /*  update the copy-location action  */
+  action = g_action_map_lookup_action (action_map, "copy-location");
+  g_simple_action_set_enabled (G_SIMPLE_ACTION (action),
+                               webkit_web_view_get_uri (WEBKIT_WEB_VIEW (self->webview)) != NULL);
 
-  /* Searchbar */
-  self->searchbar = build_searchbar (self);
-  gtk_box_pack_start (GTK_BOX (main_vbox), self->searchbar, FALSE, FALSE, 0);
+  /*  update the show-index action  */
+  action = g_action_map_lookup_action (action_map, "show-index");
+  g_simple_action_set_state (G_SIMPLE_ACTION (action),
+                             g_variant_new_boolean (gtk_widget_get_visible (self->sidebar)));
 }
 
 static void
-gimp_help_browser_dialog_finalize (GObject *object)
+add_tool_button (GtkWidget  *toolbar,
+                 const char *action,
+                 const char *icon,
+                 const char *label,
+                 const char *tooltip)
 {
-  GimpHelpBrowserDialog *self = GIMP_HELP_BROWSER_DIALOG (object);
+  GtkWidget *tool_icon;
+  GtkToolItem *tool_button;
 
-  g_clear_pointer (&self->uri_hash_table, g_hash_table_unref);
-  g_clear_object (&self->popup_menu_model);
-  g_clear_object (&self->copy_popup_menu_model);
+  tool_icon = gtk_image_new_from_icon_name (icon, GTK_ICON_SIZE_BUTTON);
+  gtk_widget_show (GTK_WIDGET (tool_icon));
+  tool_button = gtk_tool_button_new (tool_icon, label);
+  gtk_widget_show (GTK_WIDGET (tool_button));
+  gtk_tool_item_set_tooltip_text (tool_button, tooltip);
+  gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (tool_button), action);
 
-  G_OBJECT_CLASS (gimp_help_browser_dialog_parent_class)->finalize (object);
+  gtk_toolbar_insert (GTK_TOOLBAR (toolbar), tool_button, -1);
 }
 
-static void
-gimp_help_browser_dialog_class_init (GimpHelpBrowserDialogClass *klass)
+static GtkWidget *
+build_searchbar (GimpHelpBrowserDialog *self)
 {
-  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GtkWidget *button;
+  GtkWidget *hbox;
+  GtkWidget *label;
 
-  object_class->finalize = gimp_help_browser_dialog_finalize;
-}
+  hbox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
 
-GimpHelpBrowserDialog *
-gimp_help_browser_dialog_new (const gchar *plug_in_binary, GApplication *app)
-{
-  GimpHelpBrowserDialog *window;
-  DialogData             data = { 720, 560, 240, TRUE, 1.0 };
+  label = gtk_label_new (_("Find:"));
+  gtk_widget_show (label);
+  gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0);
 
-  gimp_ui_init (plug_in_binary);
+  self->search_entry = gtk_entry_new ();
+  gtk_widget_show (self->search_entry);
+  gtk_box_pack_start (GTK_BOX (hbox), self->search_entry, TRUE, TRUE, 0);
 
-  gimp_get_data (GIMP_HELP_BROWSER_DIALOG_DATA, &data);
+  g_signal_connect (self->search_entry, "changed",
+                    G_CALLBACK (search_entry_changed),
+                    self);
 
-  window = g_object_new (GIMP_TYPE_HELP_BROWSER_DIALOG,
-                         "application", app,
-                         "role", plug_in_binary,
-                         "default-width", data.width,
-                         "default-height", data.height,
-                         NULL);
-  gtk_paned_set_position (GTK_PANED (window->paned), data.paned_position);
-  if (data.show_index)
-    gtk_widget_show (window->sidebar);
-  webkit_web_view_set_zoom_level (WEBKIT_WEB_VIEW (window->webview), data.zoom);
+  g_signal_connect (self->search_entry, "key-press-event",
+                    G_CALLBACK (search_entry_key_press),
+                    self);
 
-  return GTK_WINDOW (window);
-}
+  button = gtk_button_new_with_mnemonic (C_("search", "_Previous"));
+  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+  gtk_button_set_image (GTK_BUTTON (button),
+                        gtk_image_new_from_icon_name (GIMP_ICON_GO_PREVIOUS,
+                                                      GTK_ICON_SIZE_BUTTON));
+  gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.search-previous");
+  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+  gtk_widget_show (button);
 
-void
-gimp_help_browser_dialog_load (GimpHelpBrowserDialog *self,
-                               const char            *uri)
-{
-  g_return_if_fail (uri && *uri);
+  button = gtk_button_new_with_mnemonic (C_("search", "_Next"));
+  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+  gtk_button_set_image (GTK_BUTTON (button),
+                        gtk_image_new_from_icon_name (GIMP_ICON_GO_NEXT,
+                                                      GTK_ICON_SIZE_BUTTON));
+  gtk_actionable_set_action_name (GTK_ACTIONABLE (button), "win.search-next");
+  gtk_box_pack_start (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+  gtk_widget_show (button);
 
-  webkit_web_view_load_uri (WEBKIT_WEB_VIEW (self->webview), uri);
+  button = gtk_button_new_with_mnemonic (C_("search", "_Close"));
+  gtk_button_set_relief (GTK_BUTTON (button), GTK_RELIEF_NONE);
+  gtk_box_pack_end (GTK_BOX (hbox), button, FALSE, FALSE, 0);
+  gtk_widget_show (button);
 
-  select_index (self, uri);
+  g_signal_connect (button, "clicked",
+                    G_CALLBACK (search_close_clicked),
+                    self);
 
-  gtk_window_present (GTK_WINDOW (gtk_widget_get_toplevel (self->webview)));
+  return hbox;
 }
 
 static void
@@ -1224,47 +1412,3 @@ add_child (GimpHelpBrowserDialog *self,
       add_child (self, store, domain, locale, &iter, item, depth + 1);
     }
 }
-
-void
-gimp_help_browser_dialog_make_index (GimpHelpBrowserDialog *self,
-                                     GimpHelpDomain        *domain,
-                                     GimpHelpLocale        *locale)
-{
-  GtkTreeStore *store;
-  GList        *list;
-
-  if (! locale->toplevel_items)
-    {
-      g_hash_table_foreach (locale->help_id_mapping,
-                            (GHFunc) browser_dialog_make_index_foreach,
-                            locale);
-
-      locale->toplevel_items = g_list_sort (locale->toplevel_items,
-                                            help_item_compare);
-    }
-
-  store = gtk_tree_store_new (2,
-                              G_TYPE_POINTER,
-                              G_TYPE_STRING);
-
-  g_object_set_data (G_OBJECT (store), "domain", domain);
-  g_object_set_data (G_OBJECT (store), "locale", locale);
-
-  if (self->uri_hash_table)
-    g_hash_table_unref (self->uri_hash_table);
-
-  self->uri_hash_table = g_hash_table_new_full (g_str_hash,
-                                                g_str_equal,
-                                                (GDestroyNotify) g_free,
-                                                (GDestroyNotify) gtk_tree_iter_free);
-
-  for (list = locale->toplevel_items; list; list = g_list_next (list))
-    {
-      GimpHelpItem *item = list->data;
-
-      add_child (self, store, domain, locale, NULL, item, 0);
-    }
-
-  gtk_tree_view_set_model (GTK_TREE_VIEW (self->tree_view), GTK_TREE_MODEL (store));
-  g_object_unref (store);
-}


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