summaryrefslogtreecommitdiff
path: root/gtk
diff options
context:
space:
mode:
Diffstat (limited to 'gtk')
-rw-r--r--gtk/gtkfilechooserprivate.h2
-rw-r--r--gtk/gtkfilechooserwidget.c186
-rw-r--r--gtk/org.gtk.gtk4.Settings.FileChooser.gschema.xml27
-rw-r--r--gtk/ui/gtkfilechooserwidget.ui12
4 files changed, 225 insertions, 2 deletions
diff --git a/gtk/gtkfilechooserprivate.h b/gtk/gtkfilechooserprivate.h
index c16fac3174..6379e0ab60 100644
--- a/gtk/gtkfilechooserprivate.h
+++ b/gtk/gtkfilechooserprivate.h
@@ -38,6 +38,7 @@ G_BEGIN_DECLS
#define SETTINGS_KEY_LOCATION_MODE "location-mode"
#define SETTINGS_KEY_SHOW_HIDDEN "show-hidden"
#define SETTINGS_KEY_SHOW_SIZE_COLUMN "show-size-column"
+#define SETTINGS_KEY_SHOW_TYPE_COLUMN "show-type-column"
#define SETTINGS_KEY_SORT_COLUMN "sort-column"
#define SETTINGS_KEY_SORT_ORDER "sort-order"
#define SETTINGS_KEY_WINDOW_SIZE "window-size"
@@ -46,6 +47,7 @@ G_BEGIN_DECLS
#define SETTINGS_KEY_SORT_DIRECTORIES_FIRST "sort-directories-first"
#define SETTINGS_KEY_CLOCK_FORMAT "clock-format"
#define SETTINGS_KEY_DATE_FORMAT "date-format"
+#define SETTINGS_KEY_TYPE_FORMAT "type-format"
#define GTK_FILE_CHOOSER_GET_IFACE(inst) (G_TYPE_INSTANCE_GET_INTERFACE ((inst), GTK_TYPE_FILE_CHOOSER, GtkFileChooserIface))
diff --git a/gtk/gtkfilechooserwidget.c b/gtk/gtkfilechooserwidget.c
index 9c40a24fce..c419e16d9c 100644
--- a/gtk/gtkfilechooserwidget.c
+++ b/gtk/gtkfilechooserwidget.c
@@ -221,6 +221,12 @@ struct _GtkFileChooserWidgetClass
GtkWidgetClass parent_class;
};
+typedef enum {
+ TYPE_FORMAT_MIME,
+ TYPE_FORMAT_DESCRIPTION,
+ TYPE_FORMAT_CATEGORY
+} TypeFormat;
+
struct _GtkFileChooserWidgetPrivate {
GtkFileChooserAction action;
@@ -247,6 +253,7 @@ struct _GtkFileChooserWidgetPrivate {
GtkWidget *add_shortcut_item;
GtkWidget *hidden_files_item;
GtkWidget *size_column_item;
+ GtkWidget *type_column_item;
GtkWidget *copy_file_location_item;
GtkWidget *visit_file_item;
GtkWidget *open_folder_item;
@@ -339,6 +346,8 @@ struct _GtkFileChooserWidgetPrivate {
GtkCellRenderer *list_time_renderer;
GtkTreeViewColumn *list_size_column;
GtkCellRenderer *list_size_renderer;
+ GtkTreeViewColumn *list_type_column;
+ GtkCellRenderer *list_type_renderer;
GtkTreeViewColumn *list_location_column;
GtkCellRenderer *list_location_renderer;
@@ -357,6 +366,8 @@ struct _GtkFileChooserWidgetPrivate {
ClockFormat clock_format;
+ TypeFormat type_format;
+
/* Flags */
guint local_only : 1;
@@ -371,6 +382,7 @@ struct _GtkFileChooserWidgetPrivate {
guint list_sort_ascending : 1;
guint shortcuts_current_folder_active : 1;
guint show_size_column : 1;
+ guint show_type_column : 1;
guint create_folders : 1;
guint auto_selecting_first_row : 1;
guint starting_search : 1;
@@ -406,9 +418,10 @@ static guint signals[LAST_SIGNAL] = { 0 };
"access::can-rename,access::can-delete,access::can-trash," \
"standard::target-uri"
enum {
- /* the first 3 must be these due to settings caching sort column */
+ /* the first 4 must be these due to settings caching sort column */
MODEL_COL_NAME,
MODEL_COL_SIZE,
+ MODEL_COL_TYPE,
MODEL_COL_TIME,
MODEL_COL_FILE,
MODEL_COL_NAME_COLLATED,
@@ -428,6 +441,7 @@ enum {
MODEL_COL_NUM_COLUMNS, \
G_TYPE_STRING, /* MODEL_COL_NAME */ \
G_TYPE_INT64, /* MODEL_COL_SIZE */ \
+ G_TYPE_STRING, /* MODEL_COL_TYPE */ \
G_TYPE_LONG, /* MODEL_COL_TIME */ \
G_TYPE_FILE, /* MODEL_COL_FILE */ \
G_TYPE_STRING, /* MODEL_COL_NAME_COLLATED */ \
@@ -1727,6 +1741,22 @@ change_show_size_state (GSimpleAction *action,
priv->show_size_column);
}
+/* Callback used when the "Show Type Column" menu item is toggled */
+static void
+change_show_type_state (GSimpleAction *action,
+ GVariant *state,
+ gpointer data)
+{
+ GtkFileChooserWidget *impl = data;
+ GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
+
+ g_simple_action_set_state (action, state);
+ priv->show_type_column = g_variant_get_boolean (state);
+
+ gtk_tree_view_column_set_visible (priv->list_type_column,
+ priv->show_type_column);
+}
+
static void
change_sort_directories_first_state (GSimpleAction *action,
GVariant *state,
@@ -2093,6 +2123,7 @@ static GActionEntry entries[] = {
{ "trash", trash_file_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-type", NULL, NULL, "false", change_show_type_state },
{ "toggle-show-time", NULL, NULL, "false", change_show_time_state },
{ "toggle-sort-dirs-first", NULL, NULL, "false", change_sort_directories_first_state }
};
@@ -2172,6 +2203,7 @@ file_list_build_popover (GtkFileChooserWidget *impl)
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->type_column_item = add_button (box, _("Show T_ype Column"), "item.toggle-show-type");
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");
}
@@ -2207,6 +2239,9 @@ file_list_update_popover (GtkFileChooserWidget *impl)
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-show-size");
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->show_size_column));
+ action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-show-type");
+ g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->show_type_column));
+
action = g_action_map_lookup_action (G_ACTION_MAP (priv->item_actions), "toggle-show-time");
g_simple_action_set_state (G_SIMPLE_ACTION (action), g_variant_new_boolean (priv->show_time));
@@ -2345,6 +2380,7 @@ file_list_set_sort_column_ids (GtkFileChooserWidget *impl)
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_type_column, MODEL_COL_TYPE);
gtk_tree_view_column_set_sort_column_id (priv->list_location_column, MODEL_COL_LOCATION_TEXT);
}
@@ -3657,8 +3693,10 @@ settings_load (GtkFileChooserWidget *impl)
GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
gboolean show_hidden;
gboolean show_size_column;
+ gboolean show_type_column;
gboolean sort_directories_first;
DateFormat date_format;
+ TypeFormat type_format;
gint sort_column;
GtkSortType sort_order;
StartupMode startup_mode;
@@ -3669,17 +3707,21 @@ settings_load (GtkFileChooserWidget *impl)
show_hidden = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_HIDDEN);
show_size_column = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_SIZE_COLUMN);
+ show_type_column = g_settings_get_boolean (settings, SETTINGS_KEY_SHOW_TYPE_COLUMN);
sort_column = g_settings_get_enum (settings, SETTINGS_KEY_SORT_COLUMN);
sort_order = g_settings_get_enum (settings, SETTINGS_KEY_SORT_ORDER);
sidebar_width = g_settings_get_int (settings, SETTINGS_KEY_SIDEBAR_WIDTH);
startup_mode = g_settings_get_enum (settings, SETTINGS_KEY_STARTUP_MODE);
sort_directories_first = g_settings_get_boolean (settings, SETTINGS_KEY_SORT_DIRECTORIES_FIRST);
date_format = g_settings_get_enum (settings, SETTINGS_KEY_DATE_FORMAT);
+ type_format = g_settings_get_enum (settings, SETTINGS_KEY_TYPE_FORMAT);
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);
+ priv->show_type_column = show_type_column;
+ gtk_tree_view_column_set_visible (priv->list_type_column, show_type_column);
priv->sort_column = sort_column;
priv->sort_order = sort_order;
@@ -3687,6 +3729,7 @@ settings_load (GtkFileChooserWidget *impl)
priv->sort_directories_first = sort_directories_first;
priv->show_time = date_format == DATE_FORMAT_WITH_TIME;
priv->clock_format = g_settings_get_enum (settings, "clock-format");
+ priv->type_format = type_format;
/* We don't call set_sort_column() here as the models may not have been
* created yet. The individual functions that create and set the models will
@@ -3719,12 +3762,14 @@ settings_save (GtkFileChooserWidget *impl)
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);
+ g_settings_set_boolean (settings, SETTINGS_KEY_SHOW_TYPE_COLUMN, priv->show_type_column);
g_settings_set_boolean (settings, SETTINGS_KEY_SORT_DIRECTORIES_FIRST, priv->sort_directories_first);
g_settings_set_enum (settings, SETTINGS_KEY_SORT_COLUMN, priv->sort_column);
g_settings_set_enum (settings, SETTINGS_KEY_SORT_ORDER, priv->sort_order);
g_settings_set_int (settings, SETTINGS_KEY_SIDEBAR_WIDTH,
gtk_paned_get_position (GTK_PANED (priv->browse_widgets_hpaned)));
g_settings_set_enum (settings, SETTINGS_KEY_DATE_FORMAT, priv->show_time ? DATE_FORMAT_WITH_TIME : DATE_FORMAT_REGULAR);
+ g_settings_set_enum (settings, SETTINGS_KEY_TYPE_FORMAT, priv->type_format);
/* Now apply the settings */
g_settings_apply (settings);
@@ -3977,6 +4022,20 @@ compare_size (GtkFileSystemModel *model,
}
static gint
+compare_type (GtkFileSystemModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ GtkFileChooserWidget *impl)
+{
+ const char *key_a, *key_b;
+
+ key_a = g_value_get_string (_gtk_file_system_model_get_value (model, a, MODEL_COL_TYPE));
+ key_b = g_value_get_string (_gtk_file_system_model_get_value (model, b, MODEL_COL_TYPE));
+
+ return g_strcmp0 (key_a, key_b);
+}
+
+static gint
compare_time (GtkFileSystemModel *model,
GtkTreeIter *a,
GtkTreeIter *b,
@@ -4042,6 +4101,25 @@ size_sort_func (GtkTreeModel *model,
return result;
}
+/* Sort callback for the type column */
+static gint
+type_sort_func (GtkTreeModel *model,
+ GtkTreeIter *a,
+ GtkTreeIter *b,
+ gpointer user_data)
+{
+ GtkFileSystemModel *fs_model = GTK_FILE_SYSTEM_MODEL (model);
+ GtkFileChooserWidget *impl = user_data;
+ gint result;
+
+ result = compare_directory (fs_model, a, b, impl);
+
+ if (result == 0)
+ result = compare_type (fs_model, a, b, impl);
+
+ return result;
+}
+
/* Sort callback for the time column */
static gint
time_sort_func (GtkTreeModel *model,
@@ -4692,6 +4770,93 @@ file_system_model_got_thumbnail (GObject *object,
g_object_unref (queried);
}
+/* Copied from src/nautilus_file.c:get_description() */
+struct {
+ const char *icon_name;
+ const char *display_name;
+} mime_type_map[] = {
+ { "application-x-executable", N_("Program") },
+ { "audio-x-generic", N_("Audio") },
+ { "font-x-generic", N_("Font") },
+ { "image-x-generic", N_("Image") },
+ { "package-x-generic", N_("Archive") },
+ { "text-html", N_("Markup") },
+ { "text-x-generic", N_("Text") },
+ { "text-x-generic-template", N_("Text") },
+ { "text-x-script", N_("Program") },
+ { "video-x-generic", N_("Video") },
+ { "x-office-address-book", N_("Contacts") },
+ { "x-office-calendar", N_("Calendar") },
+ { "x-office-document", N_("Document") },
+ { "x-office-presentation", N_("Presentation") },
+ { "x-office-spreadsheet", N_("Spreadsheet") },
+};
+
+static char *
+get_category_from_content_type (const char *content_type)
+{
+ char *icon_name;
+ char *basic_type = NULL;
+
+ icon_name = g_content_type_get_generic_icon_name (content_type);
+ if (icon_name != NULL)
+ {
+ int i;
+
+ for (i = 0; i < G_N_ELEMENTS (mime_type_map); i++)
+ {
+ if (strcmp (mime_type_map[i].icon_name, icon_name) == 0)
+ {
+ basic_type = g_strdup (gettext (mime_type_map[i].display_name));
+ break;
+ }
+ }
+
+ g_free (icon_name);
+ }
+
+ if (basic_type == NULL)
+ {
+ basic_type = g_content_type_get_description (content_type);
+ if (basic_type == NULL)
+ {
+ basic_type = g_strdup (_("Unknown"));
+ }
+ }
+
+ return basic_type;
+}
+
+static char *
+get_type_information (GtkFileChooserWidget *impl,
+ GFileInfo *info)
+{
+ const char *content_type;
+ char *mime_type;
+ char *description;
+
+ GtkFileChooserWidgetPrivate *priv = gtk_file_chooser_widget_get_instance_private (impl);
+ content_type = g_file_info_get_content_type (info);
+ switch (priv->type_format)
+ {
+ case TYPE_FORMAT_MIME:
+ mime_type = g_content_type_get_mime_type (content_type);
+ return mime_type ? mime_type : g_strdup (content_type);
+
+ case TYPE_FORMAT_DESCRIPTION:
+ description = g_content_type_get_description (content_type);
+ return description ? description : g_strdup (content_type);
+
+ case TYPE_FORMAT_CATEGORY:
+ return get_category_from_content_type (content_type);
+
+ default:
+ g_assert_not_reached ();
+ }
+
+ return g_strdup ("");
+}
+
static gboolean
file_system_model_set (GtkFileSystemModel *model,
GFile *file,
@@ -4819,6 +4984,12 @@ file_system_model_set (GtkFileSystemModel *model,
else
g_value_take_string (value, g_format_size (g_file_info_get_size (info)));
break;
+ case MODEL_COL_TYPE:
+ if (info == NULL || _gtk_file_info_consider_as_directory (info))
+ g_value_set_string (value, NULL);
+ else
+ g_value_take_string (value, get_type_information (impl, info));
+ break;
case MODEL_COL_TIME:
case MODEL_COL_DATE_TEXT:
case MODEL_COL_TIME_TEXT:
@@ -4931,6 +5102,7 @@ set_list_model (GtkFileChooserWidget *impl,
profile_msg (" set sort function", NULL);
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_NAME, name_sort_func, impl, NULL);
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_SIZE, size_sort_func, impl, NULL);
+ gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_TYPE, type_sort_func, impl, NULL);
gtk_tree_sortable_set_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), MODEL_COL_TIME, time_sort_func, impl, NULL);
gtk_tree_sortable_set_default_sort_func (GTK_TREE_SORTABLE (priv->browse_files_model), NULL, NULL, NULL);
set_sort_column (impl);
@@ -7054,6 +7226,7 @@ search_setup_model (GtkFileChooserWidget *impl)
gtk_tree_view_column_set_sort_column_id (priv->list_name_column, -1);
gtk_tree_view_column_set_sort_column_id (priv->list_time_column, -1);
gtk_tree_view_column_set_sort_column_id (priv->list_size_column, -1);
+ gtk_tree_view_column_set_sort_column_id (priv->list_type_column, -1);
gtk_tree_view_column_set_sort_column_id (priv->list_location_column, -1);
update_columns (impl, TRUE, _("Modified"));
@@ -7271,6 +7444,7 @@ recent_idle_cleanup (gpointer data)
gtk_tree_view_column_set_sort_column_id (priv->list_name_column, -1);
gtk_tree_view_column_set_sort_column_id (priv->list_time_column, -1);
gtk_tree_view_column_set_sort_column_id (priv->list_size_column, -1);
+ gtk_tree_view_column_set_sort_column_id (priv->list_type_column, -1);
gtk_tree_view_column_set_sort_column_id (priv->list_location_column, -1);
update_columns (impl, TRUE, _("Accessed"));
@@ -7712,6 +7886,12 @@ update_cell_renderer_attributes (GtkFileChooserWidget *impl)
"sensitive", MODEL_COL_IS_SENSITIVE,
NULL);
+ gtk_tree_view_column_set_attributes (priv->list_type_column,
+ priv->list_type_renderer,
+ "text", MODEL_COL_TYPE,
+ "sensitive", MODEL_COL_IS_SENSITIVE,
+ NULL);
+
gtk_tree_view_column_set_attributes (priv->list_time_column,
priv->list_date_renderer,
"text", MODEL_COL_DATE_TEXT,
@@ -8296,6 +8476,8 @@ gtk_file_chooser_widget_class_init (GtkFileChooserWidgetClass *class)
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_time_renderer);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_size_column);
gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_size_renderer);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_type_column);
+ gtk_widget_class_bind_template_child_private (widget_class, GtkFileChooserWidget, list_type_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, new_folder_name_entry);
@@ -8446,6 +8628,8 @@ gtk_file_chooser_widget_init (GtkFileChooserWidget *impl)
priv->select_multiple = FALSE;
priv->show_hidden = FALSE;
priv->show_size_column = TRUE;
+ priv->show_type_column = TRUE;
+ priv->type_format = TYPE_FORMAT_MIME;
priv->load_state = LOAD_EMPTY;
priv->reload_state = RELOAD_EMPTY;
priv->pending_select_files = NULL;
diff --git a/gtk/org.gtk.gtk4.Settings.FileChooser.gschema.xml b/gtk/org.gtk.gtk4.Settings.FileChooser.gschema.xml
index 2db786b236..985b9dda80 100644
--- a/gtk/org.gtk.gtk4.Settings.FileChooser.gschema.xml
+++ b/gtk/org.gtk.gtk4.Settings.FileChooser.gschema.xml
@@ -25,7 +25,8 @@
<enum id='org.gtk.gtk4.Settings.FileChooser.SortColumn'>
<value nick='name' value='0'/>
<value nick='size' value='1'/>
- <value nick='modified' value='2'/>
+ <value nick='type' value='2'/>
+ <value nick='modified' value='3'/>
</enum>
<enum id='org.gtk.gtk4.Settings.FileChooser.SortOrder'>
@@ -48,6 +49,12 @@
<value nick='with-time' value='1'/>
</enum>
+ <enum id='org.gtk.gtk4.Settings.FileChooser.TypeFormat'>
+ <value nick='mime' value='0'/>
+ <value nick='description' value='1'/>
+ <value nick='category' value='2'/>
+ </enum>
+
<schema id='org.gtk.gtk4.Settings.FileChooser' path='/org/gtk/gtk4/settings/file-chooser/'>
<key name='last-folder-uri' type='s'>
<default>""</default>
@@ -87,6 +94,13 @@
Controls whether the file chooser shows a column with file sizes.
</description>
</key>
+ <key name='show-type-column' type='b'>
+ <default>true</default>
+ <summary>Show file types</summary>
+ <description>
+ Controls whether the file chooser shows a column with file types.
+ </description>
+ </key>
<key name='sort-column' enum='org.gtk.gtk4.Settings.FileChooser.SortColumn'>
<default>'name'</default>
<summary>Sort column</summary>
@@ -148,6 +162,17 @@
The amount of detail to show in the Modified column.
</description>
</key>
+ <key name="type-format" enum="org.gtk.gtk4.Settings.FileChooser.TypeFormat">
+ <default>'category'</default>
+ <summary>Type format</summary>
+ <description>
+ Different ways to show the 'Type' column information.
+ Example outputs for a video mp4 file:
+ 'mime' -> 'video/mp4'
+ 'description' -> 'MPEG-4 video'
+ 'category' -> 'Video'
+ </description>
+ </key>
</schema>
</schemalist>
diff --git a/gtk/ui/gtkfilechooserwidget.ui b/gtk/ui/gtkfilechooserwidget.ui
index 07c64ffd4f..623bd86aec 100644
--- a/gtk/ui/gtkfilechooserwidget.ui
+++ b/gtk/ui/gtkfilechooserwidget.ui
@@ -218,6 +218,18 @@
</object>
</child>
<child>
+ <object class="GtkTreeViewColumn" id="list_type_column">
+ <property name="title" translatable="yes">Type</property>
+ <property name="resizable">1</property>
+ <child>
+ <object class="GtkCellRendererText" id="list_type_renderer">
+ <property name="xalign">0</property>
+ <property name="xpad">6</property>
+ </object>
+ </child>
+ </object>
+ </child>
+ <child>
<object class="GtkTreeViewColumn" id="list_time_column">
<property name="title" translatable="yes">Modified</property>
<property name="sizing">fixed</property>