diff options
author | Corey Berla <corey@berla.me> | 2022-12-30 15:31:01 -0800 |
---|---|---|
committer | Corey Berla <corey@berla.me> | 2023-04-17 10:10:19 -0700 |
commit | 7ef1452d4cb5a4eb5bc73da8efd95f501ae69c3a (patch) | |
tree | b2d463726432eaaa2942e511d79ebe454ed832f3 | |
parent | 58139b671246e42c6ad90d8d84db20224a224a76 (diff) | |
download | nautilus-7ef1452d4cb5a4eb5bc73da8efd95f501ae69c3a.tar.gz |
list-view: Implement a header menu
Fixes: https://gitlab.gnome.org/GNOME/nautilus/-/issues/2728
-rw-r--r-- | src/nautilus-list-view.c | 128 | ||||
-rw-r--r-- | src/resources/ui/nautilus-files-view-context-menus.ui | 5 |
2 files changed, 118 insertions, 15 deletions
diff --git a/src/nautilus-list-view.c b/src/nautilus-list-view.c index eed8f6f15..6c9a752ee 100644 --- a/src/nautilus-list-view.c +++ b/src/nautilus-list-view.c @@ -346,6 +346,84 @@ get_column_order (NautilusListView *self) return get_default_column_order (self); } + +static GStrv +get_columns_from_view (NautilusListView *self, + gboolean visible_only) +{ + g_autoptr (GStrvBuilder) builder = g_strv_builder_new (); + GListModel *columns = gtk_column_view_get_columns (self->view_ui); + for (guint i = 0; i < g_list_model_get_n_items (columns); i++) + { + g_autoptr (GtkColumnViewColumn) column = g_list_model_get_item (columns, i); + + if (!visible_only || gtk_column_view_column_get_visible (column)) + { + g_strv_builder_add (builder, gtk_column_view_column_get_id (column)); + } + } + return g_strv_builder_end (builder); +} + +static gboolean +is_default_column_in_header_menu (const char *name) +{ + if (g_strcmp0 (name, "type") == 0 || g_strcmp0 (name, "date_modified") == 0 || + g_strcmp0 (name, "size") == 0 || g_strcmp0 (name, "date_created") == 0 || + g_strcmp0 (name, "name") == 0 || g_strcmp0 (name, "starred") == 0) + { + return TRUE; + } + + return FALSE; +} + +static void +column_visible_changed (GObject *object, + GParamSpec *pspec, + gpointer user_data) +{ + GtkColumnViewColumn *column = GTK_COLUMN_VIEW_COLUMN (object); + NautilusListView *self = user_data; + g_autofree char *action_name = NULL; + g_auto (GStrv) visible_columns = get_visible_columns (self); + const char *column_name = gtk_column_view_column_get_id (column); + gboolean is_visible = gtk_column_view_column_get_visible (column); + NautilusFile *file; + file = nautilus_files_view_get_directory_as_file (NAUTILUS_FILES_VIEW (self)); + + if (is_visible != g_strv_contains ((const gchar * const *) visible_columns, column_name)) + { + g_auto (GStrv) new_visible_columns = get_columns_from_view (self, TRUE); + nautilus_file_set_metadata_list (file, + NAUTILUS_METADATA_KEY_LIST_VIEW_VISIBLE_COLUMNS, + new_visible_columns); + } + + /* Default columns are always visible. */ + if (is_default_column_in_header_menu (column_name)) + { + return; + } + + /* Besides the "default" columns, we only want to show column names in the + * header menu, if they are currently visible (so they can be hidden). + * We do this by removing or adding the action respectively. + */ + action_name = g_strdup_printf ("show-column-%s", column_name); + + if (!is_visible) + { + g_action_map_remove_action (G_ACTION_MAP (self->action_group), action_name); + } + else if (g_action_map_lookup_action (G_ACTION_MAP (self->action_group), action_name) == NULL) + { + g_autoptr (GAction) action = NULL; + action = G_ACTION (g_property_action_new (action_name, column, "visible")); + g_action_map_add_action (G_ACTION_MAP (self->action_group), action); + } +} + static void update_columns_settings_from_metadata_and_preferences (NautilusListView *self) { @@ -1264,7 +1342,10 @@ setup_view_columns (NautilusListView *self) { GtkListItemFactory *factory; g_autolist (NautilusColumn) nautilus_columns = NULL; + g_autoptr (GMenu) menu = NULL; + g_autoptr (GMenu) section = NULL; + menu = g_menu_new (); nautilus_columns = nautilus_get_all_columns (); self->factory_to_column_map = g_hash_table_new_full (g_direct_hash, @@ -1281,6 +1362,10 @@ setup_view_columns (NautilusListView *self) GtkSortType sort_order; g_autoptr (GtkCustomSorter) sorter = NULL; g_autoptr (GtkColumnViewColumn) view_column = NULL; + g_autoptr (GAction) action = NULL; + g_autofree char *action_name = NULL; + g_autofree char *detailed_action_name = NULL; + g_autoptr (GMenuItem) menu_item = NULL; g_object_get (nautilus_column, "name", &name, @@ -1299,6 +1384,9 @@ setup_view_columns (NautilusListView *self) gtk_column_view_column_set_resizable (view_column, TRUE); gtk_column_view_column_set_title (view_column, label); gtk_column_view_column_set_sorter (view_column, GTK_SORTER (sorter)); + gtk_column_view_column_set_id (view_column, name); + gtk_column_view_column_set_visible (view_column, FALSE); + gtk_column_view_column_set_header_menu (view_column, G_MENU_MODEL (menu)); if (!strcmp (name, "name")) { @@ -1322,13 +1410,34 @@ setup_view_columns (NautilusListView *self) g_signal_connect (factory, "setup", G_CALLBACK (setup_label_cell), self); } + action_name = g_strdup_printf ("show-column-%s", name); + detailed_action_name = g_strdup_printf ("view.%s", action_name); + + if (is_default_column_in_header_menu (name)) + { + action = G_ACTION (g_property_action_new (action_name, view_column, "visible")); + g_action_map_add_action (G_ACTION_MAP (self->action_group), action); + } + + if (g_strcmp0 (name, "name") != 0 && g_strcmp0 (name, "starred") != 0) + { + menu_item = g_menu_item_new (label, detailed_action_name); + g_menu_item_set_attribute (menu_item, "hidden-when", "s", "action-missing"); + g_menu_append_item (G_MENU (menu), menu_item); + } + gtk_column_view_append_column (self->view_ui, view_column); gtk_column_view_column_set_id (view_column, name); + g_signal_connect (view_column, "notify::visible", G_CALLBACK (column_visible_changed), self); g_hash_table_insert (self->factory_to_column_map, factory, g_object_ref (nautilus_column)); } + + section = g_menu_new (); + g_menu_append (section, _("More Columns"), "view.visible-columns"); + g_menu_append_section (menu, NULL, G_MENU_MODEL (section)); } static void @@ -1373,6 +1482,15 @@ nautilus_list_view_init (NautilusListView *self) self->view_ui = create_view_ui (self); nautilus_list_base_setup_gestures (NAUTILUS_LIST_BASE (self)); + self->action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self)); + g_action_map_add_action_entries (G_ACTION_MAP (self->action_group), + list_view_entries, + G_N_ELEMENTS (list_view_entries), + self); + + self->zoom_level = get_default_zoom_level (); + g_action_group_change_action_state (nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self)), + "zoom-to-level", g_variant_new_int32 (self->zoom_level)); setup_view_columns (self); @@ -1391,16 +1509,6 @@ nautilus_list_view_init (NautilusListView *self) gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW (content_widget), GTK_WIDGET (self->view_ui)); - self->action_group = nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self)); - g_action_map_add_action_entries (G_ACTION_MAP (self->action_group), - list_view_entries, - G_N_ELEMENTS (list_view_entries), - self); - - self->zoom_level = get_default_zoom_level (); - g_action_group_change_action_state (nautilus_files_view_get_action_group (NAUTILUS_FILES_VIEW (self)), - "zoom-to-level", g_variant_new_int32 (self->zoom_level)); - /* Set up tree expand/collapse shortcuts in capture phase otherwise they * would be handled by GtkListBase's cursor movement shortcuts. */ controller = gtk_shortcut_controller_new (); diff --git a/src/resources/ui/nautilus-files-view-context-menus.ui b/src/resources/ui/nautilus-files-view-context-menus.ui index 1f8474fc2..cc37ffe72 100644 --- a/src/resources/ui/nautilus-files-view-context-menus.ui +++ b/src/resources/ui/nautilus-files-view-context-menus.ui @@ -34,11 +34,6 @@ <attribute name="label" translatable="yes">Select _All</attribute> <attribute name="action">view.select-all</attribute> </item> - <item> - <attribute name="label" translatable="yes">_Visible Columns</attribute> - <attribute name="action">view.visible-columns</attribute> - <attribute name="hidden-when">action-missing</attribute> - </item> </section> <section> <item> |