~elementary-apps/pantheon-files/trunk

« back to all changes in this revision

Viewing changes to src/Dialogs/PropertiesWindow.vala

  • Committer: Jeremy Wootten
  • Date: 2017-01-13 13:36:33 UTC
  • mfrom: (2444 pantheon-files)
  • mto: This revision was merged to the branch mainline in revision 2471.
  • Revision ID: jeremy@elementaryos.org-20170113133633-ajg6izr1e6irmj0g
Merge r2444

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
2
* Copyright (c) 2011 Marlin Developers (http://launchpad.net/marlin)
3
 
* Copyright (c) 2015-2016 elementary LLC (http://launchpad.net/pantheon-files)
 
3
* Copyright (c) 2015-2017 elementary LLC (http://launchpad.net/pantheon-files)
4
4
*
5
5
* This program is free software; you can redistribute it and/or
6
6
* modify it under the terms of the GNU General Public
23
23
namespace Marlin.View {
24
24
 
25
25
public class PropertiesWindow : AbstractPropertiesDialog {
26
 
    private Granite.Widgets.XsEntry perm_code;
 
26
    private Gtk.Entry perm_code;
27
27
    private bool perm_code_should_update = true;
28
28
    private Gtk.Label l_perm;
29
29
 
 
30
    private PermissionButton perm_button_user;
 
31
    private PermissionButton perm_button_group;
 
32
    private PermissionButton perm_button_other;
 
33
 
30
34
    private Gtk.ListStore store_users;
31
35
    private Gtk.ListStore store_groups;
32
36
    private Gtk.ListStore store_apps;
93
97
        ICON
94
98
    }
95
99
 
96
 
    private enum PermissionType {
97
 
        USER,
98
 
        GROUP,
99
 
        OTHER
100
 
    }
101
 
 
102
 
    private enum PermissionValue {
103
 
        READ = (1<<0),
104
 
        WRITE = (1<<1),
105
 
        EXE = (1<<2)
106
 
    }
107
 
 
108
100
    private Posix.mode_t[,] vfs_perms = {
109
101
        { Posix.S_IRUSR, Posix.S_IWUSR, Posix.S_IXUSR },
110
102
        { Posix.S_IRGRP, Posix.S_IWGRP, Posix.S_IXGRP },
192
184
        cancellable = new GLib.Cancellable ();
193
185
 
194
186
        update_selection_size (); /* Start counting first to get number of selected files and folders */    
195
 
        build_header_box ();
 
187
 
 
188
        /* create some widgets first (may be hidden by update_selection_size ()) */
 
189
        var file_pix = goffile.get_icon_pixbuf (48, false, GOF.FileIconFlags.NONE);
 
190
        var file_icon = new Gtk.Image.from_pixbuf (file_pix);
 
191
        overlay_emblems (file_icon, goffile.emblems_list);
 
192
 
 
193
        /* Build header box */
 
194
        if (count > 1 || (count == 1 && !goffile.is_writable ())) {
 
195
            var label = new Gtk.Label (get_selected_label (selected_folders, selected_files));
 
196
            label.halign = Gtk.Align.START;
 
197
            header_title = label;
 
198
        } else if (count == 1 && goffile.is_writable ()) {
 
199
            entry = new Gtk.Entry ();
 
200
            original_name = goffile.info.get_name ();
 
201
            reset_entry_text ();
 
202
 
 
203
            entry.activate.connect (() => {
 
204
                rename_file (goffile, entry.get_text ());
 
205
            });
 
206
 
 
207
            entry.focus_out_event.connect (() => {
 
208
                rename_file (goffile, entry.get_text ());
 
209
                return false;
 
210
            });
 
211
            header_title = entry;
 
212
        }
 
213
 
 
214
        create_header_title ();
196
215
 
197
216
        /* Permissions */
198
217
        /* Don't show permissions for uri scheme trash and archives */
207
226
        }
208
227
 
209
228
        show_all ();
210
 
        update_widgets_state ();
211
229
    }
212
230
 
213
231
    private void update_size_value () {
214
232
        size_value.label = format_size ((int64) total_size);
215
233
        contains_value.label = get_contains_value (folder_count, file_count);
 
234
        update_widgets_state ();
216
235
        update_selection_usage (total_size);
217
236
 
218
237
        if (size_warning > 0) {
320
339
        entry.set_text (original_name);
321
340
    }
322
341
 
323
 
    private void build_header_box () {
324
 
        /* create some widgets first (may be hidden by update_selection_size ()) */
325
 
        var file_pix = goffile.get_icon_pixbuf (48, false, GOF.FileIconFlags.NONE);
326
 
        var file_icon = new Gtk.Image.from_pixbuf (file_pix);
327
 
        overlay_emblems (file_icon, goffile.emblems_list);
328
 
 
329
 
        /* Build header box */
330
 
        if (count > 1 || (count == 1 && !goffile.is_writable ())) {
331
 
            var label = new Gtk.Label (get_selected_label (selected_folders, selected_files));
332
 
            label.halign = Gtk.Align.START;
333
 
            header_title = label;
334
 
        } else if (count == 1 && goffile.is_writable ()) {
335
 
            entry = new Gtk.Entry ();
336
 
            original_name = goffile.info.get_name ();
337
 
            reset_entry_text ();
338
 
 
339
 
            entry.activate.connect (() => {
340
 
                rename_file (goffile, entry.get_text ());
341
 
            });
342
 
 
343
 
            entry.focus_out_event.connect (() => {
344
 
                rename_file (goffile, entry.get_text ());
345
 
                return false;
346
 
            });
347
 
            header_title = entry;
348
 
        }
349
 
 
350
 
        create_header_title ();
351
 
    }
352
 
 
353
342
    private string? get_common_ftype () {
354
343
        string? ftype = null;
355
344
        if (files == null)
505
494
        contains_key_label = new KeyLabel (_("Contains:"));
506
495
        contains_value = new ValueLabel ("");
507
496
 
 
497
        /* Dialog may get displayed after these labels are hidden so we set no_show_all to true */
 
498
        type_key_label.no_show_all = true;
 
499
        type_value.no_show_all = true;
 
500
        contains_key_label.no_show_all = true;
 
501
        contains_value.no_show_all = true;
 
502
 
508
503
        info_grid.attach (size_key_label, 0, 1, 1, 1);
509
504
        info_grid.attach_next_to (spinner, size_key_label, Gtk.PositionType.RIGHT);
510
505
        info_grid.attach_next_to (size_value, size_key_label, Gtk.PositionType.RIGHT);
516
511
        int n = 4;
517
512
 
518
513
        if (count == 1) {
519
 
            var time_created = file.get_formated_time (FileAttribute.TIME_CREATED);
520
 
            if (time_created != null) {
 
514
            var time_created = PF.FileUtils.get_formatted_time_attribute_from_info (file.info, FileAttribute.TIME_CREATED);
 
515
            if (time_created != "") {
521
516
                var key_label = new KeyLabel (_("Created:"));
522
517
                var value_label = new ValueLabel (time_created);
523
518
                info_grid.attach (key_label, 0, n, 1, 1);
525
520
                n++;
526
521
            }
527
522
 
528
 
            if (file.formated_modified != null) {
 
523
            var time_modified = PF.FileUtils.get_formatted_time_attribute_from_info (file.info, FileAttribute.TIME_MODIFIED);
 
524
            if (time_modified != "") {
529
525
                var key_label = new KeyLabel (_("Modified:"));
530
 
                var value_label = new ValueLabel (file.formated_modified);
531
 
                info_grid.attach (key_label, 0, n, 1, 1);
532
 
                info_grid.attach_next_to (value_label, key_label, Gtk.PositionType.RIGHT, 3, 1);
533
 
                n++;
534
 
            }
535
 
 
536
 
            var time_last_access = file.get_formated_time (FileAttribute.TIME_ACCESS);
537
 
            if (time_last_access != null) {
538
 
                var key_label = new KeyLabel (_("Last Access:"));
539
 
                var value_label = new ValueLabel (time_last_access);
 
526
                var value_label = new ValueLabel (time_modified);
540
527
                info_grid.attach (key_label, 0, n, 1, 1);
541
528
                info_grid.attach_next_to (value_label, key_label, Gtk.PositionType.RIGHT, 3, 1);
542
529
                n++;
544
531
        }
545
532
 
546
533
        if (count == 1 && file.is_trashed ()) {
547
 
            var deletion_date = file.info.get_attribute_as_string ("trash::deletion-date");
548
 
            if (deletion_date != null) {
 
534
            var deletion_date = PF.FileUtils.get_formatted_time_attribute_from_info (file.info, FileAttribute.TRASH_DELETION_DATE);
 
535
            if (deletion_date != "") {
549
536
                var key_label = new KeyLabel (_("Deleted:"));
550
537
                var value_label = new ValueLabel (deletion_date);
551
538
                info_grid.attach (key_label, 0, n, 1, 1);
663
650
        return false;
664
651
    }
665
652
 
666
 
    private void toggle_button_add_label (Gtk.ToggleButton btn, string str) {
667
 
        var l_read = new Gtk.Label ("<span size='small'>"+ str + "</span>");
668
 
        l_read.set_use_markup (true);
669
 
        btn.add (l_read);
670
 
    }
671
 
 
672
 
    private void update_perm_codes (PermissionType pt, int val, int mult) {
 
653
    private void update_perm_codes (Permissions.Type pt, int val, int mult) {
673
654
        switch (pt) {
674
 
        case PermissionType.USER:
 
655
        case Permissions.Type.USER:
675
656
            owner_perm_code += mult*val;
676
657
            break;
677
 
        case PermissionType.GROUP:
 
658
        case Permissions.Type.GROUP:
678
659
            group_perm_code += mult*val;
679
660
            break;
680
 
        case PermissionType.OTHER:
 
661
        case Permissions.Type.OTHER:
681
662
            everyone_perm_code += mult*val;
682
663
            break;
683
664
        }
684
665
    }
685
666
 
686
 
    private void action_toggled_read (Gtk.ToggleButton btn) {
687
 
        unowned PermissionType pt = btn.get_data ("permissiontype");
 
667
    private void permission_button_toggle (Gtk.ToggleButton btn) {
 
668
        unowned Permissions.Type pt = btn.get_data ("permissiontype");
 
669
        unowned Permissions.Value permission_value = btn.get_data ("permissionvalue");
688
670
        int mult = 1;
689
671
 
690
672
        reset_and_cancel_perm_timeout ();
691
 
        if (!btn.get_active ())
 
673
 
 
674
        if (!btn.get_active ()) {
692
675
            mult = -1;
693
 
        update_perm_codes (pt, 4, mult);
694
 
        if (perm_code_should_update)
 
676
        }
 
677
 
 
678
        switch (permission_value) {
 
679
            case Permissions.Value.READ:
 
680
                update_perm_codes (pt, 4, mult);
 
681
                break;
 
682
            case Permissions.Value.WRITE:
 
683
                update_perm_codes (pt, 2, mult);
 
684
                break;
 
685
            case Permissions.Value.EXE:
 
686
                update_perm_codes (pt, 1, mult);
 
687
                break;
 
688
        }
 
689
 
 
690
        if (perm_code_should_update) {
695
691
            perm_code.set_text ("%d%d%d".printf (owner_perm_code, group_perm_code, everyone_perm_code));
696
 
    }
697
 
 
698
 
    private void action_toggled_write (Gtk.ToggleButton btn) {
699
 
        unowned PermissionType pt = btn.get_data ("permissiontype");
700
 
        int mult = 1;
701
 
 
702
 
        reset_and_cancel_perm_timeout ();
703
 
        if (!btn.get_active ())
704
 
            mult = -1;
705
 
        update_perm_codes (pt, 2, mult);
706
 
        if (perm_code_should_update)
707
 
            perm_code.set_text ("%d%d%d".printf(owner_perm_code, group_perm_code, everyone_perm_code));
708
 
    }
709
 
 
710
 
    private void action_toggled_execute (Gtk.ToggleButton btn) {
711
 
        unowned PermissionType pt = btn.get_data ("permissiontype");
712
 
        int mult = 1;
713
 
 
714
 
        reset_and_cancel_perm_timeout ();
715
 
        if (!btn.get_active ())
716
 
            mult = -1;
717
 
        update_perm_codes (pt, 1, mult);
718
 
        if (perm_code_should_update)
719
 
            perm_code.set_text ("%d%d%d".printf(owner_perm_code, group_perm_code, everyone_perm_code));
720
 
    }
721
 
 
722
 
    private Gtk.Box create_perm_choice (PermissionType pt) {
723
 
        Gtk.Box hbox;
724
 
 
725
 
        hbox = new Gtk.Box (Gtk.Orientation.HORIZONTAL, 0);
726
 
        hbox.homogeneous = true;
727
 
        hbox.get_style_context ().add_class (Gtk.STYLE_CLASS_LINKED);
728
 
        var btn_read = new Gtk.ToggleButton ();
729
 
        toggle_button_add_label (btn_read, _("Read"));
730
 
        btn_read.set_data ("permissiontype", pt);
731
 
        btn_read.toggled.connect (action_toggled_read);
732
 
        var btn_write = new Gtk.ToggleButton ();
733
 
        toggle_button_add_label (btn_write, _("Write"));
734
 
        btn_write.set_data ("permissiontype", pt);
735
 
        btn_write.toggled.connect (action_toggled_write);
736
 
        var btn_exe = new Gtk.ToggleButton ();
737
 
        toggle_button_add_label (btn_exe, _("Execute"));
738
 
        btn_exe.set_data ("permissiontype", pt);
739
 
        btn_exe.toggled.connect (action_toggled_execute);
740
 
        hbox.pack_start (btn_read);
741
 
        hbox.pack_start (btn_write);
742
 
        hbox.pack_start (btn_exe);
743
 
 
744
 
        return hbox;
 
692
        }
 
693
    }
 
694
 
 
695
    private PermissionButton create_perm_choice (Permissions.Type pt) {
 
696
        var permission_button = new PermissionButton (pt);
 
697
        permission_button.btn_read.toggled.connect (permission_button_toggle);
 
698
        permission_button.btn_write.toggled.connect (permission_button_toggle);
 
699
        permission_button.btn_exe.toggled.connect (permission_button_toggle);
 
700
        return permission_button;
745
701
    }
746
702
 
747
703
    private uint32 get_perm_from_chmod_unit (uint32 vfs_perm, int nb,
748
 
                                             int chmod, PermissionType pt) {
 
704
                                             int chmod, Permissions.Type pt) {
749
705
        if (nb > 7 || nb < 0)
750
706
            critical ("erroned chmod code %d %d", chmod, nb);
751
707
 
768
724
 
769
725
        /* user */
770
726
        vfs_perm = get_perm_from_chmod_unit (vfs_perm, (int) chmod / 100,
771
 
                                             chmod, PermissionType.USER);
 
727
                                             chmod, Permissions.Type.USER);
772
728
        /* group */
773
729
        vfs_perm = get_perm_from_chmod_unit (vfs_perm, (int) (chmod / 10) % 10,
774
 
                                             chmod, PermissionType.GROUP);
 
730
                                             chmod, Permissions.Type.GROUP);
775
731
        /* other */
776
732
        vfs_perm = get_perm_from_chmod_unit (vfs_perm, (int) chmod % 10,
777
 
                                             chmod, PermissionType.OTHER);
 
733
                                             chmod, Permissions.Type.OTHER);
778
734
 
779
735
        return vfs_perm;
780
736
    }
781
737
 
782
 
    private void update_permission_type_buttons (Gtk.Box hbox, uint32 permissions, PermissionType pt) {
783
 
        int i=0;
784
 
        foreach (var widget in hbox.get_children ()) {
785
 
            Gtk.ToggleButton btn = (Gtk.ToggleButton) widget;
786
 
            ((permissions & vfs_perms[pt, i]) != 0) ? btn.active = true : btn.active = false;
787
 
            i++;
788
 
        }
789
 
    }
790
738
 
791
739
    private void update_perm_grid_toggle_states (uint32 permissions) {
792
 
        Gtk.Box hbox;
793
 
 
794
 
        /* update USR row */
795
 
        hbox = (Gtk.Box) perm_grid.get_child_at (1,3);
796
 
        update_permission_type_buttons (hbox, permissions, PermissionType.USER);
797
 
 
798
 
        /* update GRP row */
799
 
        hbox = (Gtk.Box) perm_grid.get_child_at (1,4);
800
 
        update_permission_type_buttons (hbox, permissions, PermissionType.GROUP);
801
 
 
802
 
        /* update OTHER row */
803
 
        hbox = (Gtk.Box) perm_grid.get_child_at (1,5);
804
 
        update_permission_type_buttons (hbox, permissions, PermissionType.OTHER);
805
 
    }
806
 
 
807
 
    private bool is_chmod_code (string str) {
808
 
        try {
809
 
            var regex = new Regex ("^[0-7]{3}$");
810
 
            if (regex.match (str))
811
 
                return true;
812
 
        } catch (RegexError e) {
813
 
            assert_not_reached ();
814
 
        }
815
 
 
816
 
        return false;
 
740
        perm_button_user.update_buttons (permissions);
 
741
        perm_button_group.update_buttons (permissions);
 
742
        perm_button_other.update_buttons (permissions);
817
743
    }
818
744
 
819
745
    private void reset_and_cancel_perm_timeout () {
846
772
 
847
773
    private void entry_changed () {
848
774
        var str = perm_code.get_text ();
849
 
        if (is_chmod_code (str)) {
 
775
        if (Permissions.is_chmod_code (str)) {
850
776
            reset_and_cancel_perm_timeout ();
851
777
            timeout_perm = Timeout.add (60, () => {
852
778
                uint32 perm = chmod_to_vfs (int.parse (str));
857
783
                foreach (GOF.File gof in files) {
858
784
                    if (gof.can_set_permissions() && gof.permissions != perm) {
859
785
                        gof.permissions = perm;
 
786
 
860
787
                        /* update permission label once */
861
 
                        if (n<1)
862
 
                            l_perm.set_text (goffile.get_permissions_as_string ());
 
788
                        if (n < 1) {
 
789
                            l_perm.label = "<tt>%s</tt>".printf (goffile.get_permissions_as_string ());
 
790
                        }
 
791
 
863
792
                        /* real update permissions */
864
793
                        file_set_attributes.begin (gof, FileAttribute.UNIX_MODE, perm, cancellable);
865
794
                        n++;
932
861
    }
933
862
 
934
863
    private Gtk.Grid construct_perm_panel () {
 
864
        var owner_user_label = new KeyLabel (_("Owner:"));
 
865
 
 
866
        var owner_user_choice = create_owner_choice ();
 
867
 
 
868
        var group_combo_label = new KeyLabel (_("Group:"));
 
869
        group_combo_label.margin_bottom = 12;
 
870
 
 
871
        var group_combo = create_group_choice ();
 
872
        group_combo.margin_bottom = 12;
 
873
 
 
874
        var owner_label = new KeyLabel (_("Owner:"));
 
875
        perm_button_user = create_perm_choice (Permissions.Type.USER);
 
876
 
 
877
        var group_label = new KeyLabel (_("Group:"));
 
878
        perm_button_group = create_perm_choice (Permissions.Type.GROUP);
 
879
 
 
880
        var other_label = new KeyLabel (_("Everyone:"));
 
881
        perm_button_other = create_perm_choice (Permissions.Type.OTHER);
 
882
 
 
883
        perm_code = new Gtk.Entry ();
 
884
        perm_code.text = "000";
 
885
        perm_code.max_length = perm_code.max_width_chars = perm_code.width_chars = 3;
 
886
 
 
887
        l_perm = new Gtk.Label ("<tt>%s</tt>".printf (goffile.get_permissions_as_string ()));
 
888
        l_perm.halign = Gtk.Align.START;
 
889
        l_perm.use_markup = true;
 
890
 
935
891
        perm_grid = new Gtk.Grid ();
936
892
        perm_grid.column_spacing = 6;
937
893
        perm_grid.row_spacing = 6;
938
894
        perm_grid.halign = Gtk.Align.CENTER;
939
 
 
940
 
        Gtk.Widget key_label;
941
 
        Gtk.Widget value_label;
942
 
        Gtk.Box value_hlabel;
943
 
 
944
 
        key_label = new Gtk.Label (_("Owner:"));
945
 
        key_label.halign = Gtk.Align.END;
946
 
        perm_grid.attach (key_label, 0, 1, 1, 1);
947
 
        value_label = create_owner_choice ();
948
 
        perm_grid.attach (value_label, 1, 1, 2, 1);
949
 
 
950
 
        key_label = new Gtk.Label (_("Group:"));
951
 
        key_label.halign = Gtk.Align.END;
952
 
        perm_grid.attach (key_label, 0, 2, 1, 1);
953
 
        value_label = create_group_choice ();
954
 
        perm_grid.attach (value_label, 1, 2, 2, 1);
955
 
 
956
 
        /* make a separator with margins */
957
 
        key_label.margin_bottom = 12;
958
 
        value_label.margin_bottom = 12;
959
 
 
960
 
        key_label = new KeyLabel (_("Owner:"));
961
 
        value_hlabel = create_perm_choice (PermissionType.USER);
962
 
        perm_grid.attach (key_label, 0, 3, 1, 1);
963
 
        perm_grid.attach (value_hlabel, 1, 3, 2, 1);
964
 
        key_label = new KeyLabel (_("Group:"));
965
 
        value_hlabel = create_perm_choice (PermissionType.GROUP);
966
 
        perm_grid.attach (key_label, 0, 4, 1, 1);
967
 
        perm_grid.attach (value_hlabel, 1, 4, 2, 1);
968
 
        key_label = new KeyLabel (_("Everyone:"));
969
 
        value_hlabel = create_perm_choice (PermissionType.OTHER);
970
 
        perm_grid.attach (key_label, 0, 5, 1, 1);
971
 
        perm_grid.attach (value_hlabel, 1, 5, 2, 1);
972
 
 
973
 
        perm_code = new Granite.Widgets.XsEntry ();
974
 
        perm_code.set_text ("000");
975
 
        perm_code.set_max_length (3);
976
 
        perm_code.set_size_request (35, -1);
977
 
 
978
 
        l_perm = new Gtk.Label (goffile.get_permissions_as_string ());
979
 
 
 
895
        perm_grid.attach (owner_user_label, 0, 1, 1, 1);
 
896
        perm_grid.attach (owner_user_choice, 1, 1, 2, 1);
 
897
        perm_grid.attach (group_combo_label, 0, 2, 1, 1);
 
898
        perm_grid.attach (group_combo, 1, 2, 2, 1);
 
899
        perm_grid.attach (owner_label, 0, 3, 1, 1);
 
900
        perm_grid.attach (perm_button_user, 1, 3, 2, 1);
 
901
        perm_grid.attach (group_label, 0, 4, 1, 1);
 
902
        perm_grid.attach (perm_button_group, 1, 4, 2, 1);
 
903
        perm_grid.attach (other_label, 0, 5, 1, 1);
 
904
        perm_grid.attach (perm_button_other, 1, 5, 2, 1);
980
905
        perm_grid.attach (l_perm, 1, 6, 1, 1);
981
906
        perm_grid.attach (perm_code, 2, 6, 1, 1);
982
907
 
1208
1133
    }
1209
1134
 
1210
1135
    private string get_contains_value (uint folders, uint files) {
1211
 
        string txt = "";
 
1136
        string folders_txt = "";
 
1137
        string files_txt = "";
 
1138
 
1212
1139
        if (folders > 0) {
1213
 
            if (folders > 1) {
1214
 
                if (files > 0) {
1215
 
                    if (files > 1) {
1216
 
                        txt = _("%u subfolders and %u files").printf (folders, files);
1217
 
                    } else {
1218
 
                        txt = _("%u subfolders and %u file").printf (folders,files);
1219
 
                    }
1220
 
                } else {
1221
 
                    txt = _("%u subfolders").printf (folders);
1222
 
                }
1223
 
            } else {
1224
 
                if (files > 0) {
1225
 
                    if (files > 1) {
1226
 
                        txt = _("%u subfolder and %u files").printf (folders, files);
1227
 
                    } else {
1228
 
                        txt = _("%u subfolder and %u file").printf (folders, files);
1229
 
                    }
1230
 
                } else {
1231
 
                    txt = _("%u folder").printf (folders);
1232
 
                }
1233
 
            }
 
1140
            folders_txt = (ngettext ("%u subfolder", "%u subfolders", folders)).printf (folders);
 
1141
        }
 
1142
 
 
1143
        if (files > 0) {
 
1144
            files_txt = (ngettext ("%u file", "%u files", files)).printf (files);
 
1145
        }
 
1146
 
 
1147
        if (folders > 0 && files > 0) {
 
1148
            ///TRANSLATORS: folders, files
 
1149
            return _("%s, %s").printf (folders_txt, files_txt);
 
1150
        } else if (files > 0) {
 
1151
            return files_txt;
1234
1152
        } else {
1235
 
            if (files > 0) {
1236
 
                if (files > 1) {
1237
 
                    txt = _("%u files").printf (files);
1238
 
                } else {
1239
 
                    txt = _("%u file").printf (files);
1240
 
                }
1241
 
            }
 
1153
            return folders_txt;
1242
1154
        }
1243
 
 
1244
 
        return txt;
1245
1155
    }
1246
1156
 
1247
1157
    private string get_selected_label (uint folders, uint files) {
1248
 
        string txt = "";
1249
 
        uint total = folders + files;
 
1158
        string folders_txt = "";
 
1159
        string files_txt = "";
1250
1160
 
1251
1161
        if (folders > 0) {
1252
 
            if (folders > 1) {
1253
 
                if (files > 0) {
1254
 
                    if (files > 1) {
1255
 
                        txt = _("%u selected items (%u folders and %u files)").printf (total, folders, files);
1256
 
                    } else {
1257
 
                        txt = _("%u selected items (%u folders and %u file)").printf (total, folders, files);
1258
 
                    }
1259
 
                } else {
1260
 
                    txt = _("%u folders").printf (folders);
1261
 
                }
1262
 
            } else {
1263
 
                if (files > 0) {
1264
 
                    if (files > 1) {
1265
 
                        txt = _("%u selected items (%u folder and %u files)").printf (total, folders,files);
1266
 
                    } else {
1267
 
                        txt = _("%u selected items (%u folder and %u file)").printf (total, folders,files);
1268
 
                    }
1269
 
                } else {
1270
 
                    txt = _("%u folder").printf (folders); /* displayed for background folder*/
1271
 
                }
1272
 
            }
 
1162
            folders_txt = (ngettext ("%u folder", "%u folders", folders)).printf (folders);
 
1163
        }
 
1164
 
 
1165
        if (files > 0) {
 
1166
            files_txt = (ngettext ("%u file", "%u files", files)).printf (files);
 
1167
        }
 
1168
 
 
1169
        if (files > 0 && folders > 0) {
 
1170
            string total_txt = (ngettext ("%u selected item", "%u selected items", folders + files)).printf (folders + files);
 
1171
            ///TRANSLATORS: total (folders, files)
 
1172
            return _("%s (%s, %s)").printf (total_txt, folders_txt, files_txt);
 
1173
        } else if (files > 0) {
 
1174
            return files_txt;
1273
1175
        } else {
1274
 
            if (files > 0) {
1275
 
                if (files > 1) {
1276
 
                    txt = _("%u files").printf (files);
1277
 
                } else {
1278
 
                    txt = _("%u file").printf (files); /* should not be displayed - entry instead */
1279
 
                }
1280
 
            }
 
1176
            return folders_txt;
1281
1177
        }
1282
 
 
1283
 
        /* The selection should never be empty */
1284
 
        return txt;
1285
1178
    }
1286
1179
 
1287
1180
    /** Hide certain widgets under certain conditions **/
1309
1202
        /* Only show 'contains' label when only folders selected - otherwise could be ambiguous whether
1310
1203
         * the "contained files" counted are only in the subfolders or not.*/
1311
1204
        /* Only show 'contains' label when folders selected are not empty */
1312
 
        if (count > selected_folders || contains_value.get_text ().length < 1) {
 
1205
        if (count > selected_folders || contains_value.label.length < 1) {
1313
1206
            contains_key_label.hide ();
1314
1207
            contains_value.hide ();
1315
1208
        } else { /* Make sure it shows otherwise (may have been hidden by previous call)*/