~ubuntu-branches/ubuntu/maverick/nautilus-actions/maverick

« back to all changes in this revision

Viewing changes to src/runtime/na-gconf-monitor.c

  • Committer: Bazaar Package Importer
  • Author(s): Christine Spang
  • Date: 2009-10-25 14:04:13 UTC
  • mfrom: (1.1.7 upstream) (3.1.5 squeeze)
  • Revision ID: james.westby@ubuntu.com-20091025140413-okqdth1kvcx8ko3o
Tags: 2.29.1-1
* New upstream version.
  - implements full API as defined for use by Nautilus menu
    extensions : this let the user define items which will be
    available when there is no selection, and will apply to
    current folder, either in the 'File' menu or in the
    toolbar ;
  - the ability for the user to define a full hierarchy of
    actions with menus, submenus, and so on ;
  - drag and drop ;
  - full cut/copy/paste clipboard support.
  - Gnome bugs fixed:
    - #325528 reported by Frederic Ruaudel
              (bloated  contextual menu)
    - #325587 reported by Frederic Ruaudel
              (drag & drop support)
    - #326699 reported by Frederic Ruaudel
              (action items do not remain in user defined order)
    - #353353 reported by Frederic Ruaudel
              (check if command exist and if not warn user)
    - #588482 reported by Sean
            (ordering in actions list)
    - #326699 reported by Frederic Ruaudel
            (action items do not remain in user defined order)
    - #353353 reported by Frederic Ruaudel
              (check if command exist and if not warn user)
    - #588482 reported by Sean
              (ordering in actions list)
    - #590400 reported by Pierre Wieser
              (have some sort of warnings in the ui)
    - #599520 reported by António Lima
              (do not mark authors names and emails for translating)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Nautilus Actions
 
3
 * A Nautilus extension which offers configurable context menu actions.
 
4
 *
 
5
 * Copyright (C) 2005 The GNOME Foundation
 
6
 * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
 
7
 * Copyright (C) 2009 Pierre Wieser and others (see AUTHORS)
 
8
 *
 
9
 * This Program is free software; you can redistribute it and/or
 
10
 * modify it under the terms of the GNU General Public License as
 
11
 * published by the Free Software Foundation; either version 2 of
 
12
 * the License, or (at your option) any later version.
 
13
 *
 
14
 * This Program is distributed in the hope that it will be useful,
 
15
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
16
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
17
 * GNU General Public License for more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public
 
20
 * License along with this Library; see the file COPYING.  If not,
 
21
 * write to the Free Software Foundation, Inc., 59 Temple Place,
 
22
 * Suite 330, Boston, MA 02111-1307, USA.
 
23
 *
 
24
 * Authors:
 
25
 *   Frederic Ruaudel <grumz@grumz.net>
 
26
 *   Rodrigo Moya <rodrigo@gnome-db.org>
 
27
 *   Pierre Wieser <pwieser@trychlos.org>
 
28
 *   ... and many others (see AUTHORS)
 
29
 */
 
30
 
 
31
#ifdef HAVE_CONFIG_H
 
32
#include <config.h>
 
33
#endif
 
34
 
 
35
#include "na-gconf-monitor.h"
 
36
 
 
37
/* private class data
 
38
 */
 
39
struct NAGConfMonitorClassPrivate {
 
40
        void *empty;                                            /* so that gcc -pedantic is happy */
 
41
};
 
42
 
 
43
/* private instance data
 
44
 */
 
45
struct NAGConfMonitorPrivate {
 
46
        gboolean              dispose_has_run;
 
47
        GConfClient          *gconf;
 
48
        gchar                *path;
 
49
        gint                  preload;
 
50
        GConfClientNotifyFunc handler;
 
51
        gpointer              user_data;
 
52
        guint                 monitor_id;
 
53
};
 
54
 
 
55
static GObjectClass *st_parent_class = NULL;
 
56
 
 
57
static GType register_type( void );
 
58
static void  class_init( NAGConfMonitorClass *klass );
 
59
static void  instance_init( GTypeInstance *instance, gpointer klass );
 
60
static void  instance_dispose( GObject *object );
 
61
static void  instance_finalize( GObject *object );
 
62
 
 
63
static guint install_monitor( NAGConfMonitor *monitor );
 
64
static void  release_monitor( NAGConfMonitor *monitor );
 
65
 
 
66
GType
 
67
na_gconf_monitor_get_type( void )
 
