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-2008 Frederic Ruaudel and others (see AUTHORS)
7  * Copyright (C) 2009-2014 Pierre Wieser and others (see AUTHORS)
8  *
9  * Nautilus-Actions 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  * Nautilus-Actions 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 GNU
17  * General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with Nautilus-Actions; see the file COPYING. If not, see
21  * <http://www.gnu.org/licenses/>.
22  *
23  * Authors:
24  *   Frederic Ruaudel <grumz@grumz.net>
25  *   Rodrigo Moya <rodrigo@gnome-db.org>
26  *   Pierre Wieser <pwieser@trychlos.org>
27  *   ... and many others (see AUTHORS)
28  */
29 
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
33 
34 #include <glib/gi18n.h>
35 #include <string.h>
36 
37 #include <api/na-core-utils.h>
38 #include <api/na-object-api.h>
39 
40 #include <core/na-factory-object.h>
41 #include <core/na-tokens.h>
42 
43 #include "base-window.h"
44 #include "nact-application.h"
45 #include "nact-main-statusbar.h"
46 #include "base-gtk-utils.h"
47 #include "nact-main-tab.h"
48 #include "nact-icommand-tab.h"
49 #include "nact-ischemes-tab.h"
50 
51 /* private interface data
52  */
53 struct _NactICommandTabInterfacePrivate {
54 	void *empty;						/* so that gcc -pedantic is happy */
55 };
56 
57 /* a data set in the LegendDialog GObject
58  */
59 #define ICOMMAND_TAB_LEGEND_VISIBLE			"nact-icommand-tab-legend-dialog-visible"
60 
61 /* data set against the instance
62  */
63 typedef struct {
64 	gboolean  on_selection_change;
65 	NATokens *tokens;
66 }
67 	ICommandData;
68 
69 #define ICOMMAND_TAB_PROP_DATA				"nact-icommand-tab-data"
70 
71 static guint st_initializations = 0;	/* interface initialization count */
72 
73 static GType         register_type( void );
74 static void          interface_base_init( NactICommandTabInterface *klass );
75 static void          interface_base_finalize( NactICommandTabInterface *klass );
76 
77 static void          on_base_initialize_gtk( NactICommandTab *instance, GtkWindow *toplevel, gpointer user_data );
78 static void          on_base_initialize_window( NactICommandTab *instance, gpointer user_data );
79 
80 static void          on_tree_view_content_changed( NactICommandTab *instance, NAObject *object, gpointer user_data );
81 static void          on_main_selection_changed( NactICommandTab *instance, GList *selected_items, gpointer user_data );
82 
83 static GtkWidget    *get_label_entry( NactICommandTab *instance );
84 static GtkButton    *get_legend_button( NactICommandTab *instance );
85 static GtkWindow    *get_legend_dialog( NactICommandTab *instance );
86 static GtkWidget    *get_parameters_entry( NactICommandTab *instance );
87 static GtkButton    *get_path_button( NactICommandTab *instance );
88 static GtkWidget    *get_path_entry( NactICommandTab *instance );
89 static void          legend_dialog_show( NactICommandTab *instance );
90 static void          legend_dialog_hide( NactICommandTab *instance );
91 static void          on_label_changed( GtkEntry *entry, NactICommandTab *instance );
92 static void          on_legend_clicked( GtkButton *button, NactICommandTab *instance );
93 static gboolean      on_legend_dialog_deleted( GtkWidget *dialog, GdkEvent *event, NactICommandTab *instance );
94 static void          on_parameters_changed( GtkEntry *entry, NactICommandTab *instance );
95 static void          on_path_browse( GtkButton *button, NactICommandTab *instance );
96 static void          on_path_changed( GtkEntry *entry, NactICommandTab *instance );
97 static void          on_wdir_browse( GtkButton *button, NactICommandTab *instance );
98 static void          on_wdir_changed( GtkEntry *entry, NactICommandTab *instance );
99 static gchar        *parse_parameters( NactICommandTab *instance );
100 static void          update_example_label( NactICommandTab *instance, NAObjectProfile *profile );
101 
102 static ICommandData *get_icommand_data( NactICommandTab *instance );
103 static void          on_instance_finalized( gpointer user_data, NactICommandTab *instance );
104 
105 GType
nact_icommand_tab_get_type(void)106 nact_icommand_tab_get_type( void )
107 {
108 	static GType iface_type = 0;
109 
110 	if( !iface_type ){
111 		iface_type = register_type();
112 	}
113 
114 	return( iface_type );
115 }
116 
117 static GType
register_type(void)118 register_type( void )
119 {
120 	static const gchar *thisfn = "nact_icommand_tab_register_type";
121 	GType type;
122 
123 	static const GTypeInfo info = {
124 		sizeof( NactICommandTabInterface ),
125 		( GBaseInitFunc ) interface_base_init,
126 		( GBaseFinalizeFunc ) interface_base_finalize,
127 		NULL,
128 		NULL,
129 		NULL,
130 		0,
131 		0,
132 		NULL
133 	};
134 
135 	g_debug( "%s", thisfn );
136 
137 	type = g_type_register_static( G_TYPE_INTERFACE, "NactICommandTab", &info, 0 );
138 
139 	g_type_interface_add_prerequisite( type, BASE_TYPE_WINDOW );
140 
141 	return( type );
142 }
143 
144 static void
interface_base_init(NactICommandTabInterface * klass)145 interface_base_init( NactICommandTabInterface *klass )
146 {
147 	static const gchar *thisfn = "nact_icommand_tab_interface_base_init";
148 
149 	if( !st_initializations ){
150 
151 		g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
152 
153 		klass->private = g_new0( NactICommandTabInterfacePrivate, 1 );
154 	}
155 
156 	st_initializations += 1;
157 }
158 
159 static void
interface_base_finalize(NactICommandTabInterface * klass)160 interface_base_finalize( NactICommandTabInterface *klass )
161 {
162 	static const gchar *thisfn = "nact_icommand_tab_interface_base_finalize";
163 
164 	st_initializations -= 1;
165 
166 	if( !st_initializations ){
167 
168 		g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
169 
170 		g_free( klass->private );
171 	}
172 }
173 
174 /*
175  * nact_icommand_tab_init:
176  * @instance: this #NactICommandTab instance.
177  *
178  * Initialize the interface
179  * Connect to #BaseWindow signals
180  */
181 void
nact_icommand_tab_init(NactICommandTab * instance)182 nact_icommand_tab_init( NactICommandTab *instance )
183 {
184 	static const gchar *thisfn = "nact_icommand_tab_init";
185 	ICommandData *data;
186 
187 	g_return_if_fail( NACT_IS_ICOMMAND_TAB( instance ));
188 
189 	g_debug( "%s: instance=%p (%s)",
190 			thisfn,
191 			( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
192 
193 	base_window_signal_connect(
194 			BASE_WINDOW( instance ),
195 			G_OBJECT( instance ),
196 			BASE_SIGNAL_INITIALIZE_GTK,
197 			G_CALLBACK( on_base_initialize_gtk ));
198 
199 	base_window_signal_connect(
200 			BASE_WINDOW( instance ),
201 			G_OBJECT( instance ),
202 			BASE_SIGNAL_INITIALIZE_WINDOW,
203 			G_CALLBACK( on_base_initialize_window ));
204 
205 	nact_main_tab_init( NACT_MAIN_WINDOW( instance ), TAB_COMMAND );
206 
207 	data = get_icommand_data( instance );
208 	data->on_selection_change = FALSE;
209 	data->tokens = NULL;
210 
211 	g_object_weak_ref( G_OBJECT( instance ), ( GWeakNotify ) on_instance_finalized, NULL );
212 }
213 
214 static void
on_base_initialize_gtk(NactICommandTab * instance,GtkWindow * toplevel,gpointer user_data)215 on_base_initialize_gtk( NactICommandTab *instance, GtkWindow *toplevel, gpointer user_data )
216 {
217 #if GTK_CHECK_VERSION( 3,0,0 )
218 	base_gtk_utils_table_to_grid( BASE_WINDOW( instance ), "table220" );
219 #endif
220 }
221 
222 /*
223  * on_base_initialize_window:
224  * @window: this #NactICommandTab instance.
225  *
226  * Initializes the tab widget at each time the widget will be displayed.
227  * Connect signals and setup runtime values.
228  */
229 static void
on_base_initialize_window(NactICommandTab * instance,void * user_data)230 on_base_initialize_window( NactICommandTab *instance, void *user_data )
231 {
232 	static const gchar *thisfn = "nact_icommand_tab_on_base_initialize_window";
233 	GtkWindow *legend_dialog;
234 	GtkWidget *label_entry, *path_entry, *parameters_entry, *wdir_entry;
235 	GtkButton *path_button, *legend_button, *wdir_button;
236 	ICommandData *data;
237 
238 	g_return_if_fail( NACT_IS_ICOMMAND_TAB( instance ));
239 
240 	g_debug( "%s: instance=%p (%s), user_data=%p",
241 			thisfn,
242 			( void * ) instance, G_OBJECT_TYPE_NAME( instance ),
243 			( void * ) user_data );
244 
245 	label_entry = get_label_entry( instance );
246 	base_window_signal_connect(
247 			BASE_WINDOW( instance ),
248 			G_OBJECT( label_entry ),
249 			"changed",
250 			G_CALLBACK( on_label_changed ));
251 
252 	path_entry = get_path_entry( instance );
253 	base_window_signal_connect(
254 			BASE_WINDOW( instance ),
255 			G_OBJECT( path_entry ),
256 			"changed",
257 			G_CALLBACK( on_path_changed ));
258 
259 	path_button = get_path_button( instance );
260 	base_window_signal_connect(
261 			BASE_WINDOW( instance ),
262 			G_OBJECT( path_button ),
263 			"clicked",
264 			G_CALLBACK( on_path_browse ));
265 
266 	parameters_entry = get_parameters_entry( instance );
267 	base_window_signal_connect(
268 			BASE_WINDOW( instance ),
269 			G_OBJECT( parameters_entry ),
270 			"changed",
271 			G_CALLBACK( on_parameters_changed ));
272 
273 	legend_button = get_legend_button( instance );
274 	base_window_signal_connect(
275 			BASE_WINDOW( instance ),
276 			G_OBJECT( legend_button ),
277 			"clicked",
278 			G_CALLBACK( on_legend_clicked ));
279 
280 	legend_dialog = get_legend_dialog( instance );
281 	base_window_signal_connect(
282 			BASE_WINDOW( instance ),
283 			G_OBJECT( legend_dialog ),
284 			"delete-event",
285 			G_CALLBACK( on_legend_dialog_deleted ));
286 
287 	wdir_entry = base_window_get_widget( BASE_WINDOW( instance ), "WorkingDirectoryEntry" );
288 	base_window_signal_connect(
289 			BASE_WINDOW( instance ),
290 			G_OBJECT( wdir_entry ),
291 			"changed",
292 			G_CALLBACK( on_wdir_changed ));
293 
294 	wdir_button = GTK_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "CommandWorkingDirectoryButton" ));
295 	base_window_signal_connect(
296 			BASE_WINDOW( instance ),
297 			G_OBJECT( wdir_button ),
298 			"clicked",
299 			G_CALLBACK( on_wdir_browse ));
300 
301 	base_window_signal_connect(
302 			BASE_WINDOW( instance ),
303 			G_OBJECT( instance ),
304 			MAIN_SIGNAL_SELECTION_CHANGED,
305 			G_CALLBACK( on_main_selection_changed ));
306 
307 	base_window_signal_connect(
308 			BASE_WINDOW( instance ),
309 			G_OBJECT( instance ),
310 			MAIN_SIGNAL_ITEM_UPDATED,
311 			G_CALLBACK( on_tree_view_content_changed ));
312 
313 	/* allocate a static fake NATokens object which will be used to build
314 	 * the example label - this object will be g_object_unref() on instance
315 	 * finalization
316 	 */
317 	data = get_icommand_data( instance );
318 	if( !data->tokens ){
319 		data->tokens = na_tokens_new_for_example();
320 	}
321 }
322 
323 static void
on_tree_view_content_changed(NactICommandTab * instance,NAObject * object,gpointer user_data)324 on_tree_view_content_changed( NactICommandTab *instance, NAObject *object, gpointer user_data )
325 {
326 	GtkWidget *label_widget;
327 	gchar *label;
328 
329 	g_return_if_fail( NACT_IS_ICOMMAND_TAB( instance ));
330 
331 	if( NA_IS_OBJECT_PROFILE( object )){
332 		label_widget = get_label_entry( instance );
333 		label = na_object_get_label( object );
334 		gtk_entry_set_text( GTK_ENTRY( label_widget ), label );
335 		g_free( label );
336 	}
337 }
338 
339 static void
on_main_selection_changed(NactICommandTab * instance,GList * selected_items,gpointer user_data)340 on_main_selection_changed( NactICommandTab *instance, GList *selected_items, gpointer user_data )
341 {
342 	static const gchar *thisfn = "nact_icommand_tab_on_main_selection_changed";
343 	NAObjectProfile *profile;
344 	gboolean editable;
345 	gboolean enable_tab;
346 	GtkWidget *label_entry, *path_entry, *parameters_entry, *wdir_entry;
347 	gchar *label, *path, *parameters, *wdir;
348 	GtkButton *path_button, *wdir_button;
349 	GtkButton *legend_button;
350 	ICommandData *data;
351 
352 	g_return_if_fail( NACT_IS_ICOMMAND_TAB( instance ));
353 
354 	g_debug( "%s: instance=%p (%s), selected_items=%p (count=%d)",
355 			thisfn,
356 			( void * ) instance, G_OBJECT_TYPE_NAME( instance ),
357 			( void * ) selected_items, g_list_length( selected_items ));
358 
359 	g_object_get(
360 			G_OBJECT( instance ),
361 			MAIN_PROP_PROFILE, &profile,
362 			MAIN_PROP_EDITABLE, &editable,
363 			NULL );
364 
365 	enable_tab = ( profile != NULL );
366 	nact_main_tab_enable_page( NACT_MAIN_WINDOW( instance ), TAB_COMMAND, enable_tab );
367 
368 	data = get_icommand_data( instance );
369 	data->on_selection_change = TRUE;
370 
371 	label_entry = get_label_entry( instance );
372 	label = profile ? na_object_get_label( profile ) : g_strdup( "" );
373 	label = label ? label : g_strdup( "" );
374 	gtk_entry_set_text( GTK_ENTRY( label_entry ), label );
375 	g_free( label );
376 	gtk_widget_set_sensitive( label_entry, profile != NULL );
377 	base_gtk_utils_set_editable( G_OBJECT( label_entry ), editable );
378 
379 	path_entry = get_path_entry( instance );
380 	path = profile ? na_object_get_path( profile ) : g_strdup( "" );
381 	path = path ? path : g_strdup( "" );
382 	gtk_entry_set_text( GTK_ENTRY( path_entry ), path );
383 	g_free( path );
384 	gtk_widget_set_sensitive( path_entry, profile != NULL );
385 	base_gtk_utils_set_editable( G_OBJECT( path_entry ), editable );
386 
387 	path_button = get_path_button( instance );
388 	gtk_widget_set_sensitive( GTK_WIDGET( path_button ), profile != NULL );
389 	base_gtk_utils_set_editable( G_OBJECT( path_button ), editable );
390 
391 	parameters_entry = get_parameters_entry( instance );
392 	parameters = profile ? na_object_get_parameters( profile ) : g_strdup( "" );
393 	parameters = parameters ? parameters : g_strdup( "" );
394 	gtk_entry_set_text( GTK_ENTRY( parameters_entry ), parameters );
395 	g_free( parameters );
396 	gtk_widget_set_sensitive( parameters_entry, profile != NULL );
397 	base_gtk_utils_set_editable( G_OBJECT( parameters_entry ), editable );
398 
399 	legend_button = get_legend_button( instance );
400 	gtk_widget_set_sensitive( GTK_WIDGET( legend_button ), profile != NULL );
401 
402 	update_example_label( instance, profile );
403 
404 	wdir_entry = base_window_get_widget( BASE_WINDOW( instance ), "WorkingDirectoryEntry" );
405 	wdir = profile ? na_object_get_working_dir( profile ) : g_strdup( "" );
406 	wdir = wdir ? wdir : g_strdup( "" );
407 	gtk_entry_set_text( GTK_ENTRY( wdir_entry ), wdir );
408 	g_free( wdir );
409 	gtk_widget_set_sensitive( wdir_entry, profile != NULL );
410 	base_gtk_utils_set_editable( G_OBJECT( wdir_entry ), editable );
411 
412 	wdir_button = GTK_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "CommandWorkingDirectoryButton" ));
413 	gtk_widget_set_sensitive( GTK_WIDGET( wdir_button ), profile != NULL );
414 	base_gtk_utils_set_editable( G_OBJECT( wdir_button ), editable );
415 
416 	data->on_selection_change = FALSE;
417 }
418 
419 static GtkWidget *
get_label_entry(NactICommandTab * instance)420 get_label_entry( NactICommandTab *instance )
421 {
422 	return( base_window_get_widget( BASE_WINDOW( instance ), "ProfileLabelEntry" ));
423 }
424 
425 static GtkButton *
get_legend_button(NactICommandTab * instance)426 get_legend_button( NactICommandTab *instance )
427 {
428 	return( GTK_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "CommandLegendButton" )));
429 }
430 
431 static GtkWindow *
get_legend_dialog(NactICommandTab * instance)432 get_legend_dialog( NactICommandTab *instance )
433 {
434 	return( base_window_get_gtk_toplevel_by_name( BASE_WINDOW( instance ), "LegendDialog" ));
435 }
436 
437 static GtkWidget *
get_parameters_entry(NactICommandTab * instance)438 get_parameters_entry( NactICommandTab *instance )
439 {
440 	return( base_window_get_widget( BASE_WINDOW( instance ), "CommandParametersEntry" ));
441 }
442 
443 static GtkButton *
get_path_button(NactICommandTab * instance)444 get_path_button( NactICommandTab *instance )
445 {
446 	return( GTK_BUTTON( base_window_get_widget( BASE_WINDOW( instance ), "CommandPathButton" )));
447 }
448 
449 static GtkWidget *
get_path_entry(NactICommandTab * instance)450 get_path_entry( NactICommandTab *instance )
451 {
452 	return( base_window_get_widget( BASE_WINDOW( instance ), "CommandPathEntry" ));
453 }
454 
455 static void
legend_dialog_hide(NactICommandTab * instance)456 legend_dialog_hide( NactICommandTab *instance )
457 {
458 	GtkWindow *legend_dialog;
459 	GtkButton *legend_button;
460 	gboolean is_visible;
461 
462 	is_visible = FALSE;
463 	legend_dialog = get_legend_dialog( instance );
464 	if( GTK_IS_WINDOW( legend_dialog )){
465 		is_visible = ( gboolean ) GPOINTER_TO_INT(
466 				g_object_get_data( G_OBJECT( legend_dialog ), ICOMMAND_TAB_LEGEND_VISIBLE ));
467 	}
468 
469 	if( is_visible ){
470 		base_gtk_utils_save_window_position( BASE_WINDOW( instance ), NA_IPREFS_COMMAND_LEGEND_WSP );
471 		gtk_widget_hide( GTK_WIDGET( legend_dialog ));
472 
473 		/* set the legend button state consistent for when the dialog is
474 		 * hidden by another way (eg. close the edit profile dialog)
475 		 */
476 		legend_button = get_legend_button( instance );
477 		gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( legend_button ), FALSE );
478 
479 		g_object_set_data( G_OBJECT( legend_dialog ), ICOMMAND_TAB_LEGEND_VISIBLE, GINT_TO_POINTER( FALSE ));
480 	}
481 }
482 
483 static void
legend_dialog_show(NactICommandTab * instance)484 legend_dialog_show( NactICommandTab *instance )
485 {
486 	GtkWindow *legend_dialog;
487 	GtkWindow *toplevel;
488 
489 	legend_dialog = get_legend_dialog( instance );
490 	gtk_window_set_deletable( legend_dialog, FALSE );
491 
492 	toplevel = base_window_get_gtk_toplevel( BASE_WINDOW( instance ));
493 	gtk_window_set_transient_for( GTK_WINDOW( legend_dialog ), toplevel );
494 
495 	base_gtk_utils_restore_window_position( BASE_WINDOW( instance ), NA_IPREFS_COMMAND_LEGEND_WSP );
496 	gtk_widget_show( GTK_WIDGET( legend_dialog ));
497 
498 	g_object_set_data( G_OBJECT( legend_dialog ), ICOMMAND_TAB_LEGEND_VISIBLE, GINT_TO_POINTER( TRUE ));
499 }
500 
501 static void
on_label_changed(GtkEntry * entry,NactICommandTab * instance)502 on_label_changed( GtkEntry *entry, NactICommandTab *instance )
503 {
504 	NAObjectProfile *profile;
505 	const gchar *label;
506 	ICommandData *data;
507 
508 	data = get_icommand_data( instance );
509 
510 	if( !data->on_selection_change ){
511 		g_object_get(
512 				G_OBJECT( instance ),
513 				MAIN_PROP_PROFILE, &profile,
514 				NULL );
515 
516 		if( profile ){
517 			label = gtk_entry_get_text( entry );
518 			na_object_set_label( profile, label );
519 			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, MAIN_DATA_LABEL );
520 		}
521 	}
522 }
523 
524 static void
on_legend_clicked(GtkButton * button,NactICommandTab * instance)525 on_legend_clicked( GtkButton *button, NactICommandTab *instance )
526 {
527 	if( gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( button ))){
528 		legend_dialog_show( instance );
529 
530 	} else {
531 		legend_dialog_hide( instance );
532 	}
533 }
534 
535 static gboolean
on_legend_dialog_deleted(GtkWidget * dialog,GdkEvent * event,NactICommandTab * instance)536 on_legend_dialog_deleted( GtkWidget *dialog, GdkEvent *event, NactICommandTab *instance )
537 {
538 	/*g_debug( "on_legend_dialog_deleted" );*/
539 	legend_dialog_hide( instance );
540 	return( TRUE );
541 }
542 
543 static void
on_parameters_changed(GtkEntry * entry,NactICommandTab * instance)544 on_parameters_changed( GtkEntry *entry, NactICommandTab *instance )
545 {
546 	NAObjectProfile *profile;
547 	ICommandData *data;
548 
549 	data = get_icommand_data( instance );
550 
551 	if( !data->on_selection_change ){
552 		g_object_get(
553 				G_OBJECT( instance ),
554 				MAIN_PROP_PROFILE, &profile,
555 				NULL );
556 
557 		if( profile ){
558 			na_object_set_parameters( profile, gtk_entry_get_text( entry ));
559 			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
560 			update_example_label( instance, profile );
561 		}
562 	}
563 }
564 
565 static void
on_path_browse(GtkButton * button,NactICommandTab * instance)566 on_path_browse( GtkButton *button, NactICommandTab *instance )
567 {
568 	base_gtk_utils_select_file(
569 			BASE_WINDOW( instance ),
570 			_( "Choosing a command" ), NA_IPREFS_COMMAND_CHOOSER_WSP,
571 			get_path_entry( instance ), NA_IPREFS_COMMAND_CHOOSER_URI );
572 }
573 
574 static void
on_path_changed(GtkEntry * entry,NactICommandTab * instance)575 on_path_changed( GtkEntry *entry, NactICommandTab *instance )
576 {
577 	NAObjectProfile *profile;
578 	ICommandData *data;
579 
580 	data = get_icommand_data( instance );
581 
582 	if( !data->on_selection_change ){
583 		g_object_get(
584 				G_OBJECT( instance ),
585 				MAIN_PROP_PROFILE, &profile,
586 				NULL );
587 
588 		if( profile ){
589 			na_object_set_path( profile, gtk_entry_get_text( entry ));
590 			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
591 			update_example_label( instance, profile );
592 		}
593 	}
594 }
595 
596 static void
on_wdir_browse(GtkButton * button,NactICommandTab * instance)597 on_wdir_browse( GtkButton *button, NactICommandTab *instance )
598 {
599 	GtkWidget *wdir_entry;
600 	NAObjectProfile *profile;
601 
602 	g_object_get(
603 			G_OBJECT( instance ),
604 			MAIN_PROP_PROFILE, &profile,
605 			NULL );
606 
607 	if( profile ){
608 		wdir_entry = base_window_get_widget( BASE_WINDOW( instance ), "WorkingDirectoryEntry" );
609 		base_gtk_utils_select_dir(
610 				BASE_WINDOW( instance ), _( "Choosing a working directory" ),
611 				NA_IPREFS_WORKING_DIR_WSP, wdir_entry, NA_IPREFS_WORKING_DIR_URI );
612 	}
613 }
614 
615 static void
on_wdir_changed(GtkEntry * entry,NactICommandTab * instance)616 on_wdir_changed( GtkEntry *entry, NactICommandTab *instance )
617 {
618 	NAObjectProfile *profile;
619 	ICommandData *data;
620 
621 	data = get_icommand_data( instance );
622 
623 	if( !data->on_selection_change ){
624 		g_object_get(
625 				G_OBJECT( instance ),
626 				MAIN_PROP_PROFILE, &profile,
627 				NULL );
628 
629 		if( profile ){
630 			na_object_set_working_dir( profile, gtk_entry_get_text( entry ));
631 			g_signal_emit_by_name( G_OBJECT( instance ), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED, profile, 0 );
632 		}
633 	}
634 }
635 
636 /*
637  * See core/na-tokens.c for valid parameters
638  */
639 static gchar *
parse_parameters(NactICommandTab * instance)640 parse_parameters( NactICommandTab *instance )
641 {
642 	const gchar *command = gtk_entry_get_text( GTK_ENTRY( get_path_entry( instance )));
643 	const gchar *param_template = gtk_entry_get_text( GTK_ENTRY( get_parameters_entry( instance )));
644 	gchar *exec, *returned;
645 	ICommandData *data;
646 
647 	data = get_icommand_data( instance );
648 	exec = g_strdup_printf( "%s %s", command, param_template );
649 	returned = na_tokens_parse_for_display( data->tokens, exec, FALSE );
650 	g_free( exec );
651 
652 	return( returned );
653 }
654 
655 static void
update_example_label(NactICommandTab * instance,NAObjectProfile * profile)656 update_example_label( NactICommandTab *instance, NAObjectProfile *profile )
657 {
658 	/*static const char *thisfn = "nact_iconditions_update_example_label";*/
659 	gchar *newlabel;
660 	gchar *parameters;
661 	GtkWidget *example_widget;
662 
663 	example_widget = base_window_get_widget( BASE_WINDOW( instance ), "CommandExampleLabel" );
664 
665 	if( profile ){
666 		parameters = parse_parameters( instance );
667 		/*g_debug( "%s: parameters=%s", thisfn, parameters );*/
668 
669 		/* convert special xml chars (&, <, >,...) to avoid warnings
670 		 * generated by Pango parser
671 		 */
672 		/* i18n: command-line example: Ex.: /bin/ls file1.txt file2.txt */
673 		newlabel = g_markup_printf_escaped(
674 				"<i><b><span size=\"small\">%s</span></b></i>", parameters );
675 
676 		g_free( parameters );
677 
678 	} else {
679 		newlabel = g_strdup( "" );
680 	}
681 
682 	gtk_label_set_label( GTK_LABEL( example_widget ), newlabel );
683 	g_free( newlabel );
684 }
685 
686 static ICommandData *
get_icommand_data(NactICommandTab * instance)687 get_icommand_data( NactICommandTab *instance )
688 {
689 	ICommandData *data;
690 
691 	data = ( ICommandData * ) g_object_get_data( G_OBJECT( instance ), ICOMMAND_TAB_PROP_DATA );
692 
693 	if( !data ){
694 		data = g_new0( ICommandData, 1 );
695 		/* g_object_set_data_full() would be called after the weak ref function
696 		 */
697 		g_object_set_data( G_OBJECT( instance ), ICOMMAND_TAB_PROP_DATA, data );
698 	}
699 
700 	return( data );
701 }
702 
703 static void
on_instance_finalized(gpointer user_data,NactICommandTab * instance)704 on_instance_finalized( gpointer user_data, NactICommandTab *instance )
705 {
706 	static const gchar *thisfn = "nact_icommand_tab_on_instance_finalized";
707 	ICommandData *data;
708 
709 	g_debug( "%s: instance=%p, user_data=%p", thisfn, ( void * ) instance, ( void * ) user_data );
710 
711 	legend_dialog_hide( instance );
712 
713 	data = get_icommand_data( instance );
714 
715 	if( data->tokens ){
716 		g_object_unref( data->tokens );
717 	}
718 
719 	g_free( data );
720 }
721