Manage locked and mandatory preferences
[nautilus-actions.git] / src / nact / base-iprefs.c
blob7ea64b03d5e65cafd3f7fa1aada1996ff5b67889
1 /*
2 * Nautilus-Actions
3 * A Nautilus extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006, 2007, 2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009, 2010, 2011 Pierre Wieser and others (see AUTHORS)
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.
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.
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.
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)
32 #ifdef HAVE_CONFIG_H
33 #include <config.h>
34 #endif
36 #include <core/na-iprefs.h>
37 #include <core/na-settings.h>
39 #include "base-iprefs.h"
40 #include "nact-application.h"
42 /* private interface data
44 struct BaseIPrefsInterfacePrivate {
45 void *empty; /* so that gcc -pedantic is happy */
48 static gboolean st_initialized = FALSE;
49 static gboolean st_finalized = FALSE;
51 static GType register_type( void );
52 static void interface_base_init( BaseIPrefsInterface *klass );
53 static void interface_base_finalize( BaseIPrefsInterface *klass );
55 static gchar *v_iprefs_get_window_id( const BaseWindow *window );
57 static NASettings *get_settings( const BaseWindow *window );
58 static GList *read_int_list( const BaseWindow *window, const gchar *key );
59 static void write_int_list( const BaseWindow *window, const gchar *key, GList *list );
60 static void int_list_to_position( const BaseWindow *window, GList *list, gint *x, gint *y, gint *width, gint *height );
61 static GList *position_to_int_list( const BaseWindow *window, gint x, gint y, gint width, gint height );
62 static void free_int_list( GList *list );
64 GType
65 base_iprefs_get_type( void )
67 static GType iface_type = 0;
69 if( !iface_type ){
70 iface_type = register_type();
73 return( iface_type );
76 static GType
77 register_type( void )
79 static const gchar *thisfn = "base_iprefs_register_type";
80 GType type;
82 static const GTypeInfo info = {
83 sizeof( BaseIPrefsInterface ),
84 ( GBaseInitFunc ) interface_base_init,
85 ( GBaseFinalizeFunc ) interface_base_finalize,
86 NULL,
87 NULL,
88 NULL,
91 NULL
94 g_debug( "%s", thisfn );
96 type = g_type_register_static( G_TYPE_INTERFACE, "BaseIPrefs", &info, 0 );
98 g_type_interface_add_prerequisite( type, G_TYPE_OBJECT );
100 return( type );
103 static void
104 interface_base_init( BaseIPrefsInterface *klass )
106 static const gchar *thisfn = "base_iprefs_interface_base_init";
108 if( !st_initialized ){
110 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
112 klass->private = g_new0( BaseIPrefsInterfacePrivate, 1 );
114 klass->iprefs_get_window_id = NULL;
116 st_initialized = TRUE;
120 static void
121 interface_base_finalize( BaseIPrefsInterface *klass )
123 static const gchar *thisfn = "base_iprefs_interface_base_finalize";
125 if( st_initialized && !st_finalized ){
127 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
129 st_finalized = TRUE;
131 g_free( klass->private );
136 * base_iprefs_position_window:
137 * @window: this #BaseWindow-derived window.
139 * Position the specified window on the screen.
141 * A window position is stored as a list of integers "x,y,width,height".
143 void
144 base_iprefs_position_window( const BaseWindow *window )
146 GtkWindow *toplevel;
147 gchar *key;
149 g_return_if_fail( BASE_IS_WINDOW( window ));
150 g_return_if_fail( BASE_IS_IPREFS( window ));
152 if( st_initialized && !st_finalized ){
154 key = v_iprefs_get_window_id( window );
155 if( key ){
156 toplevel = base_window_get_toplevel( BASE_WINDOW( window ));
157 base_iprefs_position_named_window( window, toplevel, key );
158 g_free( key );
164 * base_iprefs_position_named_window:
165 * @window: this #BaseWindow-derived window.
166 * @toplevel: the toplevel #GtkWindow whose size and position are to be
167 * set.
168 * @key: the string id of this toplevel.
170 * Positions the specified window on the screen, maximizing it by the
171 * actual current screen size. Note that this is a rough approximation
172 * as some of the screen is reserved by deskbars and so...
174 void
175 base_iprefs_position_named_window( const BaseWindow *window, GtkWindow *toplevel, const gchar *key )
177 static const gchar *thisfn = "base_iprefs_position_named_window";
178 GList *list;
179 gint x=0, y=0, width=0, height=0;
180 GdkDisplay *display;
181 GdkScreen *screen;
182 gint screen_width, screen_height;
184 g_return_if_fail( BASE_IS_WINDOW( window ));
185 g_return_if_fail( BASE_IS_IPREFS( window ));
187 if( st_initialized && !st_finalized ){
189 list = read_int_list( window, key );
191 if( list ){
192 int_list_to_position( window, list, &x, &y, &width, &height );
193 g_debug( "%s: key=%s, x=%d, y=%d, width=%d, height=%d", thisfn, key, x, y, width, height );
194 free_int_list( list );
197 if( width > 0 && height > 0 ){
198 display = gdk_display_get_default();
199 screen = gdk_display_get_screen( display, 0 );
200 screen_width = gdk_screen_get_width( screen );
201 screen_height = gdk_screen_get_height( screen );
203 if(( x+width < screen_width ) && ( y+height < screen_height )){
204 gtk_window_move( toplevel, x, y );
205 gtk_window_resize( toplevel, width, height );
212 * base_iprefs_save_window_position:
213 * @window: this #BaseWindow-derived window.
215 * Save the size and position of the specified window.
217 void
218 base_iprefs_save_window_position( const BaseWindow *window )
220 GtkWindow *toplevel;
221 gchar *key;
223 g_return_if_fail( BASE_IS_WINDOW( window ));
224 g_return_if_fail( BASE_IS_IPREFS( window ));
226 if( st_initialized && !st_finalized ){
228 key = v_iprefs_get_window_id( window );
229 if( key ){
230 toplevel = base_window_get_toplevel( BASE_WINDOW( window ));
231 base_iprefs_save_named_window_position( window, toplevel, key );
232 g_free( key );
238 * base_iprefs_save_named_window_position:
239 * @window: this #BaseWindow-derived window.
240 * @toplevel: the #GtkWindow whose size and position are to be saved.
241 * @key: the name of the window.
243 * Save size and position of the specified window.
245 void
246 base_iprefs_save_named_window_position( const BaseWindow *window, GtkWindow *toplevel, const gchar *key )
248 static const gchar *thisfn = "base_iprefs_save_named_window_position";
249 gint x, y, width, height;
250 GList *list;
252 g_return_if_fail( BASE_IS_WINDOW( window ));
253 g_return_if_fail( BASE_IS_IPREFS( window ));
255 if( st_initialized && !st_finalized ){
257 if( GTK_IS_WINDOW( toplevel )){
258 gtk_window_get_position( toplevel, &x, &y );
259 gtk_window_get_size( toplevel, &width, &height );
260 g_debug( "%s: key=%s, x=%d, y=%d, width=%d, height=%d", thisfn, key, x, y, width, height );
262 list = position_to_int_list( window, x, y, width, height );
263 write_int_list( window, key, list );
264 free_int_list( list );
269 static gchar *
270 v_iprefs_get_window_id( const BaseWindow *window )
272 g_return_val_if_fail( BASE_IS_IPREFS( window ), NULL );
274 if( BASE_IPREFS_GET_INTERFACE( window )->iprefs_get_window_id ){
275 return( BASE_IPREFS_GET_INTERFACE( window )->iprefs_get_window_id( window ));
278 return( NULL );
281 /* It seems inevitable that preferences are attached to the application.
282 * Unfortunately, it does not seem possible to have a base window size and
283 * position itself. So, this BaseIPrefs interface is not really a base
284 * interface, but rather a common one, attached to the application
286 static NASettings *
287 get_settings( const BaseWindow *window )
289 NactApplication *appli = NACT_APPLICATION( base_window_get_application( window ));
290 NAUpdater *updater = nact_application_get_updater( appli );
291 return( na_pivot_get_settings( NA_PIVOT( updater )));
295 * returns a list of int
297 static GList *
298 read_int_list( const BaseWindow *window, const gchar *key )
300 NASettings *settings = get_settings( window );
301 return( na_settings_get_uint_list( settings, key, NULL, NULL ));
304 static void
305 write_int_list( const BaseWindow *window, const gchar *key, GList *list )
307 NASettings *settings = get_settings( window );
308 na_settings_set_uint_list( settings, key, list );
312 * extract the position of the window from the list of unsigned integers
314 static void
315 int_list_to_position( const BaseWindow *window, GList *list, gint *x, gint *y, gint *width, gint *height )
317 GList *it;
318 int i;
320 g_assert( x );
321 g_assert( y );
322 g_assert( width );
323 g_assert( height );
325 for( it=list, i=0 ; it ; it=it->next, i+=1 ){
326 switch( i ){
327 case 0:
328 *x = GPOINTER_TO_UINT( it->data );
329 break;
330 case 1:
331 *y = GPOINTER_TO_UINT( it->data );
332 break;
333 case 2:
334 *width = GPOINTER_TO_UINT( it->data );
335 break;
336 case 3:
337 *height = GPOINTER_TO_UINT( it->data );
338 break;
343 static GList *
344 position_to_int_list( const BaseWindow *window, gint x, gint y, gint width, gint height )
346 GList *list = NULL;
348 list = g_list_append( list, GUINT_TO_POINTER( x ));
349 list = g_list_append( list, GUINT_TO_POINTER( y ));
350 list = g_list_append( list, GUINT_TO_POINTER( width ));
351 list = g_list_append( list, GUINT_TO_POINTER( height ));
353 return( list );
357 * free the list of int
359 static void
360 free_int_list( GList *list )
362 g_list_free( list );