Project

General

Profile

« Previous | Next » 

Revision 9ab27a32

Added by Patrick Plitzner over 3 years ago

ref #7912 Fix selection states in checkbox viewer

View differences:

eu.etaxonomy.taxeditor.store/src/main/java/eu/etaxonomy/taxeditor/preference/wizard/CheckBoxTreeComposite.java
40 40
    private static final Font FONT_BOLD = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
41 41
    private CheckboxTreeViewer viewer;
42 42
    private Button btnCollapse;
43
    private Button btnSelectChildren;
44 43
    private Button btnExpand;
45 44
    private Button btnSelectAllChildren;
46 45

  
......
58 57
        btnCollapse = new Button(toolbar, SWT.NONE);
59 58
        btnCollapse.addSelectionListener(this);
60 59
        btnCollapse.setImage(ImageResources.getImage(ImageResources.COLLAPSE_ALL));
60
        btnCollapse.setToolTipText("Collapse All");
61 61

  
62 62
        btnExpand = new Button(toolbar, SWT.NONE);
63 63
        btnExpand.addSelectionListener(this);
64 64
        btnExpand.setImage(ImageResources.getImage(ImageResources.EXPAND));
65
        btnExpand.setToolTipText("Expand Selected Node");
65 66

  
66 67
        btnSelectAllChildren = new Button(toolbar, SWT.NONE);
67 68
        btnSelectAllChildren.addSelectionListener(this);
68 69
        btnSelectAllChildren.setImage(ImageResources.getImage(ImageResources.HIERARCHICAL));
70
        btnSelectAllChildren.setToolTipText("Toggle Selection on all children");
69 71

  
70
        btnSelectChildren = new Button(toolbar, SWT.NONE);
71
        btnSelectChildren.addSelectionListener(this);
72
        btnSelectChildren.setImage(ImageResources.getImage(ImageResources.FLAT));
73
        btnSelectChildren.setVisible(false);
74 72
        Tree tree = new Tree(composite, SWT.BORDER | SWT.CHECK);
75 73
        tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
76 74
        tree.addListener(SWT.Selection, event -> {
77 75
            if (event.detail == SWT.CHECK) {
78 76
                TreeItem item = (TreeItem) event.item;
79
                boolean checked = item.getChecked();
80
                item.setGrayed(false);
81
                item.setChecked(checked);
82
                checkPath(item, checked, false);
77
                updateItem(item);
83 78
            }
84 79
        });
85 80
        viewer = new CheckboxTreeViewer(tree);
......
87 82
        viewer.setLabelProvider(labelProvider);
88 83
    }