68
{
 
69
        static GType object_type = 0;
 
70
 
 
71
        if( !object_type ){
 
72
                object_type = register_type();
 
73
        }
 
74
 
 
75
        return( object_type );
 
76
}
 
77
 
 
78
static GType
 
79
register_type( void )
 
80
{
 
81
        static const gchar *thisfn = "na_gconf_monitor_register_type";
 
82
        GType type;
 
83
 
 
84
        static GTypeInfo info = {
 
85
                sizeof( NAGConfMonitorClass ),
 
86
                NULL,
 
87
                NULL,
 
88
                ( GClassInitFunc ) class_init,
 
89
                NULL,
 
90
                NULL,
 
91
                sizeof( NAGConfMonitor ),
 
92
                0,
 
93
                ( GInstanceInitFunc ) instance_init
 
94
        };
 
95
 
 
96
        g_debug( "%s", thisfn );
 
97
 
 
98
        type = g_type_register_static( G_TYPE_OBJECT, "NAGConfMonitor", &info, 0 );
 
99
 
 
100
        return( type );
 
101
}
 
102
 
 
103
static void
 
104
class_init( NAGConfMonitorClass *klass )
 
105
{
 
106
        static const gchar *thisfn = "na_gconf_monitor_class_init";
 
107
        GObjectClass *object_class;
 
108
 
 
109
        g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
 
110
 
 
111
        st_parent_class = g_type_class_peek_parent( klass );
 
112
 
 
113
        object_class = G_OBJECT_CLASS( klass );
 
114
        object_class->dispose = instance_dispose;
 
115
        object_class->finalize = instance_finalize;
 
116
 
 
117
        klass->private = g_new0( NAGConfMonitorClassPrivate, 1 );
 
118
}
 
119
 
 
120
static void
 
121
instance_init( GTypeInstance *instance, gpointer klass )
 
122
{
 
123
        static const gchar *thisfn = "na_gconf_monitor_instance_init";
 
124
        NAGConfMonitor *self;
 
125
 
 
126
        g_debug( "%s: instance=%p, klass=%p", thisfn, ( void * ) instance, ( void * ) klass );
 
127
        g_return_if_fail( NA_IS_GCONF_MONITOR( instance ));
 
128
        self = NA_GCONF_MONITOR( instance );
 
129
 
 
130
        self->private = g_new0( NAGConfMonitorPrivate, 1 );
 
131
}
 
132
 
 
133
static void
 
134
instance_dispose( GObject *object )
 
135
{
 
136
        static const gchar *thisfn = "na_gconf_monitor_instance_dispose";
 
137
        NAGConfMonitor *self;
 
138
 
 
139
        g_debug( "%s: object=%p", thisfn, ( void * ) object );
 
140
        g_return_if_fail( NA_IS_GCONF_MONITOR( object ));
 
141
        self = NA_GCONF_MONITOR( object );
 
142
 
 
143
        if( !self->private->dispose_has_run ){
 
144
 
 
145
                /* release the installed monitor before setting dispose_has_run */
 
146
                release_monitor( self );
 
147
 
 
148
                self->private->dispose_has_run = TRUE;
 
149
 
 
150
                /* chain up to the parent class */
 
151
                if( G_OBJECT_CLASS( st_parent_class )->dispose ){
 
152
                        G_OBJECT_CLASS( st_parent_class )->dispose( object );
 
153
                }
 
154
        }
 
155
}
 
156
 
 
157
static void
 
158
instance_finalize( GObject *object )
 
159
{
 
160
        NAGConfMonitor *self;
 
161
 
 
162
        g_return_if_fail( NA_IS_GCONF_MONITOR( object ));
 
163
        self = NA_GCONF_MONITOR( object );
 
164
 
 
165
        g_free( self->private->path );
 
166
        g_free( self->private );
 
167
 
 
168
        /* chain call to parent class */
 
169
        if( G_OBJECT_CLASS( st_parent_class )->finalize ){
 
170
                G_OBJECT_CLASS( st_parent_class )->finalize( object );
 
171
        }
 
172
}
 
173
 
 
174
/**
 
175
 * na_gconf_monitor_new:
 
176
 * @client: a #GConfClient object already initialized by the caller.
 
177
 * @path: the absolute path to monitor.
 
178
 * @preload: a #GConfClientPreloadType for this monitoring.
 
179
 * @handler: the function to be triggered by the monitor.
 
180
 * @user_data: data to pass to the @handler.
 
181
 *
 
182
 * Initializes the monitoring of a GConf path.
 
183
 */
 
