[nautilus-actions: 1/3] Begin with porting NACT to new object hierarchy
- From: Pierre Wieser <pwieser src gnome org>
- To: svn-commits-list gnome org
- Subject: [nautilus-actions: 1/3] Begin with porting NACT to new object hierarchy
- Date: Thu, 18 Jun 2009 19:53:22 -0400 (EDT)
commit ec204bc9876d50905a0f0caa1ce8333ff2c601b6
Author: Pierre Wieser <pwieser trychlos org>
Date: Fri Jun 19 00:42:12 2009 +0200
Begin with porting NACT to new object hierarchy
ChangeLog | 24 ++
m4/.gitignore | 5 +
src/common/nact-action.c | 93 +++++
src/common/nact-action.h | 5 +
src/common/nact-iio-provider.c | 47 +++
src/common/nact-iio-provider.h | 6 +-
src/common/nact-pivot.c | 99 +++++
src/common/nact-pivot.h | 5 +
src/nact/Makefile.am | 2 +
src/nact/base-application.c | 830 ++++++++++++++++++++++++++++++++++++++++
src/nact/base-application.h | 96 +++++
src/nact/nact-application.c | 244 +++---------
src/nact/nact-application.h | 9 +-
src/nact/nact-main.c | 6 +-
src/nact/nact.c | 142 ++++---
src/nact/nact.h | 3 +-
16 files changed, 1356 insertions(+), 260 deletions(-)
---
diff --git a/ChangeLog b/ChangeLog
index ffcb644..005e898 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2009-06-18 Pierre Wieser <pwieser trychlos org>
+
+ Begin with porting NACT to new object hierarchy.
+
+ * src/common/nact-action.c:
+ * src/common/nact-action.h (nact_action_duplicate,
+ nact_action_get_version, nact_action_get_icon,
+ nact_action_set_new_uuid): New functions.
+
+ * src/common/nact-iio-provider.c:
+ * src/common/nact-iio-provider.h (+nact_iio_provider_write_action):
+ New function.
+
+ * src/common/nact-pivot.c:
+ * src/common/nact-pivot.h (nact_pivot_get_label_sorted_actions,
+ nact_pivot_get_action, nact_pivot_add_action):
+ New functions.
+
+ * src/nact/base-application.c:
+ * src/nact/base-application.h: New base class.
+
+ * src/nact/nact-application.c:
+ * src/nact/nact-application.h: Updated accordingly.
+
2009-06-14 Pierre Wieser <pwieser trychlos org>
* po/POTFILES.in: Add src/nact-application.c.
diff --git a/m4/.gitignore b/m4/.gitignore
index 9f841b0..55eaa80 100644
--- a/m4/.gitignore
+++ b/m4/.gitignore
@@ -1 +1,6 @@
intltool.m4
+libtool.m4
+ltoptions.m4
+ltsugar.m4
+ltversion.m4
+lt~obsolete.m4
diff --git a/src/common/nact-action.c b/src/common/nact-action.c
index d81ee66..95f6bd2 100644
--- a/src/common/nact-action.c
+++ b/src/common/nact-action.c
@@ -33,6 +33,7 @@
#endif
#include <string.h>
+#include <uuid/uuid.h>
#include "nact-action.h"
#include "nact-action-profile.h"
@@ -325,6 +326,39 @@ nact_action_new( const gchar *uuid )
return( action );
}
+/**
+ * Allocates a new NactAction object, and initializes it as an exact
+ * copy of the specified action.
+ *
+ * @action: the action to be duplicated.
+ *
+ * Return a newly allocated NactAction object.
+ *
+ * Please note than "an exact copy" here means that the newly allocated
+ * returned object has the _same_ UUID than the original one.
+ */
+NactAction *
+nact_action_duplicate( const NactAction *action )
+{
+ g_assert( NACT_IS_ACTION( action ));
+
+ gchar *uuid = do_get_id( NACT_OBJECT( action ));
+ NactAction *duplicate = g_object_new( NACT_ACTION_TYPE, PROP_UUID_STR, uuid, NULL );
+ g_free( uuid );
+
+ duplicate->private->version = g_strdup( action->private->version );
+ duplicate->private->label = g_strdup( action->private->label );
+ duplicate->private->tooltip = g_strdup( action->private->tooltip );
+ duplicate->private->icon = g_strdup( action->private->icon );
+
+ GSList *ip;
+ for( ip = action->private->profiles ; ip ; ip = ip->next ){
+
+ }
+
+ return( duplicate );
+}
+
static void
do_dump( const NactObject *action )
{
@@ -376,6 +410,28 @@ nact_action_get_uuid( const NactAction *action )
return( nact_object_get_id( NACT_OBJECT( action )));
}
+/**
+ * Returns the version attached to the action.
+ *
+ * @action: an NactAction object.
+ *
+ * The returned string must be g_freed by the caller.
+ *
+ * The version is always upgraded to the latest when the action is
+ * readen from the I/O provider. So we could assert here that the
+ * returned version is also the latest.
+ */
+gchar *
+nact_action_get_version( const NactAction *action )
+{
+ g_assert( NACT_IS_ACTION( action ));
+
+ gchar *version;
+ g_object_get( G_OBJECT( action ), PROP_VERSION_STR, &version, NULL );
+
+ return( version );
+}
+
static gchar *
do_get_label( const NactObject *action )
{
@@ -421,6 +477,25 @@ nact_action_get_tooltip( const NactAction *action )
}
/**
+ * Returns the name of the icon attached to the context menu item for
+ * the action.
+ *
+ * @action: an NactAction object.
+ *
+ * The returned string must be g_freed by the caller.
+ */
+gchar *
+nact_action_get_icon( const NactAction *action )
+{
+ g_assert( NACT_IS_ACTION( action ));
+
+ gchar *icon;
+ g_object_get( G_OBJECT( action ), PROP_ICON_STR, &icon, NULL );
+
+ return( icon );
+}
+
+/**
* Returns the icon name attached to the context menu item for the
* action.
*
@@ -450,6 +525,24 @@ nact_action_get_verified_icon_name( const NactAction *action )
}
/**
+ * Set a new UUID for the action.
+ *
+ * @action: action whose UUID is to be set.
+ */
+void
+nact_action_set_new_uuid( NactAction *action )
+{
+ g_assert( NACT_IS_ACTION( action ));
+ uuid_t uuid;
+ gchar uuid_str[64];
+
+ uuid_generate( uuid );
+ uuid_unparse_lower( uuid, uuid_str );
+
+ g_object_set( G_OBJECT( action ), PROP_UUID_STR, uuid_str, NULL );
+}
+
+/**
* Returns the list of profiles of the actions as a GSList of
* NactActionProfile GObjects.
*
diff --git a/src/common/nact-action.h b/src/common/nact-action.h
index 4b073a9..01e4107 100644
--- a/src/common/nact-action.h
+++ b/src/common/nact-action.h
@@ -70,12 +70,17 @@ typedef struct {
GType nact_action_get_type( void );
NactAction *nact_action_new( const gchar *uuid );
+NactAction *nact_action_duplicate( const NactAction *action );
gchar *nact_action_get_uuid( const NactAction *action );
+gchar *nact_action_get_version( const NactAction *action );
gchar *nact_action_get_label( const NactAction *action );
gchar *nact_action_get_tooltip( const NactAction *action );
+gchar *nact_action_get_icon( const NactAction *action );
gchar *nact_action_get_verified_icon_name( const NactAction *action );
+void nact_action_set_new_uuid( NactAction *action );
+
GSList *nact_action_get_profiles( const NactAction *action );
void nact_action_set_profiles( NactAction *action, GSList *list );
void nact_action_free_profiles( GSList *list );
diff --git a/src/common/nact-iio-provider.c b/src/common/nact-iio-provider.c
index 048e4f2..14d5d69 100644
--- a/src/common/nact-iio-provider.c
+++ b/src/common/nact-iio-provider.c
@@ -32,6 +32,10 @@
#include <config.h>
#endif
+#include <glib.h>
+
+#include "nact-action.h"
+#include "nact-action-profile.h"
#include "nact-iio-provider.h"
#include "nact-pivot.h"
@@ -152,3 +156,46 @@ nact_iio_provider_load_actions( const GObject *object )
return( actions );
}
+
+/**
+ * Writes an action to a willing-to storage subsystem.
+ *
+ * @obj_pivot: the pivot object which owns the list of registered
+ * interface providers.
+ *
+ * @obj_action: the action to be written.
+ *
+ * @message: the I/O provider can allocate and store here an error
+ * message.
+ *
+ * Returns TRUE if the write is successfull, FALSE else.
+ */
+gboolean
+nact_iio_provider_write_action( const GObject *obj_pivot, const GObject *obj_action, gchar **message )
+{
+ static const gchar *thisfn = "nact_iio_provider_write_action";
+ g_debug( "%s", thisfn );
+
+ g_assert( NACT_IS_PIVOT( obj_pivot ));
+ NactPivot *pivot = NACT_PIVOT( obj_pivot );
+
+ g_assert( NACT_IS_ACTION( obj_action ));
+
+ gboolean ret = TRUE;
+ GSList *ip;
+ NactIIOProvider *instance;
+
+ GSList *providers = nact_pivot_get_providers( pivot, NACT_IIO_PROVIDER_TYPE );
+
+ for( ip = providers ; ip ; ip = ip->next ){
+
+ instance = NACT_IIO_PROVIDER( ip->data );
+
+ /*if( NACT_IIO_PROVIDER_GET_INTERFACE( instance )->write_action ){
+ list = NACT_IIO_PROVIDER_GET_INTERFACE( instance )->load_actions( instance );
+ actions = g_slist_concat( actions, list );
+ }*/
+ }
+
+ return( ret );
+}
diff --git a/src/common/nact-iio-provider.h b/src/common/nact-iio-provider.h
index b58697b..1d747e4 100644
--- a/src/common/nact-iio-provider.h
+++ b/src/common/nact-iio-provider.h
@@ -61,12 +61,14 @@ typedef struct {
/* i/o api */
GSList * ( *load_actions )( NactIIOProvider *instance );
+ gboolean ( *write_action )( NactIIOProvider *instance, const GObject *action, gchar **message );
}
NactIIOProviderInterface;
-GType nact_iio_provider_get_type( void );
+GType nact_iio_provider_get_type( void );
-GSList *nact_iio_provider_load_actions( const GObject *pivot );
+GSList *nact_iio_provider_load_actions( const GObject *pivot );
+gboolean nact_iio_provider_write_action( const GObject *pivot, const GObject *action, gchar **message );
G_END_DECLS
diff --git a/src/common/nact-pivot.c b/src/common/nact-pivot.c
index 5a162dc..83a2c67 100644
--- a/src/common/nact-pivot.c
+++ b/src/common/nact-pivot.c
@@ -33,6 +33,7 @@
#endif
#include <string.h>
+#include <uuid/uuid.h>
#include "nact-action.h"
#include "nact-gconf.h"
@@ -99,6 +100,7 @@ static void instance_dispose( GObject *object );
static void instance_finalize( GObject *object );
static void free_actions( GSList *list );
+static gint sort_actions_by_label( gconstpointer a1, gconstpointer a2 );
static void action_changed_handler( NactPivot *pivot, gpointer user_data );
static gboolean on_action_changed_timeout( gpointer user_data );
static gulong time_val_diff( const GTimeVal *recent, const GTimeVal *old );
@@ -326,7 +328,28 @@ nact_pivot_get_providers( const NactPivot *pivot, GType type )
}
/**
+ * Return the list of actions, sorted by label.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * The returned list is owned by this NactPivot object, and should not
+ * be freed, nor unref by the caller.
+ */
+GSList *
+nact_pivot_get_label_sorted_actions( const NactPivot *pivot )
+{
+ g_assert( NACT_IS_PIVOT( pivot ));
+ GSList *sorted = g_slist_sort( pivot->private->actions, ( GCompareFunc ) sort_actions_by_label );
+ return( sorted );
+}
+
+/**
* Return the list of actions.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * The returned list is owned by this NactPivot object, and should not
+ * be freed, nor unref by the caller.
*/
GSList *
nact_pivot_get_actions( const NactPivot *pivot )
@@ -345,6 +368,82 @@ free_actions( GSList *list )
g_slist_free( list );
}
+static gint
+sort_actions_by_label( gconstpointer a1, gconstpointer a2 )
+{
+ NactAction *action1 = NACT_ACTION( a1 );
+ gchar *label1 = nact_action_get_label( action1 );
+
+ NactAction *action2 = NACT_ACTION( a2 );
+ gchar *label2 = nact_action_get_label( action2 );
+
+ gint ret = g_utf8_collate( label1, label2 );
+
+ g_free( label1 );
+ g_free( label2 );
+
+ return( ret );
+}
+
+/**
+ * Return the specified action.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * @uuid: required globally unique identifier (uuid).
+ *
+ * Returns the specified NactAction object, or NULL if not found.
+ *
+ * The returned pointer is owned by NactPivot, and should not be freed
+ * nor unref by the caller.
+ */
+GObject *
+nact_pivot_get_action( NactPivot *pivot, const gchar *uuid )
+{
+ GSList *ia;
+ NactAction *act;
+ GObject *found = NULL;
+ uuid_t uua, uub;
+ gchar *uuid_act;
+
+ g_assert( NACT_IS_PIVOT( pivot ));
+
+ uuid_parse( uuid, uua );
+ for( ia = pivot->private->actions ; ia ; ia = ia->next ){
+ act = NACT_ACTION( ia->data );
+ uuid_act = nact_action_get_uuid( act );
+ uuid_parse( uuid_act, uub );
+ g_free( uuid_act );
+ if( !uuid_compare( uua, uub )){
+ found = G_OBJECT( act );
+ break;
+ }
+ }
+
+ return( found );
+}
+
+/**
+ * Write an action.
+ *
+ * @pivot: this NactPivot object.
+ *
+ * @action: action to be written by the storage subsystem.
+ *
+ * @message: the I/O provider can allocate and store here an error
+ * message.
+ *
+ * Returns TRUE if the write is successfull, FALSE else.
+ */
+gboolean
+nact_pivot_add_action( NactPivot *pivot, const GObject *action, gchar **message )
+{
+ g_assert( NACT_IS_PIVOT( pivot ));
+ g_assert( NACT_IS_ACTION( action ));
+ g_assert( message );
+ return( nact_iio_provider_write_action( G_OBJECT( pivot ), action, message ));
+}
+
/*
* this handler is trigerred by IIOProviders when an action is changed
* in the underlying storage subsystems
diff --git a/src/common/nact-pivot.h b/src/common/nact-pivot.h
index 81299c0..26ed1dd 100644
--- a/src/common/nact-pivot.h
+++ b/src/common/nact-pivot.h
@@ -73,8 +73,13 @@ NactPivot *nact_pivot_new( const GObject *notified );
GSList *nact_pivot_get_providers( const NactPivot *pivot, GType type );
+GSList *nact_pivot_get_label_sorted_actions( const NactPivot *pivot );
GSList *nact_pivot_get_actions( const NactPivot *pivot );
+GObject *nact_pivot_get_action( NactPivot *pivot, const gchar *uuid );
+
+gboolean nact_pivot_add_action( NactPivot *pivot, const GObject *action, gchar **message );
+
/* data passed from the storage subsystem when an action is changed
*/
enum {
diff --git a/src/nact/Makefile.am b/src/nact/Makefile.am
index 615a929..5bce652 100644
--- a/src/nact/Makefile.am
+++ b/src/nact/Makefile.am
@@ -40,6 +40,8 @@ AM_CPPFLAGS += \
$(NULL)
nautilus_actions_config_SOURCES = \
+ base-application.c \
+ base-application.h \
nact.c \
nact.h \
nact-application.c \
diff --git a/src/nact/base-application.c b/src/nact/base-application.c
new file mode 100644
index 0000000..74f910b
--- /dev/null
+++ b/src/nact/base-application.c
@@ -0,0 +1,830 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 2 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 Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <glib/gi18n.h>
+#include <string.h>
+#include <unique/unique.h>
+
+#include "base-application.h"
+
+/* private class data
+ */
+struct BaseApplicationClassPrivate {
+};
+
+/* private instance data
+ */
+struct BaseApplicationPrivate {
+ gboolean dispose_has_run;
+ int argc;
+ gpointer argv;
+ gchar *unique_name;
+ UniqueApp *unique_app;
+ gchar *application_name;
+ gchar *icon_name;
+ GtkWindow *main_window;
+};
+
+/* private instance properties
+ */
+enum {
+ PROP_ARGC = 1,
+ PROP_ARGV,
+ PROP_UNIQUE_NAME,
+ PROP_UNIQUE_APP,
+ PROP_MAIN_WINDOW,
+ PROP_APPLICATION_NAME,
+ PROP_ICON_NAME
+};
+
+#define PROP_ARGC_STR "argc"
+#define PROP_ARGV_STR "argv"
+#define PROP_UNIQUE_NAME_STR "unique-name"
+#define PROP_UNIQUE_APP_STR "unique-app"
+#define PROP_MAIN_WINDOW_STR "main-window"
+#define PROP_APPLICATION_NAME_STR "application-name"
+#define PROP_ICON_NAME_STR "icon-name"
+
+static GObjectClass *st_parent_class = NULL;
+
+static GType register_type( void );
+static void class_init( BaseApplicationClass *klass );
+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 );
+static void instance_dispose( GObject *application );
+static void instance_finalize( GObject *application );
+
+static int do_run( BaseApplication *application );
+
+static void v_initialize( BaseApplication *application );
+static void v_initialize_i18n( BaseApplication *application );
+static void v_initialize_gtk( BaseApplication *application );
+static void v_initialize_application_name( BaseApplication *application );
+static void v_initialize_icon_name( BaseApplication *application );
+static void v_initialize_unique( BaseApplication *application );
+static gboolean v_is_willing_to_run( BaseApplication *application );
+static void v_advertise_willing_to_run( BaseApplication *application );
+static void v_advertise_not_willing_to_run( BaseApplication *application );
+static void v_start( BaseApplication *application );
+static int v_finish( BaseApplication *application );
+static gchar *v_get_unique_name( BaseApplication *application );
+static gchar *v_get_application_name( BaseApplication *application );
+static gchar *v_get_icon_name( BaseApplication *application );
+
+static void do_initialize( BaseApplication *application );
+static void do_initialize_i18n( BaseApplication *application );
+static void do_initialize_gtk( BaseApplication *application );
+static void do_initialize_application_name( BaseApplication *application );
+static void do_initialize_icon_name( BaseApplication *application );
+static void do_initialize_unique( BaseApplication *application );
+static gboolean is_willing_to_run( BaseApplication *application );
+static gboolean check_for_unique_app( BaseApplication *application );
+static void do_advertise_willing_to_run( BaseApplication *application );
+static void do_advertise_not_willing_to_run( BaseApplication *application );
+static void do_start( BaseApplication *application );
+static int do_finish( BaseApplication *application );
+static gchar *do_get_unique_name( BaseApplication *application );
+static gchar *do_get_application_name( BaseApplication *application );
+static gchar *do_get_icon_name( BaseApplication *application );
+
+/*static UniqueResponse on_unique_message_received( UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data );*/
+
+GType
+base_application_get_type( void )
+{
+ static GType application_type = 0;
+
+ if( !application_type ){
+ application_type = register_type();
+ }
+
+ return( application_type );
+}
+
+static GType
+register_type( void )
+{
+ static const gchar *thisfn = "base_application_register_type";
+ g_debug( "%s", thisfn );
+
+ g_type_init();
+
+ static GTypeInfo info = {
+ sizeof( BaseApplicationClass ),
+ ( GBaseInitFunc ) NULL,
+ ( GBaseFinalizeFunc ) NULL,
+ ( GClassInitFunc ) class_init,
+ NULL,
+ NULL,
+ sizeof( BaseApplication ),
+ 0,
+ ( GInstanceInitFunc ) instance_init
+ };
+
+ return( g_type_register_static( G_TYPE_OBJECT, "BaseApplication", &info, 0 ));
+}
+
+static void
+class_init( BaseApplicationClass *klass )
+{
+ static const gchar *thisfn = "base_application_class_init";
+ g_debug( "%s: klass=%p", thisfn, klass );
+
+ st_parent_class = g_type_class_peek_parent( klass );
+
+ GObjectClass *object_class = G_OBJECT_CLASS( klass );
+ object_class->dispose = instance_dispose;
+ object_class->finalize = instance_finalize;
+ object_class->get_property = instance_get_property;
+ object_class->set_property = instance_set_property;
+
+ GParamSpec *spec;
+ spec = g_param_spec_int(
+ PROP_ARGC_STR,
+ PROP_ARGC_STR,
+ "Command-line arguments count", 0, 65535, 0,
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_ARGC, spec );
+
+ spec = g_param_spec_pointer(
+ PROP_ARGV_STR,
+ PROP_ARGV_STR,
+ "Command-line arguments",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_ARGV, spec );
+
+ spec = g_param_spec_string(
+ PROP_UNIQUE_NAME_STR,
+ PROP_UNIQUE_NAME_STR,
+ "DBUS name for unique application", "",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_UNIQUE_NAME, spec );
+
+ spec = g_param_spec_pointer(
+ PROP_UNIQUE_APP_STR,
+ PROP_UNIQUE_APP_STR,
+ "UniqueApp object pointer",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_UNIQUE_APP, spec );
+
+ spec = g_param_spec_pointer(
+ PROP_MAIN_WINDOW_STR,
+ PROP_MAIN_WINDOW_STR,
+ "Main window widget",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_MAIN_WINDOW, spec );
+
+ spec = g_param_spec_string(
+ PROP_APPLICATION_NAME_STR,
+ PROP_APPLICATION_NAME_STR,
+ "Localized application name", "",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_APPLICATION_NAME, spec );
+
+ spec = g_param_spec_string(
+ PROP_ICON_NAME_STR,
+ PROP_ICON_NAME_STR,
+ "Default themed icon name", "",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_ICON_NAME, spec );
+
+ klass->private = g_new0( BaseApplicationClassPrivate, 1 );
+
+ klass->run = do_run;
+ klass->initialize = do_initialize;
+ klass->initialize_i18n = do_initialize_i18n;
+ klass->initialize_gtk = do_initialize_gtk;
+ klass->initialize_application_name = do_initialize_application_name;
+ klass->initialize_icon_name = do_initialize_icon_name;
+ klass->initialize_unique = do_initialize_unique;
+ klass->is_willing_to_run = is_willing_to_run;
+ klass->advertise_willing_to_run = do_advertise_willing_to_run;
+ klass->advertise_not_willing_to_run = do_advertise_not_willing_to_run;
+ klass->start = do_start;
+ klass->finish = do_finish;
+ klass->get_unique_name = do_get_unique_name;
+ klass->get_application_name = do_get_application_name;
+ klass->get_icon_name = do_get_icon_name;
+}
+
+static void
+instance_init( GTypeInstance *instance, gpointer klass )
+{
+ static const gchar *thisfn = "base_application_instance_init";
+ g_debug( "%s: instance=%p, klass=%p", thisfn, instance, klass );
+
+ g_assert( BASE_IS_APPLICATION( instance ));
+ BaseApplication *self = BASE_APPLICATION( instance );
+
+ self->private = g_new0( BaseApplicationPrivate, 1 );
+
+ self->private->dispose_has_run = FALSE;
+}
+
+static void
+instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
+{
+ g_assert( BASE_IS_APPLICATION( object ));
+ BaseApplication *self = BASE_APPLICATION( object );
+
+ switch( property_id ){
+ case PROP_ARGC:
+ g_value_set_int( value, self->private->argc );
+ break;
+
+ case PROP_ARGV:
+ g_value_set_pointer( value, self->private->argv );
+ break;
+
+ case PROP_UNIQUE_NAME:
+ g_value_set_string( value, self->private->unique_name );
+ break;
+
+ case PROP_UNIQUE_APP:
+ g_value_set_pointer( value, self->private->unique_app );
+ break;
+
+ case PROP_MAIN_WINDOW:
+ g_value_set_pointer( value, self->private->main_window );
+ break;
+
+ case PROP_APPLICATION_NAME:
+ g_value_set_string( value, self->private->application_name );
+ break;
+
+ case PROP_ICON_NAME:
+ g_value_set_string( value, self->private->icon_name );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+ break;
+ }
+}
+
+static void
+instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
+{
+ g_assert( BASE_IS_APPLICATION( object ));
+ BaseApplication *self = BASE_APPLICATION( object );
+
+ switch( property_id ){
+ case PROP_ARGC:
+ self->private->argc = g_value_get_int( value );
+ break;
+
+ case PROP_ARGV:
+ self->private->argv = g_value_get_pointer( value );
+ break;
+
+ case PROP_UNIQUE_NAME:
+ g_free( self->private->unique_name );
+ self->private->unique_name = g_value_dup_string( value );
+ break;
+
+ case PROP_UNIQUE_APP:
+ self->private->unique_app = g_value_get_pointer( value );
+ break;
+
+ case PROP_MAIN_WINDOW:
+ self->private->main_window = g_value_get_pointer( value );
+ break;
+
+ case PROP_APPLICATION_NAME:
+ g_free( self->private->application_name );
+ self->private->application_name = g_value_dup_string( value );
+ break;
+
+ case PROP_ICON_NAME:
+ g_free( self->private->icon_name );
+ self->private->icon_name = g_value_dup_string( value );
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID( object, property_id, spec );
+ break;
+ }
+}
+
+static void
+instance_dispose( GObject *application )
+{
+ static const gchar *thisfn = "base_application_instance_dispose";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+ BaseApplication *self = BASE_APPLICATION( application );
+
+ if( !self->private->dispose_has_run ){
+
+ self->private->dispose_has_run = TRUE;
+
+ g_object_unref( self->private->unique_app );
+ g_object_unref( self->private->main_window );
+
+ /* chain up to the parent class */
+ G_OBJECT_CLASS( st_parent_class )->dispose( application );
+ }
+}
+
+static void
+instance_finalize( GObject *application )
+{
+ static const gchar *thisfn = "base_application_instance_finalize";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+ BaseApplication *self = ( BaseApplication * ) application;
+
+ g_free( self->private->unique_name );
+ g_free( self->private->application_name );
+ g_free( self->private->icon_name );
+
+ /* chain call to parent class */
+ if( st_parent_class->finalize ){
+ G_OBJECT_CLASS( st_parent_class )->finalize( application );
+ }
+}
+
+/**
+ * Returns a newly allocated BaseApplication object.
+ */
+BaseApplication *
+base_application_new( void )
+{
+ return( g_object_new( BASE_APPLICATION_TYPE, NULL ));
+}
+
+/**
+ * Returns a newly allocated BaseApplication object.
+ *
+ * @argc: count of command-line arguments.
+ *
+ * @argv: command-line arguments.
+ */
+BaseApplication *
+base_application_new_with_args( int argc, char **argv )
+{
+ return( g_object_new( BASE_APPLICATION_TYPE, PROP_ARGC_STR, argc, PROP_ARGV_STR, argv, NULL ));
+}
+
+/**
+ * Executes the application.
+ *
+ * @application: the considered BaseApplication object.
+ *
+ * The returned integer should be returned to the OS.
+ *
+ * This a the main function management of the application. We iniialize
+ * it, test command line options, if it is willing to run, then start
+ * it and finally finish it.
+ *
+ * All these steps are implemented by virtual functions which provider
+ * some suitable defaults, and can be overriden by a derived class.
+ */
+int
+base_application_run( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_run";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ return( BASE_APPLICATION_GET_CLASS( application )->run( application ));
+}
+
+static int
+do_run( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_do_run";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ int code = 0;
+
+ v_initialize( application );
+
+ if( v_is_willing_to_run( application )){
+
+ v_advertise_willing_to_run( application );
+ v_start( application );
+ code = v_finish( application );
+
+ } else {
+
+ v_advertise_not_willing_to_run( application );
+
+ }
+
+ return( code );
+}
+
+static void
+v_initialize( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_initialize";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ BASE_APPLICATION_GET_CLASS( application )->initialize( application );
+}
+
+static void
+v_initialize_i18n( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_initialize_i18n";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ BASE_APPLICATION_GET_CLASS( application )->initialize_i18n( application );
+}
+
+static void
+v_initialize_gtk( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_initialize_gtk";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ BASE_APPLICATION_GET_CLASS( application )->initialize_gtk( application );
+}
+
+static void
+v_initialize_application_name( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_initialize_application_name";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ BASE_APPLICATION_GET_CLASS( application )->initialize_application_name( application );
+}
+
+static void
+v_initialize_icon_name( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_initialize_icon_name";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ BASE_APPLICATION_GET_CLASS( application )->initialize_icon_name( application );
+}
+
+static void
+v_initialize_unique( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_initialize_unique";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ BASE_APPLICATION_GET_CLASS( application )->initialize_unique( application );
+}
+
+static gboolean
+v_is_willing_to_run( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_is_willing_to_run";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ return( BASE_APPLICATION_GET_CLASS( application )->is_willing_to_run( application ));
+}
+
+static void
+v_advertise_willing_to_run( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_advertise_willing_to_run";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ return( BASE_APPLICATION_GET_CLASS( application )->advertise_willing_to_run( application ));
+}
+
+static void
+v_advertise_not_willing_to_run( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_advertise_not_willing_to_run";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ return( BASE_APPLICATION_GET_CLASS( application )->advertise_not_willing_to_run( application ));
+}
+
+static void
+v_start( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_start";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ BASE_APPLICATION_GET_CLASS( application )->start( application );
+}
+
+static int
+v_finish( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_finish";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ return( BASE_APPLICATION_GET_CLASS( application )->finish( application ));
+}
+
+static gchar *
+v_get_unique_name( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_get_unique_name";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ gchar *name;
+ g_object_get( G_OBJECT( application ), PROP_UNIQUE_NAME_STR, &name, NULL );
+
+ if( !name || !strlen( name )){
+ name = BASE_APPLICATION_GET_CLASS( application )->get_unique_name( application );
+ if( name && strlen( name )){
+ g_object_set( G_OBJECT( application ), PROP_UNIQUE_NAME_STR, name, NULL );
+ }
+ }
+
+ return( name );
+}
+
+static gchar *
+v_get_application_name( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_get_application_name";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ gchar *name;
+ g_object_get( G_OBJECT( application ), PROP_APPLICATION_NAME_STR, &name, NULL );
+
+ if( !name || !strlen( name )){
+ name = BASE_APPLICATION_GET_CLASS( application )->get_application_name( application );
+ if( name && strlen( name )){
+ g_object_set( G_OBJECT( application ), PROP_APPLICATION_NAME_STR, name, NULL );
+ }
+ }
+
+ return( name );
+}
+
+static gchar *
+v_get_icon_name( BaseApplication *application )
+{
+ static const gchar *thisfn = "base_application_v_get_icon_name";
+ g_debug( "%s: icon=%p", thisfn, application );
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ gchar *name;
+ g_object_get( G_OBJECT( application ), PROP_ICON_NAME_STR, &name, NULL );
+
+ if( !name || !strlen( name )){
+ name = BASE_APPLICATION_GET_CLASS( application )->get_icon_name( application );
+ if( name && strlen( name )){
+ g_object_set( G_OBJECT( application ), PROP_ICON_NAME_STR, name, NULL );
+ }
+ }
+
+ return( name );
+}
+
+static void
+do_initialize( BaseApplication *application )
+{
+ v_initialize_i18n( application );
+ v_initialize_gtk( application );
+ v_initialize_application_name( application );
+ v_initialize_icon_name( application );
+ v_initialize_unique( application );
+}
+
+static void
+do_initialize_i18n( BaseApplication *application )
+{
+#ifdef ENABLE_NLS
+ bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
+# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+ bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
+# endif
+ textdomain( GETTEXT_PACKAGE );
+#endif
+}
+
+static void
+do_initialize_gtk( BaseApplication *application )
+{
+ int argc;
+ gpointer argv;
+ g_object_get( G_OBJECT( application ), PROP_ARGC_STR, &argc, PROP_ARGV_STR, &argv, NULL );
+ gtk_init( &argc, ( char *** ) &argv );
+ g_object_set( G_OBJECT( application ), PROP_ARGC_STR, argc, PROP_ARGV_STR, argv, NULL );
+}
+
+static void
+do_initialize_application_name( BaseApplication *application )
+{
+ gchar *name = v_get_application_name( application );
+ if( name && strlen( name )){
+ g_set_application_name( name );
+ }
+ g_free( name );
+}
+
+static void
+do_initialize_icon_name( BaseApplication *application )
+{
+ gchar *name = v_get_icon_name( application );
+ if( name && strlen( name )){
+ gtk_window_set_default_icon_name( name );
+ }
+ g_free( name );
+}
+
+static void
+do_initialize_unique( BaseApplication *application )
+{
+ gchar *unique_name = v_get_unique_name( application );
+
+ if( unique_name && strlen( unique_name )){
+ application->private->unique_app = unique_app_new( unique_name, NULL );
+ }
+
+ g_free( unique_name );
+}
+
+static gboolean
+is_willing_to_run( BaseApplication *application )
+{
+ gboolean is_willing = TRUE;
+
+ if( application->private->unique_app ){
+ is_willing = check_for_unique_app( application );
+ }
+
+ return( is_willing );
+}
+
+/*
+ * returns TRUE if we are the first instance
+ */
+static gboolean
+check_for_unique_app( BaseApplication *application )
+{
+ gboolean is_first = TRUE;
+
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ if( unique_app_is_running( application->private->unique_app )){
+
+ is_first = FALSE;
+
+ unique_app_send_message( application->private->unique_app, UNIQUE_ACTIVATE, NULL );
+
+ /* default from libunique is actually to activate the first window
+ * so we rely on the default..
+ */
+ /*} else {
+ g_signal_connect(
+ application->private->unique,
+ "message-received",
+ G_CALLBACK( on_unique_message_received ),
+ application
+ );*/
+ }
+
+ return( is_first );
+}
+
+static void
+do_advertise_willing_to_run( BaseApplication *application )
+{
+
+}
+
+static void
+do_advertise_not_willing_to_run( BaseApplication *application )
+{
+
+}
+
+static void
+do_start( BaseApplication *application )
+{
+ if( application->private->unique_app && application->private->main_window ){
+ unique_app_watch_window( application->private->unique_app, application->private->main_window );
+ }
+
+ gtk_main();
+}
+
+static int
+do_finish( BaseApplication *application )
+{
+ int code = 0;
+ return( code );
+}
+
+static gchar *
+do_get_unique_name( BaseApplication *application )
+{
+ return( NULL );
+}
+
+static gchar *
+do_get_application_name( BaseApplication *application )
+{
+ return( NULL );
+}
+
+static gchar *
+do_get_icon_name( BaseApplication *application )
+{
+ return( NULL );
+}
+
+/*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 );
+}*/
+
+void
+base_application_error_dlg(
+ BaseApplication *application, GtkMessageType type, gchar *primary, gchar *secondary )
+{
+ g_assert( BASE_IS_APPLICATION( application ));
+
+ GtkWidget *dialog = gtk_message_dialog_new(
+ NULL, GTK_DIALOG_MODAL, type, GTK_BUTTONS_OK, primary );
+
+ gtk_message_dialog_format_secondary_text( GTK_MESSAGE_DIALOG( dialog ), secondary );
+
+ const gchar *name = g_get_application_name();
+
+ g_object_set( G_OBJECT( dialog ) , "title", name, NULL );
+
+ gtk_dialog_run( GTK_DIALOG( dialog ));
+
+ gtk_widget_destroy( dialog );
+}
diff --git a/src/nact/base-application.h b/src/nact/base-application.h
new file mode 100644
index 0000000..bf1575c
--- /dev/null
+++ b/src/nact/base-application.h
@@ -0,0 +1,96 @@
+/*
+ * Nautilus Actions
+ * A Nautilus extension which offers configurable context menu actions.
+ *
+ * Copyright (C) 2005 The GNOME Foundation
+ * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
+ * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
+ *
+ * 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 2 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 Library; see the file COPYING. If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place,
+ * Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * Authors:
+ * Frederic Ruaudel <grumz grumz net>
+ * Rodrigo Moya <rodrigo gnome-db org>
+ * Pierre Wieser <pwieser trychlos org>
+ * ... and many others (see AUTHORS)
+ */
+
+#ifndef __BASE_APPLICATION_H__
+#define __BASE_APPLICATION_H__
+
+/*
+ * BaseApplication class definition.
+ *
+ * This is a base class for Gtk+ programs.
+ */
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#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 {
+ GObject parent;
+ BaseApplicationPrivate *private;
+}
+ BaseApplication;
+
+typedef struct BaseApplicationClassPrivate BaseApplicationClassPrivate;
+
+typedef struct {
+ GObjectClass parent;
+ BaseApplicationClassPrivate *private;
+
+ /* virtual functions */
+ int ( *run ) ( BaseApplication *appli );
+ void ( *initialize ) ( BaseApplication *appli );
+ void ( *initialize_i18n ) ( BaseApplication *appli );
+ void ( *initialize_gtk ) ( BaseApplication *appli );
+ void ( *initialize_application_name ) ( BaseApplication *appli );
+ void ( *initialize_icon_name ) ( BaseApplication *appli );
+ void ( *initialize_unique ) ( BaseApplication *appli );
+ gboolean ( *is_willing_to_run ) ( BaseApplication *appli );
+ void ( *advertise_willing_to_run ) ( BaseApplication *appli );
+ void ( *advertise_not_willing_to_run )( BaseApplication *appli );
+ void ( *start ) ( BaseApplication *appli );
+ int ( *finish ) ( BaseApplication *appli );
+ gchar * ( *get_unique_name ) ( BaseApplication *appli );
+ gchar * ( *get_application_name ) ( BaseApplication *appli );
+ gchar * ( *get_icon_name ) ( BaseApplication *appli );
+}
+ BaseApplicationClass;
+
+GType base_application_get_type( void );
+
+BaseApplication *base_application_new( void );
+BaseApplication *base_application_new_with_args( int argc, char **argv );
+
+int base_application_run( BaseApplication *application );
+
+void base_application_error_dlg( BaseApplication *application, GtkMessageType type, gchar *primary, gchar *secondary );
+
+G_END_DECLS
+
+#endif /* __BASE_APPLICATION_H__ */
diff --git a/src/nact/nact-application.c b/src/nact/nact-application.c
index 3eb7987..35cb239 100644
--- a/src/nact/nact-application.c
+++ b/src/nact/nact-application.c
@@ -34,8 +34,8 @@
#include <glib/gi18n.h>
#include <gtk/gtk.h>
-#include <unique/unique.h>
+#include <common/nact-pivot.h>
#include "nact.h"
#include "nact-application.h"
@@ -48,39 +48,31 @@ struct NactApplicationClassPrivate {
*/
struct NactApplicationPrivate {
gboolean dispose_has_run;
- int argc;
- gpointer argv;
- UniqueApp *unique;
- GtkWindow *main;
+ NactPivot *pivot;
};
/* private instance properties
*/
enum {
- PROP_ARGC = 1,
- PROP_ARGV
+ PROP_PIVOT = 1
};
-#define PROP_ARGC_STR "argc"
-#define PROP_ARGV_STR "argv"
+#define PROP_PIVOT_STR "pivot"
static GObjectClass *st_parent_class = NULL;
-static GType register_type( void );
-static void class_init( NactApplicationClass *klass );
-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 );
-static void instance_dispose( GObject *application );
-static void instance_finalize( GObject *application );
-
-/*static UniqueResponse on_unique_message_received( UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data );*/
-static void warn_other_instance( NactApplication *application );
-static gboolean check_for_unique_app( NactApplication *application );
-static void initialize_i18n( NactApplication *application );
-static gboolean startup_appli( NactApplication *application );
-static int run_appli( NactApplication *application );
-static void finish_appli( NactApplication *application );
+static GType register_type( void );
+static void class_init( NactApplicationClass *klass );
+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 );
+static void instance_dispose( GObject *application );
+static void instance_finalize( GObject *application );
+
+static void warn_other_instance( BaseApplication *application );
+static gchar *get_application_name( BaseApplication *application );
+static gchar *get_icon_name( BaseApplication *application );
+static gchar *get_unique_name( BaseApplication *application );
GType
nact_application_get_type( void )
@@ -112,7 +104,7 @@ register_type( void )
( GInstanceInitFunc ) instance_init
};
- return( g_type_register_static( G_TYPE_OBJECT, "NactApplication", &info, 0 ));
+ return( g_type_register_static( BASE_APPLICATION_TYPE, "NactApplication", &info, 0 ));
}
static void
@@ -130,21 +122,21 @@ class_init( NactApplicationClass *klass )
object_class->set_property = instance_set_property;
GParamSpec *spec;
- spec = g_param_spec_int(
- PROP_ARGC_STR,
- PROP_ARGC_STR,
- "Command-line arguments count", 0, 65535, 0,
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
- g_object_class_install_property( object_class, PROP_ARGC, spec );
-
spec = g_param_spec_pointer(
- PROP_ARGV_STR,
- PROP_ARGV_STR,
- "Command-line arguments",
- G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
- g_object_class_install_property( object_class, PROP_ARGV, spec );
+ PROP_PIVOT_STR,
+ PROP_PIVOT_STR,
+ "NactPivot object pointer",
+ G_PARAM_STATIC_STRINGS | G_PARAM_READWRITE );
+ g_object_class_install_property( object_class, PROP_PIVOT, spec );
klass->private = g_new0( NactApplicationClassPrivate, 1 );
+
+ BaseApplicationClass *appli_class = BASE_APPLICATION_CLASS( klass );
+
+ appli_class->advertise_not_willing_to_run = warn_other_instance;
+ appli_class->get_application_name = get_application_name;
+ appli_class->get_icon_name = get_icon_name;
+ appli_class->get_unique_name = get_unique_name;
}
static void
@@ -159,8 +151,6 @@ instance_init( GTypeInstance *instance, gpointer klass )
self->private = g_new0( NactApplicationPrivate, 1 );
self->private->dispose_has_run = FALSE;
-
- self->private->unique = unique_app_new( "org.nautilus-actions.Config", NULL );
}
static void
@@ -170,12 +160,8 @@ instance_get_property( GObject *object, guint property_id, GValue *value, GParam
NactApplication *self = NACT_APPLICATION( object );
switch( property_id ){
- case PROP_ARGC:
- g_value_set_int( value, self->private->argc );
- break;
-
- case PROP_ARGV:
- g_value_set_pointer( value, self->private->argv );
+ case PROP_PIVOT:
+ g_value_set_pointer( value, self->private->pivot );
break;
default:
@@ -191,12 +177,8 @@ instance_set_property( GObject *object, guint property_id, const GValue *value,
NactApplication *self = NACT_APPLICATION( object );
switch( property_id ){
- case PROP_ARGC:
- self->private->argc = g_value_get_int( value );
- break;
-
- case PROP_ARGV:
- self->private->argv = g_value_get_pointer( value );
+ case PROP_PIVOT:
+ self->private->pivot = g_value_get_pointer( value );
break;
default:
@@ -218,7 +200,7 @@ instance_dispose( GObject *application )
self->private->dispose_has_run = TRUE;
- g_object_unref( self->private->unique );
+ g_object_unref( self->private->pivot );
/* chain up to the parent class */
G_OBJECT_CLASS( st_parent_class )->dispose( application );
@@ -242,15 +224,6 @@ instance_finalize( GObject *application )
/**
* Returns a newly allocated NactApplication object.
- */
-NactApplication *
-nact_application_new( void )
-{
- return( g_object_new( NACT_APPLICATION_TYPE, NULL ));
-}
-
-/**
- * Returns a newly allocated NactApplication object.
*
* @argc: count of command-line arguments.
*
@@ -259,155 +232,62 @@ nact_application_new( void )
NactApplication *
nact_application_new_with_args( int argc, char **argv )
{
- return( g_object_new( NACT_APPLICATION_TYPE, PROP_ARGC_STR, argc, PROP_ARGV_STR, argv, NULL ));
+ return( g_object_new( NACT_APPLICATION_TYPE, "argc", argc, "argv", argv, NULL ));
}
-/*static UniqueResponse
-on_unique_message_received(
- UniqueApp *app, UniqueCommand command, UniqueMessageData *message, guint time, gpointer user_data )
-{
- static const gchar *thisfn = "nact_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 );
-}*/
-
static void
-warn_other_instance( NactApplication *application )
+warn_other_instance( BaseApplication *application )
{
g_assert( NACT_IS_APPLICATION( application ));
- gchar *msg;
- msg = g_strdup_printf( "<b>%s</b>\n\n%s",
+ base_application_error_dlg(
+ application,
+ GTK_MESSAGE_INFO,
_( "Another instance of Nautilus Actions Configurator is already running." ),
_( "Please switch back to it." ));
-
- GtkWidget *dialog = gtk_message_dialog_new_with_markup(
- NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_INFO, GTK_BUTTONS_OK, msg );
-
- /* i18n: window title */
- g_object_set( G_OBJECT( dialog ) , "title", _( "Nautilus Actions" ), NULL );
-
- gtk_dialog_run( GTK_DIALOG( dialog ));
-
- gtk_widget_destroy( dialog );
- g_free( msg );
}
-/*
- * returns TRUE if we are the first instance
- */
-static gboolean
-check_for_unique_app( NactApplication *application )
+static gchar *
+get_application_name( BaseApplication *application )
{
- gboolean is_first = TRUE;
-
- g_assert( NACT_IS_APPLICATION( application ));
-
- if( unique_app_is_running( application->private->unique )){
-
- is_first = FALSE;
-
- unique_app_send_message( application->private->unique, UNIQUE_ACTIVATE, NULL );
-
- /* the screen is not actually modified, nor the main window is
- * switched back to the current screen ; the icon in the deskbar
- * applet is just highlighted
- * so a message is not too much !
- */
- warn_other_instance( application );
+ static const gchar *thisfn = "nact_application_get_application_name";
+ g_debug( "%s: application=%p", thisfn, application );
- /* default from libunique is actually to activate the first window
- * so we rely on the default..
+ /* i18n: this is the application name, used in window title
*/
- /*} else {
- g_signal_connect(
- application->private->unique,
- "message-received",
- G_CALLBACK( on_unique_message_received ),
- application
- );*/
- }
-
- return( is_first );
+ return( g_strdup( _( "Nautilus Actions Configuration Tool" )));
}
-static void
-initialize_i18n( NactApplication *application )
+static gchar *
+get_icon_name( BaseApplication *application )
{
-#ifdef ENABLE_NLS
- bindtextdomain( GETTEXT_PACKAGE, GNOMELOCALEDIR );
-# ifdef HAVE_BIND_TEXTDOMAIN_CODESET
- bind_textdomain_codeset( GETTEXT_PACKAGE, "UTF-8" );
-# endif
- textdomain( GETTEXT_PACKAGE );
-#endif
+ static const gchar *thisfn = "nact_application_get_icon_name";
+ g_debug( "%s: application=%p", thisfn, application );
+
+ return( g_strdup( PACKAGE ));
}
-static gboolean
-startup_appli( NactApplication *application )
+static gchar *
+get_unique_name( BaseApplication *application )
{
- int ret;
-
- initialize_i18n( application );
-
- g_set_application_name( PACKAGE );
-
- gtk_window_set_default_icon_name( PACKAGE );
-
- ret = check_for_unique_app( application );
+ static const gchar *thisfn = "nact_application_get_unique_name";
+ g_debug( "%s: application=%p", thisfn, application );
- return( ret );
+ return( g_strdup( "org.nautilus-actions.ConfigurationTool" ));
}
-static int
+/*static int
run_appli( NactApplication *application )
{
int code = 0;
- application->private->main = nact_init_dialog();
- unique_app_watch_window( application->private->unique, application->private->main );
-
- gtk_main();
-
- return( code );
-}
-
-static void
-finish_appli( NactApplication *application )
-{
-}
-
-/**
- * This a the whole run management for the NactApplication Object.
- *
- * @app: the considered NactApplication object.
- *
- * The returned integer should be returned to the OS.
- */
-int
-nact_application_run( NactApplication *application )
-{
- static const gchar *thisfn = "nact_application_run";
- g_debug( "%s: application=%p", thisfn, application );
+ g_object_set( G_OBJECT( application ), PROP_PIVOT_STR, nact_pivot_new( NULL ), NULL );
- g_assert( NACT_IS_APPLICATION( application ));
+ g_object_set( G_OBJECT( application ), PROP_MAINWINDOW_STR, nact_init_dialog( G_OBJECT( application ), NULL );
- int code = 0;
+ unique_app_watch_window( application->private->unique, application->private->main );
- if( startup_appli( application )){
- code = run_appli( application );
- finish_appli( application );
- }
+ gtk_main();
return( code );
-}
+}*/
diff --git a/src/nact/nact-application.h b/src/nact/nact-application.h
index be9ee78..58d59b9 100644
--- a/src/nact/nact-application.h
+++ b/src/nact/nact-application.h
@@ -37,7 +37,7 @@
* This is the main class for UI programs.
*/
-#include <glib-object.h>
+#include "base-application.h"
G_BEGIN_DECLS
@@ -51,7 +51,7 @@ G_BEGIN_DECLS
typedef struct NactApplicationPrivate NactApplicationPrivate;
typedef struct {
- GObject parent;
+ BaseApplication parent;
NactApplicationPrivate *private;
}
NactApplication;
@@ -59,18 +59,15 @@ typedef struct {
typedef struct NactApplicationClassPrivate NactApplicationClassPrivate;
typedef struct {
- GObjectClass parent;
+ BaseApplicationClass parent;
NactApplicationClassPrivate *private;
}
NactApplicationClass;
GType nact_application_get_type( void );
-NactApplication *nact_application_new( void );
NactApplication *nact_application_new_with_args( int argc, char **argv );
-int nact_application_run( NactApplication *application );
-
G_END_DECLS
#endif /* __NACT_APPLICATION_H__ */
diff --git a/src/nact/nact-main.c b/src/nact/nact-main.c
index d1ae147..30c7ac4 100644
--- a/src/nact/nact-main.c
+++ b/src/nact/nact-main.c
@@ -39,13 +39,9 @@
int
main( int argc, char *argv[] )
{
- /* need to gtk_init before unique_app_new (see Bug #585536)
- */
- gtk_init( &argc, &argv );
-
NactApplication *app = nact_application_new_with_args( argc, argv );
- int ret = nact_application_run( app );
+ int ret = base_application_run( BASE_APPLICATION( app ));
g_object_unref( app );
diff --git a/src/nact/nact.c b/src/nact/nact.c
index 672790f..6382426 100644
--- a/src/nact/nact.c
+++ b/src/nact/nact.c
@@ -28,8 +28,12 @@
* ... and many others (see AUTHORS)
*/
+#ifdef HAVE_CONFIG_H
#include <config.h>
+#endif
+
#include <stdlib.h>
+
#include <glib/gi18n.h>
#include <gtk/gtkbutton.h>
#include <gtk/gtkliststore.h>
@@ -37,14 +41,20 @@
#include <gtk/gtkmessagedialog.h>
#include <gtk/gtktreeview.h>
#include <glade/glade-xml.h>
+
+#include <common/nact-action.h>
+#include <common/nact-action-profile.h>
+#include <common/nact-pivot.h>
#include <common/nautilus-actions-config.h>
#include <common/nautilus-actions-config-gconf-writer.h>
-#include "nact-utils.h"
+
#include "nact.h"
+#include "nact-application.h"
#include "nact-editor.h"
#include "nact-import-export.h"
#include "nact-prefs.h"
#include "nact-action-editor.h"
+#include "nact-utils.h"
/* gui callback functions */
void dialog_response_cb (GtkDialog *dialog, gint response_id, gpointer user_data);
@@ -55,13 +65,12 @@ void edit_button_clicked_cb (GtkButton *button, gpointer user_data);
void im_export_button_clicked_cb (GtkButton *button, gpointer user_data);
gboolean on_ActionsList_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer data );
-static gint actions_list_sort_by_label (gconstpointer a1, gconstpointer a2);
-static guint get_profiles_count( const NautilusActionsConfigAction *action );
-static void list_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data);
-static void fill_actions_list (GtkWidget *list);
-static void setup_actions_list (GtkWidget *list);
+static NactApplication *st_application = NULL;
+static NactPivot *st_pivot = NULL;
-static NautilusActionsConfigGconfWriter *config = NULL;
+static void list_selection_changed_cb (GtkTreeSelection *selection, gpointer user_data);
+static void fill_actions_list( GtkWidget *list );
+static void setup_actions_list( GtkWidget *list );
gboolean
on_ActionsList_button_press_event( GtkWidget *widget, GdkEventButton *event, gpointer data )
@@ -74,21 +83,6 @@ on_ActionsList_button_press_event( GtkWidget *widget, GdkEventButton *event, gpo
return( FALSE );
}
-static guint
-get_profiles_count( const NautilusActionsConfigAction *action )
-{
- return( nautilus_actions_config_action_get_profiles_count( action ));
-}
-
-static gint
-actions_list_sort_by_label (gconstpointer a1, gconstpointer a2)
-{
- NautilusActionsConfigAction* action1 = (NautilusActionsConfigAction*)a1;
- NautilusActionsConfigAction* action2 = (NautilusActionsConfigAction*)a2;
-
- return g_utf8_collate (action1->label, action2->label);
-}
-
static void
fill_actions_list (GtkWidget *list)
{
@@ -97,25 +91,34 @@ fill_actions_list (GtkWidget *list)
gtk_list_store_clear (model);
- actions = nautilus_actions_config_get_actions (NAUTILUS_ACTIONS_CONFIG (config));
- actions = g_slist_sort (actions, (GCompareFunc)actions_list_sort_by_label);
- for (l = actions; l != NULL; l = l->next) {
+ actions = nact_pivot_get_label_sorted_actions( st_pivot );
+
+ for( l = actions ; l != NULL ; l = l->next ){
GtkTreeIter iter;
GtkStockItem item;
GdkPixbuf* icon = NULL;
- NautilusActionsConfigAction *action = l->data;
- if (action->icon != NULL) {
- if (gtk_stock_lookup (action->icon, &item)) {
- icon = gtk_widget_render_icon (list, action->icon, GTK_ICON_SIZE_MENU, NULL);
- } else if (g_file_test (action->icon, G_FILE_TEST_EXISTS)
- && g_file_test (action->icon, G_FILE_TEST_IS_REGULAR)) {
+ NactAction *action = NACT_ACTION( l->data );
+ gchar *uuid = nact_action_get_uuid( action );
+ gchar *label = nact_action_get_label( action );
+ gchar *iconname = nact_action_get_icon( action );
+
+ /* TODO: use the same algorythm than Nautilus to find and
+ * display an icon + move the code to NactAction class +
+ * remove nact_action_get_verified_icon_name
+ */
+ if( icon ){
+ if( gtk_stock_lookup( iconname, &item )){
+ icon = gtk_widget_render_icon( list, iconname, GTK_ICON_SIZE_MENU, NULL );
+
+ } else if( g_file_test( iconname, G_FILE_TEST_EXISTS )
+ && g_file_test( iconname, G_FILE_TEST_IS_REGULAR )){
gint width;
gint height;
GError* error = NULL;
gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height);
- icon = gdk_pixbuf_new_from_file_at_size (action->icon, width, height, &error);
+ icon = gdk_pixbuf_new_from_file_at_size( iconname, width, height, &error );
if (error)
{
icon = NULL;
@@ -126,9 +129,13 @@ fill_actions_list (GtkWidget *list)
gtk_list_store_append (model, &iter);
gtk_list_store_set (model, &iter,
MENU_ICON_COLUMN, icon,
- MENU_LABEL_COLUMN, action->label,
- UUID_COLUMN, action->uuid,
+ MENU_LABEL_COLUMN, label,
+ UUID_COLUMN, uuid,
-1);
+
+ g_free( iconname );
+ g_free( label );
+ g_free( uuid );
}
nautilus_actions_config_free_actions_list (actions);
@@ -173,18 +180,19 @@ edit_button_clicked_cb (GtkButton *button, gpointer user_data)
if (gtk_tree_selection_get_selected (selection, &model, &iter)) {
gchar *uuid;
- NautilusActionsConfigAction *action;
+ NactAction *action;
gtk_tree_model_get (model, &iter, UUID_COLUMN, &uuid, -1);
- action = nautilus_actions_config_get_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);
+ action = NACT_ACTION( nact_pivot_get_action( st_pivot, uuid ));
+
if( action ){
- guint count = get_profiles_count( action );
+ guint count = nact_action_get_profiles_count( action );
if( count > 1 ){
- if (nact_editor_edit_action (action))
+ if (nact_editor_edit_action (( NautilusActionsConfigAction *) action))
fill_actions_list (nact_actions_list);
} else {
- if( nact_action_editor_edit( action ))
+ if( nact_action_editor_edit( ( NautilusActionsConfigAction *) action ))
fill_actions_list( nact_actions_list );
}
}
@@ -200,8 +208,8 @@ duplicate_button_clicked_cb (GtkButton *button, gpointer user_data)
GtkTreeIter iter;
GtkWidget *nact_actions_list;
GtkTreeModel* model;
- GError* error = NULL;
- gchar* tmp;
+ gchar *error = NULL;
+ gchar *tmp, *label;
nact_actions_list = nact_get_glade_widget ("ActionsList");
@@ -210,29 +218,29 @@ duplicate_button_clicked_cb (GtkButton *button, gpointer user_data)
if (gtk_tree_selection_get_selected (selection, &model, &iter))
{
gchar *uuid;
- NautilusActionsConfigAction *action;
- NautilusActionsConfigAction* new_action;
+ NactAction *action;
+ NactAction* new_action;
gtk_tree_model_get (model, &iter, UUID_COLUMN, &uuid, -1);
- action = nautilus_actions_config_get_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);
- new_action = nautilus_actions_config_action_dup_new (action);
- if (new_action)
- {
- if (nautilus_actions_config_add_action (NAUTILUS_ACTIONS_CONFIG (config), new_action, &error))
- {
- fill_actions_list (nact_actions_list);
- }
- else
- {
- /* i18n notes: will be displayed in a dialog */
- tmp = g_strdup_printf (_("Can't duplicate action '%s'!"), action->label);
- nautilus_actions_display_error (tmp, error->message);
- g_error_free (error);
- g_free (tmp);
- }
+ action = NACT_ACTION( nact_pivot_get_action( st_pivot, uuid ));
+ new_action = nact_action_duplicate( action );
+ nact_action_set_new_uuid( new_action );
+
+ /*if( nautilus_actions_config_add_action( NAUTILUS_ACTIONS_CONFIG (config), new_action, &error )){*/
+ if( nact_pivot_add_action( st_pivot, G_OBJECT( new_action ), &error )){
+ fill_actions_list (nact_actions_list);
+ } else {
+ /* i18n notes: will be displayed in a dialog */
+ label = nact_action_get_label( action );
+ tmp = g_strdup_printf (_("Can't duplicate action '%s'!"), label);
+ nautilus_actions_display_error( tmp, error );
+ g_free( error );
+ g_free( label );
+ g_free( tmp );
}
- g_free (uuid);
+
+ g_free( uuid );
}
}
@@ -252,7 +260,7 @@ delete_button_clicked_cb (GtkButton *button, gpointer user_data)
gchar *uuid;
gtk_tree_model_get (model, &iter, UUID_COLUMN, &uuid, -1);
- nautilus_actions_config_remove_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);
+ /*nautilus_actions_config_remove_action (NAUTILUS_ACTIONS_CONFIG (config), uuid);*/
fill_actions_list (nact_actions_list);
g_free (uuid);
@@ -358,7 +366,7 @@ setup_actions_list (GtkWidget *list)
}
GtkWindow *
-nact_init_dialog (void)
+nact_init_dialog( GObject *application )
{
gint width, height, x, y;
GtkWidget *nact_dialog;
@@ -366,7 +374,13 @@ nact_init_dialog (void)
/*GtkWidget* nact_edit_button;*/
GtkWidget* nact_about_button;
- config = nautilus_actions_config_gconf_writer_get ();
+ g_assert( NACT_IS_APPLICATION( application ));
+ st_application = NACT_APPLICATION( application );
+
+ g_object_get( G_OBJECT( st_application ), "pivot", &st_pivot, NULL );
+ g_assert( NACT_IS_PIVOT( st_pivot ));
+
+ /*config = nautilus_actions_config_gconf_writer_get ();*/
GladeXML *gui = nact_get_glade_xml_object (GLADE_MAIN_WIDGET);
if (!gui) {
@@ -379,7 +393,7 @@ nact_init_dialog (void)
nact_dialog = nact_get_glade_widget ("ActionsDialog");
nact_actions_list = nact_get_glade_widget ("ActionsList");
- setup_actions_list (nact_actions_list);
+ setup_actions_list( nact_actions_list );
/* Get the default dialog size */
gtk_window_get_default_size (GTK_WINDOW (nact_dialog), &width, &height);
diff --git a/src/nact/nact.h b/src/nact/nact.h
index 21af99f..a641592 100644
--- a/src/nact/nact.h
+++ b/src/nact/nact.h
@@ -31,6 +31,7 @@
#ifndef __NACT_H__
#define __NACT_H__
+#include <glib.h>
#include <gtk/gtk.h>
G_BEGIN_DECLS
@@ -42,7 +43,7 @@ enum {
N_COLUMN
};
-GtkWindow *nact_init_dialog( void );
+GtkWindow *nact_init_dialog( GObject *application );
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]