Convert NASettings to a private singleton
[nautilus-actions.git] / src / nact / nact-schemes-list.c
blob46c45a3cf83975d3ca55f87bb4b63cee5ac23e43
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 <glib/gi18n.h>
37 #include <api/na-core-utils.h>
38 #include <api/na-object-api.h>
40 #include <core/na-iprefs.h>
42 #include "base-keysyms.h"
43 #include "nact-application.h"
44 #include "base-gtk-utils.h"
45 #include "nact-main-tab.h"
46 #include "nact-schemes-list.h"
48 /* data attached to the treeview widget on initial load
49 * at this time, only treeview and mode are set
50 * on runtime init, the current window is associated to the widget,
51 * and so, indirectly, to this data
52 * at this time, window is set
54 typedef struct {
55 /* set when creating the model (on_initialize_gtk_toplevel)
57 GtkTreeView *treeview;
58 guint mode;
60 /* set when initializing the view (on_initialize_base_window)
62 BaseWindow *window;
63 gboolean preferences_locked;
64 gboolean editable;
65 pf_new_selection_cb pf_on_sel_changed;
66 void *user_data;
68 SchemesListData;
70 /* column ordering in the model
72 enum {
73 SCHEMES_KEYWORD_COLUMN = 0,
74 SCHEMES_DESC_COLUMN,
75 SCHEMES_ALREADY_USED_COLUMN,
76 SCHEMES_N_COLUMN
79 #define SCHEMES_LIST_DATA "nact-schemes-list-data"
80 #define SCHEMES_LIST_TREEVIEW "nact-schemes-list-treeview"
82 static void init_view_setup_defaults( SchemesListData *data );
83 static GSList *init_view_get_default_list( SchemesListData *data );
84 static GSList *init_view_get_default_default_list( SchemesListData *data );
85 static void init_view_connect_signals( SchemesListData *data );
86 static void init_view_select_first_row( SchemesListData *data );
88 static gboolean setup_values_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter* iter, GSList *schemes );
90 static GSList *get_list_schemes( GtkTreeView *treeview );
91 static gboolean get_list_schemes_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter* iter, GSList **list );
93 static gboolean on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window );
94 static void on_selection_changed( GtkTreeSelection *selection, BaseWindow *window );
95 static void on_add_clicked( GtkButton *button, BaseWindow *window );
96 static void on_remove_clicked( GtkButton *button, BaseWindow *window );
97 static void on_desc_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, BaseWindow *window );
98 static void on_keyword_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, BaseWindow *window );
100 static void edit_cell( BaseWindow *window, const gchar *path_string, const gchar *text, gint column, gboolean *state, gchar **old_text );
101 static void edit_inline( BaseWindow *window );
102 static void insert_new_row( BaseWindow *window );
103 static void delete_row( BaseWindow *window );
104 static void display_keyword( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, SchemesListData *data );
105 static void display_description( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, SchemesListData *data );
106 static void display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, SchemesListData *data, guint column_id );
108 static GtkButton *get_add_button( BaseWindow *window );
109 static GtkButton *get_remove_button( BaseWindow *window );
110 static SchemesListData *get_schemes_list_data( GtkTreeView *treeview );
113 * nact_schemes_list_create_schemes_list:
114 * @treeview: the #GtkTreeView.
115 * @mode: whether we are opening this listview for preferences edition,
116 * or to add a new scheme from the default list.
118 * Create the treeview model when initially loading the widget from
119 * the UI manager.
120 * Associates the SchemesListData structure to the widget.
122 * The default list of schemes is displayed in two cases:
123 * - when adding a scheme to a NAObjectItem (cf. NactISchemesTab)
124 * so the schemes list is opened for selection
126 * we have chosen to not allow default schemes list edition in this mode
127 * because we do not have ok/cancel buttons; the user may start with editing
128 * and does not have any way of cancel it
130 * - when editing the default schemes list in Preferences
131 * so each row may be edited
132 * edition is only allowed if preferences are not locked and default schemes
133 * list is not a mandatory pref.
135 void
136 nact_schemes_list_create_model( GtkTreeView *treeview, guint mode )
138 static const char *thisfn = "nact_schemes_list_create_model";
139 GtkListStore *model;
140 GtkTreeViewColumn *column;
141 GtkCellRenderer *text_cell;
142 GtkTreeSelection *selection;
143 SchemesListData *data;
145 g_return_if_fail( GTK_IS_TREE_VIEW( treeview ));
146 g_debug( "%s: treeview=%p, mode=%d", thisfn, ( void * ) treeview, mode );
148 data = get_schemes_list_data( treeview );
149 data->mode = mode;
151 model = gtk_list_store_new( SCHEMES_N_COLUMN, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN );
152 gtk_tree_view_set_model( treeview, GTK_TREE_MODEL( model ));
153 g_object_unref( model );
155 /* scheme */
156 text_cell = gtk_cell_renderer_text_new();
157 column = gtk_tree_view_column_new_with_attributes(
158 _( "Keyword" ),
159 text_cell,
160 "text", SCHEMES_KEYWORD_COLUMN,
161 NULL );
162 gtk_tree_view_append_column( treeview, column );
163 gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( model ), SCHEMES_KEYWORD_COLUMN, GTK_SORT_ASCENDING );
164 gtk_tree_view_column_set_cell_data_func(
165 column, text_cell, ( GtkTreeCellDataFunc ) display_keyword, data, NULL );
167 /* description */
168 text_cell = gtk_cell_renderer_text_new();
169 column = gtk_tree_view_column_new_with_attributes(
170 _( "Description" ),
171 text_cell,
172 "text", SCHEMES_DESC_COLUMN,
173 NULL );
174 gtk_tree_view_append_column( treeview, column );
175 gtk_tree_view_column_set_cell_data_func(
176 column, text_cell, ( GtkTreeCellDataFunc ) display_description, data, NULL );
178 gtk_tree_view_set_headers_visible( treeview, TRUE );
180 selection = gtk_tree_view_get_selection( treeview );
181 gtk_tree_selection_set_mode( selection, GTK_SELECTION_BROWSE );
185 * nact_schemes_list_init_view:
186 * @treeview: the #GtkTreeView.
187 * @window: the parent #BaseWindow which embeds the view.
188 * @pf: a callback function which will be called on selection change.
189 * @user_data: user data to be passed to the callback function.
191 * Connects signals at runtime initialization of the widget, and displays
192 * the current default list of schemes.
194 * When mode is for preferences, this is all that is required for runtime
195 * initialization.
197 * When mode is for add from defaults, i.e. when editing #NAIContext schemes
198 * conditions, then #nact_schemes_list_setup_values() must also be called in
199 * order to actually setup the already used schemes.
201 void
202 nact_schemes_list_init_view( GtkTreeView *treeview, BaseWindow *window, pf_new_selection_cb pf, void *user_data )
204 static const gchar *thisfn = "nact_schemes_list_init_view";
205 SchemesListData *data;
206 NactApplication *application;
207 NAUpdater *updater;
209 g_debug( "%s: treeview=%p, window=%p",
210 thisfn,
211 ( void * ) treeview,
212 ( void * ) window );
214 g_return_if_fail( BASE_IS_WINDOW( window ));
215 g_return_if_fail( GTK_IS_TREE_VIEW( treeview ));
217 g_object_set_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW, treeview );
219 data = get_schemes_list_data( treeview );
220 data->window = window;
221 application = NACT_APPLICATION( base_window_get_application( window ));
222 updater = nact_application_get_updater( application );
223 data->preferences_locked = na_updater_are_preferences_locked( updater );
224 data->editable = ( data->mode == SCHEMES_LIST_FOR_PREFERENCES && !data->preferences_locked );
225 data->pf_on_sel_changed = pf;
226 data->user_data = user_data;
228 init_view_setup_defaults( data );
229 init_view_connect_signals( data );
232 static void
233 init_view_setup_defaults( SchemesListData *data )
235 GtkListStore *model;
236 GSList *schemes, *iter;
237 GtkTreeIter row;
238 gchar **tokens;
240 model = GTK_LIST_STORE( gtk_tree_view_get_model( data->treeview ));
242 schemes = init_view_get_default_list( data );
244 for( iter = schemes ; iter ; iter = iter->next ){
246 tokens = g_strsplit(( gchar * ) iter->data, "|", 2 );
247 gtk_list_store_append( model, &row );
248 gtk_list_store_set( model, &row,
249 SCHEMES_KEYWORD_COLUMN, tokens[0],
250 SCHEMES_DESC_COLUMN, tokens[1],
251 SCHEMES_ALREADY_USED_COLUMN, FALSE,
252 -1 );
253 g_strfreev( tokens );
256 na_core_utils_slist_free( schemes );
260 * return default schemes list
261 * the returned list must be released with #na_core_utils_slist_free()
263 static GSList *
264 init_view_get_default_list( SchemesListData *data )
266 GSList *list = NULL;
267 gboolean mandatory;
269 list = na_settings_get_string_list( NA_IPREFS_SCHEME_DEFAULT_LIST, NULL, &mandatory );
270 if( !list ){
271 list = init_view_get_default_default_list( data );
273 na_core_utils_slist_dump( "default_list", list );
275 data->editable &= !mandatory;
277 return( list );
280 static GSList *
281 init_view_get_default_default_list( SchemesListData *data )
283 GSList *list = NULL;
285 /* i18n notes : description of 'file' scheme */
286 list = g_slist_append( list, g_strdup_printf( "file|%s", _( "Local files")));
287 /* i18n notes : description of 'sftp' scheme */
288 list = g_slist_append( list, g_strdup_printf( "sftp|%s", _( "SSH files")));
289 /* i18n notes : description of 'smb' scheme */
290 list = g_slist_append( list, g_strdup_printf( "smb|%s", _( "Windows files")));
291 /* i18n notes : description of 'ftp' scheme */
292 list = g_slist_append( list, g_strdup_printf( "ftp|%s", _( "FTP files")));
293 /* i18n notes : description of 'dav' scheme */
294 list = g_slist_append( list, g_strdup_printf( "dav|%s", _( "WebDAV files")));
296 return( list );
299 static void
300 init_view_connect_signals( SchemesListData *data )
302 GtkTreeViewColumn *column;
303 GList *renderers;
304 GtkButton *add_button, *remove_button;
306 base_window_signal_connect(
307 data->window,
308 G_OBJECT( gtk_tree_view_get_selection( data->treeview )),
309 "changed",
310 G_CALLBACK( on_selection_changed ));
312 column = gtk_tree_view_get_column( data->treeview, SCHEMES_KEYWORD_COLUMN );
313 base_gtk_utils_set_editable( G_OBJECT( column ), data->editable );
314 if( data->editable ){
315 renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
316 base_window_signal_connect(
317 data->window,
318 G_OBJECT( renderers->data ),
319 "edited",
320 G_CALLBACK( on_keyword_edited ));
323 column = gtk_tree_view_get_column( data->treeview, SCHEMES_DESC_COLUMN );
324 base_gtk_utils_set_editable( G_OBJECT( column ), data->editable );
325 if( data->editable ){
326 renderers = gtk_cell_layout_get_cells( GTK_CELL_LAYOUT( column ));
327 base_window_signal_connect(
328 data->window,
329 G_OBJECT( renderers->data ),
330 "edited",
331 G_CALLBACK( on_desc_edited ));
334 add_button = get_add_button( data->window );
335 gtk_widget_set_sensitive( GTK_WIDGET( add_button ), data->editable );
336 if( data->editable ){
337 base_window_signal_connect(
338 data->window,
339 G_OBJECT( add_button ),
340 "clicked",
341 G_CALLBACK( on_add_clicked ));
344 remove_button = get_remove_button( data->window );
345 gtk_widget_set_sensitive( GTK_WIDGET( remove_button ), data->editable );
346 if( data->editable ){
347 base_window_signal_connect(
348 data->window,
349 G_OBJECT( remove_button ),
350 "clicked",
351 G_CALLBACK( on_remove_clicked ));
354 if( data->editable ){
355 base_window_signal_connect(
356 data->window,
357 G_OBJECT( data->treeview ),
358 "key-press-event",
359 G_CALLBACK( on_key_pressed_event ));
363 static void
364 init_view_select_first_row( SchemesListData *data )
366 GtkTreeSelection *selection;
367 GtkTreePath *path;
369 path = gtk_tree_path_new_first();
370 selection = gtk_tree_view_get_selection( data->treeview );
371 gtk_tree_selection_select_path( selection, path );
372 gtk_tree_path_free( path );
376 * nact_schemes_list_setup_values:
377 * @window: the #BaseWindow which embeds this treeview.
378 * @schemes: a #GSList of already used schemes.
380 * Set the used schemes for the current #NAIContext.
382 void
383 nact_schemes_list_setup_values( BaseWindow *window, GSList *schemes )
385 GtkTreeView *treeview;
386 GtkTreeModel *model;
388 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
389 model = gtk_tree_view_get_model( treeview );
390 gtk_tree_model_foreach( model, ( GtkTreeModelForeachFunc ) setup_values_iter, schemes );
393 static gboolean
394 setup_values_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter* iter, GSList *schemes )
396 gchar *keyword;
397 gchar *description, *new_description;
399 gtk_tree_model_get( model, iter, SCHEMES_KEYWORD_COLUMN, &keyword, SCHEMES_DESC_COLUMN, &description, -1 );
401 if( na_core_utils_slist_find_negated( schemes, keyword )){
402 /* i18n: add a comment when a scheme is already used by current item */
403 new_description = g_strdup_printf( _( "%s (already used)"), description );
404 gtk_list_store_set( GTK_LIST_STORE( model ), iter, SCHEMES_DESC_COLUMN, new_description, SCHEMES_ALREADY_USED_COLUMN, TRUE, -1 );
405 g_free( new_description );
408 g_free( description );
409 g_free( keyword );
411 return( FALSE ); /* don't stop looping */
415 * nact_schemes_list_show_all:
416 * @window: the #BaseWindow which embeds this treeview.
418 * Update visibility of widgets after all widgets are showed.
420 void
421 nact_schemes_list_show_all( BaseWindow *window )
423 GtkTreeView *listview;
424 SchemesListData *data;
425 GtkButton *button;
427 g_return_if_fail( BASE_IS_WINDOW( window ));
429 listview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
430 data = get_schemes_list_data( listview );
432 button = get_add_button( window );
433 #if GTK_CHECK_VERSION( 2, 18, 0 )
434 gtk_widget_set_visible( GTK_WIDGET( button ), data->mode == SCHEMES_LIST_FOR_PREFERENCES );
435 #else
436 if( data->mode == SCHEMES_LIST_FOR_PREFERENCES ){
437 gtk_widget_show( GTK_WIDGET( button ));
438 } else {
439 gtk_widget_hide( GTK_WIDGET( button ));
441 #endif
443 button = get_remove_button( window );
444 #if GTK_CHECK_VERSION( 2, 18, 0 )
445 gtk_widget_set_visible( GTK_WIDGET( button ), data->mode == SCHEMES_LIST_FOR_PREFERENCES );
446 #else
447 if( data->mode == SCHEMES_LIST_FOR_PREFERENCES ){
448 gtk_widget_show( GTK_WIDGET( button ));
449 } else {
450 gtk_widget_hide( GTK_WIDGET( button ));
452 #endif
454 init_view_select_first_row( data );
458 * nact_schemes_list_get_current_scheme:
459 * @window: the #BaseWindow which embeds this treeview.
461 * Returns: the currently selected scheme, if any, as a newly allocated
462 * string which should be g_free() by the caller.
464 gchar *
465 nact_schemes_list_get_current_scheme( BaseWindow *window )
467 GtkTreeView *treeview;
468 GtkTreeSelection *selection;
469 GtkTreeModel *model;
470 GList *rows;
471 GtkTreePath *path;
472 GtkTreeIter iter;
473 gchar *keyword;
475 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
476 selection = gtk_tree_view_get_selection( treeview );
477 rows = gtk_tree_selection_get_selected_rows( selection, &model );
478 keyword = NULL;
480 if( g_list_length( rows ) == 1 ){
481 path = ( GtkTreePath * ) rows->data;
482 gtk_tree_model_get_iter( model, &iter, path );
483 gtk_tree_model_get( model, &iter, SCHEMES_KEYWORD_COLUMN, &keyword, -1 );
486 return( keyword );
490 * nact_schemes_list_save_defaults:
491 * @window: the #BaseWindow which embeds this treeview.
493 * Save the list of schemes as a GConf preference.
495 * Default schemes are saved under a 'schemes' key as a list of strings,
496 * where each string is of the form 'keyword|description'.
498 void
499 nact_schemes_list_save_defaults( BaseWindow *window )
501 GtkTreeView *treeview;
502 GSList *schemes;
504 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
505 schemes = get_list_schemes( treeview );
507 na_settings_set_string_list( NA_IPREFS_SCHEME_DEFAULT_LIST, schemes );
509 na_core_utils_slist_free( schemes );
512 static GSList *
513 get_list_schemes( GtkTreeView *treeview )
515 GSList *list = NULL;
516 GtkTreeModel *model;
518 model = gtk_tree_view_get_model( treeview );
519 gtk_tree_model_foreach( model, ( GtkTreeModelForeachFunc ) get_list_schemes_iter, &list );
521 return( list );
524 static gboolean
525 get_list_schemes_iter( GtkTreeModel *model, GtkTreePath *path, GtkTreeIter* iter, GSList **list )
527 gchar *keyword;
528 gchar *description;
529 gchar *scheme;
531 gtk_tree_model_get( model, iter, SCHEMES_KEYWORD_COLUMN, &keyword, SCHEMES_DESC_COLUMN, &description, -1 );
532 scheme = g_strdup_printf( "%s|%s", keyword, description );
533 g_free( description );
534 g_free( keyword );
536 ( *list ) = g_slist_append(( *list ), scheme );
538 return( FALSE ); /* don't stop looping */
542 * nact_schemes_list_dispose:
543 * @treeview: the #GtkTreeView.
545 void
546 nact_schemes_list_dispose( BaseWindow *window )
548 static const gchar *thisfn = "nact_schemes_list_dispose";
549 GtkTreeView *treeview;
550 GtkTreeModel *model;
551 GtkTreeSelection *selection;
553 g_debug( "%s: window=%p", thisfn, ( void * ) window );
555 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
556 model = gtk_tree_view_get_model( treeview );
557 selection = gtk_tree_view_get_selection( treeview );
559 gtk_tree_selection_unselect_all( selection );
560 gtk_list_store_clear( GTK_LIST_STORE( model ));
563 static gboolean
564 on_key_pressed_event( GtkWidget *widget, GdkEventKey *event, BaseWindow *window )
566 gboolean stop;
568 /*g_debug( "nact_schemes_list_on_key_pressed_event" );*/
570 stop = FALSE;
572 if( event->keyval == NACT_KEY_F2 ){
573 edit_inline( window );
574 stop = TRUE;
577 if( event->keyval == NACT_KEY_Insert || event->keyval == NACT_KEY_KP_Insert ){
578 insert_new_row( window );
579 stop = TRUE;
582 if( event->keyval == NACT_KEY_Delete || event->keyval == NACT_KEY_KP_Delete ){
583 delete_row( window );
584 stop = TRUE;
587 return( stop );
590 static void
591 on_selection_changed( GtkTreeSelection *selection, BaseWindow *window )
593 /*static const gchar *thisfn = "nact_schemes_list_on_selection_changed";*/
594 GtkButton *button;
595 GtkTreeView *listview;
596 SchemesListData *data;
597 GtkTreeModel *model;
598 GList *rows;
599 GtkTreePath *path;
600 GtkTreeIter iter;
601 gchar *keyword;
602 gboolean used;
604 /*g_debug( "%s: selection=%p, window=%p", thisfn, ( void * ) selection, ( void * ) window );*/
606 listview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
607 data = ( SchemesListData * ) g_object_get_data( G_OBJECT( listview ), SCHEMES_LIST_DATA );
609 button = get_remove_button( window );
610 gtk_widget_set_sensitive( GTK_WIDGET( button ),
611 data->editable && gtk_tree_selection_count_selected_rows( selection ) > 0);
613 if( data->pf_on_sel_changed ){
614 rows = gtk_tree_selection_get_selected_rows( selection, &model );
615 keyword = NULL;
616 used = FALSE;
618 if( g_list_length( rows ) == 1 ){
619 path = ( GtkTreePath * ) rows->data;
620 gtk_tree_model_get_iter( model, &iter, path );
621 gtk_tree_model_get( model, &iter, SCHEMES_KEYWORD_COLUMN, &keyword, SCHEMES_ALREADY_USED_COLUMN, &used, -1 );
624 data->pf_on_sel_changed( keyword, used, data->user_data );
626 g_free( keyword );
630 static void
631 on_add_clicked( GtkButton *button, BaseWindow *window )
633 insert_new_row( window );
636 static void
637 on_remove_clicked( GtkButton *button, BaseWindow *window )
639 delete_row( window );
642 static void
643 on_desc_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, BaseWindow *window )
645 static const gchar *thisfn = "nact_schemes_list_on_desc_edited";
647 g_debug( "%s: renderer=%p, path=%s, text=%s, window=%p",
648 thisfn, ( void * ) renderer, path, text, ( void * ) window );
650 edit_cell( window, path, text, SCHEMES_DESC_COLUMN, NULL, NULL );
653 static void
654 on_keyword_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, BaseWindow *window )
656 edit_cell( window, path, text, SCHEMES_KEYWORD_COLUMN, NULL, NULL );
659 static void
660 edit_cell( BaseWindow *window, const gchar *path_string, const gchar *text, gint column, gboolean *state, gchar **old_text )
662 GtkTreeView *treeview;
663 GtkTreeModel *model;
664 GtkTreeIter iter;
665 GtkTreePath *path;
667 treeview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
668 model = gtk_tree_view_get_model( treeview );
669 path = gtk_tree_path_new_from_string( path_string );
670 gtk_tree_model_get_iter( model, &iter, path );
671 gtk_tree_path_free( path );
673 if( state && old_text ){
674 gtk_tree_model_get( model, &iter, SCHEMES_ALREADY_USED_COLUMN, state, SCHEMES_KEYWORD_COLUMN, old_text, -1 );
677 gtk_list_store_set( GTK_LIST_STORE( model ), &iter, column, text, -1 );
680 static void
681 edit_inline( BaseWindow *window )
683 static const gchar *thisfn = "nact_schemes_list_edit_inline";
684 GtkTreeView *listview;
685 GtkTreeSelection *selection;
686 GList *listrows;
687 GtkTreePath *path;
688 GtkTreeViewColumn *column;
690 g_debug( "%s: window=%p", thisfn, ( void * ) window );
692 listview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
693 selection = gtk_tree_view_get_selection( listview );
694 listrows = gtk_tree_selection_get_selected_rows( selection, NULL );
696 if( g_list_length( listrows ) == 1 ){
697 gtk_tree_view_get_cursor( listview, &path, &column );
698 gtk_tree_view_set_cursor( listview, path, column, TRUE );
699 gtk_tree_path_free( path );
702 g_list_foreach( listrows, ( GFunc ) gtk_tree_path_free, NULL );
703 g_list_free( listrows );
706 static void
707 insert_new_row( BaseWindow *window )
709 GtkTreeView *listview;
710 GtkTreeModel *model;
711 GtkTreeIter iter;
712 GtkTreePath *path;
713 GtkTreeViewColumn *column;
715 listview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
716 model = gtk_tree_view_get_model( listview );
718 gtk_list_store_insert_with_values( GTK_LIST_STORE( model ), &iter, 0,
719 /* i18n notes : scheme name set for a new entry in the scheme list */
720 SCHEMES_KEYWORD_COLUMN, _( "new-scheme" ),
721 SCHEMES_DESC_COLUMN, _( "New scheme description" ),
722 SCHEMES_ALREADY_USED_COLUMN, FALSE,
723 -1 );
725 path = gtk_tree_model_get_path( model, &iter );
726 column = gtk_tree_view_get_column( listview, SCHEMES_KEYWORD_COLUMN );
727 gtk_tree_view_set_cursor( listview, path, column, TRUE );
728 gtk_tree_path_free( path );
731 static void
732 delete_row( BaseWindow *window )
734 GtkTreeView *listview;
735 GtkTreeSelection *selection;
736 GtkTreeModel *model;
737 GList *rows;
738 GtkTreeIter iter;
739 GtkTreePath *path;
741 listview = GTK_TREE_VIEW( g_object_get_data( G_OBJECT( window ), SCHEMES_LIST_TREEVIEW ));
742 selection = gtk_tree_view_get_selection( listview );
743 model = gtk_tree_view_get_model( listview );
745 rows = gtk_tree_selection_get_selected_rows( selection, &model );
747 if( g_list_length( rows ) == 1 ){
748 path = ( GtkTreePath * ) rows->data;
749 gtk_tree_model_get_iter( model, &iter, path );
750 gtk_list_store_remove( GTK_LIST_STORE( model ), &iter );
752 if( gtk_tree_model_get_iter( model, &iter, path ) ||
753 gtk_tree_path_prev( path )){
754 gtk_tree_view_set_cursor( listview, path, NULL, FALSE );
758 g_list_foreach( rows, ( GFunc ) gtk_tree_path_free, NULL );
759 g_list_free( rows );
762 static void
763 display_keyword( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, SchemesListData *data )
765 display_label( column, cell, model, iter, data, SCHEMES_KEYWORD_COLUMN );
768 static void
769 display_description( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, SchemesListData *data )
771 display_label( column, cell, model, iter, data, SCHEMES_DESC_COLUMN );
774 static void
775 display_label( GtkTreeViewColumn *column, GtkCellRenderer *cell, GtkTreeModel *model, GtkTreeIter *iter, SchemesListData *data, guint column_id )
777 gboolean used;
779 gtk_tree_model_get( model, iter, SCHEMES_ALREADY_USED_COLUMN, &used, -1 );
780 g_object_set( cell, "style-set", FALSE, NULL );
782 if( used ){
783 g_object_set( cell, "style", PANGO_STYLE_ITALIC, "style-set", TRUE, NULL );
786 if( data->preferences_locked ){
787 g_object_set( cell, "foreground", "Grey", "foreground-set", TRUE, NULL );
791 static GtkButton *
792 get_add_button( BaseWindow *window )
794 GtkButton *button;
796 button = GTK_BUTTON( base_window_get_widget( window, "AddSchemeButton" ));
798 return( button );
801 static GtkButton *
802 get_remove_button( BaseWindow *window )
804 GtkButton *button;
806 button = GTK_BUTTON( base_window_get_widget( window, "RemoveSchemeButton" ));
808 return( button );
811 static SchemesListData *
812 get_schemes_list_data( GtkTreeView *treeview )
814 SchemesListData *data;
816 data = ( SchemesListData * ) g_object_get_data( G_OBJECT( treeview ), SCHEMES_LIST_DATA );
818 if( data == NULL ){
819 data = g_new0( SchemesListData, 1 );
820 g_object_set_data( G_OBJECT( treeview ), SCHEMES_LIST_DATA, data );
821 data->treeview = treeview;
824 return( data );