184
NAGConfMonitor *
 
185
na_gconf_monitor_new( const gchar *path, GConfClientNotifyFunc handler, gpointer user_data )
 
186
{
 
187
        static const gchar *thisfn = "na_gconf_monitor_new";
 
188
        NAGConfMonitor *monitor;
 
189
 
 
190
        g_debug( "%s: path=%s, user_data=%p", thisfn, path, ( void * ) user_data );
 
191
 
 
192
        monitor = g_object_new( NA_GCONF_MONITOR_TYPE, NULL );
 
193
 
 
194
        monitor->private->gconf = gconf_client_get_default();
 
195
        monitor->private->path = g_strdup( path );
 
196
        monitor->private->preload = GCONF_CLIENT_PRELOAD_RECURSIVE;
 
197
        monitor->private->handler = handler;
 
198
        monitor->private->user_data = user_data;
 
199
 
 
200
        monitor->private->monitor_id = install_monitor( monitor );
 
201
 
 
202
        return( monitor );
 
203
}
 
204
 
 
205
static guint
 
206
install_monitor( NAGConfMonitor *monitor )
 
207
{
 
208
        static const gchar *thisfn = "na_gconf_monitor_install_monitor";
 
209
        GError *error = NULL;
 
210
        guint notify_id;
 
211
 
 
212
        g_return_val_if_fail( NA_IS_GCONF_MONITOR( monitor ), 0 );
 
213
        g_return_val_if_fail( !monitor->private->dispose_has_run, 0 );
 
214
 
 
215
        gconf_client_add_dir(
 
216
                        monitor->private->gconf,
 
217
                        monitor->private->path,
 
218
                        monitor->private->preload,
 
219
                        &error );
 
220
 
 
221
        if( error ){
 
222
                g_warning( "%s[gconf_client_add_dir] path=%s, error=%s", thisfn, monitor->private->path, error->message );
 
223
                g_error_free( error );
 
224
                return( 0 );
 
225
        }
 
226
 
 
227
        notify_id = gconf_client_notify_add(
 
228
                        monitor->private->gconf,
 
229
                        monitor->private->path,
 
230
                        monitor->private->handler,
 
231
                        monitor->private->user_data,
 
232
                        NULL,
 
233
                        &error );
 
234
 
 
235
        if( error ){
 
236
                g_warning( "%s[gconf_client_notify_add] path=%s, error=%s", thisfn, monitor->private->path, error->message );
 
237
                g_error_free( error );
 
238
                return( 0 );
 
239
        }
 
240
 
 
241
        return( notify_id );
 
242
}
 
243
 
 
244
/**
 
245
 * na_gconf_monitor_release_monitors:
 
246
 * @monitors: a list of #NAGConfMonitors.
 
247
 *
 
248
 * Release allocated monitors.
 
249
 */
 
250
void
 
251
na_gconf_monitor_release_monitors( GList *monitors )
 
252
{
 
253
        g_list_foreach( monitors, ( GFunc ) g_object_unref, NULL );
 
254
        g_list_free( monitors );
 
255
}
 
256
 
 
257
/*
 
258
 * this is called by instance_dispose, before setting dispose_has_run
 
259
 */
 
260
static void
 
261
release_monitor( NAGConfMonitor *monitor )
 
262
{
 
263
        static const gchar *thisfn = "na_gconf_monitor_release_monitor";
 
264
        GError *error = NULL;
 
265
 
 
266
        g_debug( "%s: monitor=%p", thisfn, ( void * ) monitor );
 
267
        g_return_if_fail( NA_IS_GCONF_MONITOR( monitor ));
 
268
        g_return_if_fail( !monitor->private->dispose_has_run );
 
269
 
 
270
        if( monitor->private->monitor_id ){
 
271
                gconf_client_notify_remove( monitor->private->gconf, monitor->private->monitor_id );
 
272
        }
 
273
 
 
274
        gconf_client_remove_dir( monitor->private->gconf, monitor->private->path, &error );
 
275
 
 
276
        if( error ){
 
277
                g_warning( "%s: path=%s, error=%s", thisfn, monitor->private->path, error->message );
 
278
                g_error_free( error );
 
279
        }
 
280
 
 
281
        g_object_unref( monitor->private->gconf );
 
282
}