[gimp/merge-requests/734: 3/3] app: cleanup MR !734.
- From: Jehan <jehanp src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gimp/merge-requests/734: 3/3] app: cleanup MR !734.
- Date: Sun, 9 Oct 2022 14:13:17 +0000 (UTC)
commit fb1cb22f62b8db626399e6caf8cb294f0dddcef6
Author: Jehan <jehan girinstud io>
Date: Thu Oct 6 20:44:06 2022 +0200
app: cleanup MR !734.
- app_activate_callback() moved with other private functions.
- Removing the `if (app)` test in app_activate_callback() as we don't
set it to NULL anymore. The app variable is always set.
- As a consequence of the previous point, change signature of
app_exit_after_callback() which doesn't have to change the value of
app anymore.
- Don't emit direcly the "exit" signal from app_activate_callback(). We
must call `gimp_exit (gimp, TRUE);` instead, which does more than just
emitting this signal. It also takes care of cleaning any remaining
images without a display. If we don't do this, we are leaking
GeglBuffer when opening images from command lines while quitting
immediately with --quit.
- Get rid of gimp_core_app_set_values() which was completely bypassing
the fact that all the properties of a GimpCoreApp were construct-only.
Instead make these proper properties. I use a trick used in other
interface, creating a gimp_container_view_install_properties() which
is called from child classes.
The point of GimpCoreApp is not just to share a common interface, it's
rather to weakly simulate some kind of multi-inheritance in GObject.
Since we want both GimpApp and GimpConsoleApp to inherit from a same
parent class while we also want them to inherit either from
GtkApplication and GApplication respectively (yet without linking to
GTK in this second case), we are stuck as far as normal GObject
inheritance goes. This is why we use an interface to which we add a
private struct through a GQuark trick. We want the property settings
and function implementations to also be part of this shared code.
- Get rid of all the abstract methods of GimpCoreApp of the form
get_*(). These are useless as we don't expect these to have different
implementation depending on the actual child class. Once again, our
main goal was to simulate multiple inheritance rather than actually
have an interface with various implementations.
- Make "no-splash" a property of GimpApp, because it's cleaner this way.
- Fix gimp_core_app_private_finalize().
- don't use #pragma once, it's not standard. Just use include guards.
- Fix includes: order was wrong, include from the source, not other
headers, etc.
- Clean various other details, coding styles, fix several more bugs and
moreā¦
app/app.c | 369 +++++++++++++++++++++++++--------------------------
app/gimpconsoleapp.c | 25 +++-
app/gimpconsoleapp.h | 7 +-
app/gimpcoreapp.c | 236 ++++++++++++++++++++++----------
app/gimpcoreapp.h | 65 ++++-----
app/gui/gimpapp.c | 92 +++++++++++--
app/gui/gimpapp.h | 4 -
app/gui/gui-types.h | 1 +
app/gui/gui.c | 1 +
app/gui/gui.h | 1 -
app/gui/splash.h | 2 -
11 files changed, 491 insertions(+), 312 deletions(-)
---
diff --git a/app/app.c b/app/app.c
index 515618f900..af86865269 100644
--- a/app/app.c
+++ b/app/app.c
@@ -60,17 +60,18 @@
#include "file/file-open.h"
#ifndef GIMP_CONSOLE_COMPILATION
+#include <gtk/gtk.h>
+
#include "dialogs/user-install-dialog.h"
+#include "gui/gimpapp.h"
#include "gui/gui.h"
#endif
#include "app.h"
#include "errors.h"
-#ifndef GIMP_CONSOLE_COMPILATION
-#include "gui/gimpapp.h"
-#endif
#include "gimpconsoleapp.h"
+#include "gimpcoreapp.h"
#include "language.h"
#include "sanity.h"
#include "gimp-debug.h"
@@ -84,11 +85,13 @@
static void app_init_update_noop (const gchar *text1,
const gchar *text2,
gdouble percentage);
+static void app_activate_callback (GimpCoreApp *app,
+ gpointer user_data);
static void app_restore_after_callback (Gimp *gimp,
GimpInitStatusFunc status_callback);
static gboolean app_exit_after_callback (Gimp *gimp,
gboolean kill_it,
- GApplication **app);
+ GApplication *app);
#if 0
/* left here as documentation how to do compat enums */
@@ -166,183 +169,6 @@ app_exit (gint status)
exit (status);
}
-static void
-app_activate_callback (GimpCoreApp *app,
- gpointer user_data)
-{
- Gimp *gimp = NULL;
- GimpInitStatusFunc update_status_func = NULL;
- const gchar **filenames;
- const gchar *current_language;
- gchar *prev_language = NULL;
- GError *font_error = NULL;
-
- g_return_if_fail (GIMP_IS_CORE_APP (app));
-
- gimp = gimp_core_app_get_gimp (app);
-
- gimp_core_app_set_exit_status (app, EXIT_SUCCESS);
-
-#ifndef GIMP_CONSOLE_COMPILATION
- if (! gimp->no_interface)
- update_status_func = gui_init (gimp, gimp_app_get_no_splash (GIMP_APP (app)), GIMP_APP (app), NULL);
-#endif
-
- if (! update_status_func)
- update_status_func = app_init_update_noop;
-
- /* Create all members of the global Gimp instance which need an already
- * parsed gimprc, e.g. the data factories
- */
- gimp_initialize (gimp, update_status_func);
-
- g_object_get (gimp->edit_config,
- "prev-language", &prev_language,
- NULL);
- /* Language was already initialized. I call this again only to get the
- * actual language information.
- */
- current_language = language_init (NULL);
- gimp->query_all = (prev_language == NULL ||
- g_strcmp0 (prev_language, current_language) != 0);
- g_free (prev_language);
-
- /* Load all data files */
- gimp_restore (gimp, update_status_func, &font_error);
-
- /* enable autosave late so we don't autosave when the
- * monitor resolution is set in gui_init()
- */
- gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE);
-
- /* check for updates *after* enabling config autosave, so that the timestamp
- * is saved
- */
- gimp_update_auto_check (gimp->edit_config, gimp);
-
- /* Setting properties to be used for the next run. */
- g_object_set (gimp->edit_config,
- /* Set this after gimp_update_auto_check(). */
- "config-version", GIMP_VERSION,
- /* Set this after gimp_restore(). */
- "prev-language", current_language,
- NULL);
-
-#ifndef GIMP_CONSOLE_COMPILATION
- if (! gimp->no_interface)
- {
- /* Before opening images from command line, check for salvaged images
- * and query interactively to know if we should recover or discard
- * them.
- */
- GList *recovered_files;
- GList *iter;
-
- recovered_files = errors_recovered ();
- if (recovered_files &&
- gui_recover (g_list_length (recovered_files)))
- {
- for (iter = recovered_files; iter; iter = iter->next)
- {
- GFile *file;
- GimpImage *image;
- GError *error = NULL;
- GimpPDBStatusType status;
-
- file = g_file_new_for_path (iter->data);
- image = file_open_with_display (gimp,
- gimp_get_user_context (gimp),
- NULL,
- file,
- gimp_core_app_get_as_new (app),
- initial_monitor,
- &status, &error);
- if (image)
- {
- /* Break ties with the backup directory. */
- gimp_image_set_file (image, NULL);
- /* One of the rare exceptions where we should call
- * gimp_image_dirty() directly instead of creating
- * an undo. We want the image to be dirty from
- * scratch, without anything to undo.
- */
- gimp_image_dirty (image, GIMP_DIRTY_IMAGE);
- }
- else
- {
- g_error_free (error);
- }
-
- g_object_unref (file);
- }
- }
- /* Delete backup XCF images. */
- for (iter = recovered_files; iter; iter = iter->next)
- {
- g_unlink (iter->data);
- }
- g_list_free_full (recovered_files, g_free);
- }
-#endif
-
- /* Load the images given on the command-line. */
- filenames = gimp_core_app_get_filenames (app);
- if (filenames != NULL)
- {
- gint i;
-
- for (i = 0; filenames[i] != NULL; i++)
- {
- if (app)
- {
- GFile *file = g_file_new_for_commandline_arg (filenames[i]);
-
- file_open_from_command_line (gimp, file,
- gimp_core_app_get_as_new (app),
- initial_monitor);
-
- g_object_unref (file);
- }
- }
- }
-
- /* The software is now fully loaded and ready to be used and get
- * external input.
- */
- gimp->initialized = TRUE;
-
- if (font_error)
- {
- gimp_message_literal (gimp, NULL,
- GIMP_MESSAGE_INFO,
- font_error->message);
- g_error_free (font_error);
- }
-
- if (app)
- {
- gint batch_retval;
-
- batch_retval = gimp_batch_run (gimp,
- gimp_core_app_get_batch_interpreter (app),
- gimp_core_app_get_batch_commands (app));
-
- if (gimp_core_app_get_quit (app))
- {
- /* Only if we are in batch mode, we want to exit with the
- * return value of the batch command.
- */
- gimp_core_app_set_exit_status (app, batch_retval);
-
- /* Return value, needed for the signal call; let's just ignore the
- * result. */
- gboolean cb_retval;
-
- g_signal_emit_by_name (gimp, "exit", TRUE, &cb_retval);
- }
- }
-}
-
gint
app_run (const gchar *full_prog_name,
const gchar **filenames,
@@ -481,7 +307,7 @@ app_run (const gchar *full_prog_name,
g_signal_connect_after (gimp, "exit",
G_CALLBACK (app_exit_after_callback),
- &app);
+ app);
g_signal_connect (app, "activate",
G_CALLBACK (app_activate_callback),
@@ -523,6 +349,175 @@ app_init_update_noop (const gchar *text1,
/* deliberately do nothing */
}
+static void
+app_activate_callback (GimpCoreApp *app,
+ gpointer user_data)
+{
+ Gimp *gimp = NULL;
+ GimpInitStatusFunc update_status_func = NULL;
+ const gchar **filenames;
+ const gchar *current_language;
+ gchar *prev_language = NULL;
+ GError *font_error = NULL;
+ gint batch_retval;
+
+ g_return_if_fail (GIMP_IS_CORE_APP (app));
+
+ gimp = gimp_core_app_get_gimp (app);
+
+ gimp_core_app_set_exit_status (app, EXIT_SUCCESS);
+
+#ifndef GIMP_CONSOLE_COMPILATION
+ if (! gimp->no_interface)
+ update_status_func = gui_init (gimp, gimp_app_get_no_splash (GIMP_APP (app)), GIMP_APP (app), NULL);
+#endif
+
+ if (! update_status_func)
+ update_status_func = app_init_update_noop;
+
+ /* Create all members of the global Gimp instance which need an already
+ * parsed gimprc, e.g. the data factories
+ */
+ gimp_initialize (gimp, update_status_func);
+
+ g_object_get (gimp->edit_config,
+ "prev-language", &prev_language,
+ NULL);
+ /* Language was already initialized. I call this again only to get the
+ * actual language information.
+ */
+ current_language = language_init (NULL);
+ gimp->query_all = (prev_language == NULL ||
+ g_strcmp0 (prev_language, current_language) != 0);
+ g_free (prev_language);
+
+ /* Load all data files */
+ gimp_restore (gimp, update_status_func, &font_error);
+
+ /* enable autosave late so we don't autosave when the
+ * monitor resolution is set in gui_init()
+ */
+ gimp_rc_set_autosave (GIMP_RC (gimp->edit_config), TRUE);
+
+ /* check for updates *after* enabling config autosave, so that the timestamp
+ * is saved
+ */
+ gimp_update_auto_check (gimp->edit_config, gimp);
+
+ /* Setting properties to be used for the next run. */
+ g_object_set (gimp->edit_config,
+ /* Set this after gimp_update_auto_check(). */
+ "config-version", GIMP_VERSION,
+ /* Set this after gimp_restore(). */
+ "prev-language", current_language,
+ NULL);
+
+#ifndef GIMP_CONSOLE_COMPILATION
+ if (! gimp->no_interface)
+ {
+ /* Before opening images from command line, check for salvaged images
+ * and query interactively to know if we should recover or discard
+ * them.
+ */
+ GList *recovered_files;
+ GList *iter;
+
+ recovered_files = errors_recovered ();
+ if (recovered_files &&
+ gui_recover (g_list_length (recovered_files)))
+ {
+ for (iter = recovered_files; iter; iter = iter->next)
+ {
+ GFile *file;
+ GimpImage *image;
+ GError *error = NULL;
+ GimpPDBStatusType status;
+
+ file = g_file_new_for_path (iter->data);
+ image = file_open_with_display (gimp,
+ gimp_get_user_context (gimp),
+ NULL,
+ file,
+ gimp_core_app_get_as_new (app),
+ initial_monitor,
+ &status, &error);
+ if (image)
+ {
+ /* Break ties with the backup directory. */
+ gimp_image_set_file (image, NULL);
+ /* One of the rare exceptions where we should call
+ * gimp_image_dirty() directly instead of creating
+ * an undo. We want the image to be dirty from
+ * scratch, without anything to undo.
+ */
+ gimp_image_dirty (image, GIMP_DIRTY_IMAGE);
+ }
+ else
+ {
+ g_error_free (error);
+ }
+
+ g_object_unref (file);
+ }
+ }
+ /* Delete backup XCF images. */
+ for (iter = recovered_files; iter; iter = iter->next)
+ {
+ g_unlink (iter->data);
+ }
+ g_list_free_full (recovered_files, g_free);
+ }
+#endif
+
+ /* Load the images given on the command-line. */
+ filenames = gimp_core_app_get_filenames (app);
+ if (filenames != NULL)
+ {
+ gint i;
+
+ for (i = 0; filenames[i] != NULL; i++)
+ {
+ GFile *file = g_file_new_for_commandline_arg (filenames[i]);
+
+ file_open_from_command_line (gimp, file,
+ gimp_core_app_get_as_new (app),
+ initial_monitor);
+
+ g_object_unref (file);
+ }
+ }
+
+ /* The software is now fully loaded and ready to be used and get
+ * external input.
+ */
+ gimp->initialized = TRUE;
+
+ if (font_error)
+ {
+ gimp_message_literal (gimp, NULL,
+ GIMP_MESSAGE_INFO,
+ font_error->message);
+ g_error_free (font_error);
+ }
+
+ batch_retval = gimp_batch_run (gimp,
+ gimp_core_app_get_batch_interpreter (app),
+ gimp_core_app_get_batch_commands (app));
+
+ if (gimp_core_app_get_quit (app))
+ {
+ /* Only if we are in batch mode, we want to exit with the
+ * return value of the batch command.
+ */
+ gimp_core_app_set_exit_status (app, batch_retval);
+
+ /* Emit the "exit" signal, but also properly free all images still
+ * opened.
+ */
+ gimp_exit (gimp, TRUE);
+ }
+}
+
static void
app_restore_after_callback (Gimp *gimp,
GimpInitStatusFunc status_callback)
@@ -538,9 +533,9 @@ app_restore_after_callback (Gimp *gimp,
}
static gboolean
-app_exit_after_callback (Gimp *gimp,
- gboolean kill_it,
- GApplication **app)
+app_exit_after_callback (Gimp *gimp,
+ gboolean kill_it,
+ GApplication *app)
{
if (gimp->be_verbose)
g_print ("EXIT: %s\n", G_STRFUNC);
@@ -556,7 +551,7 @@ app_exit_after_callback (Gimp *gimp,
#ifdef GIMP_UNSTABLE
- g_application_quit (G_APPLICATION (*app));
+ g_application_quit (G_APPLICATION (app));
#else
@@ -564,7 +559,7 @@ app_exit_after_callback (Gimp *gimp,
gegl_exit ();
- exit (gimp_core_app_get_exit_status (GIMP_CORE_APP (*app)));
+ exit (gimp_core_app_get_exit_status (GIMP_CORE_APP (app)));
#endif
diff --git a/app/gimpconsoleapp.c b/app/gimpconsoleapp.c
index f9325991f1..82bc5a1adf 100644
--- a/app/gimpconsoleapp.c
+++ b/app/gimpconsoleapp.c
@@ -16,10 +16,17 @@
#include <config.h>
-#include "gimpconsoleapp.h"
+#include <gio/gio.h>
#include "libgimpbase/gimpbase.h"
+#include "core/core-types.h"
+
+#include "core/gimp.h"
+
+#include "gimpconsoleapp.h"
+#include "gimpcoreapp.h"
+
struct _GimpConsoleApp
{
GApplication parent_instance;
@@ -36,6 +43,10 @@ gimp_console_app_class_init (GimpConsoleAppClass *klass)
GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
gobj_class->finalize = gimp_core_app_finalize;
+ gobj_class->get_property = gimp_core_app_get_property;
+ gobj_class->set_property = gimp_core_app_set_property;
+
+ gimp_core_app_install_properties (gobj_class);
}
static void
@@ -55,11 +66,15 @@ gimp_console_app_new (Gimp *gimp,
{
GimpConsoleApp *app;
- app = g_object_new (GIMP_TYPE_CONSOLE_APP, NULL);
+ app = g_object_new (GIMP_TYPE_CONSOLE_APP,
+ "gimp", gimp,
+ "filenames", filenames,
+ "as-new", as_new,
- gimp_core_app_set_values (GIMP_CORE_APP (app), gimp,
- quit, as_new, filenames,
- batch_interpreter, batch_commands);
+ "quit", quit,
+ "batch-interpreter", batch_interpreter,
+ "batch-commands", batch_commands,
+ NULL);
return G_APPLICATION (app);
}
diff --git a/app/gimpconsoleapp.h b/app/gimpconsoleapp.h
index acb717f1e8..7b0fa7ca4c 100644
--- a/app/gimpconsoleapp.h
+++ b/app/gimpconsoleapp.h
@@ -15,9 +15,9 @@
* <https://www.gnu.org/licenses/>.
*/
-#pragma once
+#ifndef __GIMP_CONSOLE_APP_H__
+#define __GIMP_CONSOLE_APP_H__
-#include "gimpcoreapp.h"
#define GIMP_TYPE_CONSOLE_APP (gimp_console_app_get_type ())
G_DECLARE_FINAL_TYPE (GimpConsoleApp, gimp_console_app, GIMP, CONSOLE_APP, GApplication)
@@ -28,3 +28,6 @@ GApplication * gimp_console_app_new (Gimp *gimp,
const char **filenames,
const char *batch_interpreter,
const char **batch_commands);
+
+
+#endif /* __GIMP_CONSOLE_APP_H__ */
diff --git a/app/gimpcoreapp.c b/app/gimpcoreapp.c
index 140b8fc49c..fa6468a40c 100644
--- a/app/gimpcoreapp.c
+++ b/app/gimpcoreapp.c
@@ -16,37 +16,38 @@
#include <config.h>
-#include "gimpcoreapp.h"
+#include <gio/gio.h>
#include "libgimpbase/gimpbase.h"
-#define GIMP_CORE_APP_GET_PRIVATE(obj) (gimp_core_app_get_private ((GimpCoreApp *) (obj)))
+#include "core/core-types.h"
-enum
-{
- PROP_0,
- PROP_GIMP,
- N_PROPS
-};
+#include "core/gimp.h"
+
+#include "gimpcoreapp.h"
+
+
+#define GIMP_CORE_APP_GET_PRIVATE(obj) (gimp_core_app_get_private ((GimpCoreApp *) (obj)))
typedef struct _GimpCoreAppPrivate GimpCoreAppPrivate;
struct _GimpCoreAppPrivate
{
- Gimp *gimp;
- gboolean quit;
- gboolean as_new;
- const gchar **filenames;
- const gchar *batch_interpreter;
- const gchar **batch_commands;
- gint exit_status;
+ Gimp *gimp;
+ gboolean as_new;
+ gchar **filenames;
+
+ gboolean quit;
+ gchar *batch_interpreter;
+ gchar **batch_commands;
+ gint exit_status;
};
/* local function prototypes */
-static GimpCoreAppPrivate *
- gimp_core_app_get_private (GimpCoreApp *app);
-static void gimp_core_app_private_finalize (GimpCoreAppPrivate *private);
+static GimpCoreAppPrivate * gimp_core_app_get_private (GimpCoreApp *app);
+static void gimp_core_app_private_finalize (GimpCoreAppPrivate *private);
+
G_DEFINE_INTERFACE (GimpCoreApp, gimp_core_app, G_TYPE_OBJECT)
@@ -60,26 +61,146 @@ gimp_core_app_default_init (GimpCoreAppInterface *iface)
"GIMP root object",
GIMP_TYPE_GIMP,
GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boxed ("filenames",
+ "Files to open at start",
+ "Files to open at start",
+ G_TYPE_STRV,
+ GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("as-new",
+ "Open images as new",
+ "Open images as new",
+ FALSE,
+ GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
- iface->get_gimp = gimp_core_app_get_gimp;
- iface->get_quit = gimp_core_app_get_quit;
- iface->get_as_new = gimp_core_app_get_as_new;
- iface->get_filenames = gimp_core_app_get_filenames;
- iface->get_batch_interpreter = gimp_core_app_get_batch_interpreter;
- iface->get_batch_commands = gimp_core_app_get_batch_commands;
- iface->set_exit_status = gimp_core_app_set_exit_status;
- iface->get_exit_status = gimp_core_app_get_exit_status;
- iface->set_values = gimp_core_app_set_values;
+ g_object_interface_install_property (iface,
+ g_param_spec_boolean ("quit",
+ "Quit",
+ "Quit GIMP immediately after running batch
commands",
+ FALSE,
+ GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ g_object_interface_install_property (iface,
+ g_param_spec_string ("batch-interpreter",
+ "The procedure to process batch commands with",
+ "The procedure to process batch commands with",
+ NULL,
+ GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+
+ g_object_interface_install_property (iface,
+ g_param_spec_boxed ("batch-commands",
+ "Batch commands to run",
+ "Batch commands to run",
+ G_TYPE_STRV,
+ GIMP_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
}
+
+/* Protected functions. */
+
void
gimp_core_app_finalize (GObject *object)
{
- GimpCoreAppPrivate *private = gimp_core_app_get_private ((GimpCoreApp *) object);
+ g_object_set_qdata (object,
+ g_quark_from_static_string ("gimp-core-app-private"),
+ NULL);
+}
+
+/**
+ * gimp_container_view_install_properties:
+ * @klass: the class structure for a type deriving from #GObject
+ *
+ * Installs the necessary properties for a class implementing
+ * #GimpCoreApp. Please call this function in the *_class_init()
+ * function of the child class.
+ **/
+void
+gimp_core_app_install_properties (GObjectClass *klass)
+{
+ g_object_class_override_property (klass, GIMP_CORE_APP_PROP_GIMP, "gimp");
+ g_object_class_override_property (klass, GIMP_CORE_APP_PROP_FILENAMES, "filenames");
+ g_object_class_override_property (klass, GIMP_CORE_APP_PROP_AS_NEW, "as-new");
+
+ g_object_class_override_property (klass, GIMP_CORE_APP_PROP_QUIT, "quit");
+ g_object_class_override_property (klass, GIMP_CORE_APP_PROP_BATCH_INTERPRETER, "batch-interpreter");
+ g_object_class_override_property (klass, GIMP_CORE_APP_PROP_BATCH_COMMANDS, "batch-commands");
+}
+
+void
+gimp_core_app_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GimpCoreAppPrivate *private;
+
+ private = GIMP_CORE_APP_GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case GIMP_CORE_APP_PROP_GIMP:
+ private->gimp = g_value_get_object (value);
+ break;
+ case GIMP_CORE_APP_PROP_FILENAMES:
+ private->filenames = g_value_dup_boxed (value);
+ break;
+ case GIMP_CORE_APP_PROP_AS_NEW:
+ private->as_new = g_value_get_boolean (value);
+ break;
+ case GIMP_CORE_APP_PROP_QUIT:
+ private->quit = g_value_get_boolean (value);
+ break;
+ case GIMP_CORE_APP_PROP_BATCH_INTERPRETER:
+ private->batch_interpreter = g_value_dup_string (value);
+ break;
+ case GIMP_CORE_APP_PROP_BATCH_COMMANDS:
+ private->batch_commands = g_value_dup_boxed (value);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
+}
+
+void
+gimp_core_app_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GimpCoreAppPrivate *private;
- gimp_core_app_private_finalize (private);
+ private = GIMP_CORE_APP_GET_PRIVATE (object);
+
+ switch (property_id)
+ {
+ case GIMP_CORE_APP_PROP_GIMP:
+ g_value_set_object (value, private->gimp);
+ break;
+ case GIMP_CORE_APP_PROP_FILENAMES:
+ g_value_set_static_boxed (value, private->filenames);
+ break;
+ case GIMP_CORE_APP_PROP_AS_NEW:
+ g_value_set_boolean (value, private->as_new);
+ break;
+ case GIMP_CORE_APP_PROP_QUIT:
+ g_value_set_boolean (value, private->quit);
+ break;
+ case GIMP_CORE_APP_PROP_BATCH_INTERPRETER:
+ g_value_set_static_string (value, private->batch_interpreter);
+ break;
+ case GIMP_CORE_APP_PROP_BATCH_COMMANDS:
+ g_value_set_static_boxed (value, private->batch_commands);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
+ break;
+ }
}
+
+/* Public functions. */
+
Gimp *
gimp_core_app_get_gimp (GimpCoreApp *self)
{
@@ -116,7 +237,7 @@ gimp_core_app_get_as_new (GimpCoreApp *self)
return private->as_new;
}
-const char **
+const gchar **
gimp_core_app_get_filenames (GimpCoreApp *self)
{
GimpCoreAppPrivate *private;
@@ -125,10 +246,10 @@ gimp_core_app_get_filenames (GimpCoreApp *self)
private = GIMP_CORE_APP_GET_PRIVATE (self);
- return private->filenames;
+ return (const gchar **) private->filenames;
}
-const char *
+const gchar *
gimp_core_app_get_batch_interpreter (GimpCoreApp *self)
{
GimpCoreAppPrivate *private;
@@ -137,10 +258,10 @@ gimp_core_app_get_batch_interpreter (GimpCoreApp *self)
private = GIMP_CORE_APP_GET_PRIVATE (self);
- return private->batch_interpreter;
+ return (const gchar *) private->batch_interpreter;
}
-const char **
+const gchar **
gimp_core_app_get_batch_commands (GimpCoreApp *self)
{
GimpCoreAppPrivate *private;
@@ -149,7 +270,7 @@ gimp_core_app_get_batch_commands (GimpCoreApp *self)
private = GIMP_CORE_APP_GET_PRIVATE (self);
- return private->batch_commands;
+ return (const gchar **) private->batch_commands;
}
void
@@ -176,39 +297,8 @@ gimp_core_app_get_exit_status (GimpCoreApp *self)
return private->exit_status;
}
-void
-gimp_core_app_set_values(GimpCoreApp *self,
- Gimp *gimp,
- gboolean quit,
- gboolean as_new,
- const gchar **filenames,
- const gchar *batch_interpreter,
- const gchar **batch_commands)
-{
- GimpCoreAppPrivate *private;
-
- g_return_if_fail (GIMP_IS_CORE_APP (self));
-
- private = GIMP_CORE_APP_GET_PRIVATE (self);
-
- private->gimp = gimp;
- private->quit = quit;
- private->as_new = as_new;
- private->filenames = filenames;
- private->batch_interpreter = batch_interpreter;
- private->batch_commands = batch_commands;
-}
-
/* Private functions */
-static void
-gimp_core_app_private_finalize (GimpCoreAppPrivate *private)
-{
- g_slice_free (GimpCoreAppPrivate, private);
-
- g_clear_object (&private->gimp);
-}
-
static GimpCoreAppPrivate *
gimp_core_app_get_private (GimpCoreApp *app)
{
@@ -229,11 +319,17 @@ gimp_core_app_get_private (GimpCoreApp *app)
g_object_set_qdata_full ((GObject *) app, private_key, private,
(GDestroyNotify) gimp_core_app_private_finalize);
-
- /* g_signal_connect (view, "destroy",
- G_CALLBACK (gimp_core_app_private_dispose),
- private); */
}
return private;
}
+
+static void
+gimp_core_app_private_finalize (GimpCoreAppPrivate *private)
+{
+ g_clear_pointer (&private->filenames, g_strfreev);
+ g_clear_pointer (&private->batch_interpreter, g_free);
+ g_clear_pointer (&private->batch_commands, g_strfreev);
+
+ g_slice_free (GimpCoreAppPrivate, private);
+}
diff --git a/app/gimpcoreapp.h b/app/gimpcoreapp.h
index 5967adbdf6..88153d6f89 100644
--- a/app/gimpcoreapp.h
+++ b/app/gimpcoreapp.h
@@ -15,14 +15,24 @@
* <https://www.gnu.org/licenses/>.
*/
-#pragma once
+#ifndef __GIMP_CORE_APP_H__
+#define __GIMP_CORE_APP_H__
-#include <gio/gio.h>
+G_BEGIN_DECLS
-#include "core/core-types.h"
-#include "core/gimp.h"
+enum
+{
+ GIMP_CORE_APP_PROP_0,
+ GIMP_CORE_APP_PROP_GIMP,
+ GIMP_CORE_APP_PROP_FILENAMES,
+ GIMP_CORE_APP_PROP_AS_NEW,
-G_BEGIN_DECLS
+ GIMP_CORE_APP_PROP_QUIT,
+ GIMP_CORE_APP_PROP_BATCH_INTERPRETER,
+ GIMP_CORE_APP_PROP_BATCH_COMMANDS,
+
+ GIMP_CORE_APP_PROP_LAST = GIMP_CORE_APP_PROP_BATCH_COMMANDS,
+};
#define GIMP_TYPE_CORE_APP gimp_core_app_get_type()
G_DECLARE_INTERFACE (GimpCoreApp, gimp_core_app, GIMP, CORE_APP, GObject)
@@ -31,23 +41,6 @@ struct _GimpCoreAppInterface
{
GTypeInterface parent_iface;
- Gimp * (*get_gimp) (GimpCoreApp *self);
- gboolean (*get_quit) (GimpCoreApp *self);
- gboolean (*get_as_new) (GimpCoreApp *self);
- const char ** (*get_filenames) (GimpCoreApp *self);
- const char * (*get_batch_interpreter) (GimpCoreApp *self);
- const char ** (*get_batch_commands) (GimpCoreApp *self);
- void (*set_exit_status) (GimpCoreApp *self,
- gint exit_status);
- gint (*get_exit_status) (GimpCoreApp *self);
- void (*set_values) (GimpCoreApp *self,
- Gimp *gimp,
- gboolean quit,
- gboolean as_new,
- const char **filenames,
- const char *batch_interpreter,
- const char **batch_commands);
-
/* Padding to allow adding up to 12 new virtual functions without
* breaking ABI. */
gpointer padding[12];
@@ -61,23 +54,31 @@ gboolean gimp_core_app_get_quit (GimpCoreApp *self);
gboolean gimp_core_app_get_as_new (GimpCoreApp *self);
-const char ** gimp_core_app_get_filenames (GimpCoreApp *self);
+const gchar ** gimp_core_app_get_filenames (GimpCoreApp *self);
-const char * gimp_core_app_get_batch_interpreter (GimpCoreApp *self);
+const gchar * gimp_core_app_get_batch_interpreter (GimpCoreApp *self);
-const char ** gimp_core_app_get_batch_commands (GimpCoreApp *self);
+const gchar ** gimp_core_app_get_batch_commands (GimpCoreApp *self);
void gimp_core_app_set_exit_status (GimpCoreApp *self,
gint exit_status);
gboolean gimp_core_app_get_exit_status (GimpCoreApp *self);
-void gimp_core_app_set_values (GimpCoreApp *self,
- Gimp *gimp,
- gboolean quit,
- gboolean as_new,
- const char **filenames,
- const char *batch_interpreter,
- const char **batch_commands);
+
+/* Protected functions. */
+
+void gimp_core_app_install_properties (GObjectClass *klass);
+void gimp_core_app_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+void gimp_core_app_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
G_END_DECLS
+
+#endif /* __GIMP_CORE_APP_H__ */
diff --git a/app/gui/gimpapp.c b/app/gui/gimpapp.c
index 98b9afa541..cb1274d4ca 100644
--- a/app/gui/gimpapp.c
+++ b/app/gui/gimpapp.c
@@ -16,10 +16,25 @@
#include <config.h>
-#include "gimpapp.h"
+#include <gtk/gtk.h>
#include "libgimpbase/gimpbase.h"
+#include "core/core-types.h"
+
+#include "core/gimp.h"
+
+#include "gimpcoreapp.h"
+
+#include "gimpapp.h"
+
+
+enum
+{
+ PROP_0,
+ PROP_NO_SPLASH = GIMP_CORE_APP_PROP_LAST + 1,
+};
+
struct _GimpApp
{
GtkApplication parent_instance;
@@ -27,9 +42,20 @@ struct _GimpApp
gboolean no_splash;
};
+
+static void gimp_app_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec);
+static void gimp_app_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec);
+
+
G_DEFINE_TYPE_WITH_CODE (GimpApp, gimp_app, GTK_TYPE_APPLICATION,
G_IMPLEMENT_INTERFACE (GIMP_TYPE_CORE_APP,
- gimp_app_class_init))
+ NULL))
static void
@@ -38,6 +64,16 @@ gimp_app_class_init (GimpAppClass *klass)
GObjectClass *gobj_class = G_OBJECT_CLASS (klass);
gobj_class->finalize = gimp_core_app_finalize;
+ gobj_class->get_property = gimp_app_get_property;
+ gobj_class->set_property = gimp_app_set_property;
+
+ gimp_core_app_install_properties (gobj_class);
+
+ g_object_class_install_property (gobj_class, PROP_NO_SPLASH,
+ g_param_spec_boolean ("no-splash", NULL, NULL,
+ FALSE,
+ GIMP_PARAM_READWRITE |
+ G_PARAM_CONSTRUCT_ONLY));
}
static void
@@ -45,6 +81,42 @@ gimp_app_init (GimpApp *self)
{
}
+static void
+gimp_app_get_property (GObject *object,
+ guint property_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case PROP_NO_SPLASH:
+ g_value_set_boolean (value, GIMP_APP (object)->no_splash);
+ break;
+
+ default:
+ gimp_core_app_get_property (object, property_id, value, pspec);
+ break;
+ }
+}
+
+static void
+gimp_app_set_property (GObject *object,
+ guint property_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ switch (property_id)
+ {
+ case PROP_NO_SPLASH:
+ GIMP_APP (object)->no_splash = g_value_get_boolean (value);
+ break;
+
+ default:
+ gimp_core_app_set_property (object, property_id, value, pspec);
+ break;
+ }
+}
+
/* public functions */
GApplication *
@@ -58,15 +130,17 @@ gimp_app_new (Gimp *gimp,
{
GimpApp *app;
- app = g_object_new (GIMP_TYPE_APP, NULL);
+ app = g_object_new (GIMP_TYPE_APP,
+ "gimp", gimp,
+ "filenames", filenames,
+ "as-new", as_new,
- /* We shouldn't have to pass these externally, so I didn't bother making
- * GObject properties for them. In the end, they should just be parsed by
- * the GApplication code */
- app->no_splash = no_splash;
+ "quit", quit,
+ "batch-interpreter", batch_interpreter,
+ "batch-commands", batch_commands,
- gimp_core_app_set_values(GIMP_CORE_APP(app), gimp, quit, as_new, filenames,
- batch_interpreter, batch_commands);
+ "no-splash", no_splash,
+ NULL);
return G_APPLICATION (app);
}
diff --git a/app/gui/gimpapp.h b/app/gui/gimpapp.h
index bf4cb18068..c60c76753b 100644
--- a/app/gui/gimpapp.h
+++ b/app/gui/gimpapp.h
@@ -1,4 +1,3 @@
-
/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
@@ -18,9 +17,6 @@
#ifndef __GIMP_APP_H__
#define __GIMP_APP_H__
-#include <gtk/gtk.h>
-
-#include "gimpcoreapp.h"
#define GIMP_TYPE_APP (gimp_app_get_type ())
G_DECLARE_FINAL_TYPE (GimpApp, gimp_app, GIMP, APP, GtkApplication)
diff --git a/app/gui/gui-types.h b/app/gui/gui-types.h
index 82e9f20ea5..294192c652 100644
--- a/app/gui/gui-types.h
+++ b/app/gui/gui-types.h
@@ -23,5 +23,6 @@
#include "dialogs/dialogs-types.h"
#include "menus/menus-types.h"
+#include "gimpapp.h"
#endif /* __GUI_TYPES_H__ */
diff --git a/app/gui/gui.c b/app/gui/gui.c
index bf4b099fac..1538cf9790 100644
--- a/app/gui/gui.c
+++ b/app/gui/gui.c
@@ -27,6 +27,7 @@
#include "libgimpwidgets/gimpwidgets-private.h"
#include "gui-types.h"
+#include "gimpapp.h"
#include "config/gimpguiconfig.h"
diff --git a/app/gui/gui.h b/app/gui/gui.h
index e64f5fa1d9..8bfdb312b3 100644
--- a/app/gui/gui.h
+++ b/app/gui/gui.h
@@ -18,7 +18,6 @@
#ifndef __GUI_H__
#define __GUI_H__
-#include "gimpapp.h"
void gui_libs_init (GOptionContext *context);
void gui_abort (const gchar *abort_message);
diff --git a/app/gui/splash.h b/app/gui/splash.h
index 51e8af63de..9f18e02ea1 100644
--- a/app/gui/splash.h
+++ b/app/gui/splash.h
@@ -18,8 +18,6 @@
#ifndef __SPLASH_H__
#define __SPLASH_H__
-#include "gimpapp.h"
-
void splash_create (Gimp *gimp,
gboolean be_verbose,
GdkMonitor *monitor,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]