89 84

  
90
    private void checkPath(TreeItem item, boolean checked, boolean grayed) {
91
        if (item == null) {
92
            return;
85

  
86
    private void updateItem(TreeItem treeItem){
87
        TreeItem parentItem = treeItem.getParentItem();
88
        if(parentItem!=null){
89
            updateItem(parentItem);
93 90
        }
94
        TreeItem[] items = item.getItems();
95
        if (grayed) {
96
            checked = true;
97
        } else {
98
            int index = 0;
99
            while (index < items.length) {
100
                TreeItem child = items[index];
101
                if (child.getGrayed() || checked != child.getChecked()) {
102
                    checked = grayed = true;
103
                    break;
104
                }
105
                index++;
106
            }
91
        updateChildItems(treeItem);
92
    }
93

  
94
    private CheckState updateChildItems(TreeItem treeItem){
95
        CheckState checkState = CheckState.NONE;
96
        TreeItem[] children = treeItem.getItems();
97
        if(children.length==0){
98
            return treeItem.getChecked()?CheckState.CHECKED:CheckState.NONE;
107 99
        }
108
        item.setGrayed(grayed);
109
        if(checked && items.length>0){
110
            item.setFont(FONT_BOLD);
111
            if(grayed){
112
                item.setFont(FONT_ITALIC);
100
        int checkedCount = 0;
101
        for (TreeItem child : children) {
102
            CheckState childState = updateChildItems(child);
103
            if(childState.equals(CheckState.CHECKED)) {
104
                checkedCount++;
105
            }
106
            else if(childState.equals(CheckState.GRAYED)){
107
                treeItem.setFont(FONT_ITALIC);
108
                return CheckState.GRAYED;
113 109
            }
114 110
        }
115
        else{
116
            item.setFont(FONT_DEFAULT);
111
        if(checkedCount==children.length){
112
            //all children are checked
113
            checkState = CheckState.CHECKED;
114
            treeItem.setFont(FONT_BOLD);
117 115
        }
118
        item.setExpanded(true);
119
        checkPath(item.getParentItem(), checked, grayed);
120
    }
121

  
122
    private void checkItems(TreeItem item, boolean checked, boolean recurseAll) {
123
        item.setGrayed(false);
124
        item.setChecked(checked);
125
        TreeItem[] items = item.getItems();
126
        if(items.length!=0){
127
            item.setFont(FONT_BOLD);
116
        else if(checkedCount>0){
117
            //some children are checked
118
            checkState = CheckState.GRAYED;
119
            treeItem.setFont(FONT_ITALIC);
128 120
        }
129
        for (int i = 0; i < items.length; i++) {
130
            if(recurseAll){
131
                checkItems(items[i], checked, true);
121
        else{
122
            //no children are checked
123
            treeItem.setFont(FONT_DEFAULT);
124
            if(treeItem.getChecked()){
125
                //no children but item itself is checked
126
                checkState = CheckState.CHECKED;
132 127
            }
133 128
            else{
134
                //                items[i].setGrayed(false);
135
                //                items[i].setChecked(checked);
136
                //                TreeItem[] children = items[i].getItems();
137
                //                for (TreeItem child : children) {
138
                //                    child.setExpanded(true);
139
                //                    checkItems(child, false, false);
140
                //                    checkPath(child, false, false);
141
                //                }
129
                //neither children nor item itself is checked
130
                checkState = CheckState.NONE;
142 131
            }
143 132
        }
133
        return checkState;
144 134
    }
145 135

  
146 136
    public CheckboxTreeViewer getViewer() {
......
153 143
     */
154 144
    public void setCheckedElements(Object[] elements) {
155 145
        viewer.setCheckedElements(elements);
156
        for (Object element : elements) {
157
            Widget item = viewer.testFindItem(element);
158
            if(item instanceof TreeItem){
159
                checkPath((TreeItem) item, true, false);
160
            }
146
        for (Object element: elements) {
147
            viewer.reveal(element);
148
        }
149
        TreeItem[] rootItems = viewer.getTree().getItems();
150
        for (TreeItem rootItem : rootItems) {
151
            updateItem(rootItem);
161 152
        }
162 153
    }
163 154

  
......
171 162
        else if(e.widget == btnExpand){
172 163
            viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
173 164
        }
174
        else if(e.widget == btnSelectChildren){
175
            TreeItem item = (TreeItem) viewer.testFindItem(firstElement);
176
            if(item!=null){
177
                viewer.expandToLevel(firstElement, 1);
178
                boolean checked = !item.getChecked();
179
                checkItems(item, checked, false);
180
                checkPath(item, checked, false);
181
            }
182
        }
183 165
        else if(e.widget == btnSelectAllChildren){
184
            viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
185
            TreeItem item = (TreeItem) viewer.testFindItem(firstElement);
166
            Widget item = viewer.testFindItem(firstElement);
167
            boolean checked = false;
168
            Object[] checkedElements = viewer.getCheckedElements();
169
            for (Object checkedElement : checkedElements) {
170
                if(checkedElement.equals(firstElement)){
171
                    checked = true;
172
                    break;
173
                }
174
            }
186 175
            if(item!=null){
187
                boolean checked = !item.getChecked();
188
                checkItems(item, checked, true);
189
                checkPath(item, checked, false);
176
                viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
177
                viewer.setSubtreeChecked(firstElement, !checked);
178
                TreeItem[] rootItems = viewer.getTree().getItems();
179
                for (TreeItem rootItem : rootItems) {
180
                    updateItem(rootItem);
181
                }
190 182
            }
191 183
        }
192 184
    }
......
195 187
    public void widgetDefaultSelected(SelectionEvent e) {
196 188
    }
197 189

  
198
    public Button getBtnCollapse() {
199
        return btnCollapse;
200
    }
201
    public Button getBtnSelectChildren() {
202
        return btnSelectChildren;
190
    private enum CheckState{
191
        CHECKED,
192
        GRAYED,
193
        NONE
203 194
    }
204 195

  
205
    public Button getBtnExpand() {
206
        return btnExpand;
207
    }
208
    public Button getBtnSelectAllChildren() {
209
        return btnSelectAllChildren;
210
    }
211 196
}

Also available in: Unified diff