fma-object-menu.c 10.6 KB
Newer Older
1
/*
2 3
 * FileManager-Actions
 * A file-manager extension which offers configurable context menu actions.
4 5
 *
 * Copyright (C) 2005 The GNOME Foundation
6
 * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
Pierre Wieser's avatar
Pierre Wieser committed
7
 * Copyright (C) 2009-2015 Pierre Wieser and others (see AUTHORS)
8
 *
9
 * FileManager-Actions is free software; you can redistribute it and/or
10 11
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
12 13
 * the License, or (at your option) any later version.
 *
14
 * FileManager-Actions is distributed in the hope that it will be useful,
15 16
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17
 * General Public License for more details.
18
 *
19
 * You should have received a copy of the GNU General Public License
20
 * along with FileManager-Actions; see the file COPYING. If not, see
21
 * <http://www.gnu.org/licenses/>.
22 23 24 25 26 27 28 29 30 31 32 33
 *
 * 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

34
#include <glib/gi18n.h>
35
#include <string.h>
36

37
#include <api/fma-iio-provider.h>
38
#include <api/fma-ifactory-object.h>
39
#include <api/fma-object-api.h>
40

41
#include "fma-factory-provider.h"
42
#include "fma-factory-object.h"
43 44 45

/* private class data
 */
46
struct _FMAObjectMenuClassPrivate {
47 48 49
	void *empty;						/* so that gcc -pedantic is happy */
};

50 51
/* private instance data
 */
52
struct _FMAObjectMenuPrivate {
53 54 55
	gboolean dispose_has_run;
};

56
/* i18n: default label for a new menu */
57
#define NEW_NAUTILUS_MENU				N_( "New Nautilus menu" )
58

Pierre Wieser's avatar
Pierre Wieser committed
59
extern FMADataGroup menu_data_groups [];	/* defined in fma-object-menu-factory.c */
60

61
static FMAObjectItemClass *st_parent_class = NULL;
62

Pierre Wieser's avatar
Pierre Wieser committed
63 64 65 66 67 68 69 70 71 72 73 74
static GType         register_type( void );
static void          class_init( FMAObjectMenuClass *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 *object );
static void          instance_finalize( GObject *object );

static void          object_dump( const FMAObject *object );

static void          ifactory_object_iface_init( FMAIFactoryObjectInterface *iface, void *user_data );
static guint         ifactory_object_get_version( const FMAIFactoryObject *instance );
75
static FMADataGroup *ifactory_object_get_groups( const FMAIFactoryObject *instance );
Pierre Wieser's avatar
Pierre Wieser committed
76 77 78
static void          ifactory_object_read_done( FMAIFactoryObject *instance, const FMAIFactoryProvider *reader, void *reader_data, GSList **messages );
static guint         ifactory_object_write_start( FMAIFactoryObject *instance, const FMAIFactoryProvider *writer, void *writer_data, GSList **messages );
static guint         ifactory_object_write_done( FMAIFactoryObject *instance, const FMAIFactoryProvider *writer, void *writer_data, GSList **messages );
79

Pierre Wieser's avatar
Pierre Wieser committed
80 81
static void          icontext_iface_init( FMAIContextInterface *iface, void *user_data );
static gboolean      icontext_is_candidate( FMAIContext *object, guint target, GList *selection );
Pierre Wieser's avatar
Pierre Wieser committed
82

83
GType
84
fma_object_menu_get_type( void )
85
{
86 87 88
	static GType menu_type = 0;

	if( menu_type == 0 ){
89

90
		menu_type = register_type();
91 92
	}

93
	return( menu_type );
94 95 96 97 98
}

static GType
register_type( void )
{
99
	static const gchar *thisfn = "fma_object_menu_register_type";
100
	GType type;
101 102

	static GTypeInfo info = {
103
		sizeof( FMAObjectMenuClass ),
104 105
		NULL,
		NULL,
106 107 108
		( GClassInitFunc ) class_init,
		NULL,
		NULL,
109
		sizeof( FMAObjectMenu ),
110 111 112 113
		0,
		( GInstanceInitFunc ) instance_init
	};

Pierre Wieser's avatar
Pierre Wieser committed
114 115 116 117 118 119
	static const GInterfaceInfo icontext_iface_info = {
		( GInterfaceInitFunc ) icontext_iface_init,
		NULL,
		NULL
	};

120 121
	static const GInterfaceInfo ifactory_object_iface_info = {
		( GInterfaceInitFunc ) ifactory_object_iface_init,
122 123 124 125
		NULL,
		NULL
	};

126 127
	g_debug( "%s", thisfn );

128
	type = g_type_register_static( FMA_TYPE_OBJECT_ITEM, "FMAObjectMenu", &info, 0 );
129

130
	g_type_add_interface_static( type, FMA_TYPE_ICONTEXT, &icontext_iface_info );
Pierre Wieser's avatar
Pierre Wieser committed
131

132
	g_type_add_interface_static( type, FMA_TYPE_IFACTORY_OBJECT, &ifactory_object_iface_info );
133 134

	return( type );
135 136 137
}

