help-browser: Rewrite without GtkAction

The initial attempt of this commit was to remove the `GtkAction` usage,
but grew a bit wider than that. The following happened:

* The dialog became a proper GObject, rather than being a big chunk of
  static variables that were hopefully initialized before you used them.
* The dialog now uses `GAction`s to implement actions, and converted
  some signal handlers to actions as well.
* The plug-in run procedure now uses `GtkApplication`. This is one hand
  necessary to be able to set accelerators for actions, but on the other
  hand is more future-proof, as GTK4 removes `gtk_main()`
This commit is contained in:
Niels De Graef 2021-11-27 08:57:30 +01:00 committed by Jehan
parent 83434f7223
commit dddb23c6e5
10 changed files with 1151 additions and 1714 deletions

View File

@ -173,6 +173,7 @@ void gimp_plug_in_set_pdb_error_handler (GimpPlugIn *plug_in,
GimpPDBErrorHandler
gimp_plug_in_get_pdb_error_handler (GimpPlugIn *plug_in);
G_DEFINE_AUTOPTR_CLEANUP_FUNC (GimpPlugIn, g_object_unref);
G_END_DECLS

View File

@ -48,10 +48,6 @@ LDADD = \
$(help_browser_RC)
help_browser_SOURCES = \
gimpthrobber.c \
gimpthrobber.h \
gimpthrobberaction.c \
gimpthrobberaction.h \
help-browser.c \
dialog.c \
dialog.h \

File diff suppressed because it is too large Load Diff

View File

@ -24,12 +24,21 @@
#ifndef __DIALOG_H__
#define __DIALOG_H__
#include <gtk/gtk.h>
void browser_dialog_open (const gchar *plug_in_binary);
void browser_dialog_load (const gchar *uri);
#define GIMP_TYPE_HELP_BROWSER_DIALOG (gimp_help_browser_dialog_get_type ())
G_DECLARE_FINAL_TYPE (GimpHelpBrowserDialog, gimp_help_browser_dialog,
GIMP, HELP_BROWSER_DIALOG,
GtkApplicationWindow)
void browser_dialog_make_index (GimpHelpDomain *domain,
GimpHelpLocale *locale);
GimpHelpBrowserDialog * gimp_help_browser_dialog_new (const char *plug_in_binary,
GApplication *app);
void gimp_help_browser_dialog_load (GimpHelpBrowserDialog *self,
const char *uri);
void gimp_help_browser_dialog_make_index (GimpHelpBrowserDialog *self,
GimpHelpDomain *domain,
GimpHelpLocale *locale);
#endif /* ! __DIALOG_H__ */

View File

@ -1,331 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpThrobber
* Copyright (C) 2005 Sven Neumann <sven@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gimpthrobber.h"
enum
{
CLICKED,
LAST_SIGNAL
};
enum
{
PROP_0,
PROP_ICON_NAME,
PROP_IMAGE
};
static guint toolbutton_signals[LAST_SIGNAL] = { 0 };
static void gimp_throbber_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec);
static void gimp_throbber_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec);
static void gimp_throbber_finalize (GObject *object);
static gboolean gimp_throbber_create_menu_proxy (GtkToolItem *tool_item);
static void gimp_throbber_toolbar_reconfigured (GtkToolItem *tool_item);
static void gimp_throbber_button_clicked (GtkWidget *widget,
GimpThrobber *button);
static void gimp_throbber_construct_contents (GtkToolItem *tool_item);
struct _GimpThrobberPrivate
{
GtkWidget *button;
GtkWidget *image;
gchar *icon_name;
};
G_DEFINE_TYPE_WITH_PRIVATE (GimpThrobber, gimp_throbber, GTK_TYPE_TOOL_ITEM)
static void
gimp_throbber_class_init (GimpThrobberClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkToolItemClass *tool_item_class = GTK_TOOL_ITEM_CLASS (klass);
object_class->set_property = gimp_throbber_set_property;
object_class->get_property = gimp_throbber_get_property;
object_class->finalize = gimp_throbber_finalize;
tool_item_class->create_menu_proxy = gimp_throbber_create_menu_proxy;
tool_item_class->toolbar_reconfigured = gimp_throbber_toolbar_reconfigured;
g_object_class_install_property (object_class,
PROP_ICON_NAME,
g_param_spec_string ("icon-name", NULL, NULL,
NULL,
G_PARAM_READWRITE |
G_PARAM_CONSTRUCT));
g_object_class_install_property (object_class,
PROP_IMAGE,
g_param_spec_object ("image", NULL, NULL,
GTK_TYPE_IMAGE,
G_PARAM_READWRITE));
toolbutton_signals[CLICKED] =
g_signal_new ("clicked",
G_OBJECT_CLASS_TYPE (klass),
G_SIGNAL_RUN_FIRST,
G_STRUCT_OFFSET (GimpThrobberClass, clicked),
NULL, NULL, NULL,
G_TYPE_NONE, 0);
}
static void
gimp_throbber_init (GimpThrobber *button)
{
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
GtkToolItem *toolitem = GTK_TOOL_ITEM (button);
gtk_tool_item_set_homogeneous (toolitem, TRUE);
priv->button = g_object_new (GTK_TYPE_BUTTON,
"yalign", 0.0,
"focus-on-click", FALSE,
NULL);
g_signal_connect_object (priv->button, "clicked",
G_CALLBACK (gimp_throbber_button_clicked),
button, 0);
gtk_container_add (GTK_CONTAINER (button), priv->button);
gtk_widget_show (priv->button);
}
static void
gimp_throbber_construct_contents (GtkToolItem *tool_item)
{
GimpThrobber *button = GIMP_THROBBER (tool_item);
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
GtkWidget *image;
GtkToolbarStyle style;
if (priv->image && gtk_widget_get_parent (priv->image))
gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (priv->image)),
priv->image);
if (gtk_bin_get_child (GTK_BIN (priv->button)))
gtk_widget_destroy (gtk_bin_get_child (GTK_BIN (priv->button)));
style = gtk_tool_item_get_toolbar_style (tool_item);
if (style == GTK_TOOLBAR_TEXT)
{
image = gtk_image_new_from_icon_name (priv->icon_name,
GTK_ICON_SIZE_MENU);
}
else if (style == GTK_TOOLBAR_ICONS)
{
image = gtk_image_new_from_icon_name (priv->icon_name,
GTK_ICON_SIZE_LARGE_TOOLBAR);
}
else if (priv->image)
{
image = priv->image;
}
else
{
image = gtk_image_new_from_icon_name (priv->icon_name,
GTK_ICON_SIZE_DND);
}
gtk_container_add (GTK_CONTAINER (priv->button), image);
gtk_widget_show (image);
gtk_button_set_relief (GTK_BUTTON (priv->button),
gtk_tool_item_get_relief_style (tool_item));
gtk_widget_queue_resize (GTK_WIDGET (button));
}
static void
gimp_throbber_set_property (GObject *object,
guint prop_id,
const GValue *value,
GParamSpec *pspec)
{
GimpThrobber *button = GIMP_THROBBER (object);
switch (prop_id)
{
case PROP_ICON_NAME:
gimp_throbber_set_icon_name (button, g_value_get_string (value));
break;
case PROP_IMAGE:
gimp_throbber_set_image (button, g_value_get_object (value));
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gimp_throbber_get_property (GObject *object,
guint prop_id,
GValue *value,
GParamSpec *pspec)
{
GimpThrobber *button = GIMP_THROBBER (object);
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
switch (prop_id)
{
case PROP_ICON_NAME:
g_value_set_string (value, priv->icon_name);
break;
case PROP_IMAGE:
g_value_set_object (value, priv->image);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
}
}
static void
gimp_throbber_finalize (GObject *object)
{
GimpThrobber *button = GIMP_THROBBER (object);
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
g_free (priv->icon_name);
g_clear_object (&priv->image);
G_OBJECT_CLASS (gimp_throbber_parent_class)->finalize (object);
}
static void
gimp_throbber_button_clicked (GtkWidget *widget,
GimpThrobber *button)
{
g_signal_emit_by_name (button, "clicked");
}
static gboolean
gimp_throbber_create_menu_proxy (GtkToolItem *tool_item)
{
gtk_tool_item_set_proxy_menu_item (tool_item, "gimp-throbber-menu-id", NULL);
return FALSE;
}
static void
gimp_throbber_toolbar_reconfigured (GtkToolItem *tool_item)
{
gimp_throbber_construct_contents (tool_item);
}
GtkToolItem *
gimp_throbber_new (const gchar *icon_name)
{
return g_object_new (GIMP_TYPE_THROBBER,
"icon-name", icon_name,
NULL);
}
void
gimp_throbber_set_icon_name (GimpThrobber *button,
const gchar *icon_name)
{
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
gchar *old_icon_name;
g_return_if_fail (GIMP_IS_THROBBER (button));
old_icon_name = priv->icon_name;
priv->icon_name = g_strdup (icon_name);
gimp_throbber_construct_contents (GTK_TOOL_ITEM (button));
g_object_notify (G_OBJECT (button), "icon-name");
g_free (old_icon_name);
}
const gchar *
gimp_throbber_get_icon_name (GimpThrobber *button)
{
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
g_return_val_if_fail (GIMP_IS_THROBBER (button), NULL);
return priv->icon_name;
}
void
gimp_throbber_set_image (GimpThrobber *button,
GtkWidget *image)
{
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
g_return_if_fail (GIMP_IS_THROBBER (button));
g_return_if_fail (image == NULL || GTK_IS_IMAGE (image));
if (image != priv->image)
{
if (priv->image)
{
if (gtk_widget_get_parent (priv->image))
gtk_container_remove (GTK_CONTAINER (gtk_widget_get_parent (priv->image)),
priv->image);
g_object_unref (priv->image);
}
if (image)
g_object_ref_sink (image);
priv->image = image;
gimp_throbber_construct_contents (GTK_TOOL_ITEM (button));
g_object_notify (G_OBJECT (button), "image");
}
}
GtkWidget *
gimp_throbber_get_image (GimpThrobber *button)
{
GimpThrobberPrivate *priv = gimp_throbber_get_instance_private (button);
g_return_val_if_fail (GIMP_IS_THROBBER (button), NULL);
return priv->image;
}

View File

@ -1,68 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpThrobber
* Copyright (C) 2005 Sven Neumann <sven@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_THROBBER_H__
#define __GIMP_THROBBER_H__
G_BEGIN_DECLS
#define GIMP_TYPE_THROBBER (gimp_throbber_get_type ())
#define GIMP_THROBBER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_THROBBER, GimpThrobber))
#define GIMP_THROBBER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_THROBBER, GimpThrobberClass))
#define GIMP_IS_THROBBER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_THROBBER))
#define GIMP_IS_THROBBER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), GIMP_TYPE_THROBBER))
#define GIMP_THROBBER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GIMP_TYPE_THROBBER, GimpThrobberClass))
typedef struct _GimpThrobber GimpThrobber;
typedef struct _GimpThrobberClass GimpThrobberClass;
typedef struct _GimpThrobberPrivate GimpThrobberPrivate;
struct _GimpThrobber
{
GtkToolItem parent;
/*< private >*/
GimpThrobberPrivate *priv;
};
struct _GimpThrobberClass
{
GtkToolItemClass parent_class;
/* signal */
void (* clicked) (GimpThrobber *button);
};
GType gimp_throbber_get_type (void) G_GNUC_CONST;
GtkToolItem * gimp_throbber_new (const gchar *icon_name);
void gimp_throbber_set_icon_name (GimpThrobber *button,
const gchar *icon_name);
const gchar * gimp_throbber_get_icon_name (GimpThrobber *button);
void gimp_throbber_set_image (GimpThrobber *button,
GtkWidget *image);
GtkWidget * gimp_throbber_get_image (GimpThrobber *button);
G_END_DECLS
#endif /* __GIMP_THROBBER_H__ */

View File

@ -1,133 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpThrobberAction
* Copyright (C) 2005 Sven Neumann <sven@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gtk/gtk.h>
#include "gimpthrobberaction.h"
#include "gimpthrobber.h"
static void gimp_throbber_action_class_init (GimpThrobberActionClass *klass);
static void gimp_throbber_action_connect_proxy (GtkAction *action,
GtkWidget *proxy);
static void gimp_throbber_action_sync_property (GtkAction *action,
GParamSpec *pspec,
GtkWidget *proxy);
static GtkActionClass *parent_class = NULL;
GType
gimp_throbber_action_get_type (void)
{
static GType type = 0;
if (!type)
{
static const GTypeInfo type_info =
{
sizeof (GtkActionClass),
(GBaseInitFunc) NULL,
(GBaseFinalizeFunc) NULL,
(GClassInitFunc) gimp_throbber_action_class_init,
(GClassFinalizeFunc) NULL,
NULL,
sizeof (GtkAction),
0, /* n_preallocs */
(GInstanceInitFunc) NULL
};
type = g_type_register_static (GTK_TYPE_ACTION,
"GimpThrobberAction",
&type_info, 0);
}
return type;
}
static void
gimp_throbber_action_class_init (GimpThrobberActionClass *klass)
{
GtkActionClass *action_class = GTK_ACTION_CLASS (klass);
parent_class = g_type_class_peek_parent (klass);
action_class->connect_proxy = gimp_throbber_action_connect_proxy;
action_class->toolbar_item_type = GIMP_TYPE_THROBBER;
}
static void
gimp_throbber_action_connect_proxy (GtkAction *action,
GtkWidget *proxy)
{
GTK_ACTION_CLASS (parent_class)->connect_proxy (action, proxy);
if (GIMP_IS_THROBBER (proxy))
{
GParamSpec *pspec;
pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (action),
"icon-name");
gimp_throbber_action_sync_property (action, pspec, proxy);
g_signal_connect_object (action, "notify::icon-name",
G_CALLBACK (gimp_throbber_action_sync_property),
proxy, 0);
g_signal_connect_object (proxy, "clicked",
G_CALLBACK (gtk_action_activate), action,
G_CONNECT_SWAPPED);
}
}
static void
gimp_throbber_action_sync_property (GtkAction *action,
GParamSpec *pspec,
GtkWidget *proxy)
{
const gchar *property = g_param_spec_get_name (pspec);
GValue value = G_VALUE_INIT;
g_value_init (&value, G_PARAM_SPEC_VALUE_TYPE (pspec));
g_object_get_property (G_OBJECT (action), property, &value);
g_object_set_property (G_OBJECT (proxy), property, &value);
g_value_unset (&value);
}
GtkAction *
gimp_throbber_action_new (const gchar *name,
const gchar *label,
const gchar *tooltip,
const gchar *icon_name)
{
return g_object_new (GIMP_TYPE_THROBBER_ACTION,
"name", name,
"label", label,
"tooltip", tooltip,
"icon-name", icon_name,
NULL);
}

View File

@ -1,48 +0,0 @@
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* GimpThrobberAction
* Copyright (C) 2005 Sven Neumann <sven@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#ifndef __GIMP_THROBBER_ACTION_H__
#define __GIMP_THROBBER_ACTION_H__
G_BEGIN_DECLS
#define GIMP_TYPE_THROBBER_ACTION (gimp_throbber_action_get_type ())
#define GIMP_THROBBER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_THROBBER_ACTION, GimpThrobberAction))
#define GIMP_THROBBER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_THROBBER_ACTION, GimpThrobberActionClass))
#define GIMP_IS_THROBBER_ACTION(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GIMP_TYPE_THROBBER_ACTION))
#define GIMP_IS_THROBBER_ACTION_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), GIMP_TYPE_THROBBER_ACTION))
#define GIMP_THROBBER_ACTION_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), GIMP_TYPE_THROBBER_ACTION, GimpThrobberActionClass))
typedef GtkAction GimpThrobberAction;
typedef GtkActionClass GimpThrobberActionClass;
GType gimp_throbber_action_get_type (void) G_GNUC_CONST;
GtkAction * gimp_throbber_action_new (const gchar *name,
const gchar *label,
const gchar *tooltip,
const gchar *icon_name);
G_END_DECLS
#endif /* __GIMP_THROBBER_ACTION_H__ */

View File

@ -42,28 +42,10 @@
#define PLUG_IN_ROLE "gimp-help-browser"
typedef struct _HelpBrowser HelpBrowser;
typedef struct _HelpBrowserClass HelpBrowserClass;
struct _HelpBrowser
{
GimpPlugIn parent_instance;
};
struct _HelpBrowserClass
{
GimpPlugInClass parent_class;
};
#define HELP_BROWSER_TYPE (help_browser_get_type ())
#define HELP_BROWSER (obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), HELP_BROWSER_TYPE, HelpBrowser))
GType help_browser_get_type (void) G_GNUC_CONST;
static GList * help_browser_query_procedures (GimpPlugIn *plug_in);
static GimpProcedure * help_browser_create_procedure (GimpPlugIn *plug_in,
const gchar *name);
#define GIMP_TYPE_HELP_BROWSER (gimp_help_browser_get_type ())
G_DECLARE_FINAL_TYPE (GimpHelpBrowser, gimp_help_browser,
GIMP, HELP_BROWSER,
GimpPlugIn)
static GimpValueArray * help_browser_run (GimpProcedure *procedure,
const GimpValueArray *args,
@ -74,32 +56,19 @@ static GimpValueArray * temp_proc_run (GimpProcedure *pro
const GimpValueArray *args,
gpointer run_data);
static gboolean help_browser_show_help (const gchar *help_domain,
const gchar *help_locales,
const gchar *help_id);
static GimpHelpProgress * help_browser_progress_new (void);
G_DEFINE_TYPE (HelpBrowser, help_browser, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (HELP_BROWSER_TYPE)
static void
help_browser_class_init (HelpBrowserClass *klass)
struct _GimpHelpBrowser
{
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
GimpPlugIn parent_instance;
plug_in_class->query_procedures = help_browser_query_procedures;
plug_in_class->create_procedure = help_browser_create_procedure;
}
GtkApplication *app;
GimpHelpBrowserDialog *window;
};
static void
help_browser_init (HelpBrowser *help_browser)
{
}
G_DEFINE_TYPE (GimpHelpBrowser, gimp_help_browser, GIMP_TYPE_PLUG_IN)
GIMP_MAIN (GIMP_TYPE_HELP_BROWSER)
static GList *
help_browser_query_procedures (GimpPlugIn *plug_in)
@ -117,7 +86,7 @@ help_browser_create_procedure (GimpPlugIn *plug_in,
{
procedure = gimp_procedure_new (plug_in, name,
GIMP_PDB_PROC_TYPE_EXTENSION,
help_browser_run, NULL, NULL);
help_browser_run, plug_in, NULL);
gimp_procedure_set_documentation (procedure,
"Browse the GIMP user manual",
@ -154,11 +123,35 @@ help_browser_create_procedure (GimpPlugIn *plug_in,
return procedure;
}
static void
on_app_activate (GApplication *gapp, gpointer user_data)
{
GimpHelpBrowser *browser = GIMP_HELP_BROWSER (user_data);
GtkApplication *app = GTK_APPLICATION (gapp);
browser->window = gimp_help_browser_dialog_new (PLUG_IN_BINARY, gapp);
gtk_application_set_accels_for_action (app, "win.back", (const char*[]) { "<alt>Left", NULL });
gtk_application_set_accels_for_action (app, "win.forward", (const char*[]) { "<alt>Right", NULL });
gtk_application_set_accels_for_action (app, "win.reload", (const char*[]) { "<control>R", NULL });
gtk_application_set_accels_for_action (app, "win.stop", (const char*[]) { "Escape", NULL });
gtk_application_set_accels_for_action (app, "win.home", (const char*[]) { "<alt>Home", NULL });
gtk_application_set_accels_for_action (app, "win.copy-selection", (const char*[]) { "<control>C", NULL });
gtk_application_set_accels_for_action (app, "win.zoom-in", (const char*[]) { "<control>plus", NULL });
gtk_application_set_accels_for_action (app, "win.zoom-out", (const char*[]) { "<control>minus", NULL });
gtk_application_set_accels_for_action (app, "win.find", (const char*[]) { "<control>F", NULL });
gtk_application_set_accels_for_action (app, "win.find-again", (const char*[]) { "<control>G", NULL });
gtk_application_set_accels_for_action (app, "win.close", (const char*[]) { "<control>W", "<control>Q", NULL });
gtk_application_set_accels_for_action (app, "win.show-index", (const char*[]) { "<control>I", NULL });
}
static GimpValueArray *
help_browser_run (GimpProcedure *procedure,
const GimpValueArray *args,
gpointer run_data)
gpointer user_data)
{
GimpHelpBrowser *browser = GIMP_HELP_BROWSER (user_data);
INIT_I18N ();
if (! gimp_help_init (GIMP_VALUES_GET_STRV (args, 1),
@ -169,14 +162,17 @@ help_browser_run (GimpProcedure *procedure,
NULL);
}
browser_dialog_open (PLUG_IN_BINARY);
temp_proc_install (gimp_procedure_get_plug_in (procedure));
gimp_procedure_extension_ready (procedure);
gimp_plug_in_extension_enable (gimp_procedure_get_plug_in (procedure));
gtk_main ();
browser->app = gtk_application_new (NULL, G_APPLICATION_FLAGS_NONE);
g_signal_connect (browser->app, "activate", G_CALLBACK (on_app_activate), browser);
g_application_run (G_APPLICATION (browser->app), 0, NULL);
g_clear_object (&browser->app);
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
}
@ -188,7 +184,7 @@ temp_proc_install (GimpPlugIn *plug_in)
procedure = gimp_procedure_new (plug_in, GIMP_HELP_BROWSER_TEMP_EXT_PROC,
GIMP_PDB_PROC_TYPE_TEMPORARY,
temp_proc_run, NULL, NULL);
temp_proc_run, plug_in, NULL);
gimp_procedure_set_documentation (procedure,
"DON'T USE THIS ONE",
@ -224,81 +220,94 @@ temp_proc_install (GimpPlugIn *plug_in)
g_object_unref (procedure);
}
static GimpValueArray *
temp_proc_run (GimpProcedure *procedure,
const GimpValueArray *args,
gpointer run_data)
typedef struct _IdleClosure
{
const gchar *help_domain = GIMP_HELP_DEFAULT_DOMAIN;
const gchar *help_locales = NULL;
const gchar *help_id = GIMP_HELP_DEFAULT_ID;
const gchar *string;
GimpHelpBrowser *browser;
char *help_domain;
char *help_locales;
char *help_id;
} IdleClosure;
string = GIMP_VALUES_GET_STRING (args, 0);
if (string && strlen (string))
help_domain = string;
static void
idle_closure_free (gpointer data)
{
IdleClosure *closure = data;
string = GIMP_VALUES_GET_STRING (args, 1);
if (string && strlen (string))
help_locales = string;
string = GIMP_VALUES_GET_STRING (args, 2);
if (string && strlen (string))
help_id = string;
if (! help_browser_show_help (help_domain, help_locales, help_id))
{
gtk_main_quit ();
}
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
g_free (closure->help_domain);
g_free (closure->help_locales);
g_free (closure->help_id);
g_free (closure);
}
static gboolean
help_browser_show_help (const gchar *help_domain,
const gchar *help_locales,
const gchar *help_id)
show_help_on_idle (gpointer user_data)
{
GimpHelpDomain *domain;
gboolean success = TRUE;
IdleClosure *closure = user_data;
GimpHelpDomain *domain;
GimpHelpProgress *progress = NULL;
GimpHelpLocale *locale;
GList *locales;
char *uri;
gboolean fatal_error;
domain = gimp_help_lookup_domain (help_domain);
/* First get the URI to load */
domain = gimp_help_lookup_domain (closure->help_domain);
if (!domain)
return G_SOURCE_REMOVE;
if (domain)
locales = gimp_help_parse_locales (closure->help_locales);
if (! g_str_has_prefix (domain->help_uri, "file:"))
progress = help_browser_progress_new ();
uri = gimp_help_domain_map (domain, locales, closure->help_id,
progress, &locale, &fatal_error);
if (progress)
gimp_help_progress_free (progress);
g_list_free_full (locales, (GDestroyNotify) g_free);
/* Now actually load it */
if (uri)
{
GimpHelpProgress *progress = NULL;
GimpHelpLocale *locale;
GList *locales;
gchar *uri;
gboolean fatal_error;
gimp_help_browser_dialog_make_index (closure->browser->window, domain, locale);
gimp_help_browser_dialog_load (closure->browser->window, uri);
locales = gimp_help_parse_locales (help_locales);
if (! g_str_has_prefix (domain->help_uri, "file:"))
progress = help_browser_progress_new ();
uri = gimp_help_domain_map (domain, locales, help_id,
progress, &locale, &fatal_error);
if (progress)
gimp_help_progress_free (progress);
g_list_free_full (locales, (GDestroyNotify) g_free);
if (uri)
{
browser_dialog_make_index (domain, locale);
browser_dialog_load (uri);
g_free (uri);
}
else if (fatal_error)
{
success = FALSE;
}
g_free (uri);
}
return success;
return G_SOURCE_REMOVE;
}
static GimpValueArray *
temp_proc_run (GimpProcedure *procedure,
const GimpValueArray *args,
gpointer user_data)
{
GimpHelpBrowser *browser = GIMP_HELP_BROWSER (user_data);
IdleClosure *closure;
const char *str;
closure = g_new0 (IdleClosure, 1);
closure->browser = browser;
str = GIMP_VALUES_GET_STRING (args, 0);
closure->help_domain = g_strdup ((str && *str)? str : GIMP_HELP_DEFAULT_DOMAIN);
str = GIMP_VALUES_GET_STRING (args, 1);
if (str && *str)
closure->help_locales = g_strdup (str);
str = GIMP_VALUES_GET_STRING (args, 2);
closure->help_id = g_strdup ((str && *str)? str : GIMP_HELP_DEFAULT_ID);
/* Do this on idle, to make sure everything is initialized already */
g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
show_help_on_idle,
closure, idle_closure_free);
return gimp_procedure_new_return_values (procedure, GIMP_PDB_SUCCESS, NULL);
}
@ -335,3 +344,17 @@ help_browser_progress_new (void)
return gimp_help_progress_new (&vtable, NULL);
}
static void
gimp_help_browser_class_init (GimpHelpBrowserClass *klass)
{
GimpPlugInClass *plug_in_class = GIMP_PLUG_IN_CLASS (klass);
plug_in_class->query_procedures = help_browser_query_procedures;
plug_in_class->create_procedure = help_browser_create_procedure;
}
static void
gimp_help_browser_init (GimpHelpBrowser *help_browser)
{
}

View File

@ -4,8 +4,6 @@ plugin_name = 'help-browser'
plugin_sources = [
'dialog.c',
'gimpthrobber.c',
'gimpthrobberaction.c',
'help-browser.c',
'uri.c',
]