/**
 * nautilus_navigation_window_show:
 * @widget: a #GtkWidget.
 *
 * Call parent and then show/hide window items
 * base on user prefs.
 */
static void
nautilus_navigation_window_show (GtkWidget *widget)
{	
	NautilusNavigationWindow *window;
	gboolean show_location_bar;
	gboolean always_use_location_entry;
	GList *walk;

	window = NAUTILUS_NAVIGATION_WINDOW (widget);

	/* Initially show or hide views based on preferences; once the window is displayed
	 * these can be controlled on a per-window basis from View menu items. 
	 */

	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_TOOLBAR)) {
		nautilus_navigation_window_show_toolbar (window);
	} else {
		nautilus_navigation_window_hide_toolbar (window);
	}

	show_location_bar = eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_LOCATION_BAR);
	always_use_location_entry = eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY);
	for (walk = NAUTILUS_WINDOW(window)->details->panes; walk; walk = walk->next) {
		NautilusNavigationWindowPane *pane = walk->data;
		if (show_location_bar) {
			nautilus_navigation_window_pane_show_location_bar (pane, FALSE);
		} else {
			nautilus_navigation_window_pane_hide_location_bar (pane, FALSE);
		}

		if (always_use_location_entry) {
			nautilus_navigation_window_pane_set_bar_mode (pane, NAUTILUS_BAR_NAVIGATION);
		} else {
			nautilus_navigation_window_pane_set_bar_mode (pane, NAUTILUS_BAR_PATH);
		}
	}
	
	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_SIDEBAR)) {
		nautilus_navigation_window_show_sidebar (window);
	} else {
		nautilus_navigation_window_hide_sidebar (window);
	}

	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_STATUS_BAR)) {
		nautilus_navigation_window_show_status_bar (window);
	} else {
		nautilus_navigation_window_hide_status_bar (window);
	}

	GTK_WIDGET_CLASS (parent_class)->show (widget);
}
static void
real_sync_title (NautilusWindow *window,
		 NautilusWindowSlot *slot)
{
	NautilusNavigationWindow *navigation_window;
	NautilusNavigationWindowPane *pane;
	NautilusNotebook *notebook;
	char *full_title;
	char *window_title;

	navigation_window = NAUTILUS_NAVIGATION_WINDOW (window);

	EEL_CALL_PARENT (NAUTILUS_WINDOW_CLASS,
			 sync_title, (window, slot));

	if (slot == window->details->active_pane->active_slot) {
		/* if spatial mode is default, we keep "File Browser" in the window title
		 * to recognize browser windows. Otherwise, we default to the directory name.
		 */
		if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
			full_title = g_strdup_printf (_("%s - File Browser"), slot->title);
			window_title = eel_str_middle_truncate (full_title, MAX_TITLE_LENGTH);
			g_free (full_title);
		} else {
			window_title = eel_str_middle_truncate (slot->title, MAX_TITLE_LENGTH);
		}

		gtk_window_set_title (GTK_WINDOW (window), window_title);
		g_free (window_title);
	}

	pane = NAUTILUS_NAVIGATION_WINDOW_PANE (slot->pane);
	notebook = NAUTILUS_NOTEBOOK (pane->notebook);
	nautilus_notebook_sync_tab_label (notebook, slot);
}
static char *
get_desktop_path (void)
{
	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR)) {
		return g_strdup (g_get_home_dir());
	} else {
		return nautilus_get_xdg_dir ("DESKTOP");
	}
}
void 
nautilus_navigation_window_show_toolbar (NautilusNavigationWindow *window)
{
	gtk_widget_show (window->details->toolbar);
	nautilus_navigation_window_update_show_hide_menu_items (window);
	if (eel_preferences_key_is_writable (NAUTILUS_PREFERENCES_START_WITH_TOOLBAR) &&
	    !eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_TOOLBAR)) {
		eel_preferences_set_boolean (NAUTILUS_PREFERENCES_START_WITH_TOOLBAR, TRUE);
	}
}
void 
nautilus_navigation_window_hide_status_bar (NautilusNavigationWindow *window)
{
	gtk_widget_hide (NAUTILUS_WINDOW (window)->details->statusbar);

	nautilus_navigation_window_update_show_hide_menu_items (window);
	if (eel_preferences_key_is_writable (NAUTILUS_PREFERENCES_START_WITH_STATUS_BAR) &&
	    eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_STATUS_BAR)) {
		eel_preferences_set_boolean (NAUTILUS_PREFERENCES_START_WITH_STATUS_BAR, FALSE);
	}
}
/**
 * nautilus_window_initialize_menus
 * 
 * Create and install the set of menus for this window.
 * @window: A recently-created NautilusWindow.
 */
