Set Nautilus-Actions as being the actual official product name
[nautilus-actions.git] / src / nact / nact-providers-list.c
blobe38491802e63957bac6271d0a7697a8f7a5269b1
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)
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
35 #include <gconf/gconf-client.h>
36 #include <gdk/gdkkeysyms.h>
37 #include <glib/gi18n.h>
39 #include <api/na-core-utils.h>
40 #include <api/na-gconf-utils.h>
41 #include <api/na-object-api.h>
43 #include <core/na-io-provider.h>
44 #include <core/na-iprefs.h>
46 #include "nact-application.h"
47 #include "nact-gtk-utils.h"
48 #include "nact-providers-list.h"
50 /* column ordering
52 enum {
53 PROVIDER_READABLE_COLUMN = 0,
54 PROVIDER_WRITABLE_COLUMN,
55 PROVIDER_LIBELLE_COLUMN,
56 PROVIDER_ID_COLUMN,
57 PROVIDER_PROVIDER_COLUMN,
58 PROVIDER_N_COLUMN
61 /* some data needed when saving the list sore
63 typedef struct {
64 GList *providers;
65 GConfClient *gconf;
66 gchar *path;
67 GSList *order;
69 ProvidersListSaveData;
71 #define PROVIDERS_LIST_TREEVIEW "nact-providers-list-treeview"
73 static gboolean st_on_selection_change = FALSE;
75 static void init_view_setup_providers( GtkTreeView *treeview, BaseWindow *window );
76 static void init_view_connect_signals( GtkTreeView *treeview, BaseWindow *window );
77 static void init_view_select_first_row( GtkTreeView *treeview );
79 static gboolean providers_list_save_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter* iter, ProvidersListSaveData *plsd );
81 static void on_selection_changed( GtkTreeSelection *selection, BaseWindow *window );
82 static void on_readable_toggled( GtkCellRendererToggle *renderer, gchar *path, BaseWindow *window );
83 static void on_writable_toggled( GtkCellRendererToggle *renderer, gchar *path, BaseWindow *window );
84 static void on_up_clicked( GtkButton *button, BaseWindow *window );
85 static void on_down_clicked( GtkButton *button, BaseWindow *window );
87 static void display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, GtkTreeView *treeview );
88 static GtkButton *get_up_button( BaseWindow *window );
89 static GtkButton *get_down_button( BaseWindow *window );
91 /**
92 * nact_providers_list_create_providers_list:
93 * @treeview: the #GtkTreeView.
95 * Create the treeview model when initially loading the widget from
96 * the UI manager.
98 void
99 nact_providers_list_create_model( GtkTreeView *treeview )
101 static const char *thisfn = "nact_providers_list_create_model";
102 GtkListStore *model;
103 GtkCellRenderer *toggled_cell;
104 GtkTreeViewColumn *column;
105 GtkCellRenderer *text_cell;
106 GtkTreeSelection *selection;
108 g_debug( "%s: treeview=%p", thisfn, ( void * ) treeview );
109 g_return_if_fail( GTK_IS_TREE_VIEW( treeview ));
111 model = gtk_list_store_new( PROVIDER_N_COLUMN, G_TYPE_BOOLEAN, G_TYPE_BOOLEAN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_OBJECT );
112 gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( model ));
113 g_object_unref( model );
115 toggled_cell = gtk_cell_renderer_toggle_new();
116 column = gtk_tree_view_column_new_with_attributes(
117 _( "To be read" ),
118 toggled_cell,
119 "active", PROVIDER_READABLE_COLUMN,
120 NULL );
121 gtk_tree_view_append_column( treeview, column );
123 toggled_cell = gtk_cell_renderer_toggle_new();
124 column = gtk_tree_view_column_new_with_attributes(
125 _( "Writable" ),
126 toggled_cell,
127 "active", PROVIDER_WRITABLE_COLUMN,
128 NULL );
129 gtk_tree_view_append_column( treeview, column );
131 text_cell = gtk_cell_renderer_text_new();
132 column = gtk_tree_view_column_new_with_attributes(
133 _( "I/O Provider" ),
134 text_cell,
135 "text", PROVIDER_LIBELLE_COLUMN,
136 NULL );
137 gtk_tree_view_column_set_cell_data_func( column, text_cell, ( GtkTreeCellDataFunc ) display_label, treeview, NULL );
138 gtk_tree_view_append_column( treeview, column );
140 /* PROVIDER_ID_COLUMN */
141 column = gtk_tree_view_column_new();
142 gtk_tree_view_append_column( treeview, column );
143 gtk_tree_view_column_set_visible( column, FALSE );
145 /* PROVIDER_PROVIDER_COLUMN */
146 column = gtk_tree_view_column_new();
147 gtk_tree_view_append_column( treeview, column );
148 gtk_tree_view_column_set_visible( column, FALSE );
150 gtk_tree_view_set_headers_visible( treeview, TRUE );
152 selection = gtk_tree_view_get_selection( treeview );
153 gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE );
157 * nact_providers_list_init_view:
158 * @treeview: the #GtkTreeView.
159 * @window: the parent #BaseWindow which embeds the view.
161 * Connects signals at runtime initialization of the widget, and setup
162 * current default values.
164 void
165 nact_providers_list_init_view( GtkTreeView *treeview, BaseWindow *window )
167 static const gchar *thisfn = "nact_providers_list_init_view";
169 g_debug( "%s: treeview=%p, window=%p", thisfn, ( void * ) treeview, ( void * ) window );
170 g_return_if_fail( BASE_IS_WINDOW( window ));
171 g_return_if_fail( GTK_IS_TREE_VIEW( treeview ));
173 g_object_set_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW, treeview );
175 init_view_setup_providers( treeview, window );
176 init_view_connect_signals( treeview, window );
178 init_view_select_first_row( treeview );
181 static void
182 init_view_setup_providers( GtkTreeView *treeview, BaseWindow *window )
184 NactApplication *application;
185 NAUpdater *updater;
186 GtkListStore *model;
187 GList *providers, *iter;
188 GtkTreeIter row;
189 gchar *id, *libelle;
191 model = GTK_LIST_STORE( gtk_tree_view_get_model( treeview ));
193 application = NACT_APPLICATION( base_window_get_application( window ));
194 updater = nact_application_get_updater( application );
195 providers = na_io_provider_get_providers_list( NA_PIVOT( updater ));
197 for( iter = providers ; iter ; iter = iter->next ){
199 gtk_list_store_append( model, &row );
201 id = na_io_provider_get_id( NA_IO_PROVIDER( iter->data ));
202 libelle = na_io_provider_get_name( NA_IO_PROVIDER( iter->data ));
204 if( !libelle || !g_utf8_strlen( libelle, -1 )){
206 g_free( libelle );
207 if( na_io_provider_get_provider( NA_IO_PROVIDER( iter->data ))){
209 /* i18n: default name when the I/O providers doesn't provide one */
210 libelle = g_strdup_printf( "<%s: %s>", id, _( "no name" ));
211 } else {
213 /* i18n: name displayed when the corresponding I/O provider is unavailable at runtime */
214 libelle = g_strdup_printf( "<%s: %s>", id, _( "unavailable I/O provider" ));
218 gtk_list_store_set( model, &row,
219 PROVIDER_READABLE_COLUMN, na_io_provider_is_user_readable_at_startup( NA_IO_PROVIDER( iter->data ), NA_IPREFS( updater )),
220 PROVIDER_WRITABLE_COLUMN, na_io_provider_is_user_writable( NA_IO_PROVIDER( iter->data ), NA_IPREFS( updater )),
221 PROVIDER_LIBELLE_COLUMN, libelle,
222 PROVIDER_ID_COLUMN, id,
223 PROVIDER_PROVIDER_COLUMN, iter->data,
224 -1 );
226 g_free( libelle );
227 g_free( id );
231 static void
232 init_view_connect_signals( GtkTreeView *treeview, BaseWindow *window )
234 GtkTreeViewColumn *column;
235 GList *renderers;
236 GtkButton *up_button, *down_button;
238 column = gtk_tree_view_get_column( treeview, PROVIDER_READABLE_COLUMN );
239 renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
240 base_window_signal_connect(
241 window,
242 G_OBJECT( renderers->data ),
243 "toggled",
244 G_CALLBACK( on_readable_toggled ));
246 column = gtk_tree_view_get_column( treeview, PROVIDER_WRITABLE_COLUMN );
247 renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
248 base_window_signal_connect(
249 window,
250 G_OBJECT( renderers->data ),
251 "toggled",
252 G_CALLBACK( on_writable_toggled ));
254 up_button = get_up_button( window );
255 base_window_signal_connect(
256 window,
257 G_OBJECT( up_button ),
258 "clicked",
259 G_CALLBACK( on_up_clicked ));
261 down_button = get_down_button( window );
262 base_window_signal_connect(
263 window,
264 G_OBJECT( down_button ),
265 "clicked",
266 G_CALLBACK( on_down_clicked ));
268 base_window_signal_connect(
269 window,
270 G_OBJECT( gtk_tree_view_get_selection( treeview )),
271 "changed",
272 G_CALLBACK( on_selection_changed ));
275 static void
276 init_view_select_first_row( GtkTreeView *treeview )
278 GtkTreeSelection *selection;
279 GtkTreePath *path;
281 path = gtk_tree_path_new_first();
282 if( path ){
283 selection = gtk_tree_view_get_selection( treeview );
284 gtk_tree_selection_select_path( selection, path );
285 gtk_tree_path_free( path );
290 * nact_providers_list_save:
291 * @window: the #BaseWindow which embeds this treeview.
293 * Save the I/O provider status as a GConf preference,
294 * and update the I/O providers list maintained by #NAIOProvider class.
296 void
297 nact_providers_list_save( BaseWindow *window )
299 static const gchar *thisfn = "nact_providers_list_save";
300 NactApplication *application;
301 NAUpdater *updater;
302 GList *providers;
303 GtkTreeView *treeview;
304 GtkTreeModel *model;
305 ProvidersListSaveData *plsd;
307 g_debug( "%s: window=%p", thisfn, ( void * ) window );
309 application = NACT_APPLICATION( base_window_get_application( window ));
310 updater = nact_application_get_updater( application );
311 providers = na_io_provider_get_providers_list( NA_PIVOT( updater ));
313 plsd = g_new0( ProvidersListSaveData, 1 );
314 plsd->providers = providers;
315 plsd->gconf = na_iprefs_get_gconf_client( NA_IPREFS( updater ));
316 plsd->path = gconf_concat_dir_and_key( IPREFS_GCONF_BASEDIR, IO_PROVIDER_KEY_ROOT );
317 plsd->order = NULL;
319 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
320 model = gtk_tree_view_get_model( treeview );
321 gtk_tree_model_foreach( model, ( GtkTreeModelForeachFunc ) providers_list_save_iter, plsd );
323 plsd->order = g_slist_reverse( plsd->order );
324 na_iprefs_write_string_list( NA_IPREFS( updater ), IO_PROVIDER_KEY_ORDER, plsd->order );
325 na_io_provider_reorder_providers_list( NA_PIVOT( updater ));
327 na_core_utils_slist_free( plsd->order );
328 g_free( plsd->path );
329 g_free( plsd );
332 static gboolean
333 providers_list_save_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter* iter, ProvidersListSaveData *plsd )
335 gchar *id;
336 gboolean readable, writable;
337 NAIOProvider *provider;
338 gchar *key, *entry;
340 gtk_tree_model_get( model, iter,
341 PROVIDER_ID_COLUMN, &id,
342 PROVIDER_READABLE_COLUMN, &readable,
343 PROVIDER_WRITABLE_COLUMN, &writable,
344 PROVIDER_PROVIDER_COLUMN, &provider,
345 -1 );
347 key = gconf_concat_dir_and_key( plsd->path, id );
349 entry = gconf_concat_dir_and_key( key, IO_PROVIDER_KEY_READABLE );
350 na_gconf_utils_write_bool( plsd->gconf, entry, readable, NULL );
351 g_free( entry );
353 entry = gconf_concat_dir_and_key( key, IO_PROVIDER_KEY_WRITABLE );
354 na_gconf_utils_write_bool( plsd->gconf, entry, writable, NULL );
355 g_free( entry );
357 plsd->order = g_slist_prepend( plsd->order, g_strdup( id ));
359 g_object_unref( provider );
360 g_free( id );
361 g_free( key );
363 return( FALSE ); /* don't stop looping */
367 * nact_providers_list_dispose:
368 * @treeview: the #GtkTreeView.
370 * Release the content of the page when we are closing the Preferences dialog.
372 void
373 nact_providers_list_dispose( BaseWindow *window )
375 static const gchar *thisfn = "nact_providers_list_dispose";
376 GtkTreeView *treeview;
377 GtkTreeModel *model;
378 GtkTreeSelection *selection;
380 g_debug( "%s: window=%p", thisfn, ( void * ) window );
382 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
383 model = gtk_tree_view_get_model( treeview );
384 selection = gtk_tree_view_get_selection( treeview );
386 gtk_tree_selection_unselect_all( selection );
387 gtk_list_store_clear( GTK_LIST_STORE( model ));
390 static void
391 on_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
393 GtkTreeModel *model;
394 GtkTreeIter iter;
395 GtkButton *button;
396 GtkTreePath *path;
397 gboolean may_up, may_down;
399 may_up = FALSE;
400 may_down = FALSE;
402 if( gtk_tree_selection_get_selected( selection, &model, &iter )){
403 path = gtk_tree_model_get_path( model, &iter );
404 may_up = gtk_tree_path_prev( path );
405 gtk_tree_path_free( path );
407 may_down = gtk_tree_model_iter_next( model, &iter );
410 button = get_up_button( window );
411 gtk_widget_set_sensitive( GTK_WIDGET( button ), may_up );
413 button = get_down_button( window );
414 gtk_widget_set_sensitive( GTK_WIDGET( button ), may_down );
417 static void
418 on_readable_toggled( GtkCellRendererToggle *renderer, gchar *path_string, BaseWindow *window )
420 GtkTreeView *treeview;
421 GtkTreeModel *model;
422 GtkTreeIter iter;
423 gboolean state;
425 if( !st_on_selection_change ){
427 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
428 model = gtk_tree_view_get_model( treeview );
429 if( gtk_tree_model_get_iter_from_string( model, &iter, path_string )){
430 gtk_tree_model_get( model, &iter, PROVIDER_READABLE_COLUMN, &state, -1 );
431 gtk_list_store_set( GTK_LIST_STORE( model ), &iter, PROVIDER_READABLE_COLUMN, !state, -1 );
436 static void
437 on_writable_toggled( GtkCellRendererToggle *renderer, gchar *path_string, BaseWindow *window )
439 GtkTreeView *treeview;
440 GtkTreeModel *model;
441 GtkTreeIter iter;
442 gboolean state;
444 if( !st_on_selection_change ){
446 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
447 model = gtk_tree_view_get_model( treeview );
448 if( gtk_tree_model_get_iter_from_string( model, &iter, path_string )){
449 gtk_tree_model_get( model, &iter, PROVIDER_WRITABLE_COLUMN, &state, -1 );
450 gtk_list_store_set( GTK_LIST_STORE( model ), &iter, PROVIDER_WRITABLE_COLUMN, !state, -1 );
455 static void
456 on_up_clicked( GtkButton *button, BaseWindow *window )
458 GtkTreeView *treeview;
459 GtkTreeSelection *selection;
460 GtkTreeModel *model;
461 GtkTreeIter iter_selected;
462 GtkTreePath *path_prev;
463 GtkTreeIter iter_prev;
465 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
466 selection = gtk_tree_view_get_selection( treeview );
467 if( gtk_tree_selection_get_selected( selection, &model, &iter_selected )){
468 path_prev = gtk_tree_model_get_path( model, &iter_selected );
469 if( gtk_tree_path_prev( path_prev )){
470 if( gtk_tree_model_get_iter( model, &iter_prev, path_prev )){
471 gtk_list_store_move_before( GTK_LIST_STORE( model ), &iter_selected, &iter_prev );
472 gtk_tree_selection_unselect_all( selection );
473 gtk_tree_selection_select_path( selection, path_prev );
476 gtk_tree_path_free( path_prev );
480 static void
481 on_down_clicked( GtkButton *button, BaseWindow *window )
483 GtkTreeView *treeview;
484 GtkTreeSelection *selection;
485 GtkTreeModel *model;
486 GtkTreeIter iter_selected;
487 GtkTreeIter *iter_next;
488 GtkTreePath *path_next;
490 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), PROVIDERS_LIST_TREEVIEW ));
491 selection = gtk_tree_view_get_selection( treeview );
492 if( gtk_tree_selection_get_selected( selection, &model, &iter_selected )){
493 iter_next = gtk_tree_iter_copy( &iter_selected );
494 if( gtk_tree_model_iter_next( model, iter_next )){
495 path_next = gtk_tree_model_get_path( model, iter_next );
496 gtk_list_store_move_after( GTK_LIST_STORE( model ), &iter_selected, iter_next );
497 gtk_tree_selection_unselect_all( selection );
498 gtk_tree_selection_select_path( selection, path_next );
499 gtk_tree_path_free( path_next );
501 gtk_tree_iter_free( iter_next );
506 * unavailable provider: italic grey
508 static void
509 display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, GtkTreeView *treeview )
511 NAIOProvider *provider;
512 gchar *name;
514 gtk_tree_model_get( model, iter, PROVIDER_LIBELLE_COLUMN, &name, PROVIDER_PROVIDER_COLUMN, &provider, -1 );
516 g_object_set( cell, "style-set", FALSE, NULL );
517 g_object_set( cell, "foreground-set", FALSE, NULL );
519 if( !na_io_provider_get_provider( provider )){
521 g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
522 g_object_set( cell, "foreground", "grey", "foreground-set", TRUE, NULL );
526 g_object_unref( provider );
528 g_object_set( cell, "text", name, NULL );
529 g_free( name );
532 static GtkButton *
533 get_up_button( BaseWindow *window )
535 GtkButton *button;
537 button = GTK_BUTTON( base_window_get_widget( window, "ProviderButtonUp" ));
539 return( button );
542 static GtkButton *
543 get_down_button( BaseWindow *window )
545 GtkButton *button;
547 button = GTK_BUTTON( base_window_get_widget( window, "ProviderButtonDown" ));
549 return( button );