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 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 <api/na-core-utils.h>
39 #include <api/na-object-api.h>
41 #include <core/na-io-provider.h>
43 #include "base-iprefs.h"
44 #include "base-window.h"
45 #include "nact-application.h"
46 #include "nact-iprefs.h"
47 #include "nact-main-statusbar.h"
48 #include "nact-gtk-utils.h"
49 #include "nact-iactions-list.h"
50 #include "nact-main-tab.h"
51 #include "nact-iaction-tab.h"
53 /* private interface data
55 struct NactIActionTabInterfacePrivate
{
56 void *empty
; /* so that gcc -pedantic is happy */
59 /* columns in the icon combobox
62 ICON_STOCK_COLUMN
= 0,
67 #define IPREFS_ICONS_DIALOG "icons-chooser"
68 #define IPREFS_ICONS_PATH "icons-path"
70 /* IActionTab properties, set against the GObject instance
72 #define IACTION_TAB_PROP_STATUS_CONTEXT "nact-iaction-tab-status-context"
74 static gboolean st_initialized
= FALSE
;
75 static gboolean st_finalized
= FALSE
;
76 static gboolean st_on_selection_change
= FALSE
;
78 static GType
register_type( void );
79 static void interface_base_init( NactIActionTabInterface
*klass
);
80 static void interface_base_finalize( NactIActionTabInterface
*klass
);
82 static void on_iactions_list_column_edited( NactIActionTab
*instance
, NAObject
*object
, gchar
*text
, gint column
);
83 static void on_tab_updatable_selection_changed( NactIActionTab
*instance
, gint count_selected
);
85 static void on_target_selection_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
);
86 static void on_target_location_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
);
87 static void check_for_label( NactIActionTab
*instance
, GtkEntry
*entry
, const gchar
*label
);
88 static void on_label_changed( GtkEntry
*entry
, NactIActionTab
*instance
);
89 static void set_label_label( NactIActionTab
*instance
, const gchar
*color
);
90 static void on_target_toolbar_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
);
91 static void on_toolbar_same_label_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
);
92 static void toolbar_same_label_set_sensitive( NactIActionTab
*instance
, NAObjectItem
*item
);
93 static void setup_toolbar_label( NactIActionTab
*instance
, NAObjectItem
*item
, const gchar
*label
);
94 static void on_toolbar_label_changed( GtkEntry
*entry
, NactIActionTab
*instance
);
95 static void toolbar_label_set_sensitive( NactIActionTab
*instance
, NAObjectItem
*item
);
96 static void on_tooltip_changed( GtkEntry
*entry
, NactIActionTab
*instance
);
97 static GtkTreeModel
*create_stock_icon_model( void );
98 static void icon_combo_list_fill( GtkComboBoxEntry
* combo
);
99 static void on_icon_browse( GtkButton
*button
, NactIActionTab
*instance
);
100 static void on_icon_changed( GtkEntry
*entry
, NactIActionTab
*instance
);
101 static gint
sort_stock_ids( gconstpointer a
, gconstpointer b
);
102 static gchar
*strip_underscore( const gchar
*text
);
103 static void release_icon_combobox( NactIActionTab
*instance
);
106 nact_iaction_tab_get_type( void )
108 static GType iface_type
= 0;
111 iface_type
= register_type();
114 return( iface_type
);
118 register_type( void )
120 static const gchar
*thisfn
= "nact_iaction_tab_register_type";
123 static const GTypeInfo info
= {
124 sizeof( NactIActionTabInterface
),
125 ( GBaseInitFunc
) interface_base_init
,
126 ( GBaseFinalizeFunc
) interface_base_finalize
,
135 g_debug( "%s", thisfn
);
137 type
= g_type_register_static( G_TYPE_INTERFACE
, "NactIActionTab", &info
, 0 );
139 g_type_interface_add_prerequisite( type
, BASE_WINDOW_TYPE
);
145 interface_base_init( NactIActionTabInterface
*klass
)
147 static const gchar
*thisfn
= "nact_iaction_tab_interface_base_init";
149 if( !st_initialized
){
151 g_debug( "%s: klass=%p", thisfn
, ( void * ) klass
);
153 klass
->private = g_new0( NactIActionTabInterfacePrivate
, 1 );
155 st_initialized
= TRUE
;
160 interface_base_finalize( NactIActionTabInterface
*klass
)
162 static const gchar
*thisfn
= "nact_iaction_tab_interface_base_finalize";
164 if( st_initialized
&& !st_finalized
){
166 g_debug( "%s: klass=%p", thisfn
, ( void * ) klass
);
170 g_free( klass
->private );
175 * GTK_ICON_SIZE_MENU : 16x16
176 * GTK_ICON_SIZE_SMALL_TOOLBAR: 18x18
177 * GTK_ICON_SIZE_LARGE_TOOLBAR: 24x24
178 * GTK_ICON_SIZE_BUTTON : 20x20
179 * GTK_ICON_SIZE_DND : 32x32
180 * GTK_ICON_SIZE_DIALOG : 48x48
182 * icon is rendered for GTK_ICON_SIZE_MENU (na_object_item_get_pixbuf)
185 nact_iaction_tab_initial_load_toplevel( NactIActionTab
*instance
)
187 static const gchar
*thisfn
= "nact_iaction_tab_initial_load_toplevel";
188 GtkWidget
*icon_widget
;
191 GtkRequisition requisition
;
195 g_return_if_fail( NACT_IS_IACTION_TAB( instance
));
197 if( st_initialized
&& !st_finalized
){
199 g_debug( "%s: instance=%p", thisfn
, ( void * ) instance
);
201 button
= GTK_BUTTON( base_window_get_widget( BASE_WINDOW( instance
), "ActionIconBrowseButton" ));
202 gtk_widget_size_request( GTK_WIDGET( button
), &requisition
);
203 g_debug( "%s: button requisition width=%d, height=%d", thisfn
, requisition
.width
, requisition
.height
);
204 frame
= GTK_FRAME( base_window_get_widget( BASE_WINDOW( instance
), "ActionIconFrame" ));
205 size
= requisition
.height
- 4;
206 gtk_widget_set_size_request( GTK_WIDGET( frame
), size
, size
);
207 gtk_frame_set_shadow_type( frame
, GTK_SHADOW_IN
);
209 icon_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionIconComboBoxEntry" );
210 model
= create_stock_icon_model();
211 gtk_combo_box_set_model( GTK_COMBO_BOX( icon_widget
), model
);
212 g_object_unref( model
);
213 icon_combo_list_fill( GTK_COMBO_BOX_ENTRY( icon_widget
));
218 nact_iaction_tab_runtime_init_toplevel( NactIActionTab
*instance
)
220 static const gchar
*thisfn
= "nact_iaction_tab_runtime_init_toplevel";
221 GtkWidget
*label_widget
, *tooltip_widget
, *icon_widget
;
224 g_return_if_fail( NACT_IS_IACTION_TAB( instance
));
226 if( st_initialized
&& !st_finalized
){
228 g_debug( "%s: instance=%p", thisfn
, ( void * ) instance
);
230 base_window_signal_connect(
231 BASE_WINDOW( instance
),
232 G_OBJECT( instance
),
233 MAIN_WINDOW_SIGNAL_SELECTION_CHANGED
,
234 G_CALLBACK( on_tab_updatable_selection_changed
));
236 base_window_signal_connect(
237 BASE_WINDOW( instance
),
238 G_OBJECT( instance
),
239 IACTIONS_LIST_SIGNAL_COLUMN_EDITED
,
240 G_CALLBACK( on_iactions_list_column_edited
));
242 button
= base_window_get_widget( BASE_WINDOW( instance
), "ActionTargetSelectionButton" );
243 base_window_signal_connect(
244 BASE_WINDOW( instance
),
247 G_CALLBACK( on_target_selection_toggled
));
249 button
= base_window_get_widget( BASE_WINDOW( instance
), "ActionTargetLocationButton" );
250 base_window_signal_connect(
251 BASE_WINDOW( instance
),
254 G_CALLBACK( on_target_location_toggled
));
256 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionMenuLabelEntry" );
257 base_window_signal_connect(
258 BASE_WINDOW( instance
),
259 G_OBJECT( label_widget
),
261 G_CALLBACK( on_label_changed
));
263 button
= base_window_get_widget( BASE_WINDOW( instance
), "ActionTargetToolbarButton" );
264 base_window_signal_connect(
265 BASE_WINDOW( instance
),
268 G_CALLBACK( on_target_toolbar_toggled
));
270 button
= base_window_get_widget( BASE_WINDOW( instance
), "ToolbarSameLabelButton" );
271 base_window_signal_connect(
272 BASE_WINDOW( instance
),
275 G_CALLBACK( on_toolbar_same_label_toggled
));
277 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionToolbarLabelEntry" );
278 base_window_signal_connect(
279 BASE_WINDOW( instance
),
280 G_OBJECT( label_widget
),
282 G_CALLBACK( on_toolbar_label_changed
));
284 tooltip_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionTooltipEntry" );
285 base_window_signal_connect(
286 BASE_WINDOW( instance
),
287 G_OBJECT( tooltip_widget
),
289 G_CALLBACK( on_tooltip_changed
));
291 icon_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionIconComboBoxEntry" );
292 base_window_signal_connect(
293 BASE_WINDOW( instance
),
294 G_OBJECT( gtk_bin_get_child( GTK_BIN( icon_widget
))),
296 G_CALLBACK( on_icon_changed
));
298 button
= base_window_get_widget( BASE_WINDOW( instance
), "ActionIconBrowseButton" );
299 base_window_signal_connect(
300 BASE_WINDOW( instance
),
303 G_CALLBACK( on_icon_browse
));
308 nact_iaction_tab_all_widgets_showed( NactIActionTab
*instance
)
310 static const gchar
*thisfn
= "nact_iaction_tab_all_widgets_showed";
312 g_return_if_fail( NACT_IS_IACTION_TAB( instance
));
314 if( st_initialized
&& !st_finalized
){
316 g_debug( "%s: instance=%p", thisfn
, ( void * ) instance
);
321 nact_iaction_tab_dispose( NactIActionTab
*instance
)
323 static const gchar
*thisfn
= "nact_iaction_tab_dispose";
325 g_return_if_fail( NACT_IS_IACTION_TAB( instance
));
327 if( st_initialized
&& !st_finalized
){
329 g_debug( "%s: instance=%p", thisfn
, ( void * ) instance
);
331 release_icon_combobox( instance
);
336 * nact_iaction_tab_has_label:
337 * @window: this #NactIActionTab instance.
339 * An action or a menu can only be written if it has at least a label.
341 * Returns %TRUE if the label of the action or of the menu is not empty.
344 nact_iaction_tab_has_label( NactIActionTab
*instance
)
346 GtkWidget
*label_widget
;
348 gboolean has_label
= FALSE
;
350 g_return_val_if_fail( NACT_IS_IACTION_TAB( instance
), FALSE
);
352 if( st_initialized
&& !st_finalized
){
354 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionMenuLabelEntry" );
355 label
= gtk_entry_get_text( GTK_ENTRY( label_widget
));
356 has_label
= ( g_utf8_strlen( label
, -1 ) > 0 );
363 on_iactions_list_column_edited( NactIActionTab
*instance
, NAObject
*object
, gchar
*text
, gint column
)
365 GtkWidget
*label_widget
;
367 g_return_if_fail( NACT_IS_IACTION_TAB( instance
));
369 if( st_initialized
&& !st_finalized
){
371 if( object
&& NA_IS_OBJECT_ITEM( object
)){
372 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionMenuLabelEntry" );
373 gtk_entry_set_text( GTK_ENTRY( label_widget
), text
);
379 on_tab_updatable_selection_changed( NactIActionTab
*instance
, gint count_selected
)
381 static const gchar
*thisfn
= "nact_iaction_tab_on_tab_updatable_selection_changed";
385 gboolean target_selection
, target_location
, target_toolbar
;
386 gboolean enable_label
;
388 GtkWidget
*label_widget
, *tooltip_widget
, *icon_widget
;
389 gchar
*label
, *tooltip
, *icon
;
390 GtkButton
*icon_button
;
391 GtkToggleButton
*toggle
;
393 g_return_if_fail( BASE_IS_WINDOW( instance
));
394 g_return_if_fail( NACT_IS_IACTION_TAB( instance
));
396 if( st_initialized
&& !st_finalized
){
398 g_debug( "%s: instance=%p, count_selected=%d", thisfn
, ( void * ) instance
, count_selected
);
400 enable_tab
= ( count_selected
== 1 );
401 nact_main_tab_enable_page( NACT_MAIN_WINDOW( instance
), TAB_ACTION
, enable_tab
);
403 st_on_selection_change
= TRUE
;
406 G_OBJECT( instance
),
407 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
408 TAB_UPDATABLE_PROP_EDITABLE
, &editable
,
414 NA_IS_OBJECT_ACTION( item
) &&
415 na_object_is_target_selection( item
);
420 NA_IS_OBJECT_ACTION( item
) &&
421 na_object_is_target_location( item
);
426 NA_IS_OBJECT_ACTION( item
) &&
427 na_object_is_target_toolbar( item
);
429 toggle
= GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance
), "ActionTargetSelectionButton" ));
430 gtk_toggle_button_set_active( toggle
, target_selection
|| ( item
&& NA_IS_OBJECT_MENU( item
)));
431 gtk_widget_set_sensitive( GTK_WIDGET( toggle
), item
&& NA_IS_OBJECT_ACTION( item
));
432 nact_gtk_utils_set_editable( GTK_OBJECT( toggle
), editable
);
434 toggle
= GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance
), "ActionTargetLocationButton" ));
435 gtk_toggle_button_set_active( toggle
, target_location
|| ( item
&& NA_IS_OBJECT_MENU( item
)));
436 gtk_widget_set_sensitive( GTK_WIDGET( toggle
), item
&& NA_IS_OBJECT_ACTION( item
));
437 nact_gtk_utils_set_editable( GTK_OBJECT( toggle
), editable
);
439 enable_label
= target_selection
|| target_location
|| ( item
&& NA_IS_OBJECT_MENU( item
));
440 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionMenuLabelEntry" );
441 label
= item
? na_object_get_label( item
) : g_strdup( "" );
442 label
= label
? label
: g_strdup( "" );
443 gtk_entry_set_text( GTK_ENTRY( label_widget
), label
);
445 check_for_label( instance
, GTK_ENTRY( label_widget
), label
);
448 gtk_widget_set_sensitive( label_widget
, enable_label
);
449 nact_gtk_utils_set_editable( GTK_OBJECT( label_widget
), editable
);
451 toggle
= GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance
), "ActionTargetToolbarButton" ));
452 gtk_toggle_button_set_active( toggle
, target_toolbar
);
453 gtk_widget_set_sensitive( GTK_WIDGET( toggle
), item
&& NA_IS_OBJECT_ACTION( item
));
454 nact_gtk_utils_set_editable( GTK_OBJECT( toggle
), editable
);
456 toggle
= GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance
), "ToolbarSameLabelButton" ));
457 same_label
= item
&& NA_IS_OBJECT_ACTION( item
) ? na_object_is_toolbar_same_label( item
) : FALSE
;
458 gtk_toggle_button_set_active( toggle
, same_label
);
459 gtk_widget_set_sensitive( GTK_WIDGET( toggle
), target_toolbar
);
460 nact_gtk_utils_set_editable( GTK_OBJECT( toggle
), editable
);
462 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionToolbarLabelEntry" );
463 label
= item
&& NA_IS_OBJECT_ACTION( item
) ? na_object_get_toolbar_label( item
) : g_strdup( "" );
464 gtk_entry_set_text( GTK_ENTRY( label_widget
), label
);
466 gtk_widget_set_sensitive( label_widget
, target_toolbar
&& !same_label
);
467 nact_gtk_utils_set_editable( GTK_OBJECT( label_widget
), editable
);
469 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionToolbarLabelLabel" );
470 gtk_widget_set_sensitive( label_widget
, target_toolbar
&& !same_label
);
472 tooltip_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionTooltipEntry" );
473 tooltip
= item
? na_object_get_tooltip( item
) : g_strdup( "" );
474 tooltip
= tooltip
? tooltip
: g_strdup( "" );
475 gtk_entry_set_text( GTK_ENTRY( tooltip_widget
), tooltip
);
477 nact_gtk_utils_set_editable( GTK_OBJECT( tooltip_widget
), editable
);
479 icon_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionIconComboBoxEntry" );
480 icon
= item
? na_object_get_icon( item
) : g_strdup( "" );
481 icon
= icon
? icon
: g_strdup( "" );
482 gtk_entry_set_text( GTK_ENTRY( gtk_bin_get_child( GTK_BIN( icon_widget
))), icon
);
484 nact_gtk_utils_set_editable( GTK_OBJECT( icon_widget
), editable
);
486 icon_button
= GTK_BUTTON( base_window_get_widget( BASE_WINDOW( instance
), "ActionIconBrowseButton" ));
487 nact_gtk_utils_set_editable( GTK_OBJECT( icon_button
), editable
);
489 st_on_selection_change
= FALSE
;
494 on_target_selection_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
)
496 static const gchar
*thisfn
= "nact_iaction_tab_on_target_selection_toggled";
501 if( !st_on_selection_change
){
503 g_debug( "%s: button=%p, instance=%p", thisfn
, ( void * ) button
, ( void * ) instance
);
506 G_OBJECT( instance
),
507 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
508 TAB_UPDATABLE_PROP_EDITABLE
, &editable
,
511 g_debug( "%s: item=%p (%s), editable=%s",
512 thisfn
, ( void * ) item
, item
? G_OBJECT_TYPE_NAME( item
) : "null",
513 editable
? "True":"False" );
515 if( item
&& NA_IS_OBJECT_ACTION( item
)){
516 is_target
= gtk_toggle_button_get_active( button
);
519 na_object_set_target_selection( item
, is_target
);
520 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, FALSE
);
523 g_signal_handlers_block_by_func(( gpointer
) button
, on_target_selection_toggled
, instance
);
524 gtk_toggle_button_set_active( button
, !is_target
);
525 g_signal_handlers_unblock_by_func(( gpointer
) button
, on_target_selection_toggled
, instance
);
532 on_target_location_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
)
534 static const gchar
*thisfn
= "nact_iaction_tab_on_target_location_toggled";
539 if( !st_on_selection_change
){
541 g_debug( "%s: button=%p, instance=%p", thisfn
, ( void * ) button
, ( void * ) instance
);
544 G_OBJECT( instance
),
545 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
546 TAB_UPDATABLE_PROP_EDITABLE
, &editable
,
549 g_debug( "%s: item=%p (%s), editable=%s",
550 thisfn
, ( void * ) item
, item
? G_OBJECT_TYPE_NAME( item
) : "null",
551 editable
? "True":"False" );
553 if( item
&& NA_IS_OBJECT_ACTION( item
)){
554 is_target
= gtk_toggle_button_get_active( button
);
557 na_object_set_target_location( item
, is_target
);
558 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, FALSE
);
561 g_signal_handlers_block_by_func(( gpointer
) button
, on_target_location_toggled
, instance
);
562 gtk_toggle_button_set_active( button
, !is_target
);
563 g_signal_handlers_unblock_by_func(( gpointer
) button
, on_target_location_toggled
, instance
);
570 check_for_label( NactIActionTab
*instance
, GtkEntry
*entry
, const gchar
*label
)
574 g_return_if_fail( NACT_IS_IACTION_TAB( instance
));
575 g_return_if_fail( GTK_IS_ENTRY( entry
));
577 if( st_initialized
&& !st_finalized
){
579 nact_main_statusbar_hide_status(
580 NACT_MAIN_WINDOW( instance
),
581 IACTION_TAB_PROP_STATUS_CONTEXT
);
583 set_label_label( instance
, "black" );
586 G_OBJECT( instance
),
587 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
590 if( item
&& g_utf8_strlen( label
, -1 ) == 0 ){
592 /* i18n: status bar message when the action label is empty */
593 nact_main_statusbar_display_status(
594 NACT_MAIN_WINDOW( instance
),
595 IACTION_TAB_PROP_STATUS_CONTEXT
,
596 _( "Caution: a label is mandatory for the action or the menu." ));
598 set_label_label( instance
, "red" );
604 on_label_changed( GtkEntry
*entry
, NactIActionTab
*instance
)
610 G_OBJECT( instance
),
611 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
615 label
= gtk_entry_get_text( entry
);
616 na_object_set_label( item
, label
);
617 check_for_label( instance
, entry
, label
);
619 if( NA_IS_OBJECT_ACTION( item
)){
620 setup_toolbar_label( instance
, item
, label
);
623 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, TRUE
);
628 set_label_label( NactIActionTab
*instance
, const gchar
*color_str
)
633 label
= base_window_get_widget( BASE_WINDOW( instance
), "ActionMenuLabelLabel" );
634 gdk_color_parse( color_str
, &color
);
635 gtk_widget_modify_fg( label
, GTK_STATE_NORMAL
, &color
);
639 on_target_toolbar_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
)
641 static const gchar
*thisfn
= "nact_iaction_tab_on_target_toolbar_toggled";
642 NAObjectAction
*item
;
646 if( !st_on_selection_change
){
648 g_debug( "%s: button=%p, instance=%p", thisfn
, ( void * ) button
, ( void * ) instance
);
651 G_OBJECT( instance
),
652 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
653 TAB_UPDATABLE_PROP_EDITABLE
, &editable
,
656 g_debug( "%s: item=%p (%s), editable=%s",
657 thisfn
, ( void * ) item
, item
? G_OBJECT_TYPE_NAME( item
) : "null",
658 editable
? "True":"False" );
660 if( item
&& NA_IS_OBJECT_ACTION( item
)){
661 is_target
= gtk_toggle_button_get_active( button
);
664 na_object_set_target_toolbar( item
, is_target
);
665 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, FALSE
);
666 toolbar_same_label_set_sensitive( instance
, NA_OBJECT_ITEM( item
));
667 toolbar_label_set_sensitive( instance
, NA_OBJECT_ITEM( item
));
670 g_signal_handlers_block_by_func(( gpointer
) button
, on_target_toolbar_toggled
, instance
);
671 gtk_toggle_button_set_active( button
, !is_target
);
672 g_signal_handlers_unblock_by_func(( gpointer
) button
, on_target_toolbar_toggled
, instance
);
679 on_toolbar_same_label_toggled( GtkToggleButton
*button
, NactIActionTab
*instance
)
681 static const gchar
*thisfn
= "nact_iaction_tab_on_toolbar_same_label_toggled";
686 GtkWidget
*label_widget
;
688 if( !st_on_selection_change
){
689 g_debug( "%s: button=%p, instance=%p", thisfn
, ( void * ) button
, ( void * ) instance
);
692 G_OBJECT( instance
),
693 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
694 TAB_UPDATABLE_PROP_EDITABLE
, &editable
,
697 g_debug( "%s: item=%p (%s), editable=%s",
698 thisfn
, ( void * ) item
, item
? G_OBJECT_TYPE_NAME( item
) : "null",
699 editable
? "True":"False" );
701 if( item
&& NA_IS_OBJECT_ACTION( item
)){
702 same_label
= gtk_toggle_button_get_active( button
);
705 na_object_set_toolbar_same_label( NA_OBJECT_ACTION( item
), same_label
);
708 label
= na_object_get_label( item
);
709 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionToolbarLabelEntry" );
710 gtk_entry_set_text( GTK_ENTRY( label_widget
), label
);
714 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, FALSE
);
715 toolbar_same_label_set_sensitive( instance
, NA_OBJECT_ITEM( item
));
716 toolbar_label_set_sensitive( instance
, NA_OBJECT_ITEM( item
));
719 g_signal_handlers_block_by_func(( gpointer
) button
, on_toolbar_same_label_toggled
, instance
);
720 gtk_toggle_button_set_active( button
, !same_label
);
721 g_signal_handlers_unblock_by_func(( gpointer
) button
, on_toolbar_same_label_toggled
, instance
);
728 toolbar_same_label_set_sensitive( NactIActionTab
*instance
, NAObjectItem
*item
)
730 GtkToggleButton
*toggle
;
731 gboolean target_toolbar
;
734 readonly
= item
? na_object_is_readonly( item
) : FALSE
;
735 toggle
= GTK_TOGGLE_BUTTON( base_window_get_widget( BASE_WINDOW( instance
), "ToolbarSameLabelButton" ));
736 target_toolbar
= item
&& NA_IS_OBJECT_ACTION( item
) ? na_object_is_target_toolbar( NA_OBJECT_ACTION( item
)) : FALSE
;
737 gtk_widget_set_sensitive( GTK_WIDGET( toggle
), target_toolbar
&& !readonly
);
741 * setup the label of the toolbar according to the toolbar_same_label flag
744 setup_toolbar_label( NactIActionTab
*instance
, NAObjectItem
*item
, const gchar
*label
)
746 GtkWidget
*label_widget
;
748 if( item
&& NA_IS_OBJECT_ACTION( item
)){
749 if( na_object_is_toolbar_same_label( item
)){
750 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionToolbarLabelEntry" );
751 gtk_entry_set_text( GTK_ENTRY( label_widget
), label
);
757 on_toolbar_label_changed( GtkEntry
*entry
, NactIActionTab
*instance
)
763 G_OBJECT( instance
),
764 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
767 if( item
&& NA_IS_OBJECT_ACTION( item
)){
768 label
= gtk_entry_get_text( entry
);
769 na_object_set_toolbar_label( NA_OBJECT_ACTION( item
), label
);
771 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, FALSE
);
776 toolbar_label_set_sensitive( NactIActionTab
*instance
, NAObjectItem
*item
)
780 GtkWidget
*label_widget
;
782 is_action
= item
&& NA_IS_OBJECT_ACTION( item
);
783 same_label
= is_action
? na_object_is_toolbar_same_label( NA_OBJECT_ACTION( item
)) : FALSE
;
784 label_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionToolbarLabelEntry" );
785 gtk_widget_set_sensitive( label_widget
, is_action
&& !same_label
);
789 on_tooltip_changed( GtkEntry
*entry
, NactIActionTab
*instance
)
794 G_OBJECT( instance
),
795 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
799 na_object_set_tooltip( item
, gtk_entry_get_text( entry
));
800 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, FALSE
);
804 static GtkTreeModel
*
805 create_stock_icon_model( void )
807 GtkStockItem stock_item
;
811 GSList
*stock_list
, *iter
;
812 GtkIconTheme
*icon_theme
;
813 GtkIconInfo
*icon_info
;
815 model
= gtk_list_store_new( ICON_N_COLUMN
, G_TYPE_STRING
, G_TYPE_STRING
);
817 gtk_list_store_append( model
, &row
);
818 /* i18n notes: when no icon is selected in the drop-down list */
819 gtk_list_store_set( model
, &row
, ICON_STOCK_COLUMN
, "", ICON_LABEL_COLUMN
, _( "None" ), -1 );
821 stock_list
= gtk_stock_list_ids();
822 icon_theme
= gtk_icon_theme_get_default();
823 stock_list
= g_slist_sort( stock_list
, ( GCompareFunc
) sort_stock_ids
);
825 for( iter
= stock_list
; iter
; iter
= iter
->next
){
826 icon_info
= gtk_icon_theme_lookup_icon( icon_theme
, ( gchar
* ) iter
->data
, GTK_ICON_SIZE_MENU
, GTK_ICON_LOOKUP_GENERIC_FALLBACK
);
828 if( gtk_stock_lookup(( gchar
* ) iter
->data
, &stock_item
)){
829 gtk_list_store_append( model
, &row
);
830 label
= strip_underscore( stock_item
.label
);
831 gtk_list_store_set( model
, &row
, ICON_STOCK_COLUMN
, ( gchar
* ) iter
->data
, ICON_LABEL_COLUMN
, label
, -1 );
834 gtk_icon_info_free( icon_info
);
838 g_slist_foreach( stock_list
, ( GFunc
) g_free
, NULL
);
839 g_slist_free( stock_list
);
841 return( GTK_TREE_MODEL( model
));
845 icon_combo_list_fill( GtkComboBoxEntry
* combo
)
847 GtkCellRenderer
*cell_renderer_pix
;
848 GtkCellRenderer
*cell_renderer_text
;
850 if( gtk_combo_box_entry_get_text_column( combo
) == -1 ){
851 gtk_combo_box_entry_set_text_column( combo
, ICON_STOCK_COLUMN
);
854 gtk_cell_layout_clear( GTK_CELL_LAYOUT( combo
));
856 cell_renderer_pix
= gtk_cell_renderer_pixbuf_new();
857 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( combo
), cell_renderer_pix
, FALSE
);
858 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT( combo
), cell_renderer_pix
, "stock-id", ICON_STOCK_COLUMN
);
860 cell_renderer_text
= gtk_cell_renderer_text_new();
861 gtk_cell_layout_pack_start( GTK_CELL_LAYOUT( combo
), cell_renderer_text
, TRUE
);
862 gtk_cell_layout_add_attribute( GTK_CELL_LAYOUT( combo
), cell_renderer_text
, "text", ICON_LABEL_COLUMN
);
864 gtk_combo_box_set_active( GTK_COMBO_BOX( combo
), 0 );
868 on_icon_browse( GtkButton
*button
, NactIActionTab
*instance
)
870 GtkWidget
*icon_widget
;
872 icon_widget
= base_window_get_widget( BASE_WINDOW( instance
), "ActionIconComboBoxEntry" );
874 nact_gtk_utils_select_file(
875 BASE_WINDOW( instance
),
876 _( "Choosing an icon" ), IPREFS_ICONS_DIALOG
,
877 gtk_bin_get_child( GTK_BIN( icon_widget
)), IPREFS_ICONS_DIALOG
, "" );
881 on_icon_changed( GtkEntry
*icon_entry
, NactIActionTab
*instance
)
883 static const gchar
*thisfn
= "nact_iaction_tab_on_icon_changed";
886 const gchar
*icon_name
;
888 g_debug( "%s: entry=%p, instance=%p", thisfn
, ( void * ) icon_entry
, ( void * ) instance
);
893 G_OBJECT( instance
),
894 TAB_UPDATABLE_PROP_SELECTED_ITEM
, &item
,
898 icon_name
= gtk_entry_get_text( icon_entry
);
899 na_object_set_icon( item
, icon_name
);
900 g_signal_emit_by_name( G_OBJECT( instance
), TAB_UPDATABLE_SIGNAL_ITEM_UPDATED
, item
, TRUE
);
902 image
= GTK_IMAGE( base_window_get_widget( BASE_WINDOW( instance
), "ActionIconImage" ));
903 nact_gtk_utils_render( icon_name
, image
, GTK_ICON_SIZE_MENU
);
908 sort_stock_ids( gconstpointer a
, gconstpointer b
)
910 GtkStockItem stock_item_a
;
911 GtkStockItem stock_item_b
;
912 gchar
*label_a
, *label_b
;
916 is_a
= gtk_stock_lookup(( gchar
* ) a
, &stock_item_a
);
917 is_b
= gtk_stock_lookup(( gchar
* ) b
, &stock_item_b
);
922 } else if( !is_a
&& is_b
){
925 } else if( !is_a
&& !is_b
){
929 label_a
= strip_underscore( stock_item_a
.label
);
930 label_b
= strip_underscore( stock_item_b
.label
);
931 retv
= na_core_utils_str_collate( label_a
, label_b
);
940 strip_underscore( const gchar
*text
)
942 /* Code from gtk-demo */
943 gchar
*p
, *q
, *result
;
945 result
= g_strdup( text
);
960 release_icon_combobox( NactIActionTab
*instance
)
965 combo
= base_window_get_widget( BASE_WINDOW( instance
), "ActionIconComboBoxEntry" );
966 model
= gtk_combo_box_get_model( GTK_COMBO_BOX( combo
));
967 gtk_list_store_clear( GTK_LIST_STORE( model
));