void 
nautilus_window_initialize_menus (NautilusWindow *window)
{
	GtkActionGroup *action_group;
	GtkUIManager *ui_manager;
	GtkAction *action;
	const char *ui;
	
	action_group = gtk_action_group_new ("ShellActions");
	gtk_action_group_set_translation_domain (action_group, GETTEXT_PACKAGE);
	window->details->main_action_group = action_group;
	gtk_action_group_add_actions (action_group, 
				      main_entries, G_N_ELEMENTS (main_entries),
				      window);
	gtk_action_group_add_toggle_actions (action_group, 
					     main_toggle_entries, G_N_ELEMENTS (main_toggle_entries),
					     window);

	action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_UP);
	g_object_set (action, "short_label", _("_Up"), NULL);

	action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_HOME);
	g_object_set (action, "short_label", _("_Home"), NULL);

	action = gtk_action_group_get_action (action_group, NAUTILUS_ACTION_SHOW_HIDDEN_FILES);
	g_signal_handlers_block_by_func (action, action_show_hidden_files_callback, window);
	gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
				      eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES));
	g_signal_handlers_unblock_by_func (action, action_show_hidden_files_callback, window);


	eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES,
						  show_hidden_files_preference_callback,
						  window, G_OBJECT (window));

	window->details->ui_manager = gtk_ui_manager_new ();
	ui_manager = window->details->ui_manager;
	gtk_window_add_accel_group (GTK_WINDOW (window),
				    gtk_ui_manager_get_accel_group (ui_manager));
	
	g_signal_connect (ui_manager, "connect_proxy",
			  G_CALLBACK (connect_proxy_cb), window);
	g_signal_connect (ui_manager, "disconnect_proxy",
			  G_CALLBACK (disconnect_proxy_cb), window);
	
	gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
	g_object_unref (action_group); /* owned by ui manager */

	ui = nautilus_ui_string_get ("nautilus-shell-ui.xml");
	gtk_ui_manager_add_ui_from_string (ui_manager, ui, -1, NULL);

	nautilus_window_initialize_trash_icon_monitor (window);
	nautilus_window_initialize_bookmarks_menu (window);
}
void
nautilus_navigation_window_update_spatial_menu_item (NautilusNavigationWindow *window) 
{
	GtkAction *action;

	g_assert (NAUTILUS_IS_NAVIGATION_WINDOW (window));

	action = gtk_action_group_get_action (window->details->navigation_action_group,
					      NAUTILUS_ACTION_FOLDER_WINDOW);
	gtk_action_set_visible (action,
				!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER));
}
void 
nautilus_navigation_window_show_sidebar (NautilusNavigationWindow *window)
{
	if (window->sidebar != NULL) {
		return;
	}

	nautilus_navigation_window_set_up_sidebar (window);
	nautilus_navigation_window_update_show_hide_menu_items (window);
	if (eel_preferences_key_is_writable (NAUTILUS_PREFERENCES_START_WITH_SIDEBAR) &&
	    !eel_preferences_get_boolean (NAUTILUS_PREFERENCES_START_WITH_SIDEBAR)) {
		eel_preferences_set_boolean (NAUTILUS_PREFERENCES_START_WITH_SIDEBAR, TRUE);
	}
}
static void
always_use_location_entry_changed (gpointer callback_data)
{
	NautilusNavigationWindow *window;
	GList *walk;
	gboolean use_entry;

	window = NAUTILUS_NAVIGATION_WINDOW (callback_data);

	use_entry = eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_LOCATION_ENTRY);

	for (walk = NAUTILUS_WINDOW(window)->details->panes; walk; walk = walk->next) {
		nautilus_navigation_window_pane_always_use_location_entry (walk->data, use_entry);
	}
}
static void
open_selected_bookmark (gpointer user_data, GdkScreen *screen)
{
	NautilusBookmark *selected;
	NautilusWindow *window;
	GFile *location;
	
	selected = get_selected_bookmark ();

	if (!selected) {
		return;
	}

	location = nautilus_bookmark_get_location (selected);
	if (location == NULL) { 
		return;
	}

	if (NAUTILUS_IS_NAVIGATION_WINDOW (user_data)) {
		nautilus_window_go_to (NAUTILUS_WINDOW (user_data), location);
	} else if (NAUTILUS_IS_SPATIAL_WINDOW (user_data)) {
		window = nautilus_application_present_spatial_window (application, 
								      NULL,
								      NULL,
								      location,
								      screen);
	} else { /* window that opened bookmarks window has been closed */
		if (parent_is_browser_window || eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
			window = nautilus_application_create_navigation_window (application, 
										NULL,
										screen);
			nautilus_window_go_to (window, location);
		} else {
			window = nautilus_application_present_spatial_window (application, 
									      NULL,
									      NULL,
									      location,
									      screen);
		}
	}

	g_object_unref (location);
}
static void
nautilus_file_background_get_default_settings (char **color,
                                               char **image,
                                               EelBackgroundImagePlacement *placement)
{
        gboolean background_set;

        background_set = eel_preferences_get_boolean
                (NAUTILUS_PREFERENCES_BACKGROUND_SET);
        
        if (background_set && color) {
                *color = eel_preferences_get (NAUTILUS_PREFERENCES_BACKGROUND_COLOR);
        }
        
        if (background_set && image) {
                *image = eel_preferences_get (NAUTILUS_PREFERENCES_BACKGROUND_FILENAME);
        }

        if (placement) {
                *placement = EEL_BACKGROUND_TILED;
        }
}
/**
 * nautilus_get_desktop_directory:
 * 
 * Get the path for the directory containing files on the desktop.
 *
 * Return value: the directory path.
 **/
