static gboolean
skeleton_handle_show_folders_cb (NautilusFreedesktopFileManager1 *object,
				 GDBusMethodInvocation *invocation,
				 const gchar *const *uris,
				 const gchar *startup_id,
				 gpointer data)
{
        NautilusApplication *application;
	int i;

        application = NAUTILUS_APPLICATION (g_application_get_default ());

	for (i = 0; uris[i] != NULL; i++) {
		GFile *file;

		file = g_file_new_for_uri (uris[i]);

		nautilus_application_open_location (application, file, NULL, startup_id);

		g_object_unref (file);
	}

	nautilus_freedesktop_file_manager1_complete_show_folders (object, invocation);
	return TRUE;
}
static void
action_bookmarks (GSimpleAction *action,
		  GVariant *parameter,
		  gpointer user_data)
{
	GtkApplication *application = user_data;

	nautilus_application_edit_bookmarks (NAUTILUS_APPLICATION (application),
					     NAUTILUS_WINDOW (gtk_application_get_active_window (application)));
}
/* callback for showing or hiding the desktop based on the user's preference */
static void
desktop_changed_callback (gpointer user_data)
{
	NautilusApplication *application;

	application = NAUTILUS_APPLICATION (user_data);
	if (g_settings_get_boolean (gnome_background_preferences, NAUTILUS_PREFERENCES_SHOW_DESKTOP)) {
		nautilus_application_open_desktop (application);
	} else {
		nautilus_application_close_desktop ();
	}
}
static void
action_add_bookmark_callback (GtkAction *action,
                              gpointer user_data)
{
    NautilusWindow *window = user_data;
    NautilusApplication *app = NAUTILUS_APPLICATION (g_application_get_default ());
    NautilusWindowSlot *slot;

    slot = nautilus_window_get_active_slot (window);
    nautilus_bookmark_list_append (nautilus_application_get_bookmarks (app),
                                   nautilus_window_slot_get_bookmark (slot));
}
static void
action_new_window (GSimpleAction *action,
		   GVariant *parameter,
		   gpointer user_data)
{
	GtkApplication *application = user_data;
        GFile *home;

        home = g_file_new_for_path (g_get_home_dir ());
        nautilus_application_open_location_full (NAUTILUS_APPLICATION (application), home,
                                                 NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW, NULL, NULL, NULL);

        g_object_unref (home);
}
static void
nautilus_application_open (GApplication *app,
			   GFile **files,
			   gint n_files,
			   const gchar *hint)
{
	NautilusApplication *self = NAUTILUS_APPLICATION (app);

	DEBUG ("Open called on the GApplication instance; %d files", n_files);

	gboolean force_new = (g_strcmp0 (hint, "new-window") == 0);

	open_windows (self, force_new, files, n_files,
		      gdk_screen_get_default (),
		      self->priv->geometry);
}
static void
action_new_window (GSimpleAction *action,
		   GVariant *parameter,
		   gpointer user_data)
{
	GtkApplication *application = user_data;
	NautilusWindow *window;
	GtkWindow *cur_window;

	cur_window = gtk_application_get_active_window (application);
	window = nautilus_application_create_window (NAUTILUS_APPLICATION (application),
						     cur_window ?
						     gtk_window_get_screen (cur_window) :
						     gdk_screen_get_default ());

	nautilus_window_slot_go_home (nautilus_window_get_active_slot (window), 0);
}
static void
action_search (GSimpleAction *action,
	       GVariant *parameter,
	       gpointer user_data)
{
	GtkApplication *application = user_data;
	const gchar *string, *uri;
	NautilusQuery *query;
	NautilusDirectory *directory;
	gchar *search_uri;
	NautilusWindow *window;
	GtkWindow *cur_window;
	GFile *location;

	g_variant_get (parameter, "(ss)", &uri, &string);

	if (strlen (string) == 0 ||
	    strlen (uri) == 0) {
		return;
	}

	query = nautilus_query_new ();
	nautilus_query_set_location (query, uri);
	nautilus_query_set_text (query, string);

	search_uri = nautilus_search_directory_generate_new_uri ();
	location = g_file_new_for_uri (search_uri);
	g_free (search_uri);

	directory = nautilus_directory_get (location);
	nautilus_search_directory_set_query (NAUTILUS_SEARCH_DIRECTORY (directory), query);

	cur_window = gtk_application_get_active_window (application);
	window = nautilus_application_create_window (NAUTILUS_APPLICATION (application),
						     cur_window ?
						     gtk_window_get_screen (cur_window) :
						     gdk_screen_get_default ());

	nautilus_window_slot_open_location (nautilus_window_get_active_slot (window), location, 0);

	nautilus_directory_unref (directory);
	g_object_unref (query);
	g_object_unref (location);
}
static void
switch_location (NautilusDragSlotProxyInfo *drag_info)
{
    GFile *location;
    GtkWidget *window;

    if (drag_info->target_file == NULL) {
        return;
    }

    window = gtk_widget_get_toplevel (drag_info->widget);
    g_assert (NAUTILUS_IS_WINDOW (window));

    location = nautilus_file_get_location (drag_info->target_file);
    nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()),
            location, NAUTILUS_WINDOW_OPEN_FLAG_DONT_MAKE_ACTIVE,
            NULL, NAUTILUS_WINDOW (window), NULL);
    g_object_unref (location);
}
static void
nautilus_application_finalize (GObject *object)
{
	NautilusApplication *application;

	application = NAUTILUS_APPLICATION (object);

	g_clear_object (&application->priv->progress_handler);
	g_clear_object (&application->priv->bookmark_list);

	g_free (application->priv->geometry);

	g_clear_object (&application->priv->dbus_manager);
	g_clear_object (&application->priv->fdb_manager);
	g_clear_object (&application->priv->search_provider);

	notify_uninit ();

        G_OBJECT_CLASS (nautilus_application_parent_class)->finalize (object);
}
static void
nautilus_bookmarks_window_constructed (GObject *object)
{
	NautilusBookmarksWindow *self = NAUTILUS_BOOKMARKS_WINDOW (object);
	GtkBuilder *builder;
	GError *error = NULL;
	GtkWindow *window;
	GtkWidget *content;
	GtkTreeViewColumn *col;
	GtkCellRenderer *rend;

	G_OBJECT_CLASS (nautilus_bookmarks_window_parent_class)->constructed (object);

	builder = gtk_builder_new ();
	if (!gtk_builder_add_from_resource (builder,
					    "/org/gnome/nautilus/nautilus-bookmarks-window.ui",
					    &error)) {
		g_object_unref (builder);

		g_critical ("Can't load UI description for the bookmarks editor: %s", error->message);
		g_error_free (error);
		return;
	}

	window = GTK_WINDOW (object);
	gtk_window_set_title (window, _("Bookmarks"));
	gtk_window_set_default_size (window, 
				     BOOKMARKS_WINDOW_INITIAL_WIDTH, 
				     BOOKMARKS_WINDOW_INITIAL_HEIGHT);
	gtk_window_set_application (window,
				    gtk_window_get_application (GTK_WINDOW (self->priv->parent_window)));

	gtk_window_set_destroy_with_parent (window, TRUE);
	gtk_window_set_transient_for (window, GTK_WINDOW (self->priv->parent_window));
	gtk_window_set_position (window, GTK_WIN_POS_CENTER_ON_PARENT);
	gtk_container_set_border_width (GTK_CONTAINER (window), 6);

	g_signal_connect (window, "key-press-event",
			  G_CALLBACK (nautilus_bookmarks_window_key_press_event_cb), NULL);

	content = GTK_WIDGET (gtk_builder_get_object (builder, "bookmarks_window_content"));
	gtk_container_add (GTK_CONTAINER (window), content);

	/* tree view */
	self->priv->tree_view = GTK_TREE_VIEW (gtk_builder_get_object (builder, "bookmark_tree_view"));
	self->priv->selection = gtk_tree_view_get_selection (self->priv->tree_view);
	gtk_tree_selection_set_mode (self->priv->selection, GTK_SELECTION_BROWSE);

	rend = gtk_cell_renderer_pixbuf_new ();
	g_object_set (rend, "follow-state", TRUE, NULL);
	col = gtk_tree_view_column_new_with_attributes ("Icon", 
							rend,
							"gicon", 
							BOOKMARK_LIST_COLUMN_ICON,
							NULL);
	gtk_tree_view_append_column (self->priv->tree_view,
				     GTK_TREE_VIEW_COLUMN (col));
	gtk_tree_view_column_set_fixed_width (GTK_TREE_VIEW_COLUMN (col),
					      NAUTILUS_ICON_SIZE_SMALLER);

	rend = gtk_cell_renderer_text_new ();
	g_object_set (rend,
		      "ellipsize", PANGO_ELLIPSIZE_END,
		      "ellipsize-set", TRUE,
		      NULL);

	col = gtk_tree_view_column_new_with_attributes ("Icon", 
							rend,
							"text", 
							BOOKMARK_LIST_COLUMN_NAME,
							"style",
							BOOKMARK_LIST_COLUMN_STYLE,
							NULL);
	gtk_tree_view_append_column (self->priv->tree_view,
				     GTK_TREE_VIEW_COLUMN (col));

	self->priv->model = create_bookmark_store ();
	setup_empty_list (self);

	/* name entry */
	self->priv->name_field = nautilus_entry_new ();
	gtk_widget_show (self->priv->name_field);
	gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (builder, "bookmark_name_placeholder")),
			    self->priv->name_field, TRUE, TRUE, 0);
	
	gtk_label_set_mnemonic_widget (
		GTK_LABEL (gtk_builder_get_object (builder, "bookmark_name_label")),
		self->priv->name_field);

	/* URI entry */
	self->priv->uri_field = nautilus_entry_new ();
	gtk_widget_show (self->priv->uri_field);
	gtk_box_pack_start (GTK_BOX (gtk_builder_get_object (builder, "bookmark_location_placeholder")),
			    self->priv->uri_field, TRUE, TRUE, 0);

	gtk_label_set_mnemonic_widget (
		GTK_LABEL (gtk_builder_get_object (builder, "bookmark_location_label")),
		self->priv->uri_field);

	/* buttons */
	self->priv->remove_button = GTK_WIDGET (gtk_builder_get_object (builder, "bookmark_remove_button"));
	self->priv->up_button = GTK_WIDGET (gtk_builder_get_object (builder, "bookmark_up_button"));
	self->priv->down_button = GTK_WIDGET (gtk_builder_get_object (builder, "bookmark_down_button"));

	g_object_unref (builder);

	/* setup bookmarks list and signals */
	self->priv->bookmarks = nautilus_application_get_bookmarks
		(NAUTILUS_APPLICATION (g_application_get_default ()));
	self->priv->bookmarks_changed_id =
		g_signal_connect (self->priv->bookmarks, "changed",
				  G_CALLBACK (on_bookmark_list_changed), self);

	self->priv->row_changed_id =
		g_signal_connect (self->priv->model, "row-changed",
				  G_CALLBACK (on_row_changed), self);
	self->priv->row_deleted_id =
		g_signal_connect (self->priv->model, "row-deleted",
				  G_CALLBACK (on_row_deleted), self);

        self->priv->row_activated_id =
                g_signal_connect (self->priv->tree_view, "row-activated",
                                  G_CALLBACK (on_row_activated), self);
        self->priv->button_press_id =
                g_signal_connect (self->priv->tree_view, "button-press-event",
                                  G_CALLBACK (on_button_pressed), self);
        self->priv->key_press_id =
                g_signal_connect (self->priv->tree_view, "key-press-event",
                                  G_CALLBACK (on_key_pressed), self);
	self->priv->selection_changed_id =
		g_signal_connect (self->priv->selection, "changed",
				  G_CALLBACK (on_selection_changed), self);

	self->priv->name_changed_id =
		g_signal_connect (self->priv->name_field, "changed",
				  G_CALLBACK (on_name_field_changed), self);
	g_signal_connect (self->priv->name_field, "focus_out_event",
			  G_CALLBACK (on_text_field_focus_out_event), self);
	g_signal_connect (self->priv->name_field, "activate",
			  G_CALLBACK (name_or_uri_field_activate), self);

	self->priv->uri_changed_id =
		g_signal_connect (self->priv->uri_field, "changed",
				  G_CALLBACK (on_uri_field_changed), self);
	g_signal_connect (self->priv->uri_field, "focus_out_event",
			  G_CALLBACK (on_text_field_focus_out_event), self);
	g_signal_connect (self->priv->uri_field, "activate",
			  G_CALLBACK (name_or_uri_field_activate), self);

	g_signal_connect (self->priv->remove_button, "clicked",
			  G_CALLBACK (on_remove_button_clicked), self);
	g_signal_connect (self->priv->up_button, "clicked",
			  G_CALLBACK (on_up_button_clicked), self);
	g_signal_connect (self->priv->down_button, "clicked",
			  G_CALLBACK (on_down_button_clicked), self);
	
	/* Fill in list widget with bookmarks, must be after signals are wired up. */
	repopulate (self);
}
static gboolean
nautilus_application_local_command_line (GApplication *application,
					 gchar ***arguments,
					 gint *exit_status)
{
	gboolean perform_self_check = FALSE;
	gboolean version = FALSE;
	gboolean browser = FALSE;
	gboolean kill_shell = FALSE;
	gboolean open_new_window = FALSE;
	gboolean no_default_window = FALSE;
	gboolean select_uris = FALSE;
	gchar **remaining = NULL;
	NautilusApplication *self = NAUTILUS_APPLICATION (application);

	const GOptionEntry options[] = {
#ifndef NAUTILUS_OMIT_SELF_CHECK
		{ "check", 'c', 0, G_OPTION_ARG_NONE, &perform_self_check, 
		  N_("Perform a quick set of self-check tests."), NULL },
#endif
		/* dummy, only for compatibility reasons */
		{ "browser", '\0', G_OPTION_FLAG_HIDDEN, G_OPTION_ARG_NONE, &browser,
		  NULL, NULL },
		{ "version", '\0', 0, G_OPTION_ARG_NONE, &version,
		  N_("Show the version of the program."), NULL },
		{ "geometry", 'g', 0, G_OPTION_ARG_STRING, &self->priv->geometry,
		  N_("Create the initial window with the given geometry."), N_("GEOMETRY") },
		{ "new-window", 'w', 0, G_OPTION_ARG_NONE, &open_new_window,
		  N_("Always open a new window for browsing specified URIs"), NULL },
		{ "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, &self->priv->no_desktop,
		  N_("Never manage the desktop (ignore the GSettings preference)."), NULL },
		{ "force-desktop", '\0', 0, G_OPTION_ARG_NONE, &self->priv->force_desktop,
		  N_("Always manage the desktop (ignore the GSettings preference)."), NULL },
		{ "quit", 'q', 0, G_OPTION_ARG_NONE, &kill_shell, 
		  N_("Quit Nautilus."), NULL },
		{ "select", 's', 0, G_OPTION_ARG_NONE, &select_uris,
		  N_("Select specified URI in parent folder."), NULL },
		{ G_OPTION_REMAINING, 0, 0, G_OPTION_ARG_STRING_ARRAY, &remaining, NULL,  N_("[URI...]") },

		{ NULL }
	};
	GOptionContext *context;
	GError *error = NULL;
	gint argc = 0;
	gchar **argv = NULL;
	*exit_status = EXIT_SUCCESS;

	nautilus_profile_start (NULL);

	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 (FALSE));

	argv = *arguments;
	argc = g_strv_length (argv);

	if (!g_option_context_parse (context, &argc, &argv, &error)) {
		/* Translators: this is a fatal error quit message printed on the
		 * command line */
		g_printerr ("%s: %s\n", _("Could not parse arguments"), error->message);
		g_error_free (error);

		*exit_status = EXIT_FAILURE;
		goto out;
	}

	if (version) {
		g_print ("GNOME nautilus " PACKAGE_VERSION "\n");
		goto out;
	}

	if (!do_cmdline_sanity_checks (self, perform_self_check,
				       version, kill_shell, select_uris, remaining)) {
		*exit_status = EXIT_FAILURE;
		goto out;
	}

	if (perform_self_check) {
		do_perform_self_checks (exit_status);
		goto out;
	}

	DEBUG ("Parsing local command line: open_new_window %d, no_default_window %d, "
	       "quit %d, self checks %d, no_desktop %d, show_desktop %d",
	       open_new_window, no_default_window, kill_shell, perform_self_check,
	       self->priv->no_desktop, self->priv->force_desktop);

	g_application_register (application, NULL, &error);

	if (error != NULL) {
		/* Translators: this is a fatal error quit message printed on the
		 * command line */
		g_printerr ("%s: %s\n", _("Could not register the application"), error->message);
		g_error_free (error);

		*exit_status = EXIT_FAILURE;
		goto out;
	}

	if (kill_shell) {
		DEBUG ("Killing application, as requested");
		g_action_group_activate_action (G_ACTION_GROUP (application),
						"kill", NULL);
		goto out;
	}

	GFile **files;
	gint idx, len;

	len = 0;
	files = NULL;

	/* Convert args to GFiles */
	if (remaining != NULL) {
		GFile *file;
		GPtrArray *file_array;

		file_array = g_ptr_array_new ();

		for (idx = 0; remaining[idx] != NULL; idx++) {
			file = g_file_new_for_commandline_arg (remaining[idx]);
			if (file != NULL) {
				g_ptr_array_add (file_array, file);
			}
		}

		len = file_array->len;
		files = (GFile **) g_ptr_array_free (file_array, FALSE);
		g_strfreev (remaining);
	}

	if (files == NULL && !no_default_window && !select_uris) {
		files = g_malloc0 (2 * sizeof (GFile *));
		len = 1;

		files[0] = g_file_new_for_path (g_get_home_dir ());
		files[1] = NULL;
	}

	if (len == 0) {
		goto out;
	}

	if (select_uris) {
		nautilus_application_select (self, files, len);
	} else {
		/* Invoke "Open" to create new windows */
		g_application_open (application, files, len, open_new_window ? "new-window" : "");
	}

	for (idx = 0; idx < len; idx++) {
		g_object_unref (files[idx]);
	}
	g_free (files);

 out:
	g_option_context_free (context);
	nautilus_profile_end (NULL);

	return TRUE;	
}
static void
drag_data_received_callback (GtkWidget *widget,
			     GdkDragContext *context,
			     int x,
			     int y,
			     GtkSelectionData *data,
			     guint info,
			     guint32 time,
			     gpointer callback_data)
{
	char **names;
	int name_count;
	GtkWidget *window;
	gboolean new_windows_for_extras;
	char *prompt;
	char *detail;
	GFile *location;
	NautilusLocationEntry *self = NAUTILUS_LOCATION_ENTRY (widget);

	g_assert (data != NULL);
	g_assert (callback_data == NULL);

	names = g_uri_list_extract_uris ((const gchar *) gtk_selection_data_get_data (data));

	if (names == NULL || *names == NULL) {
		g_warning ("No D&D URI's");
		gtk_drag_finish (context, FALSE, FALSE, time);
		return;
	}

	window = gtk_widget_get_toplevel (widget);
	new_windows_for_extras = FALSE;
	/* Ask user if they really want to open multiple windows
	 * for multiple dropped URIs. This is likely to have been
	 * a mistake.
	 */
	name_count = g_strv_length (names);
	if (name_count > 1) {
		prompt = g_strdup_printf (ngettext("Do you want to view %d location?",
						   "Do you want to view %d locations?",
						   name_count),
					  name_count);
		detail = g_strdup_printf (ngettext("This will open %d separate window.",
						   "This will open %d separate windows.",
						   name_count),
					  name_count);
		/* eel_run_simple_dialog should really take in pairs
		 * like gtk_dialog_new_with_buttons() does. */
		new_windows_for_extras = eel_run_simple_dialog (GTK_WIDGET (window),
								TRUE,
								GTK_MESSAGE_QUESTION,
								prompt,
								detail,
								_("_Cancel"), _("_OK"),
								NULL) != 0 /* GNOME_OK */;

		g_free (prompt);
		g_free (detail);

		if (!new_windows_for_extras) {
			gtk_drag_finish (context, FALSE, FALSE, time);
			return;
		}
	}

	location = g_file_new_for_uri (names[0]);
	nautilus_location_entry_set_location (self, location);
	emit_location_changed (self);
	g_object_unref (location);

	if (new_windows_for_extras) {
		int i;

		for (i = 1; names[i] != NULL; ++i) {
			location = g_file_new_for_uri (names[i]);
                        nautilus_application_open_location_full (NAUTILUS_APPLICATION (g_application_get_default ()),
                                                                 location, NAUTILUS_WINDOW_OPEN_FLAG_NEW_WINDOW, NULL, NULL, NULL);
			g_object_unref (location);
		}
	}

	g_strfreev (names);

	gtk_drag_finish (context, TRUE, FALSE, time);
}