diff options
author | Peter Eisenmann <p3732@getgoogleoff.me> | 2021-12-31 05:22:54 +0100 |
---|---|---|
committer | António Fernandes <antoniof@gnome.org> | 2022-01-02 19:22:17 +0000 |
commit | b1d5df437c3f0077c96e621acff8e3fcb2fe7044 (patch) | |
tree | c3fa2792047f642acb364c96792d4e847319e8e7 | |
parent | b21e15ed7313f583de6868af4d33651f6e8b9c14 (diff) | |
download | nautilus-b1d5df437c3f0077c96e621acff8e3fcb2fe7044.tar.gz |
properties-window: calculate permissions once per update
Previously every call to permission_combo_update() calculated combined
permissions of all target files, independent of whether they were
actually used. With this change combined permission are only calculated
once and provided, in the form of a new TargetPermissions struct, to
each combo box.
Additionally, a new PermissionValue to represent inconsistent permission
states was added, to avoid tracking this via a separate boolean.
-rw-r--r-- | src/nautilus-properties-window.c | 224 |
1 files changed, 109 insertions, 115 deletions
diff --git a/src/nautilus-properties-window.c b/src/nautilus-properties-window.c index 7202789b0..4f9e6bb83 100644 --- a/src/nautilus-properties-window.c +++ b/src/nautilus-properties-window.c @@ -254,16 +254,31 @@ typedef enum PERMISSION_NONE = (0), PERMISSION_READ = (1 << 0), PERMISSION_WRITE = (1 << 1), - PERMISSION_EXEC = (1 << 2) + PERMISSION_EXEC = (1 << 2), + PERMISSION_INCONSISTENT = (1 << 3) } PermissionValue; typedef enum { PERMISSION_USER, PERMISSION_GROUP, - PERMISSION_OTHER + PERMISSION_OTHER, + NUM_PERMISSION_TYPE } PermissionType; +/** Contains permissions for files and folders for each PermissionType */ +typedef struct +{ + NautilusPropertiesWindow *window; + + PermissionValue folder_permissions[NUM_PERMISSION_TYPE]; + PermissionValue file_permissions[NUM_PERMISSION_TYPE]; + gboolean has_files; + gboolean has_folders; + gboolean can_set_all_folder_permission; + gboolean can_set_all_file_permission; +} TargetPermissions; + enum { COLUMN_NAME, @@ -324,7 +339,7 @@ static void file_changed_callback (NautilusFile *file, static void permission_button_update (GtkCheckButton *button, NautilusPropertiesWindow *self); static void permission_combo_update (GtkComboBox *combo, - NautilusPropertiesWindow *self); + TargetPermissions *target_perm); static void value_field_update (GtkLabel *field, NautilusPropertiesWindow *self); static void properties_window_update (NautilusPropertiesWindow *self, @@ -909,6 +924,75 @@ permission_from_vfs (PermissionType type, return perm; } +static TargetPermissions * +get_target_permissions (NautilusPropertiesWindow *self) +{ + TargetPermissions *p = g_new0 (TargetPermissions, 1); + p->window = self; + p->can_set_all_folder_permission = TRUE; + p->can_set_all_file_permission = TRUE; + + for (GList *entry = self->target_files; entry != NULL; entry = entry->next) + { + guint32 vfs_permissions; + gboolean can_set_permissions; + NautilusFile *file = NAUTILUS_FILE (entry->data); + + if (nautilus_file_is_gone (file) || !nautilus_file_can_get_permissions (file)) + { + continue; + } + + vfs_permissions = nautilus_file_get_permissions (file); + can_set_permissions = nautilus_file_can_set_permissions (file); + + if (nautilus_file_is_directory (file)) + { + /* Gather permissions for each type (owner, group, other) */ + for (PermissionType type = PERMISSION_USER ; type < NUM_PERMISSION_TYPE; type += 1) + { + PermissionValue permissions = permission_from_vfs (type, vfs_permissions) + & (PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXEC); + if (!p->has_folders) + { + /* first found folder, initialize with its permissions */ + p->folder_permissions[type] = permissions; + } + else if (permissions != p->folder_permissions[type]) + { + p->folder_permissions[type] = PERMISSION_INCONSISTENT; + } + } + + p->can_set_all_folder_permission &= can_set_permissions; + p->has_folders = TRUE; + } + else + { + for (PermissionType type = PERMISSION_USER ; type < NUM_PERMISSION_TYPE; type += 1) + { + PermissionValue permissions = permission_from_vfs (type, vfs_permissions) + & (PERMISSION_READ | PERMISSION_WRITE); + + if (!p->has_files) + { + /* first found file, initialize with its permissions */ + p->file_permissions[type] = permissions; + } + else if (permissions != p->file_permissions[type]) + { + p->file_permissions[type] = PERMISSION_INCONSISTENT; + } + } + + p->can_set_all_file_permission &= can_set_permissions; + p->has_files = TRUE; + } + } + + return p; +} + static void properties_window_update (NautilusPropertiesWindow *self, GList *files) @@ -963,15 +1047,17 @@ properties_window_update (NautilusPropertiesWindow *self, if (dirty_target) { + TargetPermissions *target_perm = get_target_permissions(self); g_list_foreach (self->permission_buttons, (GFunc) permission_button_update, self); g_list_foreach (self->permission_combos, (GFunc) permission_combo_update, - self); + target_perm); g_list_foreach (self->value_fields, (GFunc) value_field_update, self); + free(target_perm); } mime_list = get_mime_list (self); @@ -3033,124 +3119,39 @@ permission_combo_add_multiple_choice (GtkComboBox *combo, gtk_list_store_append (store, iter); gtk_list_store_set (store, iter, COLUMN_NAME, "---", - COLUMN_VALUE, 0, + COLUMN_VALUE, PERMISSION_INCONSISTENT, COLUMN_USE_ORIGINAL, TRUE, -1); } } static void -permission_combo_update (GtkComboBox *combo, - NautilusPropertiesWindow *self) +permission_combo_update (GtkComboBox *combo, + TargetPermissions *target_perm) { - PermissionType type; - PermissionValue perm, all_dir_perm, all_file_perm, all_perm; - gboolean is_folder, no_files, no_dirs, all_file_same, all_dir_same, all_same; - gboolean all_dir_cannot_set, all_file_cannot_set, sensitive; + PermissionValue all_perm; + gboolean all_same; GtkTreeIter iter; - int mask; - GtkTreeModel *model; - GtkListStore *store; - GList *l; - gboolean is_multi; - model = gtk_combo_box_get_model (combo); - - is_folder = (FOLDERS_ONLY == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), "filter-type"))); - type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), "permission-type")); - - is_multi = FALSE; - if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (combo), &iter)) - { - gtk_tree_model_get (model, &iter, COLUMN_USE_ORIGINAL, &is_multi, -1); - } - - no_files = TRUE; - no_dirs = TRUE; - all_dir_same = TRUE; - all_file_same = TRUE; - all_dir_perm = 0; - all_file_perm = 0; - all_dir_cannot_set = TRUE; - all_file_cannot_set = TRUE; - - for (l = self->target_files; l != NULL; l = l->next) - { - NautilusFile *file; - guint32 file_permissions; - - file = NAUTILUS_FILE (l->data); - - if (!nautilus_file_can_get_permissions (file)) - { - continue; - } - - if (nautilus_file_is_directory (file)) - { - mask = PERMISSION_READ | PERMISSION_WRITE | PERMISSION_EXEC; - } - else - { - mask = PERMISSION_READ | PERMISSION_WRITE; - } - - file_permissions = nautilus_file_get_permissions (file); - - perm = permission_from_vfs (type, file_permissions) & mask; - - if (nautilus_file_is_directory (file)) - { - if (no_dirs) - { - all_dir_perm = perm; - no_dirs = FALSE; - } - else if (perm != all_dir_perm) - { - all_dir_same = FALSE; - } - - if (nautilus_file_can_set_permissions (file)) - { - all_dir_cannot_set = FALSE; - } - } - else - { - if (no_files) - { - all_file_perm = perm; - no_files = FALSE; - } - else if (perm != all_file_perm) - { - all_file_same = FALSE; - } - - if (nautilus_file_can_set_permissions (file)) - { - all_file_cannot_set = FALSE; - } - } - } + NautilusPropertiesWindow *self = target_perm->window; + gboolean is_folder = (FOLDERS_ONLY == GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), "filter-type"))); + PermissionType type = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (combo), "permission-type")); if (is_folder) { - all_same = all_dir_same; - all_perm = all_dir_perm; + all_perm = target_perm->folder_permissions[type]; + all_same = all_perm != PERMISSION_INCONSISTENT; } else { - all_same = all_file_same && !no_files; - all_perm = all_file_perm; + all_perm = target_perm->file_permissions[type]; + all_same = all_perm != PERMISSION_INCONSISTENT && target_perm->has_files; } - store = GTK_LIST_STORE (model); if (all_same) { - gboolean found; + GtkTreeModel *model = gtk_combo_box_get_model (combo); + gboolean found = FALSE; - found = FALSE; gtk_tree_model_get_iter_first (model, &iter); do { @@ -3167,9 +3168,8 @@ permission_combo_update (GtkComboBox *combo, if (!found) { - g_autoptr (GString) str = NULL; - - str = g_string_new (""); + GtkListStore *store = GTK_LIST_STORE (model); + g_autoptr (GString) str = g_string_new (""); if (!(all_perm & PERMISSION_READ)) { @@ -3232,15 +3232,9 @@ permission_combo_update (GtkComboBox *combo, /* Also enable if no files found (for recursive * file changes when only selecting folders) */ - if (is_folder) - { - sensitive = !all_dir_cannot_set; - } - else - { - sensitive = !all_file_cannot_set; - } - gtk_widget_set_sensitive (GTK_WIDGET (combo), sensitive); + gtk_widget_set_sensitive (GTK_WIDGET (combo), is_folder ? + target_perm->can_set_all_folder_permission : + target_perm->can_set_all_file_permission); g_signal_handlers_unblock_by_func (G_OBJECT (combo), G_CALLBACK (permission_combo_changed), |