adapt master to develop
[taxeditor.git] / eu.etaxonomy.taxeditor.store / src / main / java / eu / etaxonomy / taxeditor / preference / wizard / CheckBoxTreeComposite.java
index d3cea9eab1a380c45a269bcb1fcfe0afda3a5706..e5b52e0d258fcbf714a62fd70b5b45ef54128257 100644 (file)
@@ -9,7 +9,10 @@
 package eu.etaxonomy.taxeditor.preference.wizard;
 
 import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashSet;
 import java.util.List;
+import java.util.Set;
 
 import org.eclipse.jface.resource.JFaceResources;
 import org.eclipse.jface.viewers.AbstractTreeViewer;
@@ -29,26 +32,30 @@ import org.eclipse.swt.widgets.Tree;
 import org.eclipse.swt.widgets.TreeItem;
 import org.eclipse.swt.widgets.Widget;
 
+import eu.etaxonomy.cdm.persistence.dto.TermDto;
+import eu.etaxonomy.cdm.persistence.dto.TermNodeDto;
 import eu.etaxonomy.taxeditor.l10n.Messages;
 import eu.etaxonomy.taxeditor.model.ImageResources;
 
 /**
  * @author pplitzner
  * @since Oct 26, 2018
- *
  */
 public class CheckBoxTreeComposite extends Composite implements SelectionListener {
 
     private static final Font FONT_DEFAULT = JFaceResources.getFontRegistry().get(JFaceResources.DEFAULT_FONT);
     private static final Font FONT_ITALIC = JFaceResources.getFontRegistry().getItalic(JFaceResources.DEFAULT_FONT);
-    private static final Font FONT_BOLD = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
-    private CheckboxTreeViewer viewer;
-    private Button btnCollapse;
-    private Button btnExpand;
-    private Button btnSelectAllChildren;
-    private Button btnSelectDirectChildren;
+    protected static final Font FONT_BOLD = JFaceResources.getFontRegistry().getBold(JFaceResources.DEFAULT_FONT);
+    protected CheckboxTreeViewer viewer;
+    protected Button btnCollapse;
+    protected Button btnExpand;
+    protected Button btnSelectAllChildren;
+    protected Button btnSelectDirectChildren;
+
+    protected Object[] checkedElements;
+
+    protected boolean allowTopLevelSelection = false;
 
-    private boolean allowTopLevelSelection = false;
 
     public CheckBoxTreeComposite(Composite parent, ITreeContentProvider contentProvider, IBaseLabelProvider labelProvider, int style) {
         super(parent, style);
@@ -84,6 +91,18 @@ public class CheckBoxTreeComposite extends Composite implements SelectionListene
         btnSelectAllChildren.setImage(ImageResources.getImage(ImageResources.HIERARCHICAL));
         btnSelectAllChildren.setToolTipText(""); //$NON-NLS-1$
 
+        Tree tree = createTree();
+
+        viewer = new CdmCheckBoxTreeViewer(tree);
+        viewer.setContentProvider(contentProvider);
+        viewer.setLabelProvider(labelProvider);
+    }
+
+
+    /**
+     * @return
+     */
+    protected Tree createTree() {
         Tree tree = new Tree(this, SWT.BORDER | SWT.CHECK);
         tree.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
         tree.addListener(SWT.Selection, event -> {
@@ -94,16 +113,47 @@ public class CheckBoxTreeComposite extends Composite implements SelectionListene
                     item.setChecked(false);
                     return;
                 }
+
+                if (item.getChecked()){
+                    if (checkedElements != null){
+                        Object[] tempArray = Arrays.copyOf(checkedElements, checkedElements.length +1);
+                        tempArray[checkedElements.length] = item.getData();
+                        checkedElements = tempArray;
+                    }
+                }else{
+
+                    if (checkedElements != null){
+                        updateAfterUnCheckElement(item);
+                    }
+                }
+
                 updateItem(item);
             }
         });
-        viewer = new CheckboxTreeViewer(tree);
-        viewer.setContentProvider(contentProvider);
-        viewer.setLabelProvider(labelProvider);
+        return tree;
     }
 
 