static void
138
class_init( FMAObjectMenuClass *klass )
139
{
140
	static const gchar *thisfn = "fma_object_menu_class_init";
141
	GObjectClass *object_class;
142
	FMAObjectClass *naobject_class;
143 144 145 146 147 148

	g_debug( "%s: klass=%p", thisfn, ( void * ) klass );

	st_parent_class = g_type_class_peek_parent( klass );

	object_class = G_OBJECT_CLASS( klass );
149 150
	object_class->set_property = instance_set_property;
	object_class->get_property = instance_get_property;
151 152 153
	object_class->dispose = instance_dispose;
	object_class->finalize = instance_finalize;

154
	naobject_class = FMA_OBJECT_CLASS( klass );
Pierre Wieser's avatar
Pierre Wieser committed
155
	naobject_class->dump = object_dump;
156

157
	klass->private = g_new0( FMAObjectMenuClassPrivate, 1 );
158

159
	fma_factory_object_define_properties( object_class, menu_data_groups );
160 161 162 163 164
}

static void
instance_init( GTypeInstance *instance, gpointer klass )
{
165 166
	static const gchar *thisfn = "fma_object_menu_instance_init";
	FMAObjectMenu *self;
167

168
	g_return_if_fail( FMA_IS_OBJECT_MENU( instance ));
169

170
	self = FMA_OBJECT_MENU( instance );
171

172 173 174
	g_debug( "%s: instance=%p (%s), klass=%p",
			thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ), ( void * ) klass );

175
	self->private = g_new0( FMAObjectMenuPrivate, 1 );
176 177 178 179 180
}

static void
instance_get_property( GObject *object, guint property_id, GValue *value, GParamSpec *spec )
{
181
	g_return_if_fail( FMA_IS_OBJECT_MENU( object ));
182
	g_return_if_fail( FMA_IS_IFACTORY_OBJECT( object ));
183

184
	if( !FMA_OBJECT_MENU( object )->private->dispose_has_run ){
185

186
		fma_factory_object_get_as_value( FMA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
187 188 189 190 191 192
	}
}

static void
instance_set_property( GObject *object, guint property_id, const GValue *value, GParamSpec *spec )
{
193
	g_return_if_fail( FMA_IS_OBJECT_MENU( object ));
194
	g_return_if_fail( FMA_IS_IFACTORY_OBJECT( object ));
195

196
	if( !FMA_OBJECT_MENU( object )->private->dispose_has_run ){
197

198
		fma_factory_object_set_from_value( FMA_IFACTORY_OBJECT( object ), g_quark_to_string( property_id ), value );
199
	}
200 201 202 203 204
}

static void
instance_dispose( GObject *object )
{
205 206
	static const gchar *thisfn = "fma_object_menu_instance_dispose";
	FMAObjectMenu *self;
207

208
	g_return_if_fail( FMA_IS_OBJECT_MENU( object ));
209

210
	self = FMA_OBJECT_MENU( object );
211 212 213

	if( !self->private->dispose_has_run ){

214 215
		g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));

216 217 218 219 220 221 222 223 224 225 226 227
		self->private->dispose_has_run = TRUE;

		/* chain up to the parent class */
		if( G_OBJECT_CLASS( st_parent_class )->dispose ){
			G_OBJECT_CLASS( st_parent_class )->dispose( object );
		}
	}
}

static void
instance_finalize( GObject *object )
{
228 229
	static const gchar *thisfn = "fma_object_menu_instance_finalize";
	FMAObjectMenu *self;
230

231
	g_return_if_fail( FMA_IS_OBJECT_MENU( object ));
232

233
	self = FMA_OBJECT_MENU( object );
234

235 236
	g_debug( "%s: object=%p (%s)", thisfn, ( void * ) object, G_OBJECT_TYPE_NAME( object ));

237 238 239 240 241 242 243 244
	g_free( self->private );

	/* chain call to parent class */
	if( G_OBJECT_CLASS( st_parent_class )->finalize ){
		G_OBJECT_CLASS( st_parent_class )->finalize( object );
	}
}

Pierre Wieser's avatar
Pierre Wieser committed
245
static void
246
object_dump( const FMAObject *object )
Pierre Wieser's avatar
Pierre Wieser committed
247
{
248 249
	static const char *thisfn = "fma_object_menu_object_dump";
	FMAObjectMenu *self;
Pierre Wieser's avatar
Pierre Wieser committed
250

251
	g_return_if_fail( FMA_IS_OBJECT_MENU( object ));
Pierre Wieser's avatar
Pierre Wieser committed
252

253
	self = FMA_OBJECT_MENU( object );
Pierre Wieser's avatar
Pierre Wieser committed
254 255 256 257 258 259

	if( !self->private->dispose_has_run ){
		g_debug( "%s: object=%p (%s, ref_count=%d)", thisfn,
				( void * ) object, G_OBJECT_TYPE_NAME( object ), G_OBJECT( object )->ref_count );

		/* chain up to the parent class */
260 261
		if( FMA_OBJECT_CLASS( st_parent_class )->dump ){
			FMA_OBJECT_CLASS( st_parent_class )->dump( object );
Pierre Wieser's avatar
Pierre Wieser committed
262 263 264 265 266 267
		}

		g_debug( "+- end of dump" );
	}
}

