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/>.
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)
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
54 gboolean on_selection_change
;
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
);
79 fma_iexecution_tab_get_type( void )
81 static GType iface_type
= 0;
84 iface_type
= register_type();
93 static const gchar
*thisfn
= "fma_iexecution_tab_register_type";
96 static const GTypeInfo info
= {
97 sizeof( FMAIExecutionTabInterface
),
98 ( GBaseInitFunc
) interface_base_init
,
99 ( GBaseFinalizeFunc
) interface_base_finalize
,
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
);
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;
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
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)",
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.
183 initialize_window( FMAIExecutionTab
*instance
)
185 static const gchar
*thisfn
= "fma_iexecution_tab_initialize_window";
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
));
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
);
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
;
236 GtkWidget
*normal_toggle
, *terminal_toggle
, *embedded_toggle
, *display_toggle
;
238 GtkWidget
*notify_check
, *frame
;
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)",
247 ( void * ) selected_items
, g_list_length( selected_items
),
248 ( void * ) instance
, G_OBJECT_TYPE_NAME( instance
));
251 G_OBJECT( instance
),
252 MAIN_PROP_PROFILE
, &profile
,
253 MAIN_PROP_EDITABLE
, &editable
,
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
));
291 g_warning( "%s: unable to setup execution mode '%s'", thisfn
, 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
);
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
);
319 data
->on_selection_change
= FALSE
;
323 on_normal_mode_toggled( GtkToggleButton
*togglebutton
, FMAIExecutionTab
*instance
)
325 execution_mode_toggle( instance
, togglebutton
, G_CALLBACK( on_normal_mode_toggled
), "Normal" );
329 on_terminal_mode_toggled( GtkToggleButton
*togglebutton
, FMAIExecutionTab
*instance
)
331 execution_mode_toggle( instance
, togglebutton
, G_CALLBACK( on_terminal_mode_toggled
), "Terminal" );
335 on_embedded_mode_toggled( GtkToggleButton
*togglebutton
, FMAIExecutionTab
*instance
)
337 execution_mode_toggle( instance
, togglebutton
, G_CALLBACK( on_embedded_mode_toggled
), "Embedded" );
341 on_display_mode_toggled( GtkToggleButton
*togglebutton
, FMAIExecutionTab
*instance
)
343 execution_mode_toggle( instance
, togglebutton
, G_CALLBACK( on_display_mode_toggled
), "DisplayOutput" );
347 execution_mode_toggle( FMAIExecutionTab
*instance
, GtkToggleButton
*toggle_button
, GCallback cb
, const gchar
*mode
)
349 FMAObjectProfile
*profile
;
356 G_OBJECT( instance
),
357 MAIN_PROP_PROFILE
, &profile
,
358 MAIN_PROP_EDITABLE
, &editable
,
362 active
= gtk_toggle_button_get_active( toggle_button
);
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 );
378 base_gtk_utils_radio_reset_initial_state( GTK_RADIO_BUTTON( toggle_button
), cb
);
384 on_startup_notify_toggled( GtkToggleButton
*toggle_button
, FMAIExecutionTab
*instance
)
386 FMAObjectProfile
*profile
;
391 G_OBJECT( instance
),
392 MAIN_PROP_PROFILE
, &profile
,
393 MAIN_PROP_EDITABLE
, &editable
,
397 active
= gtk_toggle_button_get_active( toggle_button
);
400 fma_object_set_startup_notify( profile
, active
);
401 g_signal_emit_by_name( G_OBJECT( instance
), MAIN_SIGNAL_ITEM_UPDATED
, profile
, 0 );
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
);
412 on_startup_class_changed( GtkEntry
*entry
, FMAIExecutionTab
*instance
)
414 FMAObjectProfile
*profile
;
418 G_OBJECT( instance
),
419 MAIN_PROP_PROFILE
, &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 );
430 on_execute_as_changed( GtkEntry
*entry
, FMAIExecutionTab
*instance
)
432 FMAObjectProfile
*profile
;
436 G_OBJECT( instance
),
437 MAIN_PROP_PROFILE
, &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
);
455 data
= g_new0( IExecutionData
, 1 );
456 g_object_set_data( G_OBJECT( instance
), IEXECUTION_TAB_PROP_DATA
, data
);
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
);