Change help menu item from Gtk default to Gnome (apparent) standard
[nautilus-actions.git] / src / nact / nact-main-menubar-file.c
blob8a7942992809304cdd79ba0e5220b895756d40b1
1 /*
2 * Nautilus Actions
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.
24 * Authors:
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)
31 #ifdef HAVE_CONFIG_H
32 #include <config.h>
33 #endif
35 #include <glib/gi18n.h>
37 #include <core/na-io-provider.h>
39 #include "nact-application.h"
40 #include "nact-iactions-list.h"
41 #include "nact-main-tab.h"
42 #include "nact-main-menubar-file.h"
44 static void save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item );
46 /**
47 * nact_main_menubar_file_on_update_sensitivities:
48 * @window: the #NactMainWindow main window.
49 * user_data: the data passed to the function via the signal.
50 * @mis: the #MenubarIndicatorsStruct struct.
52 * Update sensitivity of items of the File menu.
54 void
55 nact_main_menubar_file_on_update_sensitivities( NactMainWindow *window, gpointer user_data, MenubarIndicatorsStruct *mis )
57 static const gchar *thisfn = "nact_main_menubar_file_on_update_sensitivities";
58 gboolean new_item_enabled;
59 gboolean new_profile_enabled;
60 NAObject *first_parent;
61 NAObject *selected_action;
62 NAObject *parent_item;
63 gboolean is_first_parent_writable;
64 gboolean has_modified_items;
65 GList *is;
67 first_parent = mis->selected_items && g_list_length( mis->selected_items )
68 ? ( NAObject * ) na_object_get_parent( mis->selected_items->data )
69 : NULL;
70 is_first_parent_writable = first_parent
71 ? nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( first_parent ), NULL )
72 : mis->is_level_zero_writable;
74 has_modified_items = nact_main_window_has_modified_items( window );
75 g_debug( "%s: has_modified_items=%s", thisfn, has_modified_items ? "True":"False" );
77 /* new menu / new action
78 * new item will be inserted just before beginning of selection
79 * parent of the first selected row must be writable
80 * we must have at least one writable provider
82 new_item_enabled = is_first_parent_writable && mis->has_writable_providers;
83 nact_main_menubar_enable_item( window, "NewMenuItem", new_item_enabled );
84 nact_main_menubar_enable_item( window, "NewActionItem", new_item_enabled );
86 /* new profile enabled if selection is relative to only one writable action
87 * i.e. contains profile(s) of the same action, or only contains one action
88 * action must be writable
90 new_profile_enabled = TRUE;
91 selected_action = NULL;
92 for( is = mis->selected_items ; is ; is = is->next ){
94 if( NA_IS_OBJECT_MENU( is->data )){
95 new_profile_enabled = FALSE;
96 break;
98 } else if( NA_IS_OBJECT_ACTION( is->data )){
99 if( !selected_action ){
100 selected_action = NA_OBJECT( is->data );
101 } else if( selected_action != is->data ){
102 new_profile_enabled = FALSE;
103 break;
106 } else if( NA_IS_OBJECT_PROFILE( is->data )){
107 parent_item = NA_OBJECT( na_object_get_parent( is->data ));
108 if( !selected_action ){
109 selected_action = parent_item;
110 } else if( selected_action != parent_item ){
111 new_profile_enabled = FALSE;
112 break;
116 nact_main_menubar_enable_item( window, "NewProfileItem",
117 new_profile_enabled &&
118 selected_action != NULL &&
119 nact_window_is_item_writable( NACT_WINDOW( window ), NA_OBJECT_ITEM( selected_action ), NULL ));
121 /* save enabled if at least one item has been modified
122 * or level-zero has been resorted and is writable
124 nact_main_menubar_enable_item( window, "SaveItem",
125 has_modified_items || ( mis->level_zero_order_changed && mis->is_level_zero_writable ));
127 /* quit always enabled */
131 * nact_main_menubar_file_on_new_menu:
132 * @gtk_action: the #GtkAction action.
133 * @window: the #NactMainWindow main window.
135 * Triggers File / New menu item.
137 void
138 nact_main_menubar_file_on_new_menu( GtkAction *gtk_action, NactMainWindow *window )
140 NAObjectMenu *menu;
141 GList *items;
143 g_return_if_fail( GTK_IS_ACTION( gtk_action ));
144 g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
146 menu = na_object_menu_new_with_defaults();
147 na_object_check_status( menu );
148 items = g_list_prepend( NULL, menu );
149 nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
150 na_object_unref_items( items );
154 * nact_main_menubar_file_on_new_action:
155 * @gtk_action: the #GtkAction action.
156 * @window: the #NactMainWindow main window.
158 * Triggers File / New action item.
160 void
161 nact_main_menubar_file_on_new_action( GtkAction *gtk_action, NactMainWindow *window )
163 NAObjectAction *action;
164 GList *items;
166 g_return_if_fail( GTK_IS_ACTION( gtk_action ));
167 g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
169 action = na_object_action_new_with_defaults();
170 na_object_check_status( action );
171 items = g_list_prepend( NULL, action );
172 nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
173 na_object_unref_items( items );
177 * nact_main_menubar_file_on_new_profile:
178 * @gtk_action: the #GtkAction action.
179 * @window: the #NactMainWindow main window.
181 * Triggers File / New profile item.
183 void
184 nact_main_menubar_file_on_new_profile( GtkAction *gtk_action, NactMainWindow *window )
186 NAObjectAction *action;
187 NAObjectProfile *profile;
188 gchar *name;
189 GList *items;
191 g_return_if_fail( GTK_IS_ACTION( gtk_action ));
192 g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
194 g_object_get(
195 G_OBJECT( window ),
196 TAB_UPDATABLE_PROP_SELECTED_ITEM, &action,
197 NULL );
199 profile = na_object_profile_new_with_defaults();
200 na_object_set_label( profile, _( "New profile" ));
202 name = na_object_action_get_new_profile_name( action );
203 na_object_set_id( profile, name );
204 g_free( name );
206 /*na_object_attach_profile( action, profile );*/
208 na_object_check_status( profile );
210 items = g_list_prepend( NULL, profile );
211 nact_iactions_list_bis_insert_items( NACT_IACTIONS_LIST( window ), items, NULL );
212 na_object_unref_items( items );
216 * nact_main_menubar_file_on_save:
217 * @gtk_action: the #GtkAction action.
218 * @window: the #NactMainWindow main window.
220 * Triggers File /Save item.
222 * Saving is not only saving modified items, but also saving hierarchy
223 * (and order if alpha order is not set).
225 * This is the same function that #nact_main_menubar_file_save_items(), just with
226 * different arguments.
228 void
229 nact_main_menubar_file_on_save( GtkAction *gtk_action, NactMainWindow *window )
231 static const gchar *thisfn = "nact_main_menubar_file_on_save";
233 g_debug( "%s: gtk_action=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
234 g_return_if_fail( GTK_IS_ACTION( gtk_action ));
235 g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
237 nact_main_menubar_file_save_items( window );
241 * nact_main_menubar_file_save_items:
242 * @gtk_action: the #GtkAction action.
243 * @window: the #NactMainWindow main window.
245 * Save items.
246 * This is the same function that #nact_main_menubar_file_on_save(), just with
247 * different arguments.
249 void
250 nact_main_menubar_file_save_items( NactMainWindow *window )
252 static const gchar *thisfn = "nact_main_menubar_file_save_items";
253 GList *items, *it;
254 NactApplication *application;
255 NAUpdater *updater;
256 MenubarIndicatorsStruct *mis;
257 gchar *label;
258 GList *new_pivot;
259 NAObjectItem *duplicate;
261 g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
263 g_debug( "%s: window=%p", thisfn, ( void * ) window );
265 /* remove deleted items
266 * so that new actions with same id do not risk to be deleted later
268 nact_main_window_remove_deleted( window );
270 /* always write the level zero list of items
271 * and reset the corresponding modification flag
273 application = NACT_APPLICATION( base_window_get_application( BASE_WINDOW( window )));
274 updater = nact_application_get_updater( application );
275 items = nact_iactions_list_bis_get_items( NACT_IACTIONS_LIST( window ));
277 na_pivot_write_level_zero( NA_PIVOT( updater ), items );
278 mis = ( MenubarIndicatorsStruct * ) g_object_get_data( G_OBJECT( window ), MENUBAR_PROP_INDICATORS );
279 mis->level_zero_order_changed = FALSE;
281 /* recursively save the modified items
282 * check is useless here if item was not modified, but not very costly
283 * above all, it is less costly to check the status here, than to check
284 * recursively each and every modified item
286 new_pivot = NULL;
288 for( it = items ; it ; it = it->next ){
289 label = na_object_get_label( it->data );
290 g_debug( "%s saving item %s %p (%s), modified=%s",
291 thisfn,
292 G_OBJECT_TYPE_NAME( it->data ),
293 ( void * ) it->data, label,
294 na_object_is_modified( it->data ) ? "True":"False" );
295 g_free( label );
297 save_item( window, updater, NA_OBJECT_ITEM( it->data ));
299 duplicate = NA_OBJECT_ITEM( na_object_duplicate( it->data ));
300 na_object_reset_origin( it->data, duplicate );
301 na_object_check_status( it->data );
302 new_pivot = g_list_prepend( new_pivot, duplicate );
305 na_pivot_set_new_items( NA_PIVOT( updater ), g_list_reverse( new_pivot ));
306 g_list_free( items );
308 /* when new_pivot is empty, then there has been no chance of updating
309 * sensibilities on check status - so force it there
311 if( !new_pivot ){
312 g_signal_emit_by_name( window, MAIN_WINDOW_SIGNAL_UPDATE_ACTION_SENSITIVITIES, NULL );
315 /* get ride of notification messages of IOProviders
317 na_ipivot_consumer_delay_notify( NA_IPIVOT_CONSUMER( window ));
321 * iterates here on each and every NAObjectItem row stored in the tree
323 * do not deal with profiles as they are directly managed by the action
324 * they are attached to
326 * level zero order has already been saved from tree store order, so that
327 * we actually do not care of the exact order of level zero NAPivot items
329 * saving means non-recursively save modified NAObjectItem, simultaneously
330 * reproducing the new item in NAPivot
331 * +- A
332 * | +- B
333 * | | +- C
334 * | | | +- D
335 * | | | +- E
336 * | | +- F
337 * | +- G
338 * +- H
339 * | +- ...
340 * save order: A-B-C-D-E-F-G-H (first parent, then children)
342 static void
343 save_item( NactMainWindow *window, NAUpdater *updater, NAObjectItem *item )
345 NAIOProvider *provider_before;
346 NAIOProvider *provider_after;
347 GList *subitems, *it;
349 g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
350 g_return_if_fail( NA_IS_UPDATER( updater ));
351 g_return_if_fail( NA_IS_OBJECT_ITEM( item ));
353 provider_before = na_object_get_provider( item );
355 if( na_object_is_modified( item ) &&
356 nact_window_save_item( NACT_WINDOW( window ), item )){
358 if( NA_IS_OBJECT_ACTION( item )){
359 na_object_reset_last_allocated( item );
362 nact_iactions_list_bis_remove_modified( NACT_IACTIONS_LIST( window ), item );
364 provider_after = na_object_get_provider( item );
365 if( provider_after != provider_before ){
366 g_signal_emit_by_name( window, TAB_UPDATABLE_SIGNAL_PROVIDER_CHANGED, item );
370 if( NA_IS_OBJECT_MENU( item )){
371 subitems = na_object_get_items( item );
372 for( it = subitems ; it ; it = it->next ){
373 save_item( window, updater, NA_OBJECT_ITEM( it->data ));
379 * nact_main_menubar_file_on_quit:
380 * @gtk_action: the #GtkAction action.
381 * @window: the #NactMainWindow main window.
383 * Triggers the File / Quit item.
385 void
386 nact_main_menubar_file_on_quit( GtkAction *gtk_action, NactMainWindow *window )
388 static const gchar *thisfn = "nact_main_menubar_file_on_quit";
389 gboolean has_modified;
391 g_debug( "%s: item=%p, window=%p", thisfn, ( void * ) gtk_action, ( void * ) window );
392 g_return_if_fail( GTK_IS_ACTION( gtk_action ) || gtk_action == NULL );
393 g_return_if_fail( NACT_IS_MAIN_WINDOW( window ));
395 has_modified = nact_main_window_has_modified_items( window );
396 if( !has_modified || nact_window_warn_modified( NACT_WINDOW( window ))){
397 g_object_unref( window );