268
static void
269
ifactory_object_iface_init( FMAIFactoryObjectInterface *iface, void *user_data )
270
{
271
	static const gchar *thisfn = "fma_object_menu_ifactory_object_iface_init";
272

273
	g_debug( "%s: iface=%p, user_data=%p", thisfn, ( void * ) iface, ( void * ) user_data );
274

275
	iface->get_version = ifactory_object_get_version;
276
	iface->get_groups = ifactory_object_get_groups;
277
	iface->read_done = ifactory_object_read_done;
278
	iface->write_start = ifactory_object_write_start;
279
	iface->write_done = ifactory_object_write_done;
280
}
281

282
static guint
283
ifactory_object_get_version( const FMAIFactoryObject *instance )
284 285
{
	return( 1 );
286 287
}

288
static FMADataGroup *
289
ifactory_object_get_groups( const FMAIFactoryObject *instance )
290 291 292 293
{
	return( menu_data_groups );
}

294
static void
295
ifactory_object_read_done( FMAIFactoryObject *instance, const FMAIFactoryProvider *reader, void *reader_data, GSList **messages )
296
{
297
	g_debug( "fma_object_menu_ifactory_object_read_done: instance=%p", ( void * ) instance );
298

299
	fma_object_item_deals_with_version( FMA_OBJECT_ITEM( instance ));
300

301
	/* prepare the context after the reading
Pierre Wieser's avatar
Pierre Wieser committed
302
	 */
303
	fma_icontext_read_done( FMA_ICONTEXT( instance ));
Pierre Wieser's avatar
Pierre Wieser committed
304

305
	/* last, set menu defaults
Pierre Wieser's avatar
Pierre Wieser committed
306
	 */
307
	fma_factory_object_set_defaults( instance );
308 309
}

310
static guint
311
ifactory_object_write_start( FMAIFactoryObject *instance, const FMAIFactoryProvider *writer, void *writer_data, GSList **messages )
312
{
313
	fma_object_item_rebuild_children_slist( FMA_OBJECT_ITEM( instance ));
314

Pierre Wieser's avatar
Pierre Wieser committed
315
	return( IIO_PROVIDER_CODE_OK );
316
}
317

318
static guint
319
ifactory_object_write_done( FMAIFactoryObject *instance, const FMAIFactoryProvider *writer, void *writer_data, GSList **messages )
320
{
Pierre Wieser's avatar
Pierre Wieser committed
321
	return( IIO_PROVIDER_CODE_OK );
322 323
}

Pierre Wieser's avatar
Pierre Wieser committed
324
static void
325
icontext_iface_init( FMAIContextInterface *iface, void *user_data )
Pierre Wieser's avatar
Pierre Wieser committed
326
{
327
	static const gchar *thisfn = "fma_object_menu_icontext_iface_init";
Pierre Wieser's avatar
Pierre Wieser committed
328

329
	g_debug( "%s: iface=%p, user_data=%p", thisfn, ( void * ) iface, ( void * ) user_data );
Pierre Wieser's avatar
Pierre Wieser committed
330 331 332 333 334

	iface->is_candidate = icontext_is_candidate;
}

static gboolean
335
icontext_is_candidate( FMAIContext *object, guint target, GList *selection )
Pierre Wieser's avatar
Pierre Wieser committed
336 337 338 339
{
	return( TRUE );
}

340
/**
341
 * fma_object_menu_new:
342
 *
343
 * Allocates a new #FMAObjectMenu object.
344
 *
345
 * Returns: the newly allocated #FMAObjectMenu object.
346
 *
347
 * Since: 2.30
348
 */
349 350
FMAObjectMenu *
fma_object_menu_new( void )
351
{
352
	FMAObjectMenu *menu;
353

354
	menu = g_object_new( FMA_TYPE_OBJECT_MENU, NULL );
355

356
	return( menu );
357
}
Pierre Wieser's avatar
Pierre Wieser committed
358 359

/**
360
 * fma_object_menu_new_with_defaults:
Pierre Wieser's avatar
Pierre Wieser committed
361
 *
362
 * Allocates a new #FMAObjectMenu object, and setup default values.
Pierre Wieser's avatar
Pierre Wieser committed
363
 *
364
 * Returns: the newly allocated #FMAObjectMenu object.
365
 *
366
 * Since: 2.30
Pierre Wieser's avatar
Pierre Wieser committed
367
 */
368 369
FMAObjectMenu *
fma_object_menu_new_with_defaults( void )
Pierre Wieser's avatar
Pierre Wieser committed
370
{
371 372 373
	FMAObjectMenu *menu = fma_object_menu_new();
	fma_object_set_new_id( menu, NULL );
	fma_object_set_label( menu, gettext( NEW_NAUTILUS_MENU ));
374
	fma_factory_object_set_defaults( FMA_IFACTORY_OBJECT( menu ));
Pierre Wieser's avatar
Pierre Wieser committed
375 376 377

	return( menu );
}