char *
nautilus_get_desktop_directory (void)
{
	char *desktop_directory;
	
	desktop_directory = get_desktop_path ();

	/* Don't try to create a home directory */
	if (!eel_preferences_get_boolean (NAUTILUS_PREFERENCES_DESKTOP_IS_HOME_DIR)) {
		if (!g_file_test (desktop_directory, G_FILE_TEST_EXISTS)) {
			mkdir (desktop_directory, DEFAULT_DESKTOP_DIRECTORY_MODE);
			/* FIXME bugzilla.gnome.org 41286: 
			 * How should we handle the case where this mkdir fails? 
			 * Note that nautilus_application_startup will refuse to launch if this 
			 * directory doesn't get created, so that case is OK. But the directory 
			 * could be deleted after Nautilus was launched, and perhaps
			 * there is some bad side-effect of not handling that case.
			 */
		}
	}

	return desktop_directory;
}
static void
show_hidden_files_preference_callback (gpointer callback_data)
{
	NautilusWindow *window;
	GtkAction *action;

	window = NAUTILUS_WINDOW (callback_data);

	if (window->details->show_hidden_files_mode == NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT) {
		action = gtk_action_group_get_action (window->details->main_action_group, NAUTILUS_ACTION_SHOW_HIDDEN_FILES);
		g_assert (GTK_IS_ACTION (action));

		/* update button */
		g_signal_handlers_block_by_func (action, action_show_hidden_files_callback, window);
		gtk_toggle_action_set_active (GTK_TOGGLE_ACTION (action),
					      eel_preferences_get_boolean (NAUTILUS_PREFERENCES_SHOW_HIDDEN_FILES));
		g_signal_handlers_unblock_by_func (action, action_show_hidden_files_callback, window);

		/* inform views */
		nautilus_window_info_set_hidden_files_mode (window, NAUTILUS_WINDOW_SHOW_HIDDEN_FILES_DEFAULT);

	}
}
void
nautilus_connect_server_dialog_present_uri (NautilusApplication *application,
					    GFile *location,
					    GtkWidget *widget)
{
	NautilusWindow *window;

	if (eel_preferences_get_boolean (NAUTILUS_PREFERENCES_ALWAYS_USE_BROWSER)) {
		window = nautilus_application_create_navigation_window (application,
									NULL,
									gtk_widget_get_screen (widget));
		nautilus_window_go_to (window, location);
	} else {
		nautilus_application_present_spatial_window (application,
							     NULL,
							     NULL,
							     location,
							     gtk_widget_get_screen (widget));
	}

	gtk_widget_destroy (widget);
	g_object_unref (location);
}
static void
nautilus_file_management_properties_dialog_update_media_sensitivity (GladeXML *xml_dialog)
{
	gtk_widget_set_sensitive (glade_xml_get_widget (xml_dialog, "media_handling_vbox"), 
				  ! eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MEDIA_AUTORUN_NEVER));
}
int
main (int argc, char *argv[])
{
    gboolean kill_shell;
    gboolean no_default_window;
    gboolean browser_window;
    gboolean no_desktop;
    gboolean version;
    gboolean autostart_mode;
    const char *autostart_id;
    gchar *geometry;
    gchar **remaining;
    gboolean perform_self_check;
    CajaApplication *application;
    GOptionContext *context;
    GFile *file;
    char *uri;
    char **uris;
    GPtrArray *uris_array;
    GError *error;
    int i;

    const GOptionEntry options[] =
    {
#ifndef CAJA_OMIT_SELF_CHECK
        {
            "check", 'c', 0, G_OPTION_ARG_NONE, &perform_self_check,
            N_("Perform a quick set of self-check tests."), NULL
        },
#endif
        {
            "version", '\0', 0, G_OPTION_ARG_NONE, &version,
            N_("Show the version of the program."), NULL
        },
        {
            "geometry", 'g', 0, G_OPTION_ARG_STRING, &geometry,
            N_("Create the initial window with the given geometry."), N_("GEOMETRY")
        },
        {
            "no-default-window", 'n', 0, G_OPTION_ARG_NONE, &no_default_window,
            N_("Only create windows for explicitly specified URIs."), NULL
        },
        {
            "no-desktop", '\0', 0, G_OPTION_ARG_NONE, &no_desktop,
            N_("Do not manage the desktop (ignore the preference set in the preferences dialog)."), NULL
        },
        {
            "browser", '\0', 0, G_OPTION_ARG_NONE, &browser_window,
            N_("open a browser window."), NULL
        },
        {
            "quit", 'q', 0, G_OPTION_ARG_NONE, &kill_shell,
            N_("Quit Caja."), NULL
        },
        { G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL,  N_("[URI...]") },

        { NULL }
    };

#if defined (HAVE_MALLOPT) && defined(M_MMAP_THRESHOLD)
    /* Caja uses lots and lots of small and medium size allocations,
     * and then a few large ones for the desktop background. By default
     * glibc uses a dynamic treshold for how large allocations should
     * be mmaped. Unfortunately this triggers quickly for caja when
     * it does the desktop background allocations, raising the limit
     * such that a lot of temporary large allocations end up on the
     * heap and are thus not returned to the OS. To fix this we set
     * a hardcoded limit. I don't know what a good value is, but 128K
     * was the old glibc static limit, lets use that.
     */
    mallopt (M_MMAP_THRESHOLD, 128 *1024);
#endif

    g_thread_init (NULL);

    /* This will be done by gtk+ later, but for now, force it to MATE */
    g_desktop_app_info_set_desktop_env ("MATE");

    if (g_getenv ("CAJA_DEBUG") != NULL)
    {
        eel_make_warnings_and_criticals_stop_in_debugger ();
    }

    /* Initialize gettext support */
    bindtextdomain (GETTEXT_PACKAGE, MATELOCALEDIR);
    bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
    textdomain (GETTEXT_PACKAGE);

    autostart_mode = FALSE;

    autostart_id = g_getenv ("DESKTOP_AUTOSTART_ID");
    if (autostart_id != NULL && *autostart_id != '\0')
    {
        autostart_mode = TRUE;
    }

    /* Get parameters. */
    remaining = NULL;
    geometry = NULL;
    version = FALSE;
    kill_shell = FALSE;
    no_default_window = FALSE;
    no_desktop = FALSE;
    perform_self_check = FALSE;
    browser_window = FALSE;

    g_set_prgname ("caja");

    if (g_file_test (DATADIR "/applications/caja.desktop", G_FILE_TEST_EXISTS))
    {
        egg_set_desktop_file (DATADIR "/applications/caja.desktop");
    }

    context = g_option_context_new (_("\n\nBrowse the file system with the file manager"));
    g_option_context_add_main_entries (context, options, NULL);

    g_option_context_add_group (context, gtk_get_option_group (TRUE));
    g_option_context_add_group (context, egg_sm_client_get_option_group ());

    error = NULL;
    if (!g_option_context_parse (context, &argc, &argv, &error))
    {
        g_printerr ("Could not parse arguments: %s\n", error->message);
        g_error_free (error);
        return 1;
    }

    g_option_context_free (context);

    if (version)
    {
        g_print ("MATE caja " PACKAGE_VERSION "\n");
        return 0;
    }

#ifdef HAVE_EXEMPI
    xmp_init();
#endif

    setup_debug_log ();

    /* If in autostart mode (aka started by mate-session), we need to ensure
         * caja starts with the correct options.
         */
    if (autostart_mode)
    {
        no_default_window = TRUE;
        no_desktop = FALSE;
    }

    if (perform_self_check && remaining != NULL)
    {
        /* translators: %s is an option (e.g. --check) */
        fprintf (stderr, _("caja: %s cannot be used with URIs.\n"),
                 "--check");
        return EXIT_FAILURE;
    }
    if (perform_self_check && kill_shell)
    {
        fprintf (stderr, _("caja: --check cannot be used with other options.\n"));
        return EXIT_FAILURE;
    }
    if (kill_shell && remaining != NULL)
    {
        fprintf (stderr, _("caja: %s cannot be used with URIs.\n"),
                 "--quit");
        return EXIT_FAILURE;
    }
    if (geometry != NULL && remaining != NULL && remaining[0] != NULL && remaining[1] != NULL)
    {
        fprintf (stderr, _("caja: --geometry cannot be used with more than one URI.\n"));
        return EXIT_FAILURE;
    }

    /* Initialize the services that we use. */
    LIBXML_TEST_VERSION

    /* Initialize preferences. This is needed so that proper
     * defaults are available before any preference peeking
     * happens.
     */
    caja_global_preferences_init ();

    /* exit_with_last_window being FALSE, caja can run without window. */
    exit_with_last_window = eel_preferences_get_boolean (CAJA_PREFERENCES_EXIT_WITH_LAST_WINDOW);

    if (no_desktop)
    {
        eel_preferences_set_is_invisible
        (CAJA_PREFERENCES_SHOW_DESKTOP, TRUE);
        eel_preferences_set_is_invisible
        (CAJA_PREFERENCES_DESKTOP_IS_HOME_DIR, TRUE);
    }

    application = NULL;

    /* Do either the self-check or the real work. */
    if (perform_self_check)
    {
		#ifndef CAJA_OMIT_SELF_CHECK
			/* Run the checks (each twice) for caja and libcaja-private. */

			caja_run_self_checks ();
			caja_run_lib_self_checks ();
			eel_exit_if_self_checks_failed ();

			caja_run_self_checks ();
			caja_run_lib_self_checks ();
			eel_exit_if_self_checks_failed ();
		#endif
    }
    else
    {
        /* Convert args to URIs */
        uris = NULL;
        if (remaining != NULL)
        {
            uris_array = g_ptr_array_new ();
            for (i = 0; remaining[i] != NULL; i++)
            {
                file = g_file_new_for_commandline_arg (remaining[i]);
                if (file != NULL)
                {
                    uri = g_file_get_uri (file);
                    g_object_unref (file);
                    if (uri)
                    {
                        g_ptr_array_add (uris_array, uri);
                    }
                }
            }
            g_ptr_array_add (uris_array, NULL);
            uris = (char**) g_ptr_array_free (uris_array, FALSE);
            g_strfreev (remaining);
        }


        /* Run the caja application. */
        application = caja_application_new ();

        if (egg_sm_client_is_resumed (application->smclient))
        {
            no_default_window = TRUE;
        }

        caja_application_startup
        (application,
         kill_shell, no_default_window, no_desktop,
         browser_window,
         geometry,
         uris);
        g_strfreev (uris);

        if (unique_app_is_running (application->unique_app) ||
                kill_shell)
        {
            exit_with_last_window = TRUE;
        }

        if (is_event_loop_needed ())
        {
            gtk_main ();
        }
    }

    caja_icon_info_clear_caches ();

    if (application != NULL)
    {
        g_object_unref (application);
    }

    eel_debug_shut_down ();

    caja_application_save_accel_map (NULL);

    return EXIT_SUCCESS;
}
static void
use_extra_mouse_buttons_changed (gpointer callback_data)
{
	mouse_extra_buttons = eel_preferences_get_boolean (NAUTILUS_PREFERENCES_MOUSE_USE_EXTRA_BUTTONS);
}