guint settings_signal_id;
int icon_size;
+#if 0
GdkDragContext *shortcuts_drag_context;
GSource *shortcuts_drag_outside_idle;
+#endif
/* Flags */
guint changing_folder : 1;
guint shortcuts_current_folder_active : 1;
guint shortcuts_current_folder_is_volume : 1;
+
+#if 0
guint shortcuts_drag_outside : 1;
+#endif
};
/* Signal IDs */
enum {
LOCATION_POPUP,
UP_FOLDER,
+ DOWN_FOLDER,
HOME_FOLDER,
LAST_SIGNAL
};
static void location_popup_handler (GtkFileChooserDefault *impl);
static void up_folder_handler (GtkFileChooserDefault *impl);
+static void down_folder_handler (GtkFileChooserDefault *impl);
static void home_folder_handler (GtkFileChooserDefault *impl);
static void update_appearance (GtkFileChooserDefault *impl);
NULL, NULL,
_gtk_marshal_VOID__VOID,
G_TYPE_NONE, 0);
+ signals[DOWN_FOLDER] =
+ _gtk_binding_signal_new ("down-folder",
+ G_OBJECT_CLASS_TYPE (class),
+ G_SIGNAL_RUN_FIRST | G_SIGNAL_ACTION,
+ G_CALLBACK (down_folder_handler),
+ NULL, NULL,
+ _gtk_marshal_VOID__VOID,
+ G_TYPE_NONE, 0);
signals[HOME_FOLDER] =
_gtk_binding_signal_new ("home-folder",
G_OBJECT_CLASS_TYPE (class),
"up-folder",
0);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_Down, GDK_MOD1_MASK,
+ "down-folder",
+ 0);
+ gtk_binding_entry_add_signal (binding_set,
+ GDK_KP_Down, GDK_MOD1_MASK,
+ "down-folder",
+ 0);
+
gtk_binding_entry_add_signal (binding_set,
GDK_Home, GDK_MOD1_MASK,
"home-folder",
} while (gtk_tree_model_iter_next (GTK_TREE_MODEL (impl->shortcuts_model),&iter));
}
-/* Clears the selection in the shortcuts tree */
+/* If a shortcut corresponds to the current folder, selects it */
static void
-shortcuts_unselect_all (GtkFileChooserDefault *impl)
+shortcuts_find_current_folder (GtkFileChooserDefault *impl)
{
GtkTreeSelection *selection;
+ int pos;
+ GtkTreePath *path;
selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view));
- gtk_tree_selection_unselect_all (selection);
+
+ pos = shortcut_find_position (impl, impl->current_folder);
+ if (pos == -1)
+ {
+ gtk_tree_selection_unselect_all (selection);
+ return;
+ }
+
+ path = gtk_tree_path_new_from_indices (pos, -1);
+ gtk_tree_selection_select_path (selection, path);
+ gtk_tree_path_free (path);
+}
+
+/* Returns whether a path is a folder */
+static gboolean
+check_is_folder (GtkFileSystem *file_system, const GtkFilePath *path, GError **error)
+{
+ GtkFileFolder *folder;
+
+ folder = gtk_file_system_get_folder (file_system, path,
+ GTK_FILE_INFO_DISPLAY_NAME,
+ error);
+ if (!folder)
+ return FALSE;
+
+ g_object_unref (folder);
+ return TRUE;
}
/* Convenience function to get the display name and icon info for a path */
parent_folder = gtk_file_system_get_folder (file_system, parent_path ? parent_path : path,
GTK_FILE_INFO_DISPLAY_NAME
-#if 0
- | GTK_FILE_INFO_ICON
-#endif
| (name_only ? 0 : GTK_FILE_INFO_IS_FOLDER),
error);
- gtk_file_path_free (parent_path);
-
if (!parent_folder)
- return NULL;
+ goto out;
- info = gtk_file_folder_get_info (parent_folder, path, error);
+ info = gtk_file_folder_get_info (parent_folder, parent_path ? path : NULL, error);
g_object_unref (parent_folder);
+ out:
+
+ gtk_file_path_free (parent_path);
return info;
}
}
else
{
- /* Always check to make sure that the directory exists. */
- GtkFileInfo *info = get_file_info (impl->file_system, path, FALSE, error);
-
- if (info == NULL)
+ if (!check_is_folder (impl->file_system, path, error))
return FALSE;
if (label)
label_copy = g_strdup (label);
else
- label_copy = g_strdup (gtk_file_info_get_display_name (info));
+ {
+ GtkFileInfo *info = get_file_info (impl->file_system, path, TRUE, error);
- gtk_file_info_free (info);
+ if (!info)
+ return FALSE;
+
+ label_copy = g_strdup (gtk_file_info_get_display_name (info));
+ gtk_file_info_free (info);
+ }
data = gtk_file_path_copy (path);
pixbuf = gtk_file_system_render_icon (impl->file_system, path, GTK_WIDGET (impl),
path = paths->data;
error = NULL;
+ if (impl->local_only &&
+ !gtk_file_system_path_is_local (impl->file_system, path))
+ continue;
+
/* NULL GError, but we don't really want to show error boxes here */
if (shortcuts_insert_path (impl, start_row + num_inserted, FALSE, NULL, path, NULL, TRUE, NULL))
num_inserted++;
int start_row;
GSList *list, *l;
int n;
+ gboolean old_changing_folders;
+
+ old_changing_folders = impl->changing_folder;
+ impl->changing_folder = TRUE;
start_row = shortcuts_get_index (impl, SHORTCUTS_VOLUMES);
shortcuts_remove_rows (impl, start_row, impl->num_volumes, volume_remove_cb);
GtkFileSystemVolume *volume;
volume = l->data;
- shortcuts_insert_path (impl, start_row + n, TRUE, volume, NULL, NULL, FALSE, NULL);
- n++;
+
+ if (impl->local_only)
+ {
+ GtkFilePath *base_path = gtk_file_system_volume_get_base_path (impl->file_system, volume);
+ gboolean is_local = gtk_file_system_path_is_local (impl->file_system, base_path);
+ gtk_file_path_free (base_path);
+
+ if (!is_local)
+ {
+ gtk_file_system_volume_free (impl->file_system, volume);
+ continue;
+ }
+ }
+
+ if (shortcuts_insert_path (impl, start_row + n, TRUE, volume, NULL, NULL, FALSE, NULL))
+ n++;
+ else
+ gtk_file_system_volume_free (impl->file_system, volume);
}
impl->num_volumes = n;
if (impl->shortcuts_filter_model)
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model));
+
+ impl->changing_folder = old_changing_folders;
}
/* Used from shortcuts_remove_rows() */
shortcuts_add_bookmarks (GtkFileChooserDefault *impl)
{
GSList *bookmarks;
+ gboolean old_changing_folders;
+
+ old_changing_folders = impl->changing_folder;
+ impl->changing_folder = TRUE;
if (impl->num_bookmarks > 0)
{
}
if (impl->shortcuts_filter_model)
gtk_tree_model_filter_refilter (GTK_TREE_MODEL_FILTER (impl->shortcuts_filter_model));
+
+ impl->changing_folder = old_changing_folders;
}
/* Appends a separator and a row to the shortcuts list for the current folder */
const GtkFilePath *path,
int pos)
{
- GtkFileInfo *info;
GError *error;
- gboolean result;
if (shortcut_find_position (impl, path) != -1)
return FALSE;
- result = FALSE;
-
+ /* FIXME: this check really belongs in gtk_file_system_insert_bookmark. */
error = NULL;
- info = get_file_info (impl->file_system, path, FALSE, &error);
-
- if (!info)
- error_getting_info_dialog (impl, path, error);
- else if (!gtk_file_info_get_is_folder (info))
+ if (!check_is_folder (impl->file_system, path, &error))
{
- char *msg;
- char *uri;
-
- uri = gtk_file_system_path_to_uri (impl->file_system, path);
- msg = g_strdup_printf (_("Could not add bookmark for %s because it is not a folder."),
- uri);
- error_message (impl, msg);
- g_free (uri);
- g_free (msg);
+ error_dialog (impl,
+ _("Could not add bookmark for %s because it is not a folder."),
+ path,
+ error);
+ return FALSE;
}
- else
+
+ error = NULL;
+ if (!gtk_file_system_insert_bookmark (impl->file_system, path, pos, &error))
{
- error = NULL;
- if (gtk_file_system_insert_bookmark (impl->file_system, path, pos, &error))
- result = TRUE;
- else
- error_could_not_add_bookmark_dialog (impl, path, error);
+ error_could_not_add_bookmark_dialog (impl, path, error);
+ return FALSE;
}
- return result;
+ return TRUE;
}
static void
GdkDragContext *context,
GtkFileChooserDefault *impl)
{
+#if 0
impl->shortcuts_drag_context = g_object_ref (context);
+#endif
}
+#if 0
/* Removes the idle handler for outside drags */
static void
shortcuts_cancel_drag_outside_idle (GtkFileChooserDefault *impl)
g_source_destroy (impl->shortcuts_drag_outside_idle);
impl->shortcuts_drag_outside_idle = NULL;
}
+#endif
/* GtkWidget::drag-end handler for the shortcuts list. */
static void
GdkDragContext *context,
GtkFileChooserDefault *impl)
{
+#if 0
g_object_unref (impl->shortcuts_drag_context);
shortcuts_cancel_drag_outside_idle (impl);
gtk_button_clicked (GTK_BUTTON (impl->browse_shortcuts_remove_button));
impl->shortcuts_drag_outside = FALSE;
+#endif
}
/* GtkWidget::drag-data-delete handler for the shortcuts list. */
g_signal_stop_emission_by_name (widget, "drag-data-delete");
}
+#if 0
/* Creates a suitable drag cursor to indicate that the selected bookmark will be
* deleted or not.
*/
shortcuts_cancel_drag_outside_idle (impl);
return FALSE;
}
-
+#endif
+
/* GtkWidget::drag-leave handler for the shortcuts list. We unhighlight the
* drop position.
*/
guint time_,
GtkFileChooserDefault *impl)
{
+#if 0
if (gtk_drag_get_source_widget (context) == widget && !impl->shortcuts_drag_outside_idle)
{
impl->shortcuts_drag_outside_idle = g_idle_source_new ();
G_OBJECT (impl)));
g_source_attach (impl->shortcuts_drag_outside_idle, NULL);
}
+#endif
gtk_tree_view_set_drag_dest_row (GTK_TREE_VIEW (impl->browse_shortcuts_tree_view),
NULL,
GtkTreeViewDropPosition pos;
GdkDragAction action;
+#if 0
if (gtk_drag_get_source_widget (context) == widget)
{
shortcuts_cancel_drag_outside_idle (impl);
impl->shortcuts_drag_outside = FALSE;
}
}
+#endif
if (context->suggested_action == GDK_ACTION_COPY || (context->actions & GDK_ACTION_COPY) != 0)
action = GDK_ACTION_COPY;
guint time_,
GtkFileChooserDefault *impl)
{
+#if 0
shortcuts_cancel_drag_outside_idle (impl);
+#endif
g_signal_stop_emission_by_name (widget, "drag-drop");
return TRUE;
widget = file_pane_create (impl, size_group);
gtk_paned_pack2 (GTK_PANED (hpaned), widget, TRUE, FALSE);
+ g_object_unref (size_group);
+
/* Alignment to hold custom widget */
impl->browse_extra_align = gtk_alignment_new (0.0, .5, 1.0, 1.0);
gtk_box_pack_start (GTK_BOX (vbox), impl->browse_extra_align, FALSE, FALSE, 0);
impl->extra_widget = extra_widget;
}
+static void
+set_local_only (GtkFileChooserDefault *impl,
+ gboolean local_only)
+{
+ if (local_only != impl->local_only)
+ {
+ impl->local_only = local_only;
+
+ if (impl->shortcuts_model && impl->file_system)
+ {
+ shortcuts_add_volumes (impl);
+ shortcuts_add_bookmarks (impl);
+ }
+
+ if (local_only &&
+ !gtk_file_system_path_is_local (impl->file_system, impl->current_folder))
+ {
+ /* If we are pointing to a non-local folder, make an effort to change
+ * back to a local folder, but it's really up to the app to not cause
+ * such a situation, so we ignore errors.
+ */
+ const gchar *home = g_get_home_dir ();
+ GtkFilePath *home_path = gtk_file_system_filename_to_path (impl->file_system, home);
+
+ _gtk_file_chooser_set_current_folder_path (GTK_FILE_CHOOSER (impl), home_path, NULL);
+
+ gtk_file_path_free (home_path);
+ }
+ }
+}
+
static void
volumes_changed_cb (GtkFileSystem *file_system,
GtkFileChooserDefault *impl)
_gtk_file_system_model_set_show_files (impl->browse_files_model, TRUE);
}
- if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
- || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN)
gtk_widget_hide (impl->browse_new_folder_button);
else
gtk_widget_show (impl->browse_new_folder_button);
set_current_filter (impl, g_value_get_object (value));
break;
case GTK_FILE_CHOOSER_PROP_LOCAL_ONLY:
- impl->local_only = g_value_get_boolean (value);
+ set_local_only (impl, g_value_get_boolean (value));
break;
case GTK_FILE_CHOOSER_PROP_PREVIEW_WIDGET:
set_preview_widget (impl, g_value_get_object (value));
if (impl->settings_signal_id)
return;
- settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
- impl->settings_signal_id = g_signal_connect (settings, "notify",
- G_CALLBACK (settings_notify_cb), impl);
+ if (gtk_widget_has_screen (GTK_WIDGET (impl)))
+ {
+ settings = gtk_settings_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (impl)));
+ impl->settings_signal_id = g_signal_connect (settings, "notify",
+ G_CALLBACK (settings_notify_cb), impl);
- change_icon_theme (impl);
+ change_icon_theme (impl);
+ }
}
static void
GError **error)
{
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
- GtkFileInfo *info;
/* Test validity of path here. */
- info = get_file_info (impl->file_system, path, FALSE, error);
- if (!info)
+ if (!check_is_folder (impl->file_system, path, error))
return FALSE;
- gtk_file_info_free (info);
+
+ if (impl->local_only &&
+ !gtk_file_system_path_is_local (impl->file_system, path))
+ {
+ g_set_error (error,
+ GTK_FILE_SYSTEM_ERROR,
+ GTK_FILE_SYSTEM_ERROR_FAILED,
+ _("Can't change to folder because it isn't local"));
+
+ return FALSE;
+ }
if (!_gtk_path_bar_set_path (GTK_PATH_BAR (impl->browse_path_bar), path, error))
return FALSE;
/* Refresh controls */
- shortcuts_unselect_all (impl);
+ shortcuts_find_current_folder (impl);
g_signal_emit_by_name (impl, "current-folder-changed", 0);
{
GtkFileChooserDefault *impl = GTK_FILE_CHOOSER_DEFAULT (chooser);
- g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE);
+ g_return_if_fail (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
gtk_entry_set_text (GTK_ENTRY (impl->save_file_name_entry), name);
}
gtk_tree_model_sort_convert_iter_to_child_iter (info->impl->sort_model, &sel_iter, iter);
file_path = _gtk_file_system_model_get_path (GTK_FILE_SYSTEM_MODEL (fs_model), &sel_iter);
+ if (!file_path)
+ return; /* We are on the editable row */
if (!info->path_from_entry
|| gtk_file_path_compare (info->path_from_entry, file_path) != 0)
gboolean result;
int pos;
+ /* Test validity of path here. */
+ if (!check_is_folder (impl->file_system, path, error))
+ return FALSE;
+
pos = shortcuts_get_pos_for_shortcut_folder (impl, impl->num_shortcuts);
result = shortcuts_insert_path (impl, pos, FALSE, NULL, path, NULL, FALSE, error);
if (!info)
{
-#if 0
- if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE)
- return;
-#endif
- error_getting_info_dialog (impl, subfolder_path, error);
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER)
+ {
+ if (!change_folder_and_display_error (impl, folder_path))
+ goto out;
+
+ gtk_file_chooser_default_set_current_name (GTK_FILE_CHOOSER (impl), file_part);
+ }
+ else
+ error_getting_info_dialog (impl, subfolder_path, error);
+
goto out;
}
GtkWidget *label;
GtkWidget *entry;
gboolean refocus;
+ char *title;
/* Create dialog */
if (!GTK_WIDGET_TOPLEVEL (toplevel))
toplevel = NULL;
- dialog = gtk_dialog_new_with_buttons (_("Open Location"),
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ {
+ title = _("Open Location");
+ }
+ else
+ {
+ g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
+ title = ""; /* FIXME: #137272, fix for 2.4.1 */
+ }
+
+ dialog = gtk_dialog_new_with_buttons (title,
GTK_WINDOW (toplevel),
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
{
if (update_from_entry (impl, GTK_WINDOW (dialog), GTK_FILE_CHOOSER_ENTRY (entry)))
{
- gtk_widget_grab_focus (impl->browse_files_tree_view);
+ if (impl->action == GTK_FILE_CHOOSER_ACTION_OPEN
+ || impl->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER)
+ {
+ gtk_widget_grab_focus (impl->browse_files_tree_view);
+ }
+ else
+ {
+ g_assert (impl->action == GTK_FILE_CHOOSER_ACTION_SAVE
+ || impl->action == GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER);
+ gtk_widget_grab_focus (impl->save_file_name_entry);
+ }
refocus = FALSE;
}
}
static void
up_folder_handler (GtkFileChooserDefault *impl)
{
- GtkFilePath *parent_path;
- GError *error;
+ _gtk_path_bar_up (GTK_PATH_BAR (impl->browse_path_bar));
+}
- error = NULL;
- if (gtk_file_system_get_parent (impl->file_system, impl->current_folder, &parent_path, &error))
- {
- if (parent_path) /* If we were on a root, parent_path will be NULL */
- {
- change_folder_and_display_error (impl, parent_path);
- gtk_file_path_free (parent_path);
- }
- }
- else
- {
- error_dialog (impl,
- _("Could not go to the parent folder of %s:\n%s"),
- impl->current_folder, error);
- }
+/* Handler for the "down-folder" keybinding signal */
+static void
+down_folder_handler (GtkFileChooserDefault *impl)
+{
+ _gtk_path_bar_down (GTK_PATH_BAR (impl->browse_path_bar));
}
/* Handler for the "home-folder" keybinding signal */