Forked from Dudemanguy/gtk3-filechooser-icon-view.patch
Last active
August 27, 2021 20:20
-
-
Save yatima1460/ae4a7ecf3871fe456d31760159ba19c4 to your computer and use it in GitHub Desktop.
GTK3 File Picker with thumbnails as default view, forked from https://github.com/Dudemanguy911/gtk/tree/gtk3-filechooser-icon-view
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h | |
index 0094beb299..433a623963 100644 | |
--- a/gtk/gtkfilechooserprivate.h | |
+++ b/gtk/gtkfilechooserprivate.h | |
@@ -32,10 +32,14 @@ | |
#include "gtktreestore.h" | |
#include "gtktreeview.h" | |
#include "gtkbox.h" | |
+#include "gtkiconview.h" | |
+#include "gtkscale.h" | |
G_BEGIN_DECLS | |
#define SETTINGS_KEY_LOCATION_MODE "location-mode" | |
+#define SETTINGS_KEY_VIEW_MODE "view-mode" | |
+#define SETTINGS_KEY_ICON_VIEW_SCALE "icon-view-scale" | |
#define SETTINGS_KEY_SHOW_HIDDEN "show-hidden" | |
#define SETTINGS_KEY_SHOW_SIZE_COLUMN "show-size-column" | |
#define SETTINGS_KEY_SORT_COLUMN "sort-column" | |
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c | |
index ce708670c9..e723cb9b6c 100644 | |
--- a/gtk/gtkfilechooserwidget.c | |
+++ b/gtk/gtkfilechooserwidget.c | |
@@ -1,4 +1,4 @@ | |
-/* -*- Mode: C; c-file-style: "gnu"; tab-width: 8 -*- */ | |
+/* -*- Mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; tab-width: 8 -*- */ | |
/* GTK - The GIMP Toolkit | |
* gtkfilechooserwidget.c: Embeddable file selector widget | |
* Copyright (C) 2003, Red Hat, Inc. | |
@@ -44,10 +44,12 @@ | |
#include "gtkfilesystemmodel.h" | |
#include "gtkgrid.h" | |
#include "gtkicontheme.h" | |
+#include "gtkiconview.h" | |
#include "gtklabel.h" | |
#include "gtkmarshalers.h" | |
#include "gtkmessagedialog.h" | |
#include "gtkmountoperation.h" | |
+#include "gtknotebook.h" | |
#include "gtkpaned.h" | |
#include "gtkpathbar.h" | |
#include "gtkplacessidebar.h" | |
@@ -80,6 +82,7 @@ | |
#include "gtkgesturelongpress.h" | |
#include <cairo-gobject.h> | |
+#include <math.h> | |
#ifdef HAVE_UNISTD_H | |
#include <unistd.h> | |
@@ -197,6 +200,11 @@ typedef enum { | |
STARTUP_MODE_CWD | |
} StartupMode; | |
+typedef enum { | |
+ VIEW_MODE_LIST, | |
+ VIEW_MODE_ICON, | |
+} ViewMode; | |
+ | |
typedef enum { | |
CLOCK_FORMAT_24, | |
CLOCK_FORMAT_12 | |
@@ -221,8 +229,12 @@ struct _GtkFileChooserWidgetPrivate { | |
GtkWidget *browse_header_revealer; | |
GtkWidget *browse_header_stack; | |
GtkWidget *browse_files_stack; | |
- GtkWidget *browse_files_swin; | |
+ GtkNotebook *view_notebook; | |
+ GtkWidget *browse_files_list_swin; | |
+ GtkWidget *browse_files_icon_swin; | |
+ GtkWidget *browse_files_current_view; | |
GtkWidget *browse_files_tree_view; | |
+ GtkWidget *browse_files_icon_view; | |
GtkWidget *remote_warning_bar; | |
GtkWidget *browse_files_popover; | |
@@ -237,6 +249,12 @@ struct _GtkFileChooserWidgetPrivate { | |
GtkWidget *delete_file_item; | |
GtkWidget *sort_directories_item; | |
GtkWidget *show_time_item; | |
+ GtkWidget *arrange_item; | |
+ GtkWidget *sort_by_name_item; | |
+ GtkWidget *sort_by_size_item; | |
+ GtkWidget *sort_by_time_item; | |
+ GtkWidget *ascending_item; | |
+ GtkWidget *descending_item; | |
GtkWidget *browse_new_folder_button; | |
GtkSizeGroup *browse_path_bar_size_group; | |
@@ -253,6 +271,7 @@ struct _GtkFileChooserWidgetPrivate { | |
GtkGesture *long_press_gesture; | |
+ GtkTreeModel *current_model; | |
GtkFileSystemModel *browse_files_model; | |
char *browse_files_last_selected_name; | |
@@ -337,10 +356,17 @@ struct _GtkFileChooserWidgetPrivate { | |
guint location_changed_id; | |
gulong settings_signal_id; | |
- int icon_size; | |
+ int list_view_icon_size; | |
+ int icon_view_icon_size; | |
GSource *focus_entry_idle; | |
+ GtkWidget *view_mode_combo_box; | |
+ GtkWidget *icon_view_scale; | |
+ ViewMode view_mode; | |
+ | |
+ GtkCellRenderer *list_icon_renderer; | |
+ | |
gulong toplevel_set_focus_id; | |
GtkWidget *toplevel_last_focus_widget; | |
@@ -403,7 +429,8 @@ enum { | |
MODEL_COL_NAME_COLLATED, | |
MODEL_COL_IS_FOLDER, | |
MODEL_COL_IS_SENSITIVE, | |
- MODEL_COL_SURFACE, | |
+ MODEL_COL_LIST_SURFACE, | |
+ MODEL_COL_ICON_PIXBUF, | |
MODEL_COL_SIZE_TEXT, | |
MODEL_COL_DATE_TEXT, | |
MODEL_COL_TIME_TEXT, | |
@@ -422,7 +449,8 @@ enum { | |
G_TYPE_STRING, /* MODEL_COL_NAME_COLLATED */ \ | |
G_TYPE_BOOLEAN, /* MODEL_COL_IS_FOLDER */ \ | |
G_TYPE_BOOLEAN, /* MODEL_COL_IS_SENSITIVE */ \ | |
- CAIRO_GOBJECT_TYPE_SURFACE, /* MODEL_COL_SURFACE */ \ | |
+ CAIRO_GOBJECT_TYPE_SURFACE, /* MODEL_COL_LIST_SURFACE */ \ | |
+ GDK_TYPE_PIXBUF, /* MODEL_COL_ICON_PIXBUF */ \ | |
G_TYPE_STRING, /* MODEL_COL_SIZE_TEXT */ \ | |
G_TYPE_STRING, /* MODEL_COL_DATE_TEXT */ \ | |
G_TYPE_STRING, /* MODEL_COL_TIME_TEXT */ \ | |
@@ -432,7 +460,10 @@ enum { | |
#define DEFAULT_RECENT_FILES_LIMIT 50 | |
/* Icon size for if we can't get it from the theme */ | |
-#define FALLBACK_ICON_SIZE 16 | |
+#define FALLBACK_LIST_VIEW_ICON_SIZE 16 | |
+#define FALLBACK_ICON_VIEW_ICON_SIZE 48 | |
+ | |
+#define ICON_VIEW_ITEM_WIDTH 128 | |
#define PREVIEW_HBOX_SPACING 12 | |
#define NUM_LINES 45 | |
@@ -553,7 +584,7 @@ static gboolean list_select_func (GtkTreeSelection *selection, | |
gboolean path_currently_selected, | |
gpointer data); | |
-static void list_selection_changed (GtkTreeSelection *tree_selection, | |
+static void list_selection_changed (void *selection, | |
GtkFileChooserWidget *impl); | |
static void list_row_activated (GtkTreeView *tree_view, | |
GtkTreePath *path, | |
@@ -561,6 +592,13 @@ static void list_row_activated (GtkTreeView *tree_view, | |
GtkFileChooserWidget *impl); | |
static void list_cursor_changed (GtkTreeView *treeview, | |
GtkFileChooserWidget *impl); | |
+static void icon_item_activated (GtkIconView *icon_view, | |
+ GtkTreePath *path, | |
+ GtkFileChooserWidget *impl); | |
+static void item_activated (GtkTreeModel *model, | |
+ GtkTreePath *path, | |
+ GtkFileChooserWidget *impl); | |
+ | |
static void path_bar_clicked (GtkPathBar *path_bar, | |
GFile *file, | |
@@ -573,6 +611,13 @@ static void update_cell_renderer_attributes (GtkFileChooserWidget *impl); | |
static void load_remove_timer (GtkFileChooserWidget *impl, LoadState new_load_state); | |
static void browse_files_center_selected_row (GtkFileChooserWidget *impl); | |
+static void icon_view_scale_value_changed_cb (GtkRange *range, | |
+ GtkFileChooserWidget *impl); | |
+ | |
+static void view_mode_set (GtkFileChooserWidget *impl, ViewMode view_mode); | |
+static void view_mode_combo_box_changed_cb (GtkComboBox *combo, | |
+ GtkFileChooserWidget *impl); | |
+ | |
static void location_switch_to_path_bar (GtkFileChooserWidget *impl); | |
static void stop_loading_and_clear_list_model (GtkFileChooserWidget *impl, | |
@@ -602,13 +647,33 @@ static gboolean recent_should_respond (GtkFileChooserWidget *impl); | |
static void set_file_system_backend (GtkFileChooserWidget *impl); | |
static void unset_file_system_backend (GtkFileChooserWidget *impl); | |
+static gboolean get_selected_tree_iter_from_icon_view (GtkFileChooserWidget *impl, | |
+ GtkTreeIter *iter_out); | |
+static void current_selection_selected_foreach (GtkFileChooserWidget *impl, | |
+ GtkTreeSelectionForeachFunc func, | |
+ gpointer data); | |
+static guint current_selection_count_selected_rows (GtkFileChooserWidget *impl); | |
+static void current_selection_select_iter (GtkFileChooserWidget *impl, | |
+ GtkTreeIter *iter); | |
+static void copy_old_selection_to_current_view (GtkFileChooserWidget *impl, | |
+ ViewMode old_view_mode); | |
+static void current_selection_unselect_iter (GtkFileChooserWidget *impl, | |
+ GtkTreeIter *iter); | |
+static void current_selection_unselect_all (GtkFileChooserWidget *impl); | |
+static void current_view_set_file_model (GtkFileChooserWidget *impl, | |
+ GtkTreeModel *model); | |
+static void current_view_set_cursor (GtkFileChooserWidget *impl, | |
+ GtkTreePath *path); | |
+static void current_view_set_select_multiple (GtkFileChooserWidget *impl, | |
+ gboolean select_multiple); | |
+ | |
static void clear_model_cache (GtkFileChooserWidget *impl, | |
gint column); | |
static void set_model_filter (GtkFileChooserWidget *impl, | |
GtkFileFilter *filter); | |
static void switch_to_home_dir (GtkFileChooserWidget *impl); | |
- | |
+ | |
G_DEFINE_TYPE_WITH_CODE (GtkFileChooserWidget, gtk_file_chooser_widget, GTK_TYPE_BOX, | |
G_ADD_PRIVATE (GtkFileChooserWidget) | |
@@ -937,7 +1002,7 @@ update_preview_widget_visibility (GtkFileChooserWidget *impl) | |
} | |
} | |
- if (priv->preview_widget_active && priv->preview_widget) | |
+ if (priv->preview_widget_active && priv->preview_widget && priv->view_mode == VIEW_MODE_LIST) | |
gtk_widget_show (priv->preview_box); | |
else | |
gtk_widget_hide (priv->preview_box); | |
@@ -1205,19 +1270,17 @@ selection_check (GtkFileChooserWidget *impl, | |
gboolean *all_files, | |
gboolean *all_folders) | |
{ | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
struct selection_check_closure closure; | |
- GtkTreeSelection *selection; | |
closure.impl = impl; | |
closure.num_selected = 0; | |
closure.all_files = TRUE; | |
closure.all_folders = TRUE; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_selected_foreach (selection, | |
- selection_check_foreach_cb, | |
- &closure); | |
+ | |
+ current_selection_selected_foreach (impl, | |
+ selection_check_foreach_cb, | |
+ &closure); | |
g_assert (closure.num_selected == 0 || !(closure.all_files && closure.all_folders)); | |
@@ -1339,7 +1402,7 @@ browse_files_key_press_event_cb (GtkWidget *widget, | |
return TRUE; | |
} | |
- if (key_is_left_or_right (event)) | |
+ if (priv->view_mode == VIEW_MODE_LIST && key_is_left_or_right (event)) | |
{ | |
if (gtk_widget_child_focus (priv->places_sidebar, GTK_DIR_LEFT)) | |
return TRUE; | |
@@ -1442,12 +1505,8 @@ add_to_shortcuts_cb (GSimpleAction *action, | |
gpointer data) | |
{ | |
GtkFileChooserWidget *impl = data; | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- | |
- gtk_tree_selection_selected_foreach (selection, | |
+ current_selection_selected_foreach (impl, | |
add_bookmark_foreach_cb, | |
impl); | |
} | |
@@ -1802,6 +1861,86 @@ open_folder_cb (GSimpleAction *action, | |
} | |
G_GNUC_END_IGNORE_DEPRECATIONS | |
+/* callback used when "Sort by Name" menu item is activated */ | |
+static void | |
+sort_by_name_cb (GSimpleAction *action, | |
+ GVariant *parameter, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidget *impl = data; | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkTreeSortable *sortable; | |
+ | |
+ sortable = GTK_TREE_SORTABLE (priv->browse_files_model); | |
+ gtk_tree_sortable_set_sort_column_id (sortable, | |
+ priv->sort_column=MODEL_COL_NAME, | |
+ priv->sort_order); | |
+} | |
+ | |
+/* callback used when "Sort by Size" menu item is activated */ | |
+static void | |
+sort_by_size_cb (GSimpleAction *action, | |
+ GVariant *parameter, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidget *impl = data; | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkTreeSortable *sortable; | |
+ | |
+ sortable = GTK_TREE_SORTABLE (priv->browse_files_model); | |
+ gtk_tree_sortable_set_sort_column_id (sortable, | |
+ priv->sort_column=MODEL_COL_SIZE, | |
+ priv->sort_order); | |
+} | |
+ | |
+/* callback used when "Sort by Time" menu item is activated */ | |
+static void | |
+sort_by_time_cb (GSimpleAction *action, | |
+ GVariant *parameter, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidget *impl = data; | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkTreeSortable *sortable; | |
+ | |
+ sortable = GTK_TREE_SORTABLE (priv->browse_files_model); | |
+ gtk_tree_sortable_set_sort_column_id (sortable, | |
+ priv->sort_column=MODEL_COL_TIME, | |
+ priv->sort_order); | |
+} | |
+ | |
+/* callback used when "Ascending" menu item is activated */ | |
+static void | |
+ascending_cb (GSimpleAction *action, | |
+ GVariant *parameter, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidget *impl = data; | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkTreeSortable *sortable; | |
+ | |
+ sortable = GTK_TREE_SORTABLE (priv->browse_files_model); | |
+ gtk_tree_sortable_set_sort_column_id (sortable, | |
+ priv->sort_column, | |
+ priv->sort_order=GTK_SORT_ASCENDING); | |
+} | |
+ | |
+/* callback used when "Descending" menu item is activated */ | |
+static void | |
+descending_cb (GSimpleAction *action, | |
+ GVariant *parameter, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidget *impl = data; | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkTreeSortable *sortable; | |
+ | |
+ sortable = GTK_TREE_SORTABLE (priv->browse_files_model); | |
+ gtk_tree_sortable_set_sort_column_id (sortable, | |
+ priv->sort_column, | |
+ priv->sort_order=GTK_SORT_DESCENDING); | |
+} | |
+ | |
/* callback used when the "Show Hidden Files" menu item is toggled */ | |
static void | |
change_show_hidden_state (GSimpleAction *action, | |
@@ -2113,6 +2252,7 @@ check_file_list_popover_sensitivity (GtkFileChooserWidget *impl) | |
gboolean all_files; | |
gboolean all_folders; | |
gboolean active; | |
+ gboolean always_active; | |
GActionGroup *actions; | |
GAction *action, *action2; | |
@@ -2121,6 +2261,7 @@ check_file_list_popover_sensitivity (GtkFileChooserWidget *impl) | |
selection_check (impl, &num_selected, &all_files, &all_folders); | |
active = (num_selected != 0); | |
+ always_active = (num_selected >= 0); | |
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "copy-location"); | |
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), active); | |
@@ -2134,6 +2275,21 @@ check_file_list_popover_sensitivity (GtkFileChooserWidget *impl) | |
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "open"); | |
g_simple_action_set_enabled (G_SIMPLE_ACTION (action), (num_selected == 1) && all_folders); | |
+ action = g_action_map_lookup_action (G_ACTION_MAP (actions), "sort-by-name"); | |
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), always_active); | |
+ | |
+ action = g_action_map_lookup_action (G_ACTION_MAP (actions), "sort-by-size"); | |
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), always_active); | |
+ | |
+ action = g_action_map_lookup_action (G_ACTION_MAP (actions), "sort-by-time"); | |
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), always_active); | |
+ | |
+ action = g_action_map_lookup_action (G_ACTION_MAP (actions), "ascending"); | |
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), always_active); | |
+ | |
+ action = g_action_map_lookup_action (G_ACTION_MAP (actions), "descending"); | |
+ g_simple_action_set_enabled (G_SIMPLE_ACTION (action), always_active); | |
+ | |
action = g_action_map_lookup_action (G_ACTION_MAP (actions), "rename"); | |
if (num_selected == 1) | |
{ | |
@@ -2199,6 +2355,11 @@ static GActionEntry entries[] = { | |
{ "rename", rename_file_cb, NULL, NULL, NULL }, | |
{ "delete", delete_file_cb, NULL, NULL, NULL }, | |
{ "trash", trash_file_cb, NULL, NULL, NULL }, | |
+ { "sort-by-name", sort_by_name_cb, NULL, NULL, NULL }, | |
+ { "sort-by-size", sort_by_size_cb, NULL, NULL, NULL }, | |
+ { "sort-by-time", sort_by_time_cb, NULL, NULL, NULL }, | |
+ { "ascending", ascending_cb, NULL, NULL, NULL }, | |
+ { "descending", descending_cb, NULL, NULL, NULL }, | |
{ "toggle-show-hidden", NULL, NULL, "false", change_show_hidden_state }, | |
{ "toggle-show-size", NULL, NULL, "false", change_show_size_state }, | |
{ "toggle-show-time", NULL, NULL, "false", change_show_time_state }, | |
@@ -2222,17 +2383,9 @@ static GtkWidget * | |
append_separator (GtkWidget *box) | |
{ | |
GtkWidget *separator; | |
- | |
- separator = g_object_new (GTK_TYPE_SEPARATOR, | |
- "orientation", GTK_ORIENTATION_HORIZONTAL, | |
- "visible", TRUE, | |
- "margin-start", 12, | |
- "margin-end", 12, | |
- "margin-top", 6, | |
- "margin-bottom", 6, | |
- NULL); | |
- gtk_container_add (GTK_CONTAINER (box), separator); | |
- | |
+ separator = gtk_separator_menu_item_new (); | |
+ gtk_widget_set_visible (GTK_WIDGET (separator), TRUE); | |
+ gtk_menu_shell_append (GTK_MENU_SHELL (box), separator); | |
return separator; | |
} | |
@@ -2244,13 +2397,13 @@ add_button (GtkWidget *box, | |
{ | |
GtkWidget *item; | |
- item = g_object_new (GTK_TYPE_MODEL_BUTTON, | |
- "visible", TRUE, | |
- "action-name", action, | |
- "text", label, | |
- NULL); | |
- gtk_container_add (GTK_CONTAINER (box), item); | |
- | |
+ if (g_str_match_string ("toggle", action, TRUE)) | |
+ item = gtk_check_menu_item_new_with_mnemonic (label); | |
+ else | |
+ item = gtk_menu_item_new_with_mnemonic (label); | |
+ g_object_set (G_OBJECT (item), "action-name", action, NULL); | |
+ gtk_widget_set_visible (GTK_WIDGET (item), TRUE); | |
+ gtk_menu_shell_append (GTK_MENU_SHELL (box), item); | |
return item; | |
} | |
@@ -2263,11 +2416,9 @@ file_list_build_popover (GtkFileChooserWidget *impl) | |
if (priv->browse_files_popover) | |
return; | |
- priv->browse_files_popover = gtk_popover_new (priv->browse_files_tree_view); | |
- box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); | |
- g_object_set (box, "margin", 10, NULL); | |
- gtk_widget_show (box); | |
- gtk_container_add (GTK_CONTAINER (priv->browse_files_popover), box); | |
+ priv->browse_files_popover = gtk_menu_new (); | |
+ gtk_menu_attach_to_widget (GTK_MENU (priv->browse_files_popover), GTK_WIDGET (priv->browse_files_tree_view), NULL); | |
+ box = priv->browse_files_popover; | |
priv->visit_file_item = add_button (box, _("_Visit File"), "item.visit"); | |
priv->open_folder_item = add_button (box, _("_Open With File Manager"), "item.open"); | |
@@ -2276,13 +2427,30 @@ file_list_build_popover (GtkFileChooserWidget *impl) | |
priv->rename_file_item = add_button (box, _("_Rename"), "item.rename"); | |
priv->delete_file_item = add_button (box, _("_Delete"), "item.delete"); | |
priv->trash_file_item = add_button (box, _("_Move to Trash"), "item.trash"); | |
- | |
append_separator (box); | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ priv->hidden_files_item = add_button (box, _("Show _Hidden Files"), "item.toggle-show-hidden"); | |
+ priv->size_column_item = add_button (box, _("Show _Size Column"), "item.toggle-show-size"); | |
+ priv->show_time_item = add_button (box, _("Show _Time"), "item.toggle-show-time"); | |
+ priv->sort_directories_item = add_button (box, _("Sort _Folders before Files"), "item.toggle-sort-dirs-first"); | |
+ } | |
+ if (priv->view_mode == VIEW_MODE_ICON) | |
+ { | |
+ GtkWidget *menu; | |
- priv->hidden_files_item = add_button (box, _("Show _Hidden Files"), "item.toggle-show-hidden"); | |
- priv->size_column_item = add_button (box, _("Show _Size Column"), "item.toggle-show-size"); | |
- priv->show_time_item = add_button (box, _("Show _Time"), "item.toggle-show-time"); | |
- priv->sort_directories_item = add_button (box, _("Sort _Folders before Files"), "item.toggle-sort-dirs-first"); | |
+ priv->arrange_item = add_button (box, _("Arrange Items"), NULL); | |
+ menu = gtk_menu_new (); | |
+ gtk_menu_item_set_submenu (GTK_MENU_ITEM (priv->arrange_item), menu); | |
+ priv->sort_by_name_item = add_button (menu, _("Sort _by Name"), "item.sort-by-name"); | |
+ priv->sort_by_size_item = add_button (menu, _("Sort _by Size"), "item.sort-by-size"); | |
+ priv->sort_by_time_item = add_button (menu, _("Sort _by Time"), "item.sort-by-time"); | |
+ append_separator (menu); | |
+ priv->ascending_item = add_button (menu, _("Ascending"), "item.ascending"); | |
+ priv->descending_item = add_button (menu, _("Descending"), "item.descending"); | |
+ priv->hidden_files_item = add_button (box, _("Show _Hidden Files"), "item.toggle-show-hidden"); | |
+ priv->sort_directories_item = add_button (box, _("Sort _Folders before Files"), "item.toggle-sort-dirs-first"); | |
+ } | |
} | |
/* Updates the popover for the file list, creating it if necessary */ | |
@@ -2331,39 +2499,10 @@ file_list_show_popover (GtkFileChooserWidget *impl, | |
gdouble y) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GdkRectangle rect; | |
- GtkTreeSelection *selection; | |
- GtkTreeModel *model; | |
- GList *list; | |
- GtkTreePath *path; | |
- | |
file_list_update_popover (impl); | |
- | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- list = gtk_tree_selection_get_selected_rows (selection, &model); | |
- if (list) | |
- { | |
- path = list->data; | |
- gtk_tree_view_get_cell_area (GTK_TREE_VIEW (priv->browse_files_tree_view), path, NULL, &rect); | |
- gtk_tree_view_convert_bin_window_to_widget_coords (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
- rect.x, rect.y, &rect.x, &rect.y); | |
- | |
- rect.x = CLAMP (x - 20, 0, gtk_widget_get_allocated_width (priv->browse_files_tree_view) - 40); | |
- rect.width = 40; | |
- | |
- g_list_free_full (list, (GDestroyNotify) gtk_tree_path_free); | |
- } | |
- else | |
- { | |
- rect.x = x; | |
- rect.y = y; | |
- rect.width = 1; | |
- rect.height = 1; | |
- } | |
- | |
- gtk_popover_set_pointing_to (GTK_POPOVER (priv->browse_files_popover), &rect); | |
- gtk_popover_popup (GTK_POPOVER (priv->browse_files_popover)); | |
+ gtk_menu_popup_at_pointer (GTK_MENU (priv->browse_files_popover), NULL); | |
+ return; | |
} | |
/* Callback used for the GtkWidget::popup-menu signal of the file list */ | |
@@ -2387,7 +2526,6 @@ list_button_press_event_cb (GtkWidget *widget, | |
GdkEventButton *event, | |
GtkFileChooserWidget *impl) | |
{ | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
static gboolean in_press = FALSE; | |
if (in_press) | |
@@ -2397,7 +2535,7 @@ list_button_press_event_cb (GtkWidget *widget, | |
return FALSE; | |
in_press = TRUE; | |
- gtk_widget_event (priv->browse_files_tree_view, (GdkEvent *) event); | |
+ gtk_widget_event (widget, (GdkEvent *) event); | |
in_press = FALSE; | |
file_list_show_popover (impl, event->x, event->y); | |
@@ -2428,12 +2566,15 @@ file_list_set_sort_column_ids (GtkFileChooserWidget *impl) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- gtk_tree_view_set_search_column (GTK_TREE_VIEW (priv->browse_files_tree_view), -1); | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ gtk_tree_view_set_search_column (GTK_TREE_VIEW (priv->browse_files_tree_view), -1); | |
- gtk_tree_view_column_set_sort_column_id (priv->list_name_column, MODEL_COL_NAME); | |
- gtk_tree_view_column_set_sort_column_id (priv->list_time_column, MODEL_COL_TIME); | |
- gtk_tree_view_column_set_sort_column_id (priv->list_size_column, MODEL_COL_SIZE); | |
- gtk_tree_view_column_set_sort_column_id (priv->list_location_column, MODEL_COL_LOCATION_TEXT); | |
+ gtk_tree_view_column_set_sort_column_id (priv->list_name_column, MODEL_COL_NAME); | |
+ gtk_tree_view_column_set_sort_column_id (priv->list_time_column, MODEL_COL_TIME); | |
+ gtk_tree_view_column_set_sort_column_id (priv->list_size_column, MODEL_COL_SIZE); | |
+ gtk_tree_view_column_set_sort_column_id (priv->list_location_column, MODEL_COL_LOCATION_TEXT); | |
+ } | |
} | |
static gboolean | |
@@ -2456,11 +2597,22 @@ file_list_query_tooltip_cb (GtkWidget *widget, | |
return FALSE; | |
- if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
- &x, &y, | |
- keyboard_tip, | |
- &model, &path, &iter)) | |
- return FALSE; | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ if (!gtk_tree_view_get_tooltip_context (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
+ &x, &y, | |
+ keyboard_tip, | |
+ &model, &path, &iter)) | |
+ return FALSE; | |
+ } | |
+ else if(priv->view_mode == VIEW_MODE_ICON) | |
+ { | |
+ if (!gtk_icon_view_get_tooltip_context (GTK_ICON_VIEW (priv->browse_files_icon_view), | |
+ &x, &y, | |
+ keyboard_tip, | |
+ &model, &path, &iter)) | |
+ return FALSE; | |
+ } | |
gtk_tree_model_get (model, &iter, | |
MODEL_COL_FILE, &file, | |
@@ -2474,10 +2626,18 @@ file_list_query_tooltip_cb (GtkWidget *widget, | |
filename = g_file_get_path (file); | |
gtk_tooltip_set_text (tooltip, filename); | |
- gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
- tooltip, | |
- path); | |
- | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ gtk_tree_view_set_tooltip_row (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
+ tooltip, | |
+ path); | |
+ } | |
+ else if(priv->view_mode == VIEW_MODE_ICON) | |
+ { | |
+ gtk_icon_view_set_tooltip_item (GTK_ICON_VIEW (priv->browse_files_icon_view), | |
+ tooltip, | |
+ path); | |
+ } | |
g_free (filename); | |
g_object_unref (file); | |
gtk_tree_path_free (path); | |
@@ -2493,8 +2653,8 @@ set_icon_cell_renderer_fixed_size (GtkFileChooserWidget *impl) | |
gtk_cell_renderer_get_padding (priv->list_pixbuf_renderer, &xpad, &ypad); | |
gtk_cell_renderer_set_fixed_size (priv->list_pixbuf_renderer, | |
- xpad * 2 + priv->icon_size, | |
- ypad * 2 + priv->icon_size); | |
+ xpad * 2 + priv->list_view_icon_size, | |
+ ypad * 2 + priv->list_view_icon_size); | |
} | |
static gboolean | |
@@ -2778,7 +2938,7 @@ location_mode_set (GtkFileChooserWidget *impl, | |
location_switch_to_path_bar (impl); | |
if (switch_to_file_list) | |
- gtk_widget_grab_focus (priv->browse_files_tree_view); | |
+ gtk_widget_grab_focus (priv->browse_files_current_view); | |
break; | |
@@ -2849,6 +3009,118 @@ location_toggle_popup_handler (GtkFileChooserWidget *impl) | |
} | |
} | |
+/* Creates icon view (alternative for the list view) */ | |
+static GtkWidget * | |
+create_browse_files_icon_view (GtkFileChooserWidget *impl) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ | |
+ gtk_icon_view_set_text_column (GTK_ICON_VIEW (priv->browse_files_icon_view), | |
+ MODEL_COL_NAME); | |
+ gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (priv->browse_files_icon_view), | |
+ MODEL_COL_ICON_PIXBUF); | |
+ gtk_icon_view_set_item_width (GTK_ICON_VIEW (priv->browse_files_icon_view), | |
+ ICON_VIEW_ITEM_WIDTH); | |
+ | |
+ return priv->browse_files_icon_view; | |
+} | |
+ | |
+static void | |
+view_mode_set (GtkFileChooserWidget *impl, ViewMode view_mode) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkWidget *old_view = NULL; | |
+ ViewMode old_view_mode = priv->view_mode; | |
+ priv->browse_files_popover = NULL; | |
+ | |
+ if (old_view_mode == view_mode) | |
+ return; | |
+ | |
+ priv->view_mode = view_mode; | |
+ gtk_combo_box_set_active (GTK_COMBO_BOX (priv->view_mode_combo_box), | |
+ view_mode); | |
+ | |
+ /* Creating the target view */ | |
+ if (view_mode == VIEW_MODE_ICON) | |
+ { | |
+ create_browse_files_icon_view (impl); | |
+ priv->browse_files_current_view = priv->browse_files_icon_view; | |
+ old_view = priv->browse_files_tree_view; | |
+ gtk_widget_show (priv->icon_view_scale); | |
+ } | |
+ else if (view_mode == VIEW_MODE_LIST) | |
+ { | |
+ priv->browse_files_current_view = priv->browse_files_tree_view; | |
+ old_view = priv->browse_files_icon_view; | |
+ gtk_widget_hide (priv->icon_view_scale); | |
+ } | |
+ else | |
+ g_assert_not_reached (); | |
+ | |
+ /* Set model and selection */ | |
+ current_view_set_file_model (impl, priv->current_model); | |
+ current_view_set_select_multiple (impl, priv->select_multiple); | |
+ copy_old_selection_to_current_view (impl, old_view_mode); | |
+ | |
+ /* Hide the old view */ | |
+ g_object_set (old_view, "model", NULL, NULL); | |
+ gtk_widget_hide (old_view); | |
+ | |
+ /* Show the new view */ | |
+ gtk_widget_show (priv->browse_files_current_view); | |
+ gtk_notebook_set_current_page(priv->view_notebook, view_mode); | |
+} | |
+ | |
+/* Callback used when view mode combo box active item is changed */ | |
+static void | |
+view_mode_combo_box_changed_cb (GtkComboBox *combo, | |
+ GtkFileChooserWidget *impl) | |
+{ | |
+ ViewMode target = gtk_combo_box_get_active (combo); | |
+ | |
+ view_mode_set (impl, target); | |
+} | |
+ | |
+/* Callback used when view mode is changed */ | |
+gboolean | |
+view_notebook_switch_page_cb (GtkNotebook *notebook, | |
+ GtkWidget *page, | |
+ guint page_num, | |
+ gpointer user_data) | |
+{ | |
+ GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (user_data); | |
+ view_mode_set (impl, page_num); | |
+ return TRUE; | |
+} | |
+ | |
+static void | |
+icon_view_scale_value_changed_cb (GtkRange *range, | |
+ GtkFileChooserWidget *impl) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ gdouble value = gtk_range_get_value (range); | |
+ value = round (value / 16) * 16; | |
+ | |
+ if (priv->icon_view_icon_size == (gint)value) | |
+ return; | |
+ | |
+ priv->icon_view_icon_size = (gint)value; | |
+ | |
+ if (priv->view_mode != VIEW_MODE_ICON) | |
+ return; | |
+ | |
+ set_icon_cell_renderer_fixed_size (impl); | |
+ | |
+ if (priv->browse_files_model) | |
+ _gtk_file_system_model_clear_cache (priv->browse_files_model, MODEL_COL_ICON_PIXBUF); | |
+ if (priv->search_model) | |
+ _gtk_file_system_model_clear_cache (priv->search_model, MODEL_COL_ICON_PIXBUF); | |
+ if (priv->recent_model) | |
+ _gtk_file_system_model_clear_cache (priv->recent_model, MODEL_COL_ICON_PIXBUF); | |
+ | |
+ gtk_widget_queue_resize (priv->browse_files_current_view); | |
+} | |
+ | |
static void | |
gtk_file_chooser_widget_constructed (GObject *object) | |
{ | |
@@ -2884,7 +3156,6 @@ set_extra_widget (GtkFileChooserWidget *impl, | |
if (extra_widget) | |
{ | |
g_object_ref (extra_widget); | |
- /* FIXME: is this right ? */ | |
gtk_widget_show (extra_widget); | |
} | |
@@ -2957,18 +3228,11 @@ set_select_multiple (GtkFileChooserWidget *impl, | |
gboolean property_notify) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection; | |
- GtkSelectionMode mode; | |
if (select_multiple == priv->select_multiple) | |
return; | |
- mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_SINGLE; | |
- | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_set_mode (selection, mode); | |
- | |
- gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (priv->browse_files_tree_view), select_multiple); | |
+ current_view_set_select_multiple (impl, select_multiple); | |
priv->select_multiple = select_multiple; | |
g_object_notify (G_OBJECT (impl), "select-multiple"); | |
@@ -3095,6 +3359,7 @@ operation_mode_set_enter_location (GtkFileChooserWidget *impl) | |
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_header_stack), "location"); | |
gtk_revealer_set_reveal_child (GTK_REVEALER (priv->browse_header_revealer), TRUE); | |
location_bar_update (impl); | |
+ gtk_tree_view_column_set_visible (priv->list_location_column, FALSE); | |
gtk_widget_set_sensitive (priv->filter_combo, TRUE); | |
location_mode_set (impl, LOCATION_MODE_FILENAME_ENTRY); | |
} | |
@@ -3124,7 +3389,7 @@ operation_mode_set_search (GtkFileChooserWidget *impl) | |
visible_widget = gtk_stack_get_visible_child (GTK_STACK (priv->browse_files_stack)); | |
if (visible_widget != priv->places_view && | |
- visible_widget != priv->browse_files_swin) | |
+ visible_widget != priv->browse_files_list_swin) | |
{ | |
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_files_stack), "list"); | |
} | |
@@ -3249,6 +3514,12 @@ update_appearance (GtkFileChooserWidget *impl) | |
location_mode_set (impl, priv->location_mode); | |
} | |
+ if (priv->action == GTK_FILE_CHOOSER_ACTION_OPEN || | |
+ priv->action == GTK_FILE_CHOOSER_ACTION_SAVE) | |
+ gtk_widget_show (priv->view_mode_combo_box); | |
+ else | |
+ gtk_widget_hide (priv->view_mode_combo_box); | |
+ | |
if (priv->location_entry) | |
_gtk_file_chooser_entry_set_action (GTK_FILE_CHOOSER_ENTRY (priv->location_entry), priv->action); | |
@@ -3257,7 +3528,7 @@ update_appearance (GtkFileChooserWidget *impl) | |
/* This *is* needed; we need to redraw the file list because the "sensitivity" | |
* of files may change depending whether we are in a file or folder-only mode. | |
*/ | |
- gtk_widget_queue_draw (priv->browse_files_tree_view); | |
+ gtk_widget_queue_draw (priv->browse_files_current_view); | |
emit_default_size_changed (impl); | |
} | |
@@ -3687,14 +3958,28 @@ change_icon_theme (GtkFileChooserWidget *impl) | |
profile_start ("start", NULL); | |
if (gtk_icon_size_lookup (GTK_ICON_SIZE_MENU, &width, &height)) | |
- priv->icon_size = MAX (width, height); | |
+ priv->list_view_icon_size = MAX (width, height); | |
+ else | |
+ priv->list_view_icon_size = FALLBACK_LIST_VIEW_ICON_SIZE; | |
+ | |
+ if (gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &width, &height)) | |
+ { | |
+ priv->icon_view_icon_size = MAX (width, height); | |
+ } | |
else | |
- priv->icon_size = FALLBACK_ICON_SIZE; | |
+ priv->list_view_icon_size = FALLBACK_LIST_VIEW_ICON_SIZE; | |
/* the first cell in the first column is the icon column, and we have a fixed size there */ | |
- set_icon_cell_renderer_fixed_size (impl); | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ set_icon_cell_renderer_fixed_size (impl); | |
+ } | |
- clear_model_cache (impl, MODEL_COL_SURFACE); | |
+ if (priv->browse_files_model) | |
+ { | |
+ clear_model_cache (impl, MODEL_COL_LIST_SURFACE); | |
+ clear_model_cache (impl, MODEL_COL_ICON_PIXBUF); | |
+ } | |
gtk_widget_queue_resize (priv->browse_files_tree_view); | |
profile_end ("end", NULL); | |
@@ -3795,7 +4080,7 @@ set_sort_column (GtkFileChooserWidget *impl) | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
GtkTreeSortable *sortable; | |
- sortable = GTK_TREE_SORTABLE (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view))); | |
+ sortable = GTK_TREE_SORTABLE (priv->current_model); | |
/* can happen when we're still populating the model */ | |
if (sortable == NULL) | |
@@ -3810,11 +4095,12 @@ static void | |
settings_load (GtkFileChooserWidget *impl) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ ViewMode view_mode; | |
gboolean show_hidden; | |
gboolean show_size_column; | |
gboolean sort_directories_first; | |
DateFormat date_format; | |
- gint sort_column; | |
+ gint sort_column, icon_view_scale; | |
GtkSortType sort_order; | |
StartupMode startup_mode; | |
gint sidebar_width; | |
@@ -3822,6 +4108,8 @@ settings_load (GtkFileChooserWidget *impl) | |
settings = _gtk_file_chooser_get_settings_for_widget (GTK_WIDGET (impl)); | |
+ view_mode = g_settings_get_enum (settings, SETTINGS_KEY_VIEW_MODE); | |
+ icon_view_scale = g_settings_get_int (settings, SETTINGS_KEY_ICON_VIEW_SCALE); | |
show_hidden = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_HIDDEN); | |
show_size_column = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN); | |
sort_column = g_settings_get_enum (settings, SETTINGS_KEY_SORT_COLUMN); | |
@@ -3831,10 +4119,16 @@ settings_load (GtkFileChooserWidget *impl) | |
sort_directories_first = g_settings_get_boolean (settings, SETTINGS_KEY_SORT_DIRECTORIES_FIRST); | |
date_format = g_settings_get_enum (settings, SETTINGS_KEY_DATE_FORMAT); | |
+ view_mode_set (impl, view_mode); | |
+ | |
+ gtk_range_set_value (GTK_RANGE (priv->icon_view_scale), icon_view_scale); | |
+ priv->icon_view_icon_size = icon_view_scale; | |
+ | |
if (!priv->show_hidden_set) | |
set_show_hidden (impl, show_hidden); | |
priv->show_size_column = show_size_column; | |
- gtk_tree_view_column_set_visible (priv->list_size_column, show_size_column); | |
+ if (priv->list_size_column) | |
+ gtk_tree_view_column_set_visible (priv->list_size_column, show_size_column); | |
priv->sort_column = sort_column; | |
priv->sort_order = sort_order; | |
@@ -3862,6 +4156,8 @@ settings_save (GtkFileChooserWidget *impl) | |
/* All the other state */ | |
g_settings_set_enum (settings, SETTINGS_KEY_LOCATION_MODE, priv->location_mode); | |
+ g_settings_set_enum (settings, SETTINGS_KEY_VIEW_MODE, priv->view_mode); | |
+ g_settings_set_int (settings, SETTINGS_KEY_ICON_VIEW_SCALE, priv->icon_view_icon_size); | |
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_HIDDEN, | |
gtk_file_chooser_get_show_hidden (GTK_FILE_CHOOSER (impl))); | |
g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN, priv->show_size_column); | |
@@ -4336,10 +4632,14 @@ load_set_model (GtkFileChooserWidget *impl) | |
g_assert (priv->browse_files_model != NULL); | |
profile_msg (" gtk_tree_view_set_model start", NULL); | |
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
- GTK_TREE_MODEL (priv->browse_files_model)); | |
- update_columns (impl, FALSE, _("Modified")); | |
- file_list_set_sort_column_ids (impl); | |
+ current_view_set_file_model (impl, GTK_TREE_MODEL (priv->browse_files_model)); | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ gtk_tree_view_set_model (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
+ GTK_TREE_MODEL (priv->browse_files_model)); | |
+ update_columns (impl, FALSE, _("Modified")); | |
+ file_list_set_sort_column_ids (impl); | |
+ } | |
set_sort_column (impl); | |
profile_msg (" gtk_tree_view_set_model end", NULL); | |
priv->list_sort_ascending = TRUE; | |
@@ -4419,7 +4719,7 @@ browse_files_select_first_row (GtkFileChooserWidget *impl) | |
GtkTreeIter dummy_iter; | |
GtkTreeModel *tree_model; | |
- tree_model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ tree_model = priv->current_model; | |
if (!tree_model) | |
return; | |
@@ -4438,8 +4738,7 @@ browse_files_select_first_row (GtkFileChooserWidget *impl) | |
*/ | |
priv->auto_selecting_first_row = TRUE; | |
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->browse_files_tree_view), path, NULL, FALSE); | |
- | |
+ current_view_set_cursor (impl, path); | |
priv->auto_selecting_first_row = FALSE; | |
} | |
gtk_tree_path_free (path); | |
@@ -4465,7 +4764,13 @@ center_selected_row_foreach_cb (GtkTreeModel *model, | |
if (closure->already_centered) | |
return; | |
- gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (closure->impl->priv->browse_files_tree_view), path, NULL, TRUE, 0.5, 0.0); | |
+ if (closure->impl->priv->view_mode == VIEW_MODE_LIST) | |
+ gtk_tree_view_scroll_to_cell (GTK_TREE_VIEW (closure->impl->priv->browse_files_tree_view), path, NULL, TRUE, 0.5, 0.0); | |
+ else if (closure->impl->priv->view_mode == VIEW_MODE_ICON) | |
+ gtk_icon_view_scroll_to_path (GTK_ICON_VIEW (closure->impl->priv->browse_files_icon_view), path, TRUE, 0.5, 0.0); | |
+ else | |
+ g_assert_not_reached (); | |
+ | |
closure->already_centered = TRUE; | |
} | |
@@ -4473,15 +4778,12 @@ center_selected_row_foreach_cb (GtkTreeModel *model, | |
static void | |
browse_files_center_selected_row (GtkFileChooserWidget *impl) | |
{ | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
struct center_selected_row_closure closure; | |
- GtkTreeSelection *selection; | |
closure.impl = impl; | |
closure.already_centered = FALSE; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_selected_foreach (selection, center_selected_row_foreach_cb, &closure); | |
+ current_selection_selected_foreach(impl, center_selected_row_foreach_cb, &closure); | |
} | |
static gboolean | |
@@ -4489,7 +4791,6 @@ show_and_select_files (GtkFileChooserWidget *impl, | |
GSList *files) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection; | |
GtkFileSystemModel *fsmodel; | |
gboolean enabled_hidden, removed_filters; | |
gboolean selected_a_file; | |
@@ -4498,8 +4799,7 @@ show_and_select_files (GtkFileChooserWidget *impl, | |
g_assert (priv->load_state == LOAD_FINISHED); | |
g_assert (priv->browse_files_model != NULL); | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- fsmodel = GTK_FILE_SYSTEM_MODEL (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view))); | |
+ fsmodel = GTK_FILE_SYSTEM_MODEL (priv->current_model); | |
g_assert (fsmodel == priv->browse_files_model); | |
@@ -4554,11 +4854,10 @@ show_and_select_files (GtkFileChooserWidget *impl, | |
{ | |
GtkTreePath *path; | |
- gtk_tree_selection_select_iter (selection, &iter); | |
+ current_selection_select_iter (impl, &iter); | |
path = gtk_tree_model_get_path (GTK_TREE_MODEL (fsmodel), &iter); | |
- gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
- path, NULL, FALSE); | |
+ current_view_set_cursor (impl, path); | |
gtk_tree_path_free (path); | |
selected_a_file = TRUE; | |
@@ -4679,12 +4978,14 @@ stop_loading_and_clear_list_model (GtkFileChooserWidget *impl, | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (priv->current_model == GTK_TREE_MODEL (priv->browse_files_model)) | |
+ priv->current_model = NULL; | |
load_remove_timer (impl, LOAD_EMPTY); | |
g_set_object (&priv->browse_files_model, NULL); | |
if (remove) | |
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->browse_files_tree_view), NULL); | |
+ current_view_set_file_model (impl, NULL); | |
} | |
/* Replace 'target' with 'replacement' in the input string. */ | |
@@ -4862,6 +5163,18 @@ file_system_model_got_thumbnail (GObject *object, | |
gdk_threads_leave (); | |
} | |
+static gboolean | |
+get_visible_range (GtkTreePath **start, GtkTreePath **end, | |
+ GtkFileChooserWidget *impl) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ return gtk_tree_view_get_visible_range (GTK_TREE_VIEW (priv->browse_files_tree_view), start, end); | |
+ if (priv->view_mode == VIEW_MODE_ICON) | |
+ return gtk_icon_view_get_visible_range (GTK_ICON_VIEW (priv->browse_files_icon_view), start, end); | |
+ g_assert_not_reached (); | |
+} | |
+ | |
static gboolean | |
file_system_model_set (GtkFileSystemModel *model, | |
GFile *file, | |
@@ -4921,12 +5234,15 @@ file_system_model_set (GtkFileSystemModel *model, | |
else | |
g_value_set_boolean (value, TRUE); | |
break; | |
- case MODEL_COL_SURFACE: | |
+ case MODEL_COL_LIST_SURFACE: | |
+ /* don't load list view icons in other view modes */ | |
+ if(priv->view_mode != VIEW_MODE_LIST) | |
+ return FALSE; | |
if (info) | |
{ | |
if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_ICON)) | |
{ | |
- g_value_take_boxed (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), priv->icon_size)); | |
+ g_value_take_boxed (value, _gtk_file_info_render_icon (info, GTK_WIDGET (impl), priv->list_view_icon_size)); | |
} | |
else | |
{ | |
@@ -4980,6 +5296,76 @@ file_system_model_set (GtkFileSystemModel *model, | |
else | |
g_value_set_boxed (value, NULL); | |
break; | |
+ case MODEL_COL_ICON_PIXBUF: | |
+ if (info) | |
+ { | |
+ GtkTreeModel *tree_model; | |
+ GtkTreePath *path, *start, *end; | |
+ GtkTreeIter iter; | |
+ int icon_size; | |
+ gboolean file_visible; | |
+ | |
+ tree_model = priv->current_model; | |
+ if (tree_model != GTK_TREE_MODEL (model)) | |
+ return FALSE; | |
+ | |
+ /* #1 use standard icon if it is loaded */ | |
+ if (g_file_info_has_attribute (info, G_FILE_ATTRIBUTE_STANDARD_ICON)) | |
+ { | |
+ icon_size = priv->icon_view_icon_size; | |
+ | |
+ cairo_surface_t *icon_surface = _gtk_file_info_render_icon (info, GTK_WIDGET (impl), icon_size); | |
+ GdkPixbuf *icon_pixbuf = gdk_pixbuf_get_from_surface(icon_surface, | |
+ 0, 0, | |
+ cairo_image_surface_get_width(icon_surface), | |
+ cairo_image_surface_get_height(icon_surface)); | |
+ cairo_surface_destroy(icon_surface); | |
+ | |
+ g_value_take_object (value, icon_pixbuf); | |
+ return TRUE; | |
+ } | |
+ | |
+ if (!get_visible_range (&start, &end, impl)) | |
+ return FALSE; | |
+ | |
+ if (!_gtk_file_system_model_get_iter_for_file (model, | |
+ &iter, | |
+ file)) | |
+ g_assert_not_reached (); | |
+ | |
+ path = gtk_tree_model_get_path (tree_model, &iter); | |
+ file_visible = (gtk_tree_path_compare (start, path) != 1 && | |
+ gtk_tree_path_compare (path, end) != 1); | |
+ | |
+ gtk_tree_path_free (path); | |
+ gtk_tree_path_free (start); | |
+ gtk_tree_path_free (end); | |
+ | |
+ if (file_visible) | |
+ { | |
+ /* #2 start loading standard icon (callback will be handled by #1) */ | |
+ if (!g_file_info_has_attribute (info, "filechooser::icon_queried")) | |
+ { | |
+ g_file_info_set_attribute_boolean (info, "filechooser::icon_queried", TRUE); | |
+ g_file_query_info_async (file, | |
+ G_FILE_ATTRIBUTE_THUMBNAIL_PATH "," | |
+ G_FILE_ATTRIBUTE_THUMBNAILING_FAILED "," | |
+ G_FILE_ATTRIBUTE_STANDARD_ICON, | |
+ G_FILE_QUERY_INFO_NONE, | |
+ G_PRIORITY_DEFAULT, | |
+ _gtk_file_system_model_get_cancellable (model), | |
+ file_system_model_got_thumbnail, | |
+ model); | |
+ } | |
+ | |
+ } | |
+ return FALSE; | |
+ } | |
+ else | |
+ { | |
+ g_value_set_object (value, NULL); | |
+ } | |
+ break; | |
case MODEL_COL_SIZE: | |
g_value_set_int64 (value, info ? g_file_info_get_size (info) : 0); | |
break; | |
@@ -5162,7 +5548,6 @@ static void | |
update_chooser_entry (GtkFileChooserWidget *impl) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection; | |
struct update_chooser_entry_selected_foreach_closure closure; | |
/* no need to update the file chooser's entry if there's no entry */ | |
@@ -5179,9 +5564,8 @@ update_chooser_entry (GtkFileChooserWidget *impl) | |
g_assert (priv->location_entry != NULL); | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
closure.num_selected = 0; | |
- gtk_tree_selection_selected_foreach (selection, update_chooser_entry_selected_foreach, &closure); | |
+ current_selection_selected_foreach (impl, update_chooser_entry_selected_foreach, &closure); | |
if (closure.num_selected == 0) | |
{ | |
@@ -5678,19 +6062,15 @@ gtk_file_chooser_widget_unselect_file (GtkFileChooser *chooser, | |
{ | |
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser); | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeView *tree_view; | |
- GtkTreeModel *model; | |
GtkTreeIter iter; | |
- | |
- tree_view = GTK_TREE_VIEW (priv->browse_files_tree_view); | |
- model = gtk_tree_view_get_model (tree_view); | |
- if (!model) | |
+ | |
+ if (!priv->current_model) | |
return; | |
- if (!_gtk_file_system_model_get_iter_for_file (GTK_FILE_SYSTEM_MODEL (model), &iter, file)) | |
+ if (!_gtk_file_system_model_get_iter_for_file (GTK_FILE_SYSTEM_MODEL (priv->current_model), &iter, file)) | |
return; | |
- gtk_tree_selection_unselect_iter (gtk_tree_view_get_selection (tree_view), &iter); | |
+ current_selection_unselect_iter (impl, &iter); | |
} | |
static gboolean | |
@@ -5701,12 +6081,9 @@ maybe_select (GtkTreeModel *model, | |
{ | |
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (data); | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection; | |
gboolean is_sensitive; | |
gboolean is_folder; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- | |
gtk_tree_model_get (model, iter, | |
MODEL_COL_IS_FOLDER, &is_folder, | |
MODEL_COL_IS_SENSITIVE, &is_sensitive, | |
@@ -5715,9 +6092,9 @@ maybe_select (GtkTreeModel *model, | |
if (is_sensitive && | |
((is_folder && priv->action == GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER) || | |
(!is_folder && priv->action == GTK_FILE_CHOOSER_ACTION_OPEN))) | |
- gtk_tree_selection_select_iter (selection, iter); | |
+ current_selection_select_iter (impl, iter); | |
else | |
- gtk_tree_selection_unselect_iter (selection, iter); | |
+ current_selection_unselect_iter (impl, iter); | |
return FALSE; | |
} | |
@@ -5733,8 +6110,15 @@ gtk_file_chooser_widget_select_all (GtkFileChooser *chooser) | |
{ | |
GtkTreeSelection *selection; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_select_all (selection); | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ gtk_tree_selection_select_all (selection); | |
+ } | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ gtk_icon_view_select_all (GTK_ICON_VIEW (priv->browse_files_icon_view)); | |
+ else | |
+ g_assert_not_reached(); | |
return; | |
} | |
@@ -5747,10 +6131,7 @@ static void | |
gtk_file_chooser_widget_unselect_all (GtkFileChooser *chooser) | |
{ | |
GtkFileChooserWidget *impl = GTK_FILE_CHOOSER_WIDGET (chooser); | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- | |
- gtk_tree_selection_unselect_all (selection); | |
+ current_selection_unselect_all (impl); | |
pending_select_files_free (impl); | |
} | |
@@ -5906,15 +6287,13 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser) | |
current_focus = NULL; | |
file_list_seen = FALSE; | |
- if (current_focus == priv->browse_files_tree_view) | |
+ if (current_focus == priv->browse_files_current_view) | |
{ | |
- GtkTreeSelection *selection; | |
- | |
file_list: | |
file_list_seen = TRUE; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_selected_foreach (selection, get_files_foreach, &info); | |
+ | |
+ current_selection_selected_foreach (impl, get_files_foreach, &info); | |
/* If there is no selection in the file list, we probably have this situation: | |
* | |
@@ -5948,7 +6327,7 @@ gtk_file_chooser_widget_get_files (GtkFileChooser *chooser) | |
else | |
return NULL; | |
} | |
- else if (priv->toplevel_last_focus_widget == priv->browse_files_tree_view) | |
+ else if (priv->toplevel_last_focus_widget == priv->browse_files_current_view) | |
goto file_list; | |
else if (priv->location_entry && priv->toplevel_last_focus_widget == priv->location_entry) | |
goto file_entry; | |
@@ -6226,8 +6605,6 @@ switch_folder_foreach_cb (GtkTreeModel *model, | |
static void | |
switch_to_selected_folder (GtkFileChooserWidget *impl) | |
{ | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection; | |
struct switch_folder_closure closure; | |
/* We do this with foreach() rather than get_selected() as we may be in | |
@@ -6238,8 +6615,7 @@ switch_to_selected_folder (GtkFileChooserWidget *impl) | |
closure.file = NULL; | |
closure.num_selected = 0; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_selected_foreach (selection, switch_folder_foreach_cb, &closure); | |
+ current_selection_selected_foreach (impl, switch_folder_foreach_cb, &closure); | |
g_assert (closure.file && closure.num_selected == 1); | |
@@ -6257,19 +6633,33 @@ get_selected_file_info_from_file_list (GtkFileChooserWidget *impl, | |
GtkTreeSelection *selection; | |
GtkTreeIter iter; | |
GFileInfo *info; | |
- GtkTreeModel *model; | |
g_assert (!priv->select_multiple); | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- if (!gtk_tree_selection_get_selected (selection, &model, &iter)) | |
+ | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
{ | |
- *had_selection = FALSE; | |
- return NULL; | |
- } | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ if (!gtk_tree_selection_get_selected (selection, NULL, &iter)) | |
+ { | |
+ *had_selection = FALSE; | |
+ return NULL; | |
+ } | |
- *had_selection = TRUE; | |
+ *had_selection = TRUE; | |
+ } | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ { | |
+ if (!get_selected_tree_iter_from_icon_view (impl, &iter)) | |
+ { | |
+ *had_selection = FALSE; | |
+ return NULL; | |
+ } | |
+ *had_selection = TRUE; | |
+ } | |
+ else | |
+ g_assert_not_reached(); | |
- info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (model), &iter); | |
+ info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (priv->current_model), &iter); | |
return info; | |
} | |
@@ -6762,7 +7152,7 @@ gtk_file_chooser_widget_should_respond (GtkFileChooserEmbed *chooser_embed) | |
current_focus = gtk_window_get_focus (GTK_WINDOW (toplevel)); | |
- if (current_focus == priv->browse_files_tree_view) | |
+ if (current_focus == priv->browse_files_current_view) | |
{ | |
/* The following array encodes what we do based on the priv->action and the | |
* number of files selected. | |
@@ -7009,7 +7399,7 @@ gtk_file_chooser_widget_initial_focus (GtkFileChooserEmbed *chooser_embed) | |
{ | |
if (priv->location_mode == LOCATION_MODE_PATH_BAR | |
|| priv->operation_mode == OPERATION_MODE_RECENT) | |
- widget = priv->browse_files_tree_view; | |
+ widget = priv->browse_files_current_view; | |
else | |
widget = priv->location_entry; | |
} | |
@@ -7047,45 +7437,24 @@ selected_foreach_get_file_cb (GtkTreeModel *model, | |
static GSList * | |
get_selected_files (GtkFileChooserWidget *impl) | |
{ | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
GSList *result; | |
- GtkTreeSelection *selection; | |
result = NULL; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_selected_foreach (selection, selected_foreach_get_file_cb, &result); | |
+ current_selection_selected_foreach (impl, selected_foreach_get_file_cb, &result); | |
result = g_slist_reverse (result); | |
return result; | |
} | |
-static void | |
-selected_foreach_get_info_cb (GtkTreeModel *model, | |
- GtkTreePath *path, | |
- GtkTreeIter *iter, | |
- gpointer data) | |
-{ | |
- GSList **list; | |
- GFileInfo *info; | |
- | |
- list = data; | |
- | |
- info = _gtk_file_system_model_get_info (GTK_FILE_SYSTEM_MODEL (model), iter); | |
- *list = g_slist_prepend (*list, g_object_ref (info)); | |
-} | |
- | |
static GSList * | |
get_selected_infos (GtkFileChooserWidget *impl) | |
{ | |
- GtkFileChooserWidgetPrivate *priv = impl->priv; | |
GSList *result; | |
- GtkTreeSelection *selection; | |
result = NULL; | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- gtk_tree_selection_selected_foreach (selection, selected_foreach_get_info_cb, &result); | |
+ current_selection_selected_foreach (impl, selected_foreach_get_file_cb, &result); | |
result = g_slist_reverse (result); | |
return result; | |
@@ -7156,6 +7525,7 @@ search_engine_finished_cb (GtkSearchEngine *engine, | |
gtk_stack_set_visible_child_name (GTK_STACK (priv->browse_files_stack), "empty"); | |
gtk_entry_grab_focus_without_selecting (GTK_ENTRY (priv->search_entry)); | |
} | |
+ current_view_set_file_model (impl, GTK_TREE_MODEL (priv->search_model)); | |
} | |
static void | |
@@ -7181,7 +7551,7 @@ search_clear_model (GtkFileChooserWidget *impl, | |
if (remove && | |
gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view)) == GTK_TREE_MODEL (priv->search_model)) | |
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->browse_files_tree_view), NULL); | |
+ current_view_set_file_model (impl, NULL); | |
g_clear_object (&priv->search_model); | |
} | |
@@ -7390,7 +7760,7 @@ recent_clear_model (GtkFileChooserWidget *impl, | |
return; | |
if (remove) | |
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->browse_files_tree_view), NULL); | |
+ current_view_set_file_model (impl, NULL); | |
g_set_object (&priv->recent_model, NULL); | |
} | |
@@ -7443,8 +7813,7 @@ recent_idle_cleanup (gpointer data) | |
GtkFileChooserWidget *impl = load_data->impl; | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- gtk_tree_view_set_model (GTK_TREE_VIEW (priv->browse_files_tree_view), | |
- GTK_TREE_MODEL (priv->recent_model)); | |
+ current_view_set_file_model (impl, GTK_TREE_MODEL (priv->recent_model)); | |
gtk_tree_view_set_search_column (GTK_TREE_VIEW (priv->browse_files_tree_view), -1); | |
gtk_tree_view_column_set_sort_column_id (priv->list_name_column, -1); | |
@@ -7591,12 +7960,10 @@ static gboolean | |
recent_should_respond (GtkFileChooserWidget *impl) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- GtkTreeSelection *selection; | |
g_assert (priv->operation_mode == OPERATION_MODE_RECENT); | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- return (gtk_tree_selection_count_selected_rows (selection) != 0); | |
+ return (current_selection_count_selected_rows (impl) != 0); | |
} | |
static void | |
@@ -7656,29 +8023,41 @@ check_preview_change (GtkFileChooserWidget *impl) | |
GtkTreeModel *model; | |
GtkTreeSelection *selection; | |
- model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
- if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE || | |
- gtk_tree_selection_get_mode (selection) == GTK_SELECTION_BROWSE) | |
+ model = priv->current_model; | |
+ | |
+ //model = gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
{ | |
- GtkTreeIter iter; | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ if (gtk_tree_selection_get_mode (selection) == GTK_SELECTION_SINGLE || | |
+ gtk_tree_selection_get_mode (selection) == GTK_SELECTION_BROWSE) | |
+ { | |
+ GtkTreeIter iter; | |
- if (gtk_tree_selection_get_selected (selection, NULL, &iter)) | |
- path = gtk_tree_model_get_path (model, &iter); | |
+ if (gtk_tree_selection_get_selected (selection, NULL, &iter)) | |
+ path = gtk_tree_model_get_path (model, &iter); | |
+ else | |
+ path = NULL; | |
+ } | |
+ | |
else | |
- path = NULL; | |
- } | |
- else | |
- { | |
- gtk_tree_view_get_cursor (GTK_TREE_VIEW (priv->browse_files_tree_view), &path, NULL); | |
- if (path && !gtk_tree_selection_path_is_selected (selection, path)) | |
{ | |
- gtk_tree_path_free (path); | |
- path = NULL; | |
+ gtk_tree_view_get_cursor (GTK_TREE_VIEW (priv->browse_files_tree_view), &path, NULL); | |
+ if (path && !gtk_tree_selection_path_is_selected (selection, path)) | |
+ { | |
+ gtk_tree_path_free (path); | |
+ path = NULL; | |
+ } | |
} | |
} | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ { | |
+ gtk_icon_view_get_cursor (GTK_ICON_VIEW (priv->browse_files_icon_view), &path, NULL); | |
+ } | |
+ else | |
+ g_assert_not_reached (); | |
- if (path) | |
+ if (path && model) | |
{ | |
GtkTreeIter iter; | |
@@ -7762,15 +8141,13 @@ list_select_func (GtkTreeSelection *selection, | |
return TRUE; | |
} | |
+/* GtkTreeSelection or GtkIconView selection changed. */ | |
static void | |
-list_selection_changed (GtkTreeSelection *selection, | |
- GtkFileChooserWidget *impl) | |
+list_selection_changed (void *selection, | |
+ GtkFileChooserWidget *impl) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
- if (gtk_tree_view_get_model (GTK_TREE_VIEW (priv->browse_files_tree_view)) == NULL) | |
- return; | |
- | |
if (priv->location_entry) | |
update_chooser_entry (impl); | |
@@ -7794,16 +8171,35 @@ list_row_activated (GtkTreeView *tree_view, | |
GtkTreePath *path, | |
GtkTreeViewColumn *column, | |
GtkFileChooserWidget *impl) | |
+{ | |
+ GtkTreeModel *model; | |
+ model = gtk_tree_view_get_model (tree_view); | |
+ item_activated (model, path, impl); | |
+} | |
+ | |
+/* Callback used when a item in the icon file list is activated. */ | |
+static void | |
+icon_item_activated (GtkIconView *icon_view, | |
+ GtkTreePath *path, | |
+ GtkFileChooserWidget *impl) | |
+{ | |
+ GtkTreeModel *model; | |
+ model = gtk_icon_view_get_model (icon_view); | |
+ item_activated (model, path, impl); | |
+} | |
+ | |
+/* Common implementation for list_row_activated and icon_item_activated */ | |
+static void | |
+item_activated (GtkTreeModel *model, | |
+ GtkTreePath *path, | |
+ GtkFileChooserWidget *impl) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
GFile *file; | |
GtkTreeIter iter; | |
- GtkTreeModel *model; | |
gboolean is_folder; | |
gboolean is_sensitive; | |
- model = gtk_tree_view_get_model (tree_view); | |
- | |
if (!gtk_tree_model_get_iter (model, &iter, path)) | |
return; | |
@@ -7823,7 +8219,7 @@ list_row_activated (GtkTreeView *tree_view, | |
priv->action == GTK_FILE_CHOOSER_ACTION_SAVE) | |
g_signal_emit_by_name (impl, "file-activated"); | |
- out: | |
+ out: | |
if (file) | |
g_object_unref (file); | |
@@ -7854,10 +8250,13 @@ static void | |
update_cell_renderer_attributes (GtkFileChooserWidget *impl) | |
{ | |
GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ /* only applicable in the tree view (i.e. list view) */ | |
+ if (!priv->browse_files_tree_view) | |
+ return; | |
gtk_tree_view_column_set_attributes (priv->list_name_column, | |
priv->list_pixbuf_renderer, | |
- "surface", MODEL_COL_SURFACE, | |
+ "surface", MODEL_COL_LIST_SURFACE, | |
"sensitive", MODEL_COL_IS_SENSITIVE, | |
NULL); | |
gtk_tree_view_column_set_attributes (priv->list_name_column, | |
@@ -8433,16 +8832,20 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class) | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_widgets_hpaned); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_files_stack); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, places_sidebar); | |
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, view_notebook); | |
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_files_list_swin); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, places_view); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_files_tree_view); | |
- gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_files_swin); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_header_revealer); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_header_stack); | |
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_files_icon_swin); | |
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_files_icon_view); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_new_folder_button); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_path_bar_size_group); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, browse_path_bar); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, filter_combo_hbox); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, filter_combo); | |
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, icon_view_scale); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, preview_box); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, extra_align); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, extra_and_filters); | |
@@ -8459,6 +8862,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class) | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_size_renderer); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_location_column); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_location_renderer); | |
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_icon_renderer); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_name_entry); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_create_button); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, new_folder_error_label); | |
@@ -8468,6 +8872,7 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class) | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_error_label); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, rename_file_popover); | |
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, remote_warning_bar); | |
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, view_mode_combo_box); | |
/* And a *lot* of callbacks to bind ... */ | |
gtk_widget_class_bind_template_callback (widget_class, browse_files_key_press_event_cb); | |
@@ -8482,6 +8887,10 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class) | |
gtk_widget_class_bind_template_callback (widget_class, file_list_drag_end_cb); | |
gtk_widget_class_bind_template_callback (widget_class, list_selection_changed); | |
gtk_widget_class_bind_template_callback (widget_class, list_cursor_changed); | |
+ gtk_widget_class_bind_template_callback (widget_class, icon_item_activated); | |
+ gtk_widget_class_bind_template_callback (widget_class, icon_view_scale_value_changed_cb); | |
+ gtk_widget_class_bind_template_callback (widget_class, view_mode_combo_box_changed_cb); | |
+ gtk_widget_class_bind_template_callback (widget_class, view_notebook_switch_page_cb); | |
gtk_widget_class_bind_template_callback (widget_class, filter_combo_changed); | |
gtk_widget_class_bind_template_callback (widget_class, path_bar_clicked); | |
gtk_widget_class_bind_template_callback (widget_class, places_sidebar_open_location_cb); | |
@@ -8529,6 +8938,18 @@ post_process_ui (GtkFileChooserWidget *impl) | |
GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
gtk_drag_dest_add_uri_targets (impl->priv->browse_files_tree_view); | |
+ /* Setup file list iconview */ | |
+ gtk_icon_view_enable_model_drag_source (GTK_ICON_VIEW (impl->priv->browse_files_icon_view), | |
+ GDK_BUTTON1_MASK, | |
+ NULL, 0, | |
+ GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
+ gtk_drag_source_add_uri_targets (impl->priv->browse_files_icon_view); | |
+ gtk_drag_dest_set (impl->priv->browse_files_icon_view, | |
+ GTK_DEST_DEFAULT_ALL, | |
+ NULL, 0, | |
+ GDK_ACTION_COPY | GDK_ACTION_MOVE); | |
+ gtk_drag_dest_add_uri_targets (impl->priv->browse_files_icon_view); | |
+ | |
/* File browser treemodel columns are shared between GtkFileChooser implementations, | |
* so we don't set cell renderer attributes in GtkBuilder, but rather keep that | |
* in code. | |
@@ -8560,6 +8981,8 @@ post_process_ui (GtkFileChooserWidget *impl) | |
* that priv->icon_size be already setup. | |
*/ | |
set_icon_cell_renderer_fixed_size (impl); | |
+ | |
+ impl->priv->browse_files_current_view = impl->priv->browse_files_tree_view; | |
atk_obj = gtk_widget_get_accessible (impl->priv->browse_new_folder_button); | |
if (GTK_IS_ACCESSIBLE (atk_obj)) | |
@@ -8609,7 +9032,8 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl) | |
priv->select_multiple = FALSE; | |
priv->show_hidden = FALSE; | |
priv->show_size_column = TRUE; | |
- priv->icon_size = FALLBACK_ICON_SIZE; | |
+ priv->list_view_icon_size = FALLBACK_LIST_VIEW_ICON_SIZE; | |
+ priv->icon_view_icon_size = FALLBACK_ICON_VIEW_ICON_SIZE; | |
priv->load_state = LOAD_EMPTY; | |
priv->reload_state = RELOAD_EMPTY; | |
priv->pending_select_files = NULL; | |
@@ -8620,6 +9044,7 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl) | |
priv->recent_manager = gtk_recent_manager_get_default (); | |
priv->create_folders = TRUE; | |
priv->auto_selecting_first_row = FALSE; | |
+ priv->view_mode = VIEW_MODE_ICON; | |
/* Ensure GTK+ private types used by the template | |
* definition before calling gtk_widget_init_template() | |
@@ -8667,6 +9092,258 @@ gtk_file_chooser_widget_new (GtkFileChooserAction action) | |
NULL); | |
} | |
+static gboolean | |
+get_selected_tree_iter_from_icon_view (GtkFileChooserWidget *impl, | |
+ GtkTreeIter *iter_out) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GList *icon_selection; | |
+ GtkTreePath *icon_selection_path; | |
+ | |
+ icon_selection = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->browse_files_icon_view)); | |
+ if (!icon_selection) | |
+ return FALSE; | |
+ | |
+ icon_selection_path = g_list_nth_data (icon_selection, 0); | |
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->current_model), | |
+ iter_out, | |
+ icon_selection_path); | |
+ | |
+ g_list_foreach (icon_selection, (GFunc) gtk_tree_path_free, NULL); | |
+ g_list_free (icon_selection); | |
+ return TRUE; | |
+} | |
+ | |
+static void | |
+icon_view_selection_selected_foreach (GtkFileChooserWidget *impl, | |
+ GtkTreeSelectionForeachFunc func, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkTreeIter iter; | |
+ GList *icon_selection; | |
+ GList *elem; | |
+ GtkTreePath *icon_selection_path; | |
+ | |
+ icon_selection = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->browse_files_icon_view)); | |
+ for (elem = icon_selection; elem; elem = elem->next) | |
+ { | |
+ icon_selection_path = elem->data; | |
+ gtk_tree_model_get_iter (GTK_TREE_MODEL (priv->current_model), | |
+ &iter, | |
+ icon_selection_path); | |
+ (* func) (GTK_TREE_MODEL (priv->current_model), | |
+ icon_selection_path, | |
+ &iter, | |
+ data); | |
+ } | |
+ | |
+ g_list_foreach (icon_selection, (GFunc) gtk_tree_path_free, NULL); | |
+ g_list_free (icon_selection); | |
+} | |
+ | |
+static void | |
+selection_selected_foreach (GtkFileChooserWidget *impl, | |
+ ViewMode view, | |
+ GtkTreeSelectionForeachFunc func, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (priv->current_model == NULL) | |
+ return; | |
+ | |
+ if (view == VIEW_MODE_LIST) | |
+ { | |
+ GtkTreeSelection *selection; | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ gtk_tree_selection_selected_foreach (selection, func, data); | |
+ } | |
+ else if (view == VIEW_MODE_ICON) | |
+ icon_view_selection_selected_foreach (impl, func, data); | |
+ else | |
+ g_assert_not_reached (); | |
+} | |
+ | |
+static void | |
+current_selection_selected_foreach (GtkFileChooserWidget *impl, | |
+ GtkTreeSelectionForeachFunc func, | |
+ gpointer data) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ selection_selected_foreach (impl, priv->view_mode, func, data); | |
+} | |
+ | |
+static guint | |
+current_selection_count_selected_rows (GtkFileChooserWidget *impl) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ GtkTreeSelection *selection; | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ return gtk_tree_selection_count_selected_rows (selection); | |
+ } | |
+ if (priv->view_mode == VIEW_MODE_ICON) | |
+ { | |
+ GList *icon_selection; | |
+ icon_selection = gtk_icon_view_get_selected_items (GTK_ICON_VIEW (priv->browse_files_icon_view)); | |
+ guint count = g_list_length (icon_selection); | |
+ g_list_foreach (icon_selection, (GFunc) gtk_tree_path_free, NULL); | |
+ g_list_free (icon_selection); | |
+ return count; | |
+ } | |
+ g_assert_not_reached (); | |
+ return 0; | |
+} | |
+ | |
+static void | |
+selection_select_iter (GtkFileChooserWidget *impl, | |
+ GtkTreeIter *iter, | |
+ ViewMode target) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (target == VIEW_MODE_LIST) | |
+ { | |
+ GtkTreeSelection *selection; | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ gtk_tree_selection_select_iter (selection, iter); | |
+ } | |
+ else if (target == VIEW_MODE_ICON) | |
+ { | |
+ GtkTreePath *path; | |
+ path = gtk_tree_model_get_path (priv->current_model, iter); | |
+ gtk_icon_view_select_path (GTK_ICON_VIEW (priv->browse_files_icon_view), path); | |
+ gtk_tree_path_free (path); | |
+ } | |
+ else | |
+ g_assert_not_reached (); | |
+} | |
+ | |
+static void | |
+current_selection_select_iter (GtkFileChooserWidget *impl, | |
+ GtkTreeIter *iter) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ selection_select_iter (impl, iter, priv->view_mode); | |
+} | |
+ | |
+struct copy_old_selection_to_current_view_closure { | |
+ GtkFileChooserWidget *impl; | |
+}; | |
+ | |
+static void | |
+copy_old_selection_to_current_view_foreach_cp (GtkTreeModel *model, | |
+ GtkTreePath *path, | |
+ GtkTreeIter *iter, | |
+ gpointer data) | |
+{ | |
+ struct copy_old_selection_to_current_view_closure *closure; | |
+ closure = data; | |
+ selection_select_iter (closure->impl, iter, closure->impl->priv->view_mode); | |
+} | |
+ | |
+static void | |
+copy_old_selection_to_current_view (GtkFileChooserWidget *impl, | |
+ ViewMode old_view_mode) | |
+{ | |
+ struct copy_old_selection_to_current_view_closure closure; | |
+ closure.impl = impl; | |
+ | |
+ selection_selected_foreach(impl, | |
+ old_view_mode, | |
+ copy_old_selection_to_current_view_foreach_cp, | |
+ &closure); | |
+} | |
+ | |
+static void | |
+current_selection_unselect_iter (GtkFileChooserWidget *impl, | |
+ GtkTreeIter *iter) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ GtkTreeSelection *selection; | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ gtk_tree_selection_unselect_iter (selection, iter); | |
+ } | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ { | |
+ GtkTreePath *path; | |
+ path = gtk_tree_model_get_path (priv->current_model, iter); | |
+ gtk_icon_view_unselect_path (GTK_ICON_VIEW (priv->browse_files_icon_view), path); | |
+ gtk_tree_path_free (path); | |
+ } | |
+ else | |
+ g_assert_not_reached (); | |
+} | |
+ | |
+static void | |
+current_selection_unselect_all (GtkFileChooserWidget *impl) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ GtkTreeSelection *selection; | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ gtk_tree_selection_unselect_all (selection); | |
+ } | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ gtk_icon_view_unselect_all (GTK_ICON_VIEW (priv->browse_files_icon_view)); | |
+ else | |
+ g_assert_not_reached (); | |
+} | |
+ | |
+static void | |
+current_view_set_file_model (GtkFileChooserWidget *impl, GtkTreeModel *model) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkWidget *view; | |
+ | |
+ priv->current_model = model; | |
+ | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ view = priv->browse_files_tree_view; | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ view = priv->browse_files_icon_view; | |
+ else | |
+ g_assert_not_reached (); | |
+ | |
+ g_object_set (view, "model", priv->current_model, NULL); | |
+} | |
+ | |
+static void | |
+current_view_set_cursor (GtkFileChooserWidget *impl, GtkTreePath *path) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ gtk_tree_view_set_cursor (GTK_TREE_VIEW (priv->browse_files_tree_view), path, NULL, FALSE); | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ gtk_icon_view_set_cursor (GTK_ICON_VIEW (priv->browse_files_icon_view), path, NULL, FALSE); | |
+ else | |
+ g_assert_not_reached (); | |
+} | |
+ | |
+static void | |
+current_view_set_select_multiple (GtkFileChooserWidget *impl, gboolean select_multiple) | |
+{ | |
+ GtkFileChooserWidgetPrivate *priv = impl->priv; | |
+ GtkTreeSelection *selection; | |
+ GtkSelectionMode mode; | |
+ | |
+ mode = select_multiple ? GTK_SELECTION_MULTIPLE : GTK_SELECTION_BROWSE; | |
+ | |
+ if (priv->view_mode == VIEW_MODE_LIST) | |
+ { | |
+ selection = gtk_tree_view_get_selection (GTK_TREE_VIEW (priv->browse_files_tree_view)); | |
+ gtk_tree_selection_set_mode (selection, mode); | |
+ gtk_tree_view_set_rubber_banding (GTK_TREE_VIEW (priv->browse_files_tree_view), select_multiple); | |
+ } | |
+ else if (priv->view_mode == VIEW_MODE_ICON) | |
+ gtk_icon_view_set_selection_mode (GTK_ICON_VIEW (priv->browse_files_icon_view), mode); | |
+ else | |
+ g_assert_not_reached (); | |
+} | |
+ | |
static void | |
gtk_file_chooser_widget_add_choice (GtkFileChooser *chooser, | |
const char *id, | |
@@ -8719,7 +9396,7 @@ gtk_file_chooser_widget_add_choice (GtkFileChooser *chooser, | |
widget = check; | |
} | |
- gtk_widget_show_all (widget); | |
+ gtk_widget_show_all (widget); | |
gtk_container_add (GTK_CONTAINER (priv->choice_box), widget); | |
} | |
@@ -8786,4 +9463,3 @@ gtk_file_chooser_widget_get_choice (GtkFileChooser *chooser, | |
return NULL; | |
} | |
- | |
diff --git a/gtk/org.gtk.Settings.FileChooser.gschema.xml b/gtk/org.gtk.Settings.FileChooser.gschema.xml | |
index c3753f2f6a..e35a9c7cb0 100644 | |
--- a/gtk/org.gtk.Settings.FileChooser.gschema.xml | |
+++ b/gtk/org.gtk.Settings.FileChooser.gschema.xml | |
@@ -43,6 +43,11 @@ | |
<value nick='12h' value='1'/> | |
</enum> | |
+ <enum id='org.gtk.Settings.FileChooser.ViewMode'> | |
+ <value nick='list-view' value='0'/> | |
+ <value nick='icon-view' value='1'/> | |
+ </enum> | |
+ | |
<enum id='org.gtk.Settings.FileChooser.DateFormat'> | |
<value nick='regular' value='0'/> | |
<value nick='with-time' value='1'/> | |
@@ -61,6 +66,20 @@ | |
possible values for these modes are "path-bar" and "filename-entry". | |
</description> | |
</key> | |
+ <key name='view-mode' enum='org.gtk.Settings.FileChooser.ViewMode'> | |
+ <default>'list-view'</default> | |
+ <summary>Change view mode</summary> | |
+ <description> | |
+ Controls the view mode used. | |
+ </description> | |
+ </key> | |
+ <key name='icon-view-scale' type='i'> | |
+ <default>32</default> | |
+ <summary>Change icon size</summary> | |
+ <description> | |
+ Controls the size of the icons in icon view mode. | |
+ </description> | |
+ </key> | |
<key name='show-hidden' type='b'> | |
<default>false</default> | |
<summary>Show hidden files</summary> | |
diff --git a/gtk/ui/gtkfilechooserwidget.ui b/gtk/ui/gtkfilechooserwidget.ui | |
index ef227bdc70..ebd9f0af47 100644 | |
--- a/gtk/ui/gtkfilechooserwidget.ui | |
+++ b/gtk/ui/gtkfilechooserwidget.ui | |
@@ -8,6 +8,56 @@ | |
<object class="GtkBox" id="browse_widgets_box"> | |
<property name="visible">1</property> | |
<property name="orientation">vertical</property> | |
+ <child> | |
+ <object class="GtkBox" id="combo_box_and_scale"> | |
+ <property name="visible">1</property> | |
+ <child> | |
+ <object class="GtkComboBoxText" id="view_mode_combo_box"> | |
+ <items> | |
+ <item translatable="yes" id="browse_files_tree_view">List View</item> | |
+ <item translatable="yes" id="browse_files_icon_view">Icon View</item> | |
+ </items> | |
+ <property name="active">0</property> | |
+ <property name="visible">1</property> | |
+ <property name="tooltip-text" translatable="yes">Select filechooser view</property> | |
+ <property name="halign">start</property> | |
+ <property name="valign">start</property> | |
+ <!-- <property name="has-entry">True</property> --> | |
+ <signal name="changed" handler="view_mode_combo_box_changed_cb" swapped="no"/> | |
+ </object> | |
+ <packing> | |
+ <property name="position">0</property> | |
+ <property name="pack-type">start</property> | |
+ </packing> | |
+ </child> | |
+ <child> | |
+ <object class="GtkAdjustment" id="icon_view_icon_size"> | |
+ <property name="upper">256</property> | |
+ <property name="lower">32</property> | |
+ <property name="value">32</property> | |
+ <property name="step_increment">16</property> | |
+ </object> | |
+ </child> | |
+ <child> | |
+ <object class="GtkScale" id="icon_view_scale"> | |
+ <property name="visible">0</property> | |
+ <property name="orientation">horizontal</property> | |
+ <property name="adjustment">icon_view_icon_size</property> | |
+ <property name="can_focus">1</property> | |
+ <property name="halign">end</property> | |
+ <property name="valign">fill</property> | |
+ <property name="margin_right">10</property> | |
+ <property name="width-request">100</property> | |
+ <property name="draw_value">False</property> | |
+ <signal name="value-changed" handler="icon_view_scale_value_changed_cb" swapped="no"/> | |
+ </object> | |
+ <packing> | |
+ <property name="position">1</property> | |
+ <property name="pack-type">end</property> | |
+ </packing> | |
+ </child> | |
+ </object> | |
+ </child> | |
<child> | |
<object class="GtkPaned" id="browse_widgets_hpaned"> | |
<property name="visible">1</property> | |
@@ -155,98 +205,160 @@ | |
<property name="visible">1</property> | |
<property name="orientation">vertical</property> | |
<child> | |
- <object class="GtkScrolledWindow" id="browse_files_swin"> | |
+ <object class="GtkNotebook" id="view_notebook"> | |
<property name="visible">1</property> | |
- <property name="hscrollbar-policy">never</property> | |
+ <property name="show-tabs">False</property> | |
+ <signal name="switch-page" handler="view_notebook_switch_page_cb" swapped="no"/> | |
<child> | |
- <object class="GtkTreeView" id="browse_files_tree_view"> | |
+ <object class="GtkScrolledWindow" id="browse_files_list_swin"> | |
<property name="visible">1</property> | |
- <property name="has-tooltip">1</property> | |
- <property name="enable-search">0</property> | |
- <child internal-child="accessible"> | |
- <object class="AtkObject" id="browse_files_tree_view-atkobject"> | |
- <property name="AtkObject::accessible-name" translatable="yes">Files</property> | |
- </object> | |
- </child> | |
- <signal name="button-press-event" handler="list_button_press_event_cb" swapped="no"/> | |
- <signal name="drag-data-received" handler="file_list_drag_data_received_cb" swapped="no"/> | |
- <signal name="drag-drop" handler="file_list_drag_drop_cb" swapped="no"/> | |
- <signal name="drag-begin" handler="file_list_drag_begin_cb" swapped="no"/> | |
- <signal name="drag-motion" handler="file_list_drag_motion_cb" swapped="no"/> | |
- <signal name="drag-end" handler="file_list_drag_end_cb" swapped="no"/> | |
- <signal name="key-press-event" handler="browse_files_key_press_event_cb" swapped="no"/> | |
- <signal name="popup-menu" handler="list_popup_menu_cb" swapped="no"/> | |
- <signal name="query-tooltip" handler="file_list_query_tooltip_cb" swapped="no"/> | |
- <signal name="row-activated" handler="list_row_activated" swapped="no"/> | |
- <signal name="cursor-changed" handler="list_cursor_changed" swapped="no"/> | |
- <child internal-child="selection"> | |
- <object class="GtkTreeSelection" id="treeview-selection2"> | |
- <signal name="changed" handler="list_selection_changed" swapped="no"/> | |
- </object> | |
- </child> | |
+ <property name="hscrollbar_policy">never</property> | |
<child> | |
- <object class="GtkTreeViewColumn" id="list_name_column"> | |
- <property name="title" translatable="yes">Name</property> | |
- <property name="resizable">1</property> | |
- <property name="expand">1</property> | |
+ <object class="GtkTreeView" id="browse_files_tree_view"> | |
+ <property name="visible">True</property> | |
+ <property name="can_focus">True</property> | |
+ <property name="has_tooltip">True</property> | |
+ <property name="enable_search">False</property> | |
+ <signal name="button-press-event" handler="list_button_press_event_cb" swapped="no"/> | |
+ <signal name="cursor-changed" handler="list_cursor_changed" swapped="no"/> | |
+ <signal name="drag-data-received" handler="file_list_drag_data_received_cb" swapped="no"/> | |
+ <signal name="drag-drop" handler="file_list_drag_drop_cb" swapped="no"/> | |
+ <signal name="drag-motion" handler="file_list_drag_motion_cb" swapped="no"/> | |
+ <signal name="key-press-event" handler="browse_files_key_press_event_cb" swapped="no"/> | |
+ <signal name="popup-menu" handler="list_popup_menu_cb" swapped="no"/> | |
+ <signal name="query-tooltip" handler="file_list_query_tooltip_cb" swapped="no"/> | |
+ <signal name="row-activated" handler="list_row_activated" swapped="no"/> | |
+ <child internal-child="selection"> | |
+ <object class="GtkTreeSelection" id="treeview-selection2"> | |
+ <signal name="changed" handler="list_selection_changed" swapped="no"/> | |
+ </object> | |
+ </child> | |
<child> | |
- <object class="GtkCellRendererPixbuf" id="list_pixbuf_renderer"> | |
- <property name="xpad">6</property> | |
+ <object class="GtkTreeViewColumn" id="list_name_column"> | |
+ <property name="resizable">True</property> | |
+ <property name="title" translatable="yes">Name</property> | |
+ <property name="expand">True</property> | |
+ <child> | |
+ <object class="GtkCellRendererPixbuf" id="list_pixbuf_renderer"> | |
+ <property name="xpad">6</property> | |
+ </object> | |
+ </child> | |
+ <child> | |
+ <object class="GtkCellRendererText" id="list_name_renderer"> | |
+ <property name="width-chars">10</property> | |
+ <property name="ellipsize">end</property> | |
+ </object> | |
+ </child> | |
</object> | |
</child> | |
<child> | |
- <object class="GtkCellRendererText" id="list_name_renderer"> | |
- <property name="width-chars">10</property> | |
- <property name="ellipsize">end</property> | |
+ <object class="GtkTreeViewColumn" id="list_location_column"> | |
+ <property name="title" translatable="yes">Location</property> | |
+ <property name="resizable">1</property> | |
+ <property name="visible">0</property> | |
+ <property name="expand">1</property> | |
+ <child> | |
+ <object class="GtkCellRendererText" id="list_location_renderer"> | |
+ <property name="xalign">0</property> | |
+ <property name="width-chars">10</property> | |
+ <property name="ellipsize">start</property> | |
+ <property name="xpad">6</property> | |
+ </object> | |
+ </child> | |
</object> | |
</child> | |
- </object> | |
- </child> | |
- <child> | |
- <object class="GtkTreeViewColumn" id="list_location_column"> | |
- <property name="title" translatable="yes">Location</property> | |
- <property name="resizable">1</property> | |
- <property name="visible">0</property> | |
- <property name="expand">1</property> | |
<child> | |
- <object class="GtkCellRendererText" id="list_location_renderer"> | |
- <property name="xalign">0</property> | |
- <property name="width-chars">10</property> | |
- <property name="ellipsize">start</property> | |
- <property name="xpad">6</property> | |
+ <object class="GtkTreeViewColumn" id="list_size_column"> | |
+ <property name="title" translatable="yes">Size</property> | |
+ <property name="sizing">fixed</property> | |
+ <child> | |
+ <object class="GtkCellRendererText" id="list_size_renderer"> | |
+ <property name="xalign">0</property> | |
+ <property name="xpad">6</property> | |
+ </object> | |
+ </child> | |
</object> | |
</child> | |
- </object> | |
- </child> | |
- <child> | |
- <object class="GtkTreeViewColumn" id="list_size_column"> | |
- <property name="title" translatable="yes">Size</property> | |
- <property name="sizing">fixed</property> | |
<child> | |
- <object class="GtkCellRendererText" id="list_size_renderer"> | |
- <property name="xalign">0</property> | |
- <property name="xpad">6</property> | |
+ <object class="GtkTreeViewColumn" id="list_time_column"> | |
+ <property name="title" translatable="yes">Modified</property> | |
+ <property name="sizing">fixed</property> | |
+ <child> | |
+ <object class="GtkCellRendererText" id="list_date_renderer"> | |
+ <property name="xpad">6</property> | |
+ </object> | |
+ </child> | |
+ <child> | |
+ <object class="GtkCellRendererText" id="list_time_renderer"> | |
+ <property name="xpad">6</property> | |
+ </object> | |
+ </child> | |
</object> | |
</child> | |
</object> | |
</child> | |
+ </object> | |
+ </child> | |
+ <child type="tab"> | |
+ <object class="GtkLabel" id="label_list_view"> | |
+ <property name="visible">True</property> | |
+ <property name="can_focus">False</property> | |
+ <property name="label" translatable="yes">List View</property> | |
+ </object> | |
+ <packing> | |
+ <property name="tab_fill">False</property> | |
+ </packing> | |
+ </child> | |
+ <child> | |
+ <object class="GtkScrolledWindow" id="browse_files_icon_swin"> | |
+ <property name="visible">True</property> | |
+ <property name="can_focus">True</property> | |
+ <property name="shadow_type">in</property> | |
+ <property name="hscrollbar-policy">GTK_POLICY_AUTOMATIC</property> | |
<child> | |
- <object class="GtkTreeViewColumn" id="list_time_column"> | |
- <property name="title" translatable="yes">Modified</property> | |
- <property name="sizing">fixed</property> | |
+ <object class="GtkIconView" id="browse_files_icon_view"> | |
+ <property name="visible">True</property> | |
+ <property name="can_focus">True</property> | |
+ <property name="has_tooltip">True</property> | |
+ <property name="column-spacing">2</property> | |
+ <signal name="button-press-event" handler="list_button_press_event_cb" swapped="no"/> | |
+ <signal name="drag-data-received" handler="file_list_drag_data_received_cb" swapped="no"/> | |
+ <signal name="drag-drop" handler="file_list_drag_drop_cb" swapped="no"/> | |
+ <signal name="item-activated" handler="icon_item_activated" swapped="no"/> | |
+ <signal name="key-press-event" handler="browse_files_key_press_event_cb" swapped="no"/> | |
+ <signal name="popup-menu" handler="list_popup_menu_cb" swapped="no"/> | |
+ <signal name="query-tooltip" handler="file_list_query_tooltip_cb" swapped="no"/> | |
+ <signal name="selection-changed" handler="list_selection_changed" swapped="no"/> | |
<child> | |
- <object class="GtkCellRendererText" id="list_date_renderer"> | |
- <property name="xpad">6</property> | |
+ <object class="GtkCellRendererText" id="list_icon_renderer"> | |
</object> | |
</child> | |
<child> | |
- <object class="GtkCellRendererText" id="list_time_renderer"> | |
- <property name="xpad">6</property> | |
- </object> | |
+ <object class="GtkCellRendererPixbuf" id="icon_view_pixbuf_renderer"/> | |
</child> | |
</object> | |
</child> | |
</object> | |
+ <packing> | |
+ <property name="position">1</property> | |
+ </packing> | |
+ </child> | |
+ <child type="tab"> | |
+ <object class="GtkLabel" id="label_icon_view"> | |
+ <property name="visible">True</property> | |
+ <property name="can_focus">False</property> | |
+ <property name="label" translatable="yes">Icon View</property> | |
+ </object> | |
+ <packing> | |
+ <property name="position">1</property> | |
+ <property name="tab_fill">False</property> | |
+ </packing> | |
+ </child> | |
+ <child> | |
+ <placeholder/> | |
+ </child> | |
+ <child type="tab"> | |
+ <placeholder/> | |
</child> | |
</object> | |
<packing> | |
@@ -365,7 +477,7 @@ | |
</object> | |
<packing> | |
<property name="expand">1</property> | |
- <property name="position">1</property> | |
+ <property name="position">2</property> | |
</packing> | |
</child> | |
</object> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment