[nautilus-actions] Review construction process
- From: Pierre Wieser <pwieser src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [nautilus-actions] Review construction process
- Date: Wed, 11 Jan 2012 22:10:09 +0000 (UTC)
commit 44c15ac03615b8fb39b9e6454f5f2742f98107a2
Author: Pierre Wieser <pwieser trychlos org>
Date: Sun Jan 8 18:46:57 2012 +0100
Review construction process
ChangeLog | 12 ++
src/nact/base-application.c | 258 +++++++++++++++++--------------------------
src/nact/base-application.h | 122 +++++++++++++-------
src/nact/base-window.c | 93 ++++++++++++----
src/nact/base-window.h | 61 ++++------
src/nact/nact-application.c | 72 +++++++++---
6 files changed, 340 insertions(+), 278 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index 1fc6406..4aac6d8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,17 @@
2012-01-08 Pierre Wieser <pwieser trychlos org>
+ * src/nact/base-application.c:
+ * src/nact/base-application.h
+ (base_application_get_builder): Removed function.
+ Implements BaseIUnique interface.
+
+ * src/nact/base-window.c:
+ * src/nact/base-window.h:
+ Have a common builder at class level.
+ Gtk toplevel and BaseWindow are initialized when instance is constructed.
+
+ * src/nact/nact-application.c: Updated accordingly.
+
* src/nact/base-iunique.c:
* src/nact/base-iunique.h (base_iunique_init_with_name):
Function renamed from base_iunique_init_name().
diff --git a/src/nact/base-application.c b/src/nact/base-application.c
index d5667ea..b631242 100644
--- a/src/nact/base-application.c
+++ b/src/nact/base-application.c
@@ -34,10 +34,9 @@
#include <glib/gi18n.h>
#include <string.h>
-#include <unique/unique.h>
#include "base-application.h"
-#include "base-window.h"
+#include "base-iunique.h"
#include "egg-sm-client.h"
/* private class data
@@ -67,9 +66,6 @@ struct _BaseApplicationPrivate {
EggSMClient *sm_client;
gulong sm_client_quit_handler_id;
gulong sm_client_quit_requested_handler_id;
- BaseBuilder *builder;
- BaseWindow *main_window;
- UniqueApp *unique_app_handle;
};
/* instance properties
@@ -93,6 +89,8 @@ static GObjectClass *st_parent_class = NULL;
static GType register_type( void );
static void class_init( BaseApplicationClass *klass );
+static void iunique_iface_init( BaseIUniqueInterface *iface, void *user_data );
+static const gchar *iunique_get_application_name( const BaseIUnique *instance );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec );
static void instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec );
@@ -102,16 +100,14 @@ static void instance_finalize( GObject *application );
static gboolean init_i18n( BaseApplication *application );
static gboolean init_application_name( BaseApplication *application );
static gboolean init_gtk( BaseApplication *application );
-static gboolean v_manage_options( const BaseApplication *application );
-static gboolean init_unique_app( BaseApplication *application );
-#if 0
-static UniqueResponse on_unique_message_received( UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data );
-#endif
+static gboolean v_manage_options( BaseApplication *application );
+static gboolean init_unique_manager( BaseApplication *application );
static gboolean init_session_manager( BaseApplication *application );
static void session_manager_client_quit_cb( EggSMClient *client, BaseApplication *application );
static void session_manager_client_quit_requested_cb( EggSMClient *client, BaseApplication *application );
static gboolean init_icon_name( BaseApplication *application );
-static gboolean init_builder( BaseApplication *application );
+static gboolean v_init_application( BaseApplication *application );
+static gboolean v_create_windows( BaseApplication *application );
GType
base_application_get_type( void )
@@ -143,12 +139,20 @@ register_type( void )
( GInstanceInitFunc ) instance_init
};
+ static const GInterfaceInfo iunique_iface_info = {
+ ( GInterfaceInitFunc ) iunique_iface_init,
+ NULL,
+ NULL
+ };
+
g_debug( "%s", thisfn );
g_type_init();
type = g_type_register_static( G_TYPE_OBJECT, "BaseApplication", &info, 0 );
+ g_type_add_interface_static( type, BASE_IUNIQUE_TYPE, &iunique_iface_info );
+
return( type );
}
@@ -171,70 +175,90 @@ class_init( BaseApplicationClass *klass )
g_object_class_install_property( object_class, BASE_PROP_ARGC_ID,
g_param_spec_int(
BASE_PROP_ARGC,
- "Arguments count",
- "The count of command-line arguments",
+ _( "Arguments count" ),
+ _( "The count of command-line arguments" ),
0, 65535, 0,
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_ARGV_ID,
g_param_spec_boxed(
BASE_PROP_ARGV,
- "Arguments",
- "The array of command-line arguments",
+ _( "Arguments" ),
+ _( "The array of command-line arguments" ),
G_TYPE_STRV,
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_OPTIONS_ID,
g_param_spec_pointer(
BASE_PROP_OPTIONS,
- "Option entries",
- "The array of command-line option definitions",
+ _( "Option entries" ),
+ _( "The array of command-line option definitions" ),
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_APPLICATION_NAME_ID,
g_param_spec_string(
BASE_PROP_APPLICATION_NAME,
- "Application name",
- "The name of the application",
+ _( "Application name" ),
+ _( "The name of the application" ),
"",
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_DESCRIPTION_ID,
g_param_spec_string(
BASE_PROP_DESCRIPTION,
- "Description",
- "A short description to be displayed in the first line of --help output",
+ _( "Description" ),
+ _( "A short description to be displayed in the first line of --help output" ),
"",
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_ICON_NAME_ID,
g_param_spec_string(
BASE_PROP_ICON_NAME,
- "Icon name",
- "The name of the icon of the application",
+ _( "Icon name" ),
+ _( "The name of the icon of the application" ),
"",
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_UNIQUE_NAME_ID,
g_param_spec_string(
BASE_PROP_UNIQUE_NAME,
- "UniqueApp name",
- "The Unique name of the application",
+ _( "UniqueApp name" ),
+ _( "The Unique name of the application" ),
"",
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_CODE_ID,
g_param_spec_int(
BASE_PROP_CODE,
- "Return code",
- "The return code of the application",
- 0, 127, 0,
+ _( "Return code" ),
+ _( "The return code of the application" ),
+ -127, 127, 0,
G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
klass->private = g_new0( BaseApplicationClassPrivate, 1 );
klass->manage_options = NULL;
- klass->main_window_new = NULL;
+ klass->init_application = NULL;
+ klass->create_windows = NULL;
+}
+
+static void
+iunique_iface_init( BaseIUniqueInterface *iface, void *user_data )
+{
+ static const gchar *thisfn = "base_application_iunique_iface_init";
+
+ g_debug( "%s: iface=%p, user_data=%p", thisfn, ( void * ) iface, ( void * ) user_data );
+
+ iface->get_application_name = iunique_get_application_name;
+}
+
+static const gchar *
+iunique_get_application_name( const BaseIUnique *instance )
+{
+ g_return_val_if_fail( BASE_IS_IUNIQUE( instance ), NULL );
+ g_return_val_if_fail( BASE_IS_APPLICATION( instance ), NULL );
+
+ return( BASE_APPLICATION( instance )->private->application_name );
}
static void
@@ -378,14 +402,6 @@ instance_dispose( GObject *application )
self->private->dispose_has_run = TRUE;
- if( UNIQUE_IS_APP( self->private->unique_app_handle )){
- g_object_unref( self->private->unique_app_handle );
- }
-
- if( GTK_IS_BUILDER( self->private->builder )){
- g_object_unref( self->private->builder );
- }
-
if( self->private->sm_client_quit_handler_id &&
g_signal_handler_is_connected( self->private->sm_client, self->private->sm_client_quit_handler_id )){
g_signal_handler_disconnect( self->private->sm_client, self->private->sm_client_quit_handler_id );
@@ -453,7 +469,9 @@ base_application_run( BaseApplication *application, int argc, GStrv argv )
{
static const gchar *thisfn = "base_application_run";
BaseApplicationPrivate *priv;
+#if 0
GtkWindow *gtk_toplevel;
+#endif
g_return_val_if_fail( BASE_IS_APPLICATION( application ), BASE_EXIT_CODE_START_FAIL );
@@ -468,46 +486,22 @@ base_application_run( BaseApplication *application, int argc, GStrv argv )
priv->argc = argc;
priv->argv = g_strdupv( argv );
+#if 0
priv->main_window = NULL;
+#endif
priv->code = BASE_EXIT_CODE_OK;
if( init_i18n( application ) &&
init_application_name( application ) &&
init_gtk( application ) &&
v_manage_options( application ) &&
- init_unique_app( application ) &&
+ init_unique_manager( application ) &&
init_session_manager( application ) &&
init_icon_name( application ) &&
- init_builder( application )){
-
-
- if( BASE_APPLICATION_GET_CLASS( application )->main_window_new ){
- priv->main_window =
- ( BaseWindow * ) BASE_APPLICATION_GET_CLASS( application )->main_window_new( application, &priv->code );
- } else {
- priv->code = BASE_EXIT_CODE_MAIN_WINDOW;
- }
-
- if( priv->main_window ){
- g_return_val_if_fail( BASE_IS_WINDOW( priv->main_window ), BASE_EXIT_CODE_START_FAIL );
+ v_init_application( application ) &&
+ v_create_windows( application )){
- if( base_window_init( priv->main_window )){
- gtk_toplevel = base_window_get_gtk_toplevel( priv->main_window );
- g_return_val_if_fail( gtk_toplevel, BASE_EXIT_CODE_START_FAIL );
- g_return_val_if_fail( GTK_IS_WINDOW( gtk_toplevel ), BASE_EXIT_CODE_START_FAIL );
-
- if( priv->unique_app_handle ){
- unique_app_watch_window( priv->unique_app_handle, gtk_toplevel );
- }
-
- g_debug( "%s: invoking base_window_run", thisfn );
- priv->code = base_window_run( priv->main_window );
-
- } else {
- g_debug( "%s: base_window_init has returned FALSE", thisfn );
- priv->code = BASE_EXIT_CODE_INIT_FAIL;
- }
- }
+ gtk_main();
}
}
@@ -620,7 +614,7 @@ init_gtk( BaseApplication *application )
}
static gboolean
-v_manage_options( const BaseApplication *application )
+v_manage_options( BaseApplication *application )
{
static const gchar *thisfn = "base_application_v_manage_options";
gboolean ret;
@@ -637,79 +631,27 @@ v_manage_options( const BaseApplication *application )
}
/*
- * Relying on libunique to detect another instance already running.
- *
- * A replacement is available with GLib 2.28 in GApplication, but only
- * GLib 2.30 (Fedora 16) provides a "non-unique" property.
+ * Initialize BaseIUnique interface for the instance
*/
static gboolean
-init_unique_app( BaseApplication *application )
+init_unique_manager( BaseApplication *application )
{
- static const gchar *thisfn = "base_application_init_unique_app";
+ static const gchar *thisfn = "base_application_init_unique_manager";
gboolean ret;
- BaseApplicationPrivate *priv;
- gboolean is_first;
- gchar *msg;
g_debug( "%s: application=%p", thisfn, ( void * ) application );
- ret = TRUE;
- priv = application->private;
+ ret = base_iunique_init_with_name(
+ BASE_IUNIQUE( application ),
+ application->private->unique_app_name );
- if( priv->unique_app_name && strlen( priv->unique_app_name )){
-
- priv->unique_app_handle = unique_app_new( priv->unique_app_name, NULL );
- is_first = !unique_app_is_running( priv->unique_app_handle );
-
- if( !is_first ){
- unique_app_send_message( priv->unique_app_handle, UNIQUE_ACTIVATE, NULL );
- /* i18n: application name */
- msg = g_strdup_printf(
- _( "Another instance of %s is already running.\n"
- "Please switch back to it." ),
- priv->application_name );
- base_window_display_error_dlg( NULL, _( "The application is not unique" ), msg );
- g_free( msg );
- ret = FALSE;
- priv->code = BASE_EXIT_CODE_UNIQUE_APP;
-#if 0
- /* default from libunique is actually to activate the first window
- * so we rely on the default..
- */
- } else {
- g_signal_connect(
- priv->unique_app_handle,
- "message-received",
- G_CALLBACK( on_unique_message_received ),
- application );
-#endif
- }
+ if( !ret ){
+ application->private->code = BASE_EXIT_CODE_UNIQUE_APP;
}
return( ret );
}
-#if 0
-static UniqueResponse
-on_unique_message_received(
- UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data )
-{
- static const gchar *thisfn = "base_application_check_for_unique_app";
- UniqueResponse resp = UNIQUE_RESPONSE_OK;
-
- switch( command ){
- case UNIQUE_ACTIVATE:
- g_debug( "%s: received message UNIQUE_ACTIVATE", thisfn );
- break;
- default:
- resp = UNIQUE_RESPONSE_PASSTHROUGH;
- break;
- }
-
- return( resp );
-}
-#endif
-
/*
* Relying on session manager to have a chance to save the modifications
* before exiting a session
@@ -760,12 +702,14 @@ session_manager_client_quit_cb( EggSMClient *client, BaseApplication *applicatio
g_debug( "%s: client=%p, application=%p", thisfn, ( void * ) client, ( void * ) application );
+#if 0
if( application->private->main_window ){
g_return_if_fail( BASE_IS_WINDOW( application->private->main_window ));
g_object_unref( application->private->main_window );
application->private->main_window = NULL;
}
+#endif
}
}
@@ -784,11 +728,13 @@ session_manager_client_quit_requested_cb( EggSMClient *client, BaseApplication *
g_debug( "%s: client=%p, application=%p", thisfn, ( void * ) client, ( void * ) application );
+#if 0
if( application->private->main_window ){
g_return_if_fail( BASE_IS_WINDOW( application->private->main_window ));
willing_to = base_window_is_willing_to_quit( application->private->main_window );
}
+#endif
}
egg_sm_client_will_quit( client, willing_to );
@@ -821,62 +767,58 @@ init_icon_name( BaseApplication *application )
return( TRUE );
}
-/*
- * allocate a default builder
- */
static gboolean
-init_builder( BaseApplication *application )
+v_init_application( BaseApplication *application )
{
- static const gchar *thisfn = "base_application_init_builder";
+ static const gchar *thisfn = "base_application_v_init_application";
+ gboolean ret;
g_debug( "%s: application=%p", thisfn, ( void * ) application );
- /* allocate the common BaseBuilder instance
- */
- application->private->builder = base_builder_new();
+ ret = TRUE;
- return( TRUE );
+ if( BASE_APPLICATION_GET_CLASS( application )->init_application ){
+ ret = BASE_APPLICATION_GET_CLASS( application )->init_application( application );
+ }
+
+ return( ret );
}
-/**
- * base_application_get_application_name:
- * @application: this #BaseApplication instance.
- *
- * Returns: the application name as a newly allocated string which should
- * be be g_free() by the caller.
- */
-gchar *
-base_application_get_application_name( const BaseApplication *application )
+static gboolean
+v_create_windows( BaseApplication *application )
{
- gchar *name = NULL;
+ static const gchar *thisfn = "base_application_v_create_windows";
+ gboolean ret;
- g_return_val_if_fail( BASE_IS_APPLICATION( application ), NULL );
+ g_debug( "%s: application=%p", thisfn, ( void * ) application );
- if( !application->private->dispose_has_run ){
+ ret = TRUE;
- name = g_strdup( application->private->application_name );
+ if( BASE_APPLICATION_GET_CLASS( application )->create_windows ){
+ ret = BASE_APPLICATION_GET_CLASS( application )->create_windows( application );
}
- return( name );
+ return( ret );
}
/**
- * base_application_get_builder:
+ * base_application_get_application_name:
* @application: this #BaseApplication instance.
*
- * Returns: the default #BaseBuilder object for the application.
+ * Returns: the application name as a newly allocated string which should
+ * be be g_free() by the caller.
*/
-BaseBuilder *
-base_application_get_builder( const BaseApplication *application )
+gchar *
+base_application_get_application_name( const BaseApplication *application )
{
- BaseBuilder *builder = NULL;
+ gchar *name = NULL;
g_return_val_if_fail( BASE_IS_APPLICATION( application ), NULL );
if( !application->private->dispose_has_run ){
- builder = application->private->builder;
+ name = g_strdup( application->private->application_name );
}
- return( builder );
+ return( name );
}
diff --git a/src/nact/base-application.h b/src/nact/base-application.h
index 1970d7e..774d350 100644
--- a/src/nact/base-application.h
+++ b/src/nact/base-application.h
@@ -64,8 +64,8 @@
* </programlisting>
* </example>
*
- * main BaseApplication NactApplication
- * =================== =================== ===================
+ * main BaseApplication NactApplication BaseWindow NactWindow
+ * =================== =================== =================== =================== ===================
* appli = nact_application_new()
* appli = g_object_new()
* set properties
@@ -79,37 +79,49 @@
* init application name
* init gtk with command-line options
* manage command-line options
+ * manage specific command-line options
+ * calling parent class if ok to continue
+ * setting application code else
* init unique manager
+ * unique app name must have been set at this time
+ * application name should have been set at this time
* init session manager
* init icon name
- * init common builder
- * foreach window to display
- * create window
- * create gtk toplevel
- * unique watch toplevel
- * run the window
- * ret = last window return code
+ * create window(s)
+ * foreach window to create
+ * create BaseWindow-derived window
+ * on class init
+ * init common builder
+ * on constructed
+ * load and init gtk toplevel
+ * init window
+ * show gtk toplevel
+ * run window
+ * [...]
+ * run the main loop
+ * must be explicitely quitted by application main window
+ * after having set the application return code
* g_object_unref( appli )
* return( ret )
*
* At any time, a function may preset the exit code of the application just by
- * setting the @BASE_PROP_CODE property. Unless it also asks to quit immediately
- * by returning %FALSE, another function may always set another exit code after
- * that.
+ * setting the @BASE_PROP_CODE property. Note that unless it also asks to quit
+ * immediately by returning %FALSE, another function may always set another exit
+ * code after that.
*/
-#include "base-builder.h"
+#include "glib-object.h"
G_BEGIN_DECLS
-#define BASE_APPLICATION_TYPE ( base_application_get_type())
-#define BASE_APPLICATION( o ) ( G_TYPE_CHECK_INSTANCE_CAST( o, BASE_APPLICATION_TYPE, BaseApplication ))
-#define BASE_APPLICATION_CLASS( k ) ( G_TYPE_CHECK_CLASS_CAST( k, BASE_APPLICATION_TYPE, BaseApplicationClass ))
-#define BASE_IS_APPLICATION( o ) ( G_TYPE_CHECK_INSTANCE_TYPE( o, BASE_APPLICATION_TYPE ))
-#define BASE_IS_APPLICATION_CLASS( k ) ( G_TYPE_CHECK_CLASS_TYPE(( k ), BASE_APPLICATION_TYPE ))
-#define BASE_APPLICATION_GET_CLASS( o ) ( G_TYPE_INSTANCE_GET_CLASS(( o ), BASE_APPLICATION_TYPE, BaseApplicationClass ))
+#define BASE_APPLICATION_TYPE ( base_application_get_type())
+#define BASE_APPLICATION( object ) ( G_TYPE_CHECK_INSTANCE_CAST( object, BASE_APPLICATION_TYPE, BaseApplication ))
+#define BASE_APPLICATION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_CAST( klass, BASE_APPLICATION_TYPE, BaseApplicationClass ))
+#define BASE_IS_APPLICATION( object ) ( G_TYPE_CHECK_INSTANCE_TYPE( object, BASE_APPLICATION_TYPE ))
+#define BASE_IS_APPLICATION_CLASS( klass ) ( G_TYPE_CHECK_CLASS_TYPE(( klass ), BASE_APPLICATION_TYPE ))
+#define BASE_APPLICATION_GET_CLASS( object ) ( G_TYPE_INSTANCE_GET_CLASS(( object ), BASE_APPLICATION_TYPE, BaseApplicationClass ))
-typedef struct _BaseApplicationPrivate BaseApplicationPrivate;
+typedef struct _BaseApplicationPrivate BaseApplicationPrivate;
typedef struct {
/*< private >*/
@@ -118,7 +130,7 @@ typedef struct {
}
BaseApplication;
-typedef struct _BaseApplicationClassPrivate BaseApplicationClassPrivate;
+typedef struct _BaseApplicationClassPrivate BaseApplicationClassPrivate;
/**
* BaseApplicationClass:
@@ -143,30 +155,55 @@ typedef struct {
*
* This let the derived class an opportunity to manage command-line
* arguments. Unless it decides to stop the execution of the program,
- * the derived class should call the parent class method in order to
- * let it manage its own options.
+ * the derived class should call the parent class method (would it be
+ * defined) in order to let it manage its own options.
*
* The derived class may set the exit code of the application by
* setting the @BASE_PROP_CODE property of @appli.
*
* Returns: %TRUE to continue execution, %FALSE to stop it.
*/
- gboolean ( *manage_options ) ( const BaseApplication *appli );
+ gboolean ( *manage_options ) ( BaseApplication *appli );
/**
- * main_window_new:
+ * init_application:
* @appli: this #BaseApplication -derived instance.
*
* This is invoked by the BaseApplication base class to let the derived
- * class do its own initializations and create its main window.
+ * class do its own initializations.
+ *
+ * Versus initializations which occur at instanciation time, this method
+ * let the application terminate its initializatin process, after command-line
+ * arguments have been managed, and before creating any window.
+ *
+ * Unless it decides to stop the execution of the program,
+ * the derived class should call the parent class method (would it be
+ * defined) in order to let it manage its own options.
+ *
+ * The derived class may set the exit code of the application by
+ * setting the @BASE_PROP_CODE property of @appli.
+ *
+ * Returns: %TRUE to continue execution, %FALSE to stop it.
+ */
+ gboolean ( *init_application )( BaseApplication *appli );
+
+ /**
+ * create_windows:
+ * @appli: this #BaseApplication -derived instance.
+ *
+ * This is invoked by the BaseApplication base class to let the derived
+ * class create its startup windows. This may include a spash window,
+ * a main window, some secondary or toolbox windows, and so on.
*
* This is a pure virtual method. Only the most derived class
- * main_window_new() method is invoked.
+ * create_windows() method is invoked.
*
- * Returns: the main window of the application, as a #BaseWindow
- * -derived object. It may or may not have already been initialized.
+ * The derived class may set the exit code of the application by
+ * setting the @BASE_PROP_CODE property of @appli.
+ *
+ * Returns: %TRUE to continue execution, %FALSE to stop it.
*/
- GObject * ( *main_window_new )( const BaseApplication *appli, int *code );
+ gboolean ( *create_windows )( BaseApplication *appli );
}
BaseApplicationClass;
@@ -185,14 +222,14 @@ typedef struct {
* @BASE_PROP_UNIQUE_NAME: unique name of the application (if not empty)
* @BASE_PROP_CODE: return code of the application
*/
-#define BASE_PROP_ARGC "base-application-argc"
-#define BASE_PROP_ARGV "base-application-argv"
-#define BASE_PROP_OPTIONS "base-application-options"
-#define BASE_PROP_APPLICATION_NAME "base-application-name"
-#define BASE_PROP_DESCRIPTION "base-application-description"
-#define BASE_PROP_ICON_NAME "base-application-icon-name"
-#define BASE_PROP_UNIQUE_NAME "base-application-unique-name"
-#define BASE_PROP_CODE "base-application-code"
+#define BASE_PROP_ARGC "base-prop-application-argc"
+#define BASE_PROP_ARGV "base-prop-application-argv"
+#define BASE_PROP_OPTIONS "base-prop-application-options"
+#define BASE_PROP_APPLICATION_NAME "base-prop-application-name"
+#define BASE_PROP_DESCRIPTION "base-prop-application-description"
+#define BASE_PROP_ICON_NAME "base-prop-application-icon-name"
+#define BASE_PROP_UNIQUE_NAME "base-prop-application-unique-name"
+#define BASE_PROP_CODE "base-prop-application-code"
typedef enum {
BASE_EXIT_CODE_START_FAIL = -1,
@@ -200,7 +237,7 @@ typedef enum {
BASE_EXIT_CODE_NO_APPLICATION_NAME, /* no application name has been set by the derived class */
BASE_EXIT_CODE_ARGS, /* unable to interpret command-line options */
BASE_EXIT_CODE_UNIQUE_APP, /* another instance is already running */
- BASE_EXIT_CODE_MAIN_WINDOW,
+ BASE_EXIT_CODE_WINDOW, /* unable to create a startup window */
BASE_EXIT_CODE_INIT_FAIL,
BASE_EXIT_CODE_PROGRAM,
/*
@@ -211,12 +248,11 @@ typedef enum {
}
BaseExitCode;
-GType base_application_get_type( void );
+GType base_application_get_type ( void );
-int base_application_run( BaseApplication *application, int argc, GStrv argv );
+int base_application_run ( BaseApplication *application, int argc, GStrv argv );
-gchar *base_application_get_application_name( const BaseApplication *application );
-BaseBuilder *base_application_get_builder ( const BaseApplication *application );
+gchar *base_application_get_application_name( const BaseApplication *application );
G_END_DECLS
diff --git a/src/nact/base-window.c b/src/nact/base-window.c
index 4f7e982..2831e34 100644
--- a/src/nact/base-window.c
+++ b/src/nact/base-window.c
@@ -39,6 +39,7 @@
#include <core/na-gtk-utils.h>
#include "base-application.h"
+#include "base-builder.h"
#include "base-window.h"
#include "base-gtk-utils.h"
#include "base-marshal.h"
@@ -46,7 +47,7 @@
/* private class data
*/
struct _BaseWindowClassPrivate {
- void *empty; /* so that gcc -pedantic is happy */
+ BaseBuilder *builder; /* common builder */
};
/* private instance data
@@ -120,6 +121,8 @@ static void instance_finalize( GObject *window );
/* initialization process
*/
+static void setup_parent_vs_application( BaseWindow *window );
+static void init_gtk_toplevel( BaseWindow *window );
static gboolean setup_builder( const BaseWindow *window );
static gboolean load_gtk_toplevel( const BaseWindow *window );
static gboolean is_gtk_toplevel_initialized( const BaseWindow *window, GtkWindow *gtk_toplevel );
@@ -195,27 +198,13 @@ class_init( BaseWindowClass *klass )
object_class->dispose = instance_dispose;
object_class->finalize = instance_finalize;
- g_object_class_install_property( object_class, BASE_PROP_PARENT_ID,
- g_param_spec_pointer(
- BASE_PROP_PARENT,
- _( "Parent BaseWindow" ),
- _( "A pointer (not a reference) to the BaseWindow parent of this BaseWindow" ),
- G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
-
- g_object_class_install_property( object_class, BASE_PROP_APPLICATION_ID,
- g_param_spec_pointer(
- BASE_PROP_APPLICATION,
- _( "BaseApplication" ),
- _( "A pointer (not a reference) to the BaseApplication instance" ),
- G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
-
g_object_class_install_property( object_class, BASE_PROP_XMLUI_FILENAME_ID,
g_param_spec_string(
BASE_PROP_XMLUI_FILENAME,
_( "XML UI filename" ),
_( "The filename which contains the XML UI definition" ),
"",
- G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_HAS_OWN_BUILDER_ID,
g_param_spec_boolean(
@@ -223,7 +212,7 @@ class_init( BaseWindowClass *klass )
_( "Has its own GtkBuilder" ),
_( "Whether this BaseWindow reallocates a new GtkBuilder each time it is opened" ),
FALSE,
- G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_TOPLEVEL_NAME_ID,
g_param_spec_string(
@@ -231,7 +220,21 @@ class_init( BaseWindowClass *klass )
_( "Toplevel name" ),
_( "The internal GtkBuildable name of the toplevel window" ),
"",
- G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+ g_object_class_install_property( object_class, BASE_PROP_APPLICATION_ID,
+ g_param_spec_pointer(
+ BASE_PROP_APPLICATION,
+ _( "BaseApplication" ),
+ _( "A pointer (not a reference) to the BaseApplication instance" ),
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
+
+ g_object_class_install_property( object_class, BASE_PROP_PARENT_ID,
+ g_param_spec_pointer(
+ BASE_PROP_PARENT,
+ _( "Parent BaseWindow" ),
+ _( "A pointer (not a reference) to the BaseWindow parent of this BaseWindow" ),
+ G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE ));
g_object_class_install_property( object_class, BASE_PROP_WSP_NAME_ID,
g_param_spec_string(
@@ -243,6 +246,8 @@ class_init( BaseWindowClass *klass )
klass->private = g_new0( BaseWindowClassPrivate, 1 );
+ klass->private->builder = base_builder_new();
+
klass->initialize_gtk_toplevel = do_initialize_gtk_toplevel;
klass->initialize_base_window = do_initialize_base_window;
klass->all_widgets_showed = NULL;
@@ -464,25 +469,66 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
}
}
+/*
+ * it is time here to initialize the Gtk toplevel if this has not already
+ * been done - We do this early in the build process, and this may trigger
+ * some error conditions (mainly if the toplevel name is not found in the
+ * xml ui filename)
+ */
static void
instance_constructed( GObject *window )
{
static const gchar *thisfn = "base_window_instance_constructed";
BaseWindow *self;
+ BaseWindowPrivate *priv;
g_return_if_fail( BASE_IS_WINDOW( window ));
self = BASE_WINDOW( window );
+ priv = self->private;
- if( !self->private->dispose_has_run ){
- g_debug( "%s: window=%p (%s)", thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ));
-
- g_debug( "%s: application=%p", thisfn, ( void * ) self->private->application );
+ if( !priv->dispose_has_run ){
/* chain up to the parent class */
if( G_OBJECT_CLASS( st_parent_class )->constructed ){
G_OBJECT_CLASS( st_parent_class )->constructed( window );
}
+
+ g_debug( "%s: window=%p (%s)", thisfn, ( void * ) window, G_OBJECT_TYPE_NAME( window ));
+
+ setup_parent_vs_application( self );
+ init_gtk_toplevel( self );
+ base_window_run( self );
+
+ }
+}
+
+static void
+setup_parent_vs_application( BaseWindow *window )
+{
+ if( !window->private->application ){
+ g_return_if_fail( window->private->parent );
+ g_return_if_fail( BASE_IS_WINDOW( window->private->parent ));
+
+ window->private->application = window->private->parent->private->application;
+ }
+
+ g_return_if_fail( BASE_IS_APPLICATION( window->private->application ));
+}
+
+static void
+init_gtk_toplevel( BaseWindow *window )
+{
+ if( setup_builder( window ) &
+ load_gtk_toplevel( window )){
+
+ g_return_if_fail( GTK_IS_WINDOW( window->private->gtk_toplevel ));
+
+ if( !is_gtk_toplevel_initialized( window, window->private->gtk_toplevel )){
+
+ g_signal_emit_by_name( window, BASE_SIGNAL_INITIALIZE_GTK, window->private->gtk_toplevel );
+ set_gtk_toplevel_initialized( window, window->private->gtk_toplevel, TRUE );
+ }
}
}
@@ -669,8 +715,7 @@ setup_builder( const BaseWindow *window )
if( window->private->has_own_builder ){
window->private->builder = base_builder_new();
} else {
- g_return_val_if_fail( BASE_IS_APPLICATION( window->private->application ), FALSE );
- window->private->builder = base_application_get_builder( window->private->application );
+ window->private->builder = BASE_WINDOW_GET_CLASS( window )->private->builder;
}
/* load the XML definition from the UI file
diff --git a/src/nact/base-window.h b/src/nact/base-window.h
index 7932f7b..cd11d32 100644
--- a/src/nact/base-window.h
+++ b/src/nact/base-window.h
@@ -37,41 +37,24 @@
* @short_description: the BaseWindow base window class definition
* @include: base-window.h
*
- * This is a base class which encapsulates a Gtk+ windows.
- * It works together with the BaseApplication class to run a Gtk+
- * application.
+ * This is a base class which manages a Gtk+ toplevel.
*
- * Note that two properties of #BaseApplication may be overriden on a
- * per-#BaseWindow basis. These are :
- *
- * - the #GtkBuilder UI manager
- * the application has one global UI manager, but each window may
- * have its own, provided that it is willing to reallocate a new
- * one each time the window is opened.
+ * One global UI manager is allocated at #BaseWindow class level.
+ * Each window may have its own, provided that it is willing to
+ * reinstanciate a new builder each time the window is opened.
*
* Cf. http://bugzilla.gnome.org/show_bug.cgi?id=589746 against
* Gtk+ 2.16 : a GtkFileChooserWidget embedded in a GtkAssistant is
* not displayed when run more than once. As a work-around, reload
- * the XML ui each time we run an assistant !
- *
- * - the filename which handled the window XML definition
- * the application provides with one global default file, but each
- * window may decide to provide its own.
- *
- * Cf. http://bugzilla.gnome.org/show_bug.cgi?id=579345 against
- * GtkBuilder : duplicate ids are no more allowed in a file. But we
- * require this ability to have the same widget definition
- * (ActionsList) in main window and export assistant.
- * As a work-around, we have XML definition of export assistant in
- * its own file.
- * Another work-around could have be to let the IActionsList
- * interface asks from the actual widget name to its implementor...
+ * the XML ui in a new builder each time we run an assistant !
*
- * Note also that having its own builder implies loading in it the required
- * XML file which holds the needed UI definition, and so even it this
+ * Note that having its own builder implies loading in it the required
+ * XML file which holds the needed UI definition, and so even if this
* same XML file has already been load in the common builder.
*/
+#include <gtk/gtk.h>
+
#include "base-application.h"
G_BEGIN_DECLS
@@ -192,13 +175,19 @@ typedef struct {
/**
* Properties defined by the BaseWindow class.
* They should be provided at object instanciation time.
+ *
+ * Either PARENT or APPLICATION must be provided at instanciation time.
+ * Instanciation time also requires:
+ * - XMLUI_FILENAME
+ * - TOPLEVEL_NAME
+ * - HAS_OWN_BUILDER
*/
-#define BASE_PROP_PARENT "base-window-parent"
-#define BASE_PROP_APPLICATION "base-window-application"
-#define BASE_PROP_XMLUI_FILENAME "base-window-xmlui-filename"
-#define BASE_PROP_HAS_OWN_BUILDER "base-window-has-own-builder"
-#define BASE_PROP_TOPLEVEL_NAME "base-window-toplevel-name"
-#define BASE_PROP_WSP_NAME "base-window-wsp-name"
+#define BASE_PROP_PARENT "base-prop-window-parent"
+#define BASE_PROP_APPLICATION "base-prop-window-application"
+#define BASE_PROP_XMLUI_FILENAME "base-prop-window-xmlui-filename"
+#define BASE_PROP_HAS_OWN_BUILDER "base-prop-window-has-own-builder"
+#define BASE_PROP_TOPLEVEL_NAME "base-prop-window-toplevel-name"
+#define BASE_PROP_WSP_NAME "base-prop-window-wsp-name"
/**
* Signals defined by the BaseWindow class.
@@ -216,10 +205,10 @@ typedef struct {
* as a signal handler or as a virtual method if it is a class derived from
* BaseWindow.
*/
-#define BASE_SIGNAL_INITIALIZE_GTK "base-window-initialize-gtk"
-#define BASE_SIGNAL_INITIALIZE_WINDOW "base-window-initialize-window"
-#define BASE_SIGNAL_ALL_WIDGETS_SHOWED "base-window-all-widgets-showed"
-#define BASE_SIGNAL_WILLING_TO_QUIT "base-window-willing-to-quit"
+#define BASE_SIGNAL_INITIALIZE_GTK "base-signal-window-initialize-gtk"
+#define BASE_SIGNAL_INITIALIZE_WINDOW "base-signal-window-initialize-window"
+#define BASE_SIGNAL_ALL_WIDGETS_SHOWED "base-signal-window-all-widgets-showed"
+#define BASE_SIGNAL_WILLING_TO_QUIT "base-signal-window-willing-to-quit"
GType base_window_get_type( void );
diff --git a/src/nact/nact-application.c b/src/nact/nact-application.c
index 89064ff..12183cc 100644
--- a/src/nact/nact-application.c
+++ b/src/nact/nact-application.c
@@ -77,8 +77,10 @@ static void class_init( NactApplicationClass *klass );
static void instance_init( GTypeInstance *instance, gpointer klass );
static void instance_dispose( GObject *application );
static void instance_finalize( GObject *application );
-static gboolean appli_manage_options( const BaseApplication *application );
-static GObject *appli_main_window_new( const BaseApplication *application, int *code );
+
+static gboolean appli_manage_options( BaseApplication *application );
+static gboolean appli_init_application( BaseApplication *application );
+static gboolean appli_create_windows( BaseApplication *application );
GType
nact_application_get_type( void )
@@ -136,7 +138,8 @@ class_init( NactApplicationClass *klass )
appli_class = BASE_APPLICATION_CLASS( klass );
appli_class->manage_options = appli_manage_options;
- appli_class->main_window_new = appli_main_window_new;
+ appli_class->init_application = appli_init_application;
+ appli_class->create_windows = appli_create_windows;
}
static void
@@ -231,7 +234,7 @@ nact_application_new( void )
* overriden to manage command-line options
*/
static gboolean
-appli_manage_options( const BaseApplication *application )
+appli_manage_options( BaseApplication *application )
{
static const gchar *thisfn = "nact_application_appli_manage_options";
gboolean ret;
@@ -265,27 +268,62 @@ appli_manage_options( const BaseApplication *application )
}
/*
- * create the main window
+ * initialize the application
*/
-static GObject *
-appli_main_window_new( const BaseApplication *application, int *code )
+static gboolean
+appli_init_application( BaseApplication *application )
{
- static const gchar *thisfn = "nact_application_appli_main_window_new";
- NactApplication *appli;
- NactMainWindow *main_window;
+ static const gchar *thisfn = "nact_application_appli_init_application";
+ gboolean ret;
+ NactApplicationPrivate *priv;
- g_return_val_if_fail( NACT_IS_APPLICATION( application ), NULL );
+ g_return_val_if_fail( NACT_IS_APPLICATION( application ), FALSE );
+
+ g_debug( "%s: application=%p", thisfn, ( void * ) application );
+
+ ret = TRUE;
+ priv = NACT_APPLICATION( application )->private;
+
+ /* create the NAPivot object (loading the plugins and so on)
+ * after having dealt with command-line arguments
+ */
+ priv->updater = na_updater_new();
+ na_pivot_set_loadable( NA_PIVOT( priv->updater ), PIVOT_LOAD_ALL );
+
+ /* call parent class */
+ if( ret && BASE_APPLICATION_CLASS( st_parent_class )->manage_options ){
+ ret = BASE_APPLICATION_CLASS( st_parent_class )->manage_options( application );
+ }
- g_debug( "%s: application=%p, code=%p (%d)", thisfn, ( void * ) application, ( void * ) code, *code );
+ return( ret );
+}
- appli = NACT_APPLICATION( application );
+/*
+ * create application startup windows
+ */
+static gboolean
+appli_create_windows( BaseApplication *application )
+{
+ static const gchar *thisfn = "nact_application_appli_create_windows";
+ gboolean ret;
+ NactMainWindow *window;
- appli->private->updater = na_updater_new();
- na_pivot_set_loadable( NA_PIVOT( appli->private->updater ), PIVOT_LOAD_ALL );
+ g_return_val_if_fail( NACT_IS_APPLICATION( application ), FALSE );
- main_window = nact_main_window_new( appli );
+ g_debug( "%s: application=%p", thisfn, ( void * ) application );
- return( G_OBJECT( main_window ));
+ /* creating main window
+ */
+ window = nact_main_window_new( NACT_APPLICATION( application ));
+ if( window ){
+ g_return_val_if_fail( NACT_IS_MAIN_WINDOW( window ), FALSE );
+ ret = TRUE;
+ } else {
+ ret = FALSE;
+ g_object_set( G_OBJECT( application ), BASE_PROP_CODE, BASE_EXIT_CODE_WINDOW, NULL );
+ }
+
+ return( ret );
}
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]