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 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.
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)
35
#include <glib/gi18n.h>
38
#include <common/na-iprefs.h>
39
#include <common/na-object-api.h>
40
#include <common/na-utils.h>
42
#include <runtime/na-pivot.h>
44
#include "base-iprefs.h"
45
#include "base-window.h"
46
#include "nact-application.h"
47
#include "nact-main-tab.h"
48
#include "nact-ibackground-tab.h"
50
/* private interface data
52
struct NactIBackgroundTabInterfacePrivate {
53
void *empty; /* so that gcc -pedantic is happy */
59
BACKGROUND_URI_COLUMN = 0,
63
#define IPREFS_BACKGROUND_DIALOG "ibackground-chooser"
64
#define IPREFS_BACKGROUND_URI "ibackground-uri"
66
static gboolean st_initialized = FALSE;
67
static gboolean st_finalized = FALSE;
69
static GType register_type( void );
70
static void interface_base_init( NactIBackgroundTabInterface *klass );
71
static void interface_base_finalize( NactIBackgroundTabInterface *klass );
73
static void on_tab_updatable_selection_changed( NactIBackgroundTab *instance, gint count_selected );
74
static void on_tab_updatable_enable_tab( NactIBackgroundTab *instance, NAObjectItem *item );
75
static gboolean tab_set_sensitive( NactIBackgroundTab *instance );
77
static void add_row( NactIBackgroundTab *instance, GtkTreeView *listview, const gchar *uri );
78
static void add_uri_to_folders( NactIBackgroundTab *instance, const gchar *uri );
79
static GtkTreeView *get_folders_treeview( NactIBackgroundTab *instance );
80
static void on_folder_uri_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, NactIBackgroundTab *instance );
81
static void on_folders_selection_changed( GtkTreeSelection *selection, NactIBackgroundTab *instance );
82
static void on_add_folder_clicked( GtkButton *button, NactIBackgroundTab *instance );
83
static void on_remove_folder_clicked( GtkButton *button, NactIBackgroundTab *instance );
84
static void reset_folders( NactIBackgroundTab *instance );
85
static void setup_folders( NactIBackgroundTab *instance );
86
static void treeview_cell_edited( NactIBackgroundTab *instance, const gchar *path_string, const gchar *text, gint column, gboolean *state, gchar **old_text );
89
nact_ibackground_tab_get_type( void )
91
static GType iface_type = 0;
94
iface_type = register_type();
101
register_type( void )
103
static const gchar *thisfn = "nact_ibackground_tab_register_type";
106
static const GTypeInfo info = {
107
sizeof( NactIBackgroundTabInterface ),
108
( GBaseInitFunc ) interface_base_init,
109
( GBaseFinalizeFunc ) interface_base_finalize,
118
g_debug( "%s", thisfn );
120
type = g_type_register_static( G_TYPE_INTERFACE, "NactIBackgroundTab", &info, 0 );
122
g_type_interface_add_prerequisite( type, BASE_WINDOW_TYPE );
128
interface_base_init( NactIBackgroundTabInterface *klass )
130
static const gchar *thisfn = "nact_ibackground_tab_interface_base_init";
132
if( !st_initialized ){
133
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
135
klass->private = g_new0( NactIBackgroundTabInterfacePrivate, 1 );
137
st_initialized = TRUE;
142
interface_base_finalize( NactIBackgroundTabInterface *klass )
144
static const gchar *thisfn = "nact_ibackground_tab_interface_base_finalize";
147
g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
149
g_free( klass->private );
156
nact_ibackground_tab_initial_load_toplevel( NactIBackgroundTab *instance )
158
static const gchar *thisfn = "nact_ibackground_tab_initial_load_toplevel";
159
GtkTreeView *listview;
161
GtkTreeViewColumn *column;
162
GtkCellRenderer *text_cell;
164
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
165
g_return_if_fail( NACT_IS_IBACKGROUND_TAB( instance ));
167
if( st_initialized && !st_finalized ){
169
model = gtk_list_store_new( BACKGROUND_N_COLUMN, G_TYPE_STRING );
170
gtk_tree_sortable_set_sort_column_id( GTK_TREE_SORTABLE( model ), BACKGROUND_URI_COLUMN, GTK_SORT_ASCENDING );
171
listview = get_folders_treeview( instance );
172
gtk_tree_view_set_model( listview, GTK_TREE_MODEL( model ));
173
g_object_unref( model );
175
text_cell = gtk_cell_renderer_text_new();
176
g_object_set( G_OBJECT( text_cell ), "editable", TRUE, NULL );
177
column = gtk_tree_view_column_new_with_attributes(
180
"text", BACKGROUND_URI_COLUMN,
182
gtk_tree_view_append_column( listview, column );
184
gtk_tree_view_set_headers_visible( listview, FALSE );
189
nact_ibackground_tab_runtime_init_toplevel( NactIBackgroundTab *instance )
191
static const gchar *thisfn = "nact_ibackground_tab_runtime_init_toplevel";
192
GtkTreeView *listview;
193
GtkTreeViewColumn *column;
195
GtkWidget *add_button, *remove_button;
197
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
198
g_return_if_fail( NACT_IS_IBACKGROUND_TAB( instance ));
200
if( st_initialized && !st_finalized ){
203
G_OBJECT( instance ),
204
TAB_UPDATABLE_SIGNAL_SELECTION_CHANGED,
205
G_CALLBACK( on_tab_updatable_selection_changed ),
209
G_OBJECT( instance ),
210
TAB_UPDATABLE_SIGNAL_ENABLE_TAB,
211
G_CALLBACK( on_tab_updatable_enable_tab ),
214
listview = get_folders_treeview( instance );
215
column = gtk_tree_view_get_column( listview, BACKGROUND_URI_COLUMN );
216
renderers = gtk_tree_view_column_get_cell_renderers( column );
218
G_OBJECT( renderers->data ),
220
G_CALLBACK( on_folder_uri_edited ),
223
add_button = base_window_get_widget( BASE_WINDOW( instance ), "AddFolderButton");
225
G_OBJECT( add_button ),
227
G_CALLBACK( on_add_folder_clicked ),
230
remove_button = base_window_get_widget( BASE_WINDOW( instance ), "RemoveFolderButton");
232
G_OBJECT( remove_button ),
234
G_CALLBACK( on_remove_folder_clicked ),
238
G_OBJECT( gtk_tree_view_get_selection( listview )),
240
G_CALLBACK( on_folders_selection_changed ),
246
nact_ibackground_tab_all_widgets_showed( NactIBackgroundTab *instance )
248
static const gchar *thisfn = "nact_ibackground_tab_all_widgets_showed";
250
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
251
g_return_if_fail( NACT_IS_IBACKGROUND_TAB( instance ));
253
if( st_initialized && !st_finalized ){
258
nact_ibackground_tab_dispose( NactIBackgroundTab *instance )
260
static const gchar *thisfn = "nact_ibackground_tab_dispose";
262
g_debug( "%s: instance=%p", thisfn, ( void * ) instance );
263
g_return_if_fail( NACT_IS_IBACKGROUND_TAB( instance ));
265
if( st_initialized && !st_finalized ){
267
reset_folders( instance );
272
on_tab_updatable_selection_changed( NactIBackgroundTab *instance, gint count_selected )
274
static const gchar *thisfn = "nact_ibackground_tab_on_tab_updatable_selection_changed";
278
g_debug( "%s: instance=%p, count_selected=%d", thisfn, ( void * ) instance, count_selected );
279
g_return_if_fail( NACT_IS_IBACKGROUND_TAB( instance ));
281
if( st_initialized && !st_finalized ){
283
reset_folders( instance );
286
G_OBJECT( instance ),
287
TAB_UPDATABLE_PROP_EDITED_ACTION, &item,
290
g_return_if_fail( !item || NA_IS_OBJECT_ITEM( item ));
292
enable_tab = tab_set_sensitive( instance );
294
if( item && NA_IS_OBJECT_ACTION( item )){
295
setup_folders( instance );
301
on_tab_updatable_enable_tab( NactIBackgroundTab *instance, NAObjectItem *item )
303
static const gchar *thisfn = "nact_ibackground_tab_on_tab_updatable_enable_tab";
305
if( st_initialized && !st_finalized ){
307
g_debug( "%s: instance=%p, item=%p", thisfn, ( void * ) instance, ( void * ) item );
308
g_return_if_fail( NACT_IS_IBACKGROUND_TAB( instance ));
310
tab_set_sensitive( instance );
315
tab_set_sensitive( NactIBackgroundTab *instance )
317
NAObjectAction *action;
318
NAObjectProfile *profile;
322
G_OBJECT( instance ),
323
TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
324
TAB_UPDATABLE_PROP_EDITED_PROFILE, &profile,
327
enable_tab = ( profile != NULL &&
328
( na_object_action_is_target_background( action ) || na_object_action_is_target_toolbar( action )));
330
nact_main_tab_enable_page( NACT_MAIN_WINDOW( instance ), TAB_BACKGROUND, enable_tab );
332
return( enable_tab );
336
add_row( NactIBackgroundTab *instance, GtkTreeView *listview, const gchar *uri )
341
model = gtk_tree_view_get_model( listview );
343
gtk_list_store_append(
344
GTK_LIST_STORE( model ),
348
GTK_LIST_STORE( model ),
350
BACKGROUND_URI_COLUMN, uri,
355
add_uri_to_folders( NactIBackgroundTab *instance, const gchar *uri )
357
NAObjectAction *action;
358
NAObjectProfile *edited;
362
G_OBJECT( instance ),
363
TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
364
TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
367
folders = na_object_profile_get_folders( edited );
368
folders = g_slist_prepend( folders, ( gpointer ) g_strdup( uri ));
369
na_object_profile_set_folders( edited, folders );
370
na_utils_free_string_list( folders );
372
g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
376
get_folders_treeview( NactIBackgroundTab *instance )
380
treeview = base_window_get_widget( BASE_WINDOW( instance ), "FoldersTreeview" );
381
g_assert( GTK_IS_TREE_VIEW( treeview ));
383
return( GTK_TREE_VIEW( treeview ));
387
on_add_folder_clicked( GtkButton *button, NactIBackgroundTab *instance )
391
NactApplication *application;
394
GtkTreeView *listview;
397
listview = get_folders_treeview( instance );
398
toplevel = base_window_get_toplevel( BASE_WINDOW( instance ));
400
/* i18n: title of the FileChoose dialog when selecting an URI which
401
* will be comparent to Nautilus 'current_folder'
403
dialog = gtk_file_chooser_dialog_new( _( "Select a folder" ),
405
GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
406
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
407
GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
410
application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( instance )));
411
pivot = nact_application_get_pivot( application );
413
base_iprefs_position_named_window( BASE_WINDOW( instance ), GTK_WINDOW( dialog ), IPREFS_BACKGROUND_DIALOG );
415
uri = na_iprefs_read_string( NA_IPREFS( pivot ), IPREFS_BACKGROUND_URI, "x-nautilus-desktop:///" );
416
if( uri && strlen( uri )){
417
gtk_file_chooser_set_uri( GTK_FILE_CHOOSER( dialog ), uri );
421
if( gtk_dialog_run( GTK_DIALOG( dialog )) == GTK_RESPONSE_ACCEPT ){
422
uri = gtk_file_chooser_get_uri( GTK_FILE_CHOOSER( dialog ));
423
na_iprefs_write_string( NA_IPREFS( pivot ), IPREFS_BACKGROUND_URI, uri );
424
add_row( instance, listview, uri );
425
add_uri_to_folders( instance, uri );
429
base_iprefs_save_named_window_position( BASE_WINDOW( instance ), GTK_WINDOW( dialog ), IPREFS_BACKGROUND_DIALOG );
431
gtk_widget_destroy( dialog );
435
on_folder_uri_edited( GtkCellRendererText *renderer, const gchar *path, const gchar *text, NactIBackgroundTab *instance )
437
treeview_cell_edited( instance, path, text, BACKGROUND_URI_COLUMN, NULL, NULL );
441
on_folders_selection_changed( GtkTreeSelection *selection, NactIBackgroundTab *instance )
445
button = base_window_get_widget( BASE_WINDOW( instance ), "RemoveFolderButton");
447
gtk_widget_set_sensitive( button, gtk_tree_selection_count_selected_rows( selection ) > 0 );
451
on_remove_folder_clicked( GtkButton *button, NactIBackgroundTab *instance )
453
GtkTreeView *listview;
455
GtkTreeSelection *selection;
456
GList *selected_path, *isp;
460
NAObjectAction *action;
461
NAObjectProfile *edited;
464
listview = get_folders_treeview( instance );
465
model = gtk_tree_view_get_model( listview );
466
selection = gtk_tree_view_get_selection( listview );
467
selected_path = gtk_tree_selection_get_selected_rows( selection, NULL );
469
for( isp = selected_path ; isp ; isp = isp->next ){
470
path = ( GtkTreePath * ) isp->data;
471
gtk_tree_model_get_iter( model, &iter, path );
472
gtk_tree_model_get( model, &iter, BACKGROUND_URI_COLUMN, &uri, -1 );
473
gtk_list_store_remove( GTK_LIST_STORE( model ), &iter );
476
G_OBJECT( instance ),
477
TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
478
TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
481
folders = na_object_profile_get_folders( edited );
482
folders = na_utils_remove_from_string_list( folders, uri );
483
na_object_profile_set_folders( edited, folders );
485
na_utils_free_string_list( folders );
488
g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );
491
g_list_foreach( selected_path, ( GFunc ) gtk_tree_path_free, NULL );
492
g_list_free( selected_path );
496
reset_folders( NactIBackgroundTab *instance )
498
GtkTreeView *listview;
501
listview = get_folders_treeview( instance );
502
model = gtk_tree_view_get_model( listview );
503
gtk_list_store_clear( GTK_LIST_STORE( model ));
507
setup_folders( NactIBackgroundTab *instance )
509
NAObjectProfile *edited;
510
GSList *folders, *is;
511
GtkTreeView *listview;
513
listview = get_folders_treeview( instance );
516
G_OBJECT( instance ),
517
TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
520
folders = na_object_profile_get_folders( edited );
521
for( is = folders ; is ; is = is->next ){
522
add_row( instance, listview, ( const gchar * ) is->data );
524
na_utils_free_string_list( folders );
528
treeview_cell_edited( NactIBackgroundTab *instance, const gchar *path_string, const gchar *text, gint column, gboolean *state, gchar **old_text )
530
GtkTreeView *listview;
534
NAObjectAction *action;
535
NAObjectProfile *edited;
537
listview = get_folders_treeview( instance );
538
model = gtk_tree_view_get_model( listview );
539
path = gtk_tree_path_new_from_string( path_string );
540
gtk_tree_model_get_iter( model, &iter, path );
541
gtk_tree_path_free( path );
543
if( state && old_text ){
544
gtk_tree_model_get( model, &iter, BACKGROUND_URI_COLUMN, old_text, -1 );
547
gtk_list_store_set( GTK_LIST_STORE( model ), &iter, column, text, -1 );
550
G_OBJECT( instance ),
551
TAB_UPDATABLE_PROP_EDITED_ACTION, &action,
552
TAB_UPDATABLE_PROP_EDITED_PROFILE, &edited,
555
na_object_profile_replace_folder_uri( edited, *old_text, text );
557
g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, edited, FALSE );