README: add deprecation notice
[nautilus-actions.git] / src / ui / fma-iexecution-tab.c
blob5d58826409f8fcfed9d646543bcdf470e2696dcc
1 /*
2 * FileManager-Actions
3 * A file-manager extension which offers configurable context menu actions.
5 * Copyright (C) 2005 The GNOME Foundation
6 * Copyright (C) 2006-2008 Frederic Ruaudel and others (see AUTHORS)
7 * Copyright (C) 2009-2015 Pierre Wieser and others (see AUTHORS)
9 * FileManager-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.
14 * FileManager-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.
19 * You should have received a copy of the GNU General Public License
20 * along with FileManager-Actions; see the file COPYING. If not, see
21 * <http://www.gnu.org/licenses/>.
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)
30 #ifdef HAVE_CONFIG_H
31 #include <config.h>
32 #endif
34 #include <string.h>
36 #include "api/fma-object-api.h"
38 #include "core/fma-gtk-utils.h"
40 #include "base-gtk-utils.h"
41 #include "fma-main-tab.h"
42 #include "fma-main-window.h"
43 #include "fma-iexecution-tab.h"
45 /* private interface data
47 struct _FMAIExecutionTabInterfacePrivate {
48 void *empty; /* so that gcc -pedantic is happy */
51 /* data set against the instance
53 typedef struct {
54 gboolean on_selection_change;
56 IExecutionData;
58 #define IEXECUTION_TAB_PROP_DATA "fma-iexecution-tab-data"
60 static guint st_initializations = 0; /* interface initialization count */
62 static GType register_type( void );
63 static void interface_base_init( FMAIExecutionTabInterface *klass );
64 static void interface_base_finalize( FMAIExecutionTabInterface *klass );
65 static void initialize_window( FMAIExecutionTab *instance );
66 static void on_tree_selection_changed( FMATreeView *tview, GList *selected_items, FMAIExecutionTab *instance );
67 static void on_normal_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance );
68 static void on_terminal_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance );
69 static void on_embedded_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance );
70 static void on_display_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance );
71 static void execution_mode_toggle( FMAIExecutionTab *instance, GtkToggleButton *togglebutton, GCallback cb, const gchar *mode );
72 static void on_startup_notify_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance );
73 static void on_startup_class_changed( GtkEntry *entry, FMAIExecutionTab *instance );
74 static void on_execute_as_changed( GtkEntry *entry, FMAIExecutionTab *instance );
75 static IExecutionData *get_iexecution_data( FMAIExecutionTab *instance );
76 static void on_instance_finalized( gpointer user_data, FMAIExecutionTab *instance );
78 GType
79 fma_iexecution_tab_get_type( void )
81 static GType iface_type = 0;
83 if( !iface_type ){
84 iface_type = register_type();
87 return( iface_type );
90 static GType
91 register_type( void )
93 static const gchar *thisfn = "fma_iexecution_tab_register_type";
94 GType type;
96 static const GTypeInfo info = {
97 sizeof( FMAIExecutionTabInterface ),
98 ( GBaseInitFunc ) interface_base_init,
99 ( GBaseFinalizeFunc ) interface_base_finalize,
100 NULL,
101 NULL,
102 NULL,
105 NULL
108 g_debug( "%s", thisfn );
110 type = g_type_register_static( G_TYPE_INTERFACE, "FMAIExecutionTab", &info, 0 );
112 g_type_interface_add_prerequisite( type, GTK_TYPE_APPLICATION_WINDOW );
114 return( type );
117 static void
118 interface_base_init( FMAIExecutionTabInterface *klass )
120 static const gchar *thisfn = "fma_iexecution_tab_interface_base_init";
122 if( !st_initializations ){
124 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
126 klass->private = g_new0( FMAIExecutionTabInterfacePrivate, 1 );
129 st_initializations += 1;
132 static void
133 interface_base_finalize( FMAIExecutionTabInterface *klass )
135 static const gchar *thisfn = "fma_iexecution_tab_interface_base_finalize";
137 st_initializations -= 1;
139 if( !st_initializations ){
141 g_debug( "%s: klass=%p", thisfn, ( void * ) klass );
143 g_free( klass->private );
148 * fma_iexecution_tab_init:
149 * @instance: this #FMAIExecutionTab instance.
151 * Initialize the interface
152 * Connect to #BaseWindow signals
154 void
155 fma_iexecution_tab_init( FMAIExecutionTab *instance )
157 static const gchar *thisfn = "fma_iexecution_tab_init";
158 IExecutionData *data;
160 g_return_if_fail( instance && FMA_IS_IEXECUTION_TAB( instance ));
162 g_debug( "%s: instance=%p (%s)",
163 thisfn,
164 ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
166 fma_main_tab_init( FMA_MAIN_WINDOW( instance ), TAB_EXECUTION );
167 initialize_window( instance );
169 data = get_iexecution_data( instance );
170 data->on_selection_change = FALSE;
172 g_object_weak_ref( G_OBJECT( instance ), ( GWeakNotify ) on_instance_finalized, NULL );
176 * on_base_initialize_window:
177 * @window: this #FMAIExecutionTab instance.
179 * Initializes the tab widget at each time the widget will be displayed.
180 * Connect signals and setup runtime values.
182 static void
183 initialize_window( FMAIExecutionTab *instance )
185 static const gchar *thisfn = "fma_iexecution_tab_initialize_window";
186 FMATreeView *tview;
188 g_return_if_fail( FMA_IS_IEXECUTION_TAB( instance ));
190 g_debug( "%s: instance=%p (%s)",
191 thisfn, ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
193 tview = fma_main_window_get_items_view( FMA_MAIN_WINDOW( instance ));
195 g_signal_connect(
196 tview, TREE_SIGNAL_SELECTION_CHANGED,
197 G_CALLBACK( on_tree_selection_changed ), instance );
199 fma_gtk_utils_connect_widget_by_name(
200 GTK_CONTAINER( instance ), "ExecutionModeNormal",
201 "toggled", G_CALLBACK( on_normal_mode_toggled ), instance );
203 fma_gtk_utils_connect_widget_by_name(
204 GTK_CONTAINER( instance ), "ExecutionModeTerminal",
205 "toggled", G_CALLBACK( on_terminal_mode_toggled ), instance );
207 fma_gtk_utils_connect_widget_by_name(
208 GTK_CONTAINER( instance ), "ExecutionModeEmbedded",
209 "toggled", G_CALLBACK( on_embedded_mode_toggled ), instance );
211 fma_gtk_utils_connect_widget_by_name(
212 GTK_CONTAINER( instance ), "ExecutionModeDisplayOutput",
213 "toggled", G_CALLBACK( on_display_mode_toggled ), instance );
215 fma_gtk_utils_connect_widget_by_name(
216 GTK_CONTAINER( instance ), "StartupNotifyButton",
217 "toggled", G_CALLBACK( on_startup_notify_toggled ), instance );
219 fma_gtk_utils_connect_widget_by_name(
220 GTK_CONTAINER( instance ), "StartupWMClassEntry",
221 "changed", G_CALLBACK( on_startup_class_changed ), instance );
223 fma_gtk_utils_connect_widget_by_name(
224 GTK_CONTAINER( instance ), "ExecuteAsEntry",
225 "changed", G_CALLBACK( on_execute_as_changed ), instance );
228 static void
229 on_tree_selection_changed( FMATreeView *tview, GList *selected_items, FMAIExecutionTab *instance )
231 static const gchar *thisfn = "fma_iexecution_tab_on_tree_selection_changed";
232 FMAObjectProfile *profile;
233 gboolean editable;
234 gboolean enable_tab;
235 gchar *mode;
236 GtkWidget *normal_toggle, *terminal_toggle, *embedded_toggle, *display_toggle;
237 gboolean notify;
238 GtkWidget *notify_check, *frame;
239 gchar *class, *user;
240 GtkWidget *entry;
241 IExecutionData *data;
243 g_return_if_fail( FMA_IS_IEXECUTION_TAB( instance ));
245 g_debug( "%s: tview=%p, selected_items=%p (count=%d), instance=%p (%s)",
246 thisfn, tview,
247 ( void * ) selected_items, g_list_length( selected_items ),
248 ( void * ) instance, G_OBJECT_TYPE_NAME( instance ));
250 g_object_get(
251 G_OBJECT( instance ),
252 MAIN_PROP_PROFILE, &profile,
253 MAIN_PROP_EDITABLE, &editable,
254 NULL );
256 enable_tab = ( profile != NULL );
257 fma_main_tab_enable_page( FMA_MAIN_WINDOW( instance ), TAB_EXECUTION, enable_tab );
259 data = get_iexecution_data( instance );
260 data->on_selection_change = TRUE;
262 normal_toggle = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "ExecutionModeNormal" );
263 terminal_toggle = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "ExecutionModeTerminal" );
264 embedded_toggle = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "ExecutionModeEmbedded" );
265 display_toggle = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "ExecutionModeDisplayOutput" );
267 mode = profile ? fma_object_get_execution_mode( profile ) : g_strdup( "Normal" );
268 gtk_toggle_button_set_inconsistent( GTK_TOGGLE_BUTTON( normal_toggle ), profile == NULL );
270 if( !strcmp( mode, "Normal" )){
271 base_gtk_utils_radio_set_initial_state(
272 GTK_RADIO_BUTTON( normal_toggle ),
273 G_CALLBACK( on_normal_mode_toggled ), instance, editable, ( profile != NULL ));
275 } else if( !strcmp( mode, "Terminal" )){
276 base_gtk_utils_radio_set_initial_state(
277 GTK_RADIO_BUTTON( terminal_toggle ),
278 G_CALLBACK( on_terminal_mode_toggled ), instance, editable, ( profile != NULL ));
280 } else if( !strcmp( mode, "Embedded" )){
281 base_gtk_utils_radio_set_initial_state(
282 GTK_RADIO_BUTTON( embedded_toggle ),
283 G_CALLBACK( on_embedded_mode_toggled ), instance, editable, ( profile != NULL ));
285 } else if( !strcmp( mode, "DisplayOutput" )){
286 base_gtk_utils_radio_set_initial_state(
287 GTK_RADIO_BUTTON( display_toggle ),
288 G_CALLBACK( on_display_mode_toggled ), instance, editable, ( profile != NULL ));
290 } else {
291 g_warning( "%s: unable to setup execution mode '%s'", thisfn, mode );
294 g_free( mode );
296 frame = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "StartupModeFrame" );
297 gtk_widget_set_sensitive( frame, FALSE );
299 notify = profile ? fma_object_get_startup_notify( profile ) : FALSE;
300 notify_check = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "StartupNotifyButton" );
301 base_gtk_utils_set_editable( G_OBJECT( notify_check ), editable );
302 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON( notify_check ), notify );
304 class = profile ? fma_object_get_startup_class( profile ) : g_strdup( "" );
305 entry = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "StartupWMClassEntry" );
306 gtk_entry_set_text( GTK_ENTRY( entry ), class );
307 base_gtk_utils_set_editable( G_OBJECT( entry ), editable );
308 g_free( class );
310 frame = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "UserFrame" );
311 gtk_widget_set_sensitive( frame, FALSE );
313 user = profile ? fma_object_get_execute_as( profile ) : g_strdup( "" );
314 entry = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "ExecuteAsEntry" );
315 gtk_entry_set_text( GTK_ENTRY( entry ), user );
316 base_gtk_utils_set_editable( G_OBJECT( entry ), editable );
317 g_free( user );
319 data->on_selection_change = FALSE;
322 static void
323 on_normal_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance )
325 execution_mode_toggle( instance, togglebutton, G_CALLBACK( on_normal_mode_toggled ), "Normal" );
328 static void
329 on_terminal_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance )
331 execution_mode_toggle( instance, togglebutton, G_CALLBACK( on_terminal_mode_toggled ), "Terminal" );
334 static void
335 on_embedded_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance )
337 execution_mode_toggle( instance, togglebutton, G_CALLBACK( on_embedded_mode_toggled ), "Embedded" );
340 static void
341 on_display_mode_toggled( GtkToggleButton *togglebutton, FMAIExecutionTab *instance )
343 execution_mode_toggle( instance, togglebutton, G_CALLBACK( on_display_mode_toggled ), "DisplayOutput" );
346 static void
347 execution_mode_toggle( FMAIExecutionTab *instance, GtkToggleButton *toggle_button, GCallback cb, const gchar *mode )
349 FMAObjectProfile *profile;
350 gboolean editable;
351 gboolean active;
352 gboolean is_normal;
353 GtkWidget *widget;
355 g_object_get(
356 G_OBJECT( instance ),
357 MAIN_PROP_PROFILE, &profile,
358 MAIN_PROP_EDITABLE, &editable,
359 NULL );
361 if( profile ){
362 active = gtk_toggle_button_get_active( toggle_button );
364 if( editable ){
365 if( active ){
366 fma_object_set_execution_mode( profile, mode );
368 is_normal = ( strcmp( mode, "Normal" ) == 0 );
369 widget = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "StartupNotifyButton" );
370 gtk_widget_set_sensitive( widget, is_normal );
371 widget = fma_gtk_utils_find_widget_by_name( GTK_CONTAINER( instance ), "StartupWMClassEntry" );
372 gtk_widget_set_sensitive( widget, is_normal );
374 g_signal_emit_by_name( G_OBJECT( instance ), MAIN_SIGNAL_ITEM_UPDATED, profile, 0 );
377 } else {
378 base_gtk_utils_radio_reset_initial_state( GTK_RADIO_BUTTON( toggle_button ), cb );
383 static void
384 on_startup_notify_toggled( GtkToggleButton *toggle_button, FMAIExecutionTab *instance )
386 FMAObjectProfile *profile;
387 gboolean editable;
388 gboolean active;
390 g_object_get(
391 G_OBJECT( instance ),
392 MAIN_PROP_PROFILE, &profile,
393 MAIN_PROP_EDITABLE, &editable,
394 NULL );
396 if( profile ){
397 active = gtk_toggle_button_get_active( toggle_button );
399 if( editable ){
400 fma_object_set_startup_notify( profile, active );
401 g_signal_emit_by_name( G_OBJECT( instance ), MAIN_SIGNAL_ITEM_UPDATED, profile, 0 );
403 } else {
404 g_signal_handlers_block_by_func(( gpointer ) toggle_button, on_startup_notify_toggled, instance );
405 gtk_toggle_button_set_active( toggle_button, !active );
406 g_signal_handlers_unblock_by_func(( gpointer ) toggle_button, on_startup_notify_toggled, instance );
411 static void
412 on_startup_class_changed( GtkEntry *entry, FMAIExecutionTab *instance )
414 FMAObjectProfile *profile;
415 const gchar *text;
417 g_object_get(
418 G_OBJECT( instance ),
419 MAIN_PROP_PROFILE, &profile,
420 NULL );
422 if( profile ){
423 text = gtk_entry_get_text( entry );
424 fma_object_set_startup_class( profile, text );
425 g_signal_emit_by_name( G_OBJECT( instance ), MAIN_SIGNAL_ITEM_UPDATED, profile, 0 );
429 static void
430 on_execute_as_changed( GtkEntry *entry, FMAIExecutionTab *instance )
432 FMAObjectProfile *profile;
433 const gchar *text;
435 g_object_get(
436 G_OBJECT( instance ),
437 MAIN_PROP_PROFILE, &profile,
438 NULL );
440 if( profile ){
441 text = gtk_entry_get_text( entry );
442 fma_object_set_execute_as( profile, text );
443 g_signal_emit_by_name( G_OBJECT( instance ), MAIN_SIGNAL_ITEM_UPDATED, profile, 0 );
447 static IExecutionData *
448 get_iexecution_data( FMAIExecutionTab *instance )
450 IExecutionData *data;
452 data = ( IExecutionData * ) g_object_get_data( G_OBJECT( instance ), IEXECUTION_TAB_PROP_DATA );
454 if( !data ){
455 data = g_new0( IExecutionData, 1 );
456 g_object_set_data( G_OBJECT( instance ), IEXECUTION_TAB_PROP_DATA, data );
459 return( data );
462 static void
463 on_instance_finalized( gpointer user_data, FMAIExecutionTab *instance )
465 static const gchar *thisfn = "fma_iexecution_tab_on_instance_finalized";
466 IExecutionData *data;
468 g_debug( "%s: instance=%p, user_data=%p", thisfn, ( void * ) instance, ( void * ) user_data );
470 data = get_iexecution_data( instance );
472 g_free( data );