summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorey Berla <corey@berla.me>2022-12-30 15:31:01 -0800
committerCorey Berla <corey@berla.me>2023-04-17 10:10:19 -0700
commit7ef1452d4cb5a4eb5bc73da8efd95f501ae69c3a (patch)
treeb2d463726432eaaa2942e511d79ebe454ed832f3
parent58139b671246e42c6ad90d8d84db20224a224a76 (diff)
downloadnautilus-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.c128
-rw-r--r--src/resources/ui/nautilus-files-view-context-menus.ui5
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>