-    private void updateItem(TreeItem treeItem){
+    protected void updateAfterUnCheckElement(Object item) {
+        Object[] tempArray = new Object[checkedElements.length -1];
+
+        int index = 0;
+        for (Object o:checkedElements){
+            Object element = null;
+            if (item instanceof TreeItem) {
+                element = ((TreeItem)item).getData();
+            }else {
+                element = item;
+            }
+            if (o != null && !o.equals(element)){
+               tempArray[index] = o;
+               index++;
+            }
+        }
+        checkedElements = tempArray;
+    }
+
+    protected void updateItem(TreeItem treeItem){
         TreeItem parentItem = treeItem.getParentItem();
         if(parentItem!=null){
             updateItem(parentItem);
@@ -122,7 +172,8 @@ public class CheckBoxTreeComposite extends Composite implements SelectionListene
         int checkedCount = 0;
         for (TreeItem child : children) {
             updateChildItems(child);
-            if(child.getChecked()){
+
+            if(child.getChecked() ){
                 if ((child.getFont().equals(FONT_BOLD)) || (child.getItems().length == 0)) {
                     checkedCount++;
                 }
@@ -149,6 +200,7 @@ public class CheckBoxTreeComposite extends Composite implements SelectionListene
                 treeItem.setFont(FONT_DEFAULT);
             }
         }
+
     }
 
 
@@ -165,7 +217,25 @@ public class CheckBoxTreeComposite extends Composite implements SelectionListene
      * @param elements
      */
     public void setCheckedElements(Object[] elements) {
+
+        this.checkedElements = elements;
         viewer.setCheckedElements(elements);
+        for (Object element: checkedElements) {
+            viewer.reveal(element);
+        }
+        TreeItem[] rootItems = viewer.getTree().getItems();
+        for (TreeItem rootItem : rootItems) {
+            updateItem(rootItem);
+        }
+
+    }
+
+    /**
+     * Grays the tree items corresponding to the given elements.<br>
+     * @param elements
+     */
+    public void setGrayedElements(Object[] elements) {
+        viewer.setGrayedElements(elements);
         for (Object element: elements) {
             viewer.reveal(element);
         }
@@ -194,23 +264,84 @@ public class CheckBoxTreeComposite extends Composite implements SelectionListene
                 List<TreeItem> childItemList = Arrays.asList(childItems);
                 boolean allChecked = childItemList.stream().allMatch(childItem->childItem.getChecked());
                 childItemList.stream().forEach(childItem->childItem.setChecked(!allChecked));
-                TreeItem parent = getRoot(treeItem);
-                updateItem(parent);
+                if (!allChecked) {
+                    for (TreeItem updateItem: childItemList) {
+                        updateAfterCheckElement(updateItem);
+                    }
+
+                }else {
+                    for (TreeItem updateItem: childItemList) {
+                        updateAfterUnCheckElement(updateItem);
+                    }
+                }
+
+
             }
         }
         else if(e.widget == btnSelectAllChildren){
             Widget item = viewer.testFindItem(firstElement);
             if(item instanceof TreeItem){
                 viewer.expandToLevel(firstElement, AbstractTreeViewer.ALL_LEVELS);
-                viewer.setSubtreeChecked(firstElement, !((TreeItem) item).getFont().equals(FONT_BOLD));
-                TreeItem parent = getRoot((TreeItem) item);
-                updateItem(parent);
+                Set<TreeItem> childrenSet = getSubTreeItems((TreeItem)item);
+                Object[] children = childrenSet.toArray();
+                boolean checked = true;
+                if (children == null) {
+                    return;
+                }
+                if (children != null && ((TreeItem)children[0]).getChecked()) {
+                    checked = false;
+                }
+                viewer.setSubtreeChecked(firstElement, checked);
                 ((TreeItem) item).setChecked(false);
+                Object[] checkedElements = viewer.getCheckedElements();
+
+                for (Object updateItem: children) {
+                    if (((TreeItem)children[0]).getChecked()) {
+                        updateAfterCheckElement(updateItem);
+                    }else {
+                        updateAfterUnCheckElement(updateItem);
+                    }
+                }
+
             }
         }
     }
 
-    private TreeItem getRoot(TreeItem treeItem) {
+    private void updateAfterCheckElement(Object item) {
+        Set<Object> tempList = new HashSet<>();
+        if (checkedElements != null) {
+            Collections.addAll(tempList, checkedElements);
+        }
+        TermNodeDto checkedNode = null;
+        TermDto checkedTerm = null;
+        TreeItem treeItem = null;
+        if (item instanceof TreeItem) {
+             treeItem = (TreeItem) item;
+             if (treeItem.getData() instanceof TermNodeDto) {
+                 checkedNode = (TermNodeDto)treeItem.getData();
+                 checkedTerm = checkedNode.getTerm();
+             }else if (treeItem.getData() instanceof TermDto) {
+                 checkedTerm = (TermDto)treeItem.getData();
+             }else {
+                 return;
+             }
+        }else  if (item instanceof TermNodeDto) {
+            checkedNode = (TermNodeDto)item;
+            checkedTerm = checkedNode.getTerm();
+        }else if (item instanceof TermDto) {
+            checkedTerm = (TermDto)item;
+        }else {
+            return;
+        }
+        if (checkedTerm != null) {
+            tempList.add(checkedTerm);
+        }
+
+        setCheckedElements(tempList.toArray());
+
+    }
+
+    protected TreeItem getRoot(TreeItem treeItem) {
         TreeItem parent = treeItem;
         while(parent.getParentItem()!=null){
             parent = parent.getParentItem();
@@ -218,8 +349,23 @@ public class CheckBoxTreeComposite extends Composite implements SelectionListene
         return parent;
     }
 
+    public Object[] getCheckedElements() {
+        return checkedElements;
+    }
+    private Set<TreeItem> getSubTreeItems(TreeItem parent) {
+        Set<TreeItem> children = new HashSet<>();
+
+        if (parent.getItems() != null) {
+            children.addAll(Arrays.asList(parent.getItems()));
+            for(TreeItem child : parent.getItems()) {
+                children.addAll(getSubTreeItems(child));
+            }
+        }
+        return children;
+    }
+
+
     @Override
     public void widgetDefaultSelected(SelectionEvent e) {
     }
-
-}
+}
\ No newline at end of file