diff options
Diffstat (limited to 'gtk')
-rw-r--r-- | gtk/gtkfilechooserprivate.h | 2 | ||||
-rw-r--r-- | gtk/gtkfilechooserwidget.c | 186 | ||||
-rw-r--r-- | gtk/org.gtk.gtk4.Settings.FileChooser.gschema.xml | 27 | ||||
-rw-r--r-- | gtk/ui/gtkfilechooserwidget.ui | 12 |
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> |