Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java49
-rw-r--r--lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java1203
2 files changed, 1249 insertions, 3 deletions
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java
index efa8d8f1b9..1d00000ab6 100644
--- a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ImportTraceWizardPage.java
@@ -49,6 +49,8 @@ import org.eclipse.jface.dialogs.IDialogSettings;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.operation.ModalContext;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.ICheckStateListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.linuxtools.internal.tmf.ui.Activator;
@@ -86,9 +88,12 @@ import org.eclipse.ui.IWorkbench;
import org.eclipse.ui.dialogs.FileSystemElement;
import org.eclipse.ui.dialogs.IOverwriteQuery;
import org.eclipse.ui.dialogs.WizardResourceImportPage;
+import org.eclipse.ui.internal.ide.DialogUtil;
import org.eclipse.ui.internal.ide.dialogs.IElementFilter;
import org.eclipse.ui.model.AdaptableList;
import org.eclipse.ui.model.WorkbenchContentProvider;
+import org.eclipse.ui.model.WorkbenchLabelProvider;
+import org.eclipse.ui.model.WorkbenchViewerComparator;
import org.eclipse.ui.wizards.datatransfer.FileSystemStructureProvider;
import org.eclipse.ui.wizards.datatransfer.IImportStructureProvider;
import org.eclipse.ui.wizards.datatransfer.ImportOperation;
@@ -149,6 +154,15 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
/** The directory browse button. */
protected Button directoryBrowseButton;
+ /**
+ * ResourceTreeAndListGroup was internal in Kepler and we referenced it. It
+ * is now removed in Luna. To keep our builds compatible with Kepler, we
+ * need to have our own version of this class. Once we stop supporting
+ * Kepler, we can delete this class and use the public one from the
+ * platform.
+ */
+ private ResourceTreeAndListGroup fSelectionGroup;
+
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
@@ -166,6 +180,35 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
}
/**
+ * Create the import source selection widget. (Copied from WizardResourceImportPage
+ * but instead always uses the internal ResourceTreeAndListGroup to keep compatibility
+ * with Kepler)
+ */
+ @Override
+ protected void createFileSelectionGroup(Composite parent) {
+
+ //Just create with a dummy root.
+ fSelectionGroup = new ResourceTreeAndListGroup(parent,
+ new FileSystemElement("Dummy", null, true),//$NON-NLS-1$
+ getFolderProvider(), new WorkbenchLabelProvider(),
+ getFileProvider(), new WorkbenchLabelProvider(), SWT.NONE,
+ DialogUtil.inRegularFontMode(parent));
+
+ ICheckStateListener listener = new ICheckStateListener() {
+ @Override
+ public void checkStateChanged(CheckStateChangedEvent event) {
+ updateWidgetEnablements();
+ }
+ };
+
+ WorkbenchViewerComparator comparator = new WorkbenchViewerComparator();
+ fSelectionGroup.setTreeComparator(comparator);
+ fSelectionGroup.setListComparator(comparator);
+ fSelectionGroup.addCheckStateListener(listener);
+
+ }
+
+ /**
* Constructor
*
* @param workbench
@@ -459,7 +502,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
// ------------------------------------------------------------------------
private void resetSelection() {
TraceFileSystemElement root = getFileSystemTree();
- selectionGroup.setRoot(root);
+ fSelectionGroup.setRoot(root);
}
private TraceFileSystemElement getFileSystemTree() {
@@ -603,7 +646,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
return false;
}
- if (selectionGroup.getCheckedElementCount() == 0) {
+ if (fSelectionGroup.getCheckedElementCount() == 0) {
setMessage(null);
setErrorMessage(Messages.ImportTraceWizard_SelectTraceNoneSelected);
return false;
@@ -785,7 +828,7 @@ public class ImportTraceWizardPage extends WizardResourceImportPage {
// List fileSystemElements will be filled using the passThroughFilter
SubMonitor subMonitor = SubMonitor.convert(progressMonitor, 1);
- getSelectedResources(passThroughFilter, subMonitor);
+ fSelectionGroup.getAllCheckedListItems(passThroughFilter, subMonitor);
// Check if operation was cancelled.
ModalContext.checkCanceled(subMonitor);
diff --git a/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java
new file mode 100644
index 0000000000..d57a20cb36
--- /dev/null
+++ b/lttng/org.eclipse.linuxtools.tmf.ui/src/org/eclipse/linuxtools/tmf/ui/project/wizards/importtrace/ResourceTreeAndListGroup.java
@@ -0,0 +1,1203 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2014 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ * Marc-Andre Laperle - Copied from platform (org.eclipse.ui.internal.ide.dialogs)
+ *******************************************************************************/
+package org.eclipse.linuxtools.tmf.ui.project.wizards.importtrace;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.eclipse.core.commands.common.EventManager;
+import org.eclipse.core.resources.IWorkspaceRoot;
+import org.eclipse.core.runtime.IPath;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.core.runtime.SafeRunner;
+import org.eclipse.jface.util.SafeRunnable;
+import org.eclipse.jface.viewers.CheckStateChangedEvent;
+import org.eclipse.jface.viewers.CheckboxTableViewer;
+import org.eclipse.jface.viewers.CheckboxTreeViewer;
+import org.eclipse.jface.viewers.ICheckStateListener;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.ITreeViewerListener;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.TreeExpansionEvent;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.BusyIndicator;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.Tree;
+import org.eclipse.ui.internal.ide.dialogs.IElementFilter;
+
+/**
+ * Workbench-level composite that combines a CheckboxTreeViewer and CheckboxListViewer.
+ * All viewer selection-driven interactions are handled within this object
+ */
+@SuppressWarnings({"restriction", "rawtypes", "javadoc", "unchecked"})
+class ResourceTreeAndListGroup extends EventManager implements
+ ICheckStateListener, ISelectionChangedListener, ITreeViewerListener {
+ private Object root;
+
+ private Object currentTreeSelection;
+
+ private Collection expandedTreeNodes = new HashSet();
+
+ private Map checkedStateStore = new HashMap(9);
+
+ private HashSet whiteCheckedTreeItems = new HashSet();
+
+ private ITreeContentProvider treeContentProvider;
+
+ private IStructuredContentProvider listContentProvider;
+
+ private ILabelProvider treeLabelProvider;
+
+ private ILabelProvider listLabelProvider;
+
+ // widgets
+ private CheckboxTreeViewer treeViewer;
+
+ private CheckboxTableViewer listViewer;
+
+ //height hint for viewers
+ private static int PREFERRED_HEIGHT = 150;
+
+ /**
+ * Create an instance of this class. Use this constructor if you wish to specify
+ * the width and/or height of the combined widget (to only hardcode one of the
+ * sizing dimensions, specify the other dimension's value as -1)
+ *
+ * @param parent
+ * @param rootObject
+ * @param treeContentProvider
+ * @param treeLabelProvider
+ * @param listContentProvider
+ * @param listLabelProvider
+ * @param style
+ * @param useHeightHint If true then use the height hint
+ * to make this group big enough
+ *
+ */
+ public ResourceTreeAndListGroup(Composite parent, Object rootObject,
+ ITreeContentProvider treeContentProvider,
+ ILabelProvider treeLabelProvider,
+ IStructuredContentProvider listContentProvider,
+ ILabelProvider listLabelProvider, int style, boolean useHeightHint) {
+
+ root = rootObject;
+ this.treeContentProvider = treeContentProvider;
+ this.listContentProvider = listContentProvider;
+ this.treeLabelProvider = treeLabelProvider;
+ this.listLabelProvider = listLabelProvider;
+ createContents(parent, style, useHeightHint);
+ }
+
+ /**
+ * This method must be called just before this window becomes visible.
+ */
+ public void aboutToOpen() {
+ determineWhiteCheckedDescendents(root);
+ checkNewTreeElements(treeContentProvider.getElements(root));
+ currentTreeSelection = null;
+
+ //select the first element in the list
+ Object[] elements = treeContentProvider.getElements(root);
+ Object primary = elements.length > 0 ? elements[0] : null;
+ if (primary != null) {
+ treeViewer.setSelection(new StructuredSelection(primary));
+ }
+ treeViewer.getControl().setFocus();
+ }
+
+ /**
+ * Add the passed listener to self's collection of clients
+ * that listen for changes to element checked states
+ *
+ * @param listener ICheckStateListener
+ */
+ public void addCheckStateListener(ICheckStateListener listener) {
+ addListenerObject(listener);
+ }
+
+ /**
+ * Return a boolean indicating whether all children of the passed tree element
+ * are currently white-checked
+ *
+ * @return boolean
+ * @param treeElement java.lang.Object
+ */
+ protected boolean areAllChildrenWhiteChecked(Object treeElement) {
+ Object[] children = treeContentProvider.getChildren(treeElement);
+ for (int i = 0; i < children.length; ++i) {
+ if (!whiteCheckedTreeItems.contains(children[i])) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ /**
+ * Return a boolean indicating whether all list elements associated with
+ * the passed tree element are currently checked
+ *
+ * @return boolean
+ * @param treeElement java.lang.Object
+ */
+ protected boolean areAllElementsChecked(Object treeElement) {
+ List checkedElements = (List) checkedStateStore.get(treeElement);
+ if (checkedElements == null) {
+ return false;
+ }
+
+ return getListItemsSize(treeElement) == checkedElements.size();
+ }
+
+ /**
+ * Iterate through the passed elements which are being realized for the first
+ * time and check each one in the tree viewer as appropriate
+ */
+ protected void checkNewTreeElements(Object[] elements) {
+ for (int i = 0; i < elements.length; ++i) {
+ Object currentElement = elements[i];
+ boolean checked = checkedStateStore.containsKey(currentElement);
+ treeViewer.setChecked(currentElement, checked);
+ treeViewer.setGrayed(currentElement, checked
+ && !whiteCheckedTreeItems.contains(currentElement));
+ }
+ }
+
+ /**
+ * An item was checked in one of self's two views. Determine which
+ * view this occurred in and delegate appropriately
+ *
+ * @param event CheckStateChangedEvent
+ */
+ @Override
+ public void checkStateChanged(final CheckStateChangedEvent event) {
+
+ //Potentially long operation - show a busy cursor
+ BusyIndicator.showWhile(treeViewer.getControl().getDisplay(),
+ new Runnable() {
+ @Override
+ public void run() {
+ if (event.getCheckable().equals(treeViewer)) {
+ treeItemChecked(event.getElement(), event
+ .getChecked());
+ } else {
+ listItemChecked(event.getElement(), event
+ .getChecked(), true);
+ }
+
+ notifyCheckStateChangeListeners(event);
+ }
+ });
+ }
+
+ /**
+ * Lay out and initialize self's visual components.
+ *
+ * @param parent org.eclipse.swt.widgets.Composite
+ * @param style the style flags for the new Composite
+ * @param useHeightHint If true yse the preferredHeight.
+ */
+ protected void createContents(Composite parent, int style,
+ boolean useHeightHint) {
+ // group pane
+ Composite composite = new Composite(parent, style);
+ composite.setFont(parent.getFont());
+ GridLayout layout = new GridLayout();
+ layout.numColumns = 2;
+ layout.makeColumnsEqualWidth = true;
+ layout.marginHeight = 0;
+ layout.marginWidth = 0;
+ composite.setLayout(layout);
+ composite.setLayoutData(new GridData(GridData.FILL_BOTH));
+
+ createTreeViewer(composite, useHeightHint);
+ createListViewer(composite, useHeightHint);
+
+ initialize();
+ }
+
+ /**
+ * Create this group's list viewer.
+ */
+ protected void createListViewer(Composite parent, boolean useHeightHint) {
+ listViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ if (useHeightHint) {
+ data.heightHint = PREFERRED_HEIGHT;
+ }
+ listViewer.getTable().setLayoutData(data);
+ listViewer.getTable().setFont(parent.getFont());
+ listViewer.setContentProvider(listContentProvider);
+ listViewer.setLabelProvider(listLabelProvider);
+ listViewer.addCheckStateListener(this);
+ }
+
+ /**
+ * Create this group's tree viewer.
+ */
+ protected void createTreeViewer(Composite parent, boolean useHeightHint) {
+ Tree tree = new Tree(parent, SWT.CHECK | SWT.BORDER);
+ GridData data = new GridData(GridData.FILL_BOTH);
+ if (useHeightHint) {
+ data.heightHint = PREFERRED_HEIGHT;
+ }
+ tree.setLayoutData(data);
+ tree.setFont(parent.getFont());
+
+ treeViewer = new CheckboxTreeViewer(tree);
+ treeViewer.setContentProvider(treeContentProvider);
+ treeViewer.setLabelProvider(treeLabelProvider);
+ treeViewer.addTreeListener(this);
+ treeViewer.addCheckStateListener(this);
+ treeViewer.addSelectionChangedListener(this);
+ }
+
+ /**
+ * Returns a boolean indicating whether the passed tree element should be
+ * at LEAST gray-checked. Note that this method does not consider whether
+ * it should be white-checked, so a specified tree item which should be
+ * white-checked will result in a <code>true</code> answer from this method.
+ * To determine whether a tree item should be white-checked use method
+ * #determineShouldBeWhiteChecked(Object).
+ *
+ * @param treeElement java.lang.Object
+ * @return boolean
+ * @see #determineShouldBeWhiteChecked(Object)
+ */
+ protected boolean determineShouldBeAtLeastGrayChecked(Object treeElement) {
+ // if any list items associated with treeElement are checked then it
+ // retains its gray-checked status regardless of its children
+ List checked = (List) checkedStateStore.get(treeElement);
+ if (checked != null && (!checked.isEmpty())) {
+ return true;
+ }
+
+ // if any children of treeElement are still gray-checked then treeElement
+ // must remain gray-checked as well. Only ask expanded nodes
+ if (expandedTreeNodes.contains(treeElement)) {
+ Object[] children = treeContentProvider.getChildren(treeElement);
+ for (int i = 0; i < children.length; ++i) {
+ if (checkedStateStore.containsKey(children[i])) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns a boolean indicating whether the passed tree item should be
+ * white-checked.
+ *
+ * @return boolean
+ * @param treeElement java.lang.Object
+ */
+ protected boolean determineShouldBeWhiteChecked(Object treeElement) {
+ return areAllChildrenWhiteChecked(treeElement)
+ && areAllElementsChecked(treeElement);
+ }
+
+ /**
+ * Recursively add appropriate tree elements to the collection of
+ * known white-checked tree elements.
+ *
+ * @param treeElement java.lang.Object
+ */
+ protected void determineWhiteCheckedDescendents(Object treeElement) {
+ // always go through all children first since their white-checked
+ // statuses will be needed to determine the white-checked status for
+ // this tree element
+ Object[] children = treeContentProvider.getElements(treeElement);
+ for (int i = 0; i < children.length; ++i) {
+ determineWhiteCheckedDescendents(children[i]);
+ }
+
+ // now determine the white-checked status for this tree element
+ if (determineShouldBeWhiteChecked(treeElement)) {
+ setWhiteChecked(treeElement, true);
+ }
+ }
+
+ /**
+ * Cause the tree viewer to expand all its items
+ */
+ public void expandAll() {
+ treeViewer.expandAll();
+ }
+
+ /**
+ * Expand an element in a tree viewer
+ */
+ private void expandTreeElement(final Object item) {
+ BusyIndicator.showWhile(treeViewer.getControl().getDisplay(),
+ new Runnable() {
+ @Override
+ public void run() {
+
+ // First see if the children need to be given their checked state at all. If they've
+ // already been realized then this won't be necessary
+ if (expandedTreeNodes.contains(item)) {
+ checkNewTreeElements(treeContentProvider
+ .getChildren(item));
+ } else {
+
+ expandedTreeNodes.add(item);
+ if (whiteCheckedTreeItems.contains(item)) {
+ //If this is the first expansion and this is a white checked node then check the children
+ Object[] children = treeContentProvider
+ .getChildren(item);
+ for (int i = 0; i < children.length; ++i) {
+ if (!whiteCheckedTreeItems
+ .contains(children[i])) {
+ Object child = children[i];
+ setWhiteChecked(child, true);
+ treeViewer.setChecked(child, true);
+ checkedStateStore.put(child,
+ new ArrayList());
+ }
+ }
+
+ //Now be sure to select the list of items too
+ setListForWhiteSelection(item);
+ }
+ }
+
+ }
+ });
+ }
+
+ /**
+ * Add all of the selected children of nextEntry to result recursively.
+ * This does not set any values in the checked state.
+ * @param treeElement The tree elements being queried
+ * @param addAll a boolean to indicate if the checked state store needs to be queried
+ * @param filter IElementFilter - the filter being used on the data
+ * @param monitor IProgressMonitor or null that the cancel is polled for
+ */
+ private void findAllSelectedListElements(Object treeElement,
+ String parentLabel, boolean addAll, IElementFilter filter,
+ IProgressMonitor monitor) throws InterruptedException {
+
+ String fullLabel = null;
+ if (monitor != null && monitor.isCanceled()) {
+ return;
+ }
+ if (monitor != null) {
+ fullLabel = getFullLabel(treeElement, parentLabel);
+ monitor.subTask(fullLabel);
+ }
+
+ if (addAll) {
+ filter.filterElements(listContentProvider.getElements(treeElement),
+ monitor);
+ } else { //Add what we have stored
+ if (checkedStateStore.containsKey(treeElement)) {
+ filter.filterElements((Collection) checkedStateStore
+ .get(treeElement), monitor);
+ }
+ }
+
+ Object[] treeChildren = treeContentProvider.getChildren(treeElement);
+ for (int i = 0; i < treeChildren.length; i++) {
+ Object child = treeChildren[i];
+ if (addAll) {
+ findAllSelectedListElements(child, fullLabel, true, filter,
+ monitor);
+ } else { //Only continue for those with checked state
+ if (checkedStateStore.containsKey(child)) {
+ findAllSelectedListElements(child, fullLabel,
+ whiteCheckedTreeItems.contains(child), filter,
+ monitor);
+ }
+ }
+
+ }
+ }
+
+ /**
+ * Find all of the white checked children of the treeElement and add them to the collection.
+ * If the element itself is white select add it. If not then add any selected list elements
+ * and recurse down to the children.
+ * @param treeElement java.lang.Object
+ * @param result java.util.Collection
+ */
+ private void findAllWhiteCheckedItems(Object treeElement, Collection result) {
+
+ if (whiteCheckedTreeItems.contains(treeElement)) {
+ result.add(treeElement);
+ } else {
+ Collection listChildren = (Collection) checkedStateStore
+ .get(treeElement);
+ //if it is not in the store then it and it's children are not interesting
+ if (listChildren == null) {
+ return;
+ }
+ result.addAll(listChildren);
+ Object[] children = treeContentProvider.getChildren(treeElement);
+ for (int i = 0; i < children.length; ++i) {
+ findAllWhiteCheckedItems(children[i], result);
+ }
+ }
+ }
+
+ /**
+ * Returns a flat list of all of the leaf elements which are checked. Filter
+ * then based on the supplied ElementFilter. If monitor is cancelled then
+ * return null
+ *
+ * @param filter -
+ * the filter for the data
+ * @param monitor
+ * IProgressMonitor or null
+ * @throws InterruptedException
+ * If the find is interrupted.
+ */
+ public void getAllCheckedListItems(IElementFilter filter,
+ IProgressMonitor monitor) throws InterruptedException {
+
+ //Iterate through the children of the root as the root is not in the store
+ Object[] children = treeContentProvider.getChildren(root);
+ for (int i = 0; i < children.length; ++i) {
+ findAllSelectedListElements(children[i], null,
+ whiteCheckedTreeItems.contains(children[i]), filter,
+ monitor);
+ }
+ }
+
+ /** Returns whether all items in the list are checked.
+ * This method is required, because this widget will keep items grey
+ * checked even though all children are selected (see grayUpdateHierarchy()).
+ * @return true if all items in the list are checked - false if not
+ */
+ public boolean isEveryItemChecked() {
+ //Iterate through the children of the root as the root is not in the store
+ Object[] children = treeContentProvider.getChildren(root);
+ for (int i = 0; i < children.length; ++i) {
+ if (!whiteCheckedTreeItems.contains(children[i])) {
+ if (!treeViewer.getGrayed(children[i])) {
+ return false;
+ }
+ if (!isEveryChildrenChecked(children[i])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**Verifies of all list items of the tree element are checked, and
+ * if all children are white checked. If not, verify their children
+ * so that if an element is not white checked, but all its children
+ * are while checked, then, all items are considered checked.
+ * @param treeElement the treeElement which status to verify
+ * @return true if all items are checked, false otherwise.
+ */
+ private boolean isEveryChildrenChecked(Object treeElement) {
+ List checked = (List) checkedStateStore.get(treeElement);
+ if (checked != null && (!checked.isEmpty())) {
+ Object[] listItems = listContentProvider.getElements(treeElement);
+ if (listItems.length != checked.size()) {
+ return false;
+ }
+ }
+ Object[] children = treeContentProvider.getChildren(treeElement);
+ for (int i = 0; i < children.length; ++i) {
+ if (!whiteCheckedTreeItems.contains(children[i])) {
+ if (!treeViewer.getGrayed(children[i])) {
+ return false;
+ }
+ if (!isEveryChildrenChecked(children[i])) {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ /**
+ * Returns a flat list of all of the leaf elements which are checked.
+ *
+ * @return all of the leaf elements which are checked. This API does not
+ * return null in order to keep backwards compatibility.
+ */
+ public List getAllCheckedListItems() {
+
+ final ArrayList returnValue = new ArrayList();
+
+ IElementFilter passThroughFilter = new IElementFilter() {
+
+ @Override
+ public void filterElements(Collection elements,
+ IProgressMonitor monitor) {
+ returnValue.addAll(elements);
+ }
+
+ @Override
+ public void filterElements(Object[] elements,
+ IProgressMonitor monitor) {
+ for (int i = 0; i < elements.length; i++) {
+ returnValue.add(elements[i]);
+ }
+ }
+ };
+
+ try {
+ getAllCheckedListItems(passThroughFilter, null);
+ } catch (InterruptedException exception) {
+ return new ArrayList();
+ }
+ return returnValue;
+
+ }
+
+ /**
+ * Returns a flat list of all of the leaf elements.
+ *
+ * @return all of the leaf elements.
+ */
+ public List getAllListItems() {
+
+ final ArrayList returnValue = new ArrayList();
+
+ IElementFilter passThroughFilter = new IElementFilter() {
+
+ @Override
+ public void filterElements(Collection elements,
+ IProgressMonitor monitor) {
+ returnValue.addAll(elements);
+ }
+
+ @Override
+ public void filterElements(Object[] elements,
+ IProgressMonitor monitor) {
+ for (int i = 0; i < elements.length; i++) {
+ returnValue.add(elements[i]);
+ }
+ }
+ };
+
+ try {
+ Object[] children = treeContentProvider.getChildren(root);
+ for (int i = 0; i < children.length; ++i) {
+ findAllSelectedListElements(children[i], null, true, passThroughFilter,
+ null);
+ }
+ } catch (InterruptedException exception) {
+ return new ArrayList();
+ }
+ return returnValue;
+
+ }
+
+ /**
+ * Returns a list of all of the items that are white checked.
+ * Any folders that are white checked are added and then any files
+ * from white checked folders are added.
+ *
+ * @return the list of all of the items that are white checked
+ */
+ public List getAllWhiteCheckedItems() {
+
+ List result = new ArrayList();
+
+ //Iterate through the children of the root as the root is not in the store
+ Object[] children = treeContentProvider.getChildren(root);
+ for (int i = 0; i < children.length; ++i) {
+ findAllWhiteCheckedItems(children[i], result);
+ }
+
+ return result;
+ }
+
+ /**
+ * Answer the number of elements that have been checked by the
+ * user.
+ *
+ * @return int
+ */
+ public int getCheckedElementCount() {
+ return checkedStateStore.size();
+ }
+
+ /**
+ * Get the full label of the treeElement (its name and its parent's name).
+ * @param treeElement - the element being exported
+ * @param parentLabel - the label of the parent, can be null
+ * @return String
+ */
+ protected String getFullLabel(Object treeElement, String parentLabel) {
+ String label = parentLabel;
+ if (parentLabel == null){
+ label = ""; //$NON-NLS-1$
+ }
+ IPath parentName = new Path(label);
+
+ String elementText = treeLabelProvider.getText(treeElement);
+ if(elementText == null) {
+ return parentName.toString();
+ }
+ return parentName.append(elementText).toString();
+ }
+
+ /**
+ * Return a count of the number of list items associated with a
+ * given tree item.
+ *
+ * @return int
+ * @param treeElement java.lang.Object
+ */
+ protected int getListItemsSize(Object treeElement) {
+ Object[] elements = listContentProvider.getElements(treeElement);
+ return elements.length;
+ }
+
+ /**
+ * Get the table the list viewer uses.
+ * @return org.eclipse.swt.widgets.Table
+ */
+ public Table getListTable() {
+ return this.listViewer.getTable();
+ }
+
+ /**
+ * Logically gray-check all ancestors of treeItem by ensuring that they
+ * appear in the checked table
+ */
+ protected void grayCheckHierarchy(Object treeElement) {
+
+ //expand the element first to make sure we have populated for it
+ expandTreeElement(treeElement);
+
+ // if this tree element is already gray then its ancestors all are as well
+ if (checkedStateStore.containsKey(treeElement)) {
+ return; // no need to proceed upwards from here
+ }
+
+ checkedStateStore.put(treeElement, new ArrayList());
+ Object parent = treeContentProvider.getParent(treeElement);
+ if (parent != null) {
+ grayCheckHierarchy(parent);
+ }
+ }
+
+ /**
+ * Set the checked state of self and all ancestors appropriately. Do not white check anyone - this is
+ * only done down a hierarchy.
+ */
+ private void grayUpdateHierarchy(Object treeElement) {
+
+ boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement);
+
+ treeViewer.setGrayChecked(treeElement, shouldBeAtLeastGray);
+
+ if (whiteCheckedTreeItems.contains(treeElement)) {
+ whiteCheckedTreeItems.remove(treeElement);
+ }
+
+ // proceed up the tree element hierarchy
+ Object parent = treeContentProvider.getParent(treeElement);
+ if (parent != null) {
+ grayUpdateHierarchy(parent);
+ }
+ }
+
+ /**
+ * Set the initial checked state of the passed list element to true.
+ * @param element
+ */
+ public void initialCheckListItem(Object element) {
+ Object parent = treeContentProvider.getParent(element);
+ selectAndReveal(parent);
+ //Check the element in the viewer as if it had been manually checked
+ listViewer.setChecked(element, true);
+ //As this is not done from the UI then set the box for updating from the selection to false
+ listItemChecked(element, true, false);
+ grayUpdateHierarchy(parent);
+ }
+
+ /**
+ * Set the initial checked state of the passed element to true,
+ * as well as to all of its children and associated list elements
+ * @param element
+ */
+ public void initialCheckTreeItem(Object element) {
+ treeItemChecked(element, true);
+ selectAndReveal(element);
+ }
+
+ private void selectAndReveal(Object treeElement) {
+ treeViewer.reveal(treeElement);
+ IStructuredSelection selection = new StructuredSelection(treeElement);
+ treeViewer.setSelection(selection);
+ }
+
+ /**
+ * Initialize this group's viewers after they have been laid out.
+ */
+ protected void initialize() {
+ treeViewer.setInput(root);
+ this.expandedTreeNodes = new ArrayList();
+ this.expandedTreeNodes.add(root);
+
+ }
+
+ /**
+ * Callback that's invoked when the checked status of an item in the list
+ * is changed by the user. Do not try and update the hierarchy if we are building the
+ * initial list.
+ */
+ protected void listItemChecked(Object listElement, boolean state,
+ boolean updatingFromSelection) {
+ List checkedListItems = (List) checkedStateStore
+ .get(currentTreeSelection);
+ //If it has not been expanded do so as the selection of list items will affect gray state
+ if (!expandedTreeNodes.contains(currentTreeSelection)) {
+ expandTreeElement(currentTreeSelection);
+ }
+
+ if (state) {
+ if (checkedListItems == null) {
+ // since the associated tree item has gone from 0 -> 1 checked
+ // list items, tree checking may need to be updated
+ grayCheckHierarchy(currentTreeSelection);
+ checkedListItems = (List) checkedStateStore
+ .get(currentTreeSelection);
+ }
+ checkedListItems.add(listElement);
+ } else {
+ checkedListItems.remove(listElement);
+ if (checkedListItems.isEmpty()) {
+ // since the associated tree item has gone from 1 -> 0 checked
+ // list items, tree checking may need to be updated
+ ungrayCheckHierarchy(currentTreeSelection);
+ }
+ }
+
+ //Update the list with the selections if there are any
+ if (checkedListItems.size() > 0) {
+ checkedStateStore.put(currentTreeSelection, checkedListItems);
+ }
+ if (updatingFromSelection) {
+ grayUpdateHierarchy(currentTreeSelection);
+ }
+ }
+
+ /**
+ * Notify all checked state listeners that the passed element has had
+ * its checked state changed to the passed state
+ */
+ protected void notifyCheckStateChangeListeners(
+ final CheckStateChangedEvent event) {
+ Object[] array = getListeners();
+ for (int i = 0; i < array.length; i++) {
+ final ICheckStateListener l = (ICheckStateListener) array[i];
+ SafeRunner.run(new SafeRunnable() {
+ @Override
+ public void run() {
+ l.checkStateChanged(event);
+ }
+ });
+ }
+ }
+
+ /**
+ *Set the contents of the list viewer based upon the specified selected
+ *tree element. This also includes checking the appropriate list items.
+ *
+ *@param treeElement java.lang.Object
+ */
+ protected void populateListViewer(final Object treeElement) {
+ listViewer.setInput(treeElement);
+
+ //If the element is white checked but not expanded we have not set up all of the children yet
+ if (!(expandedTreeNodes.contains(treeElement))
+ && whiteCheckedTreeItems.contains(treeElement)) {
+
+ //Potentially long operation - show a busy cursor
+ BusyIndicator.showWhile(treeViewer.getControl().getDisplay(),
+ new Runnable() {
+ @Override
+ public void run() {
+ setListForWhiteSelection(treeElement);
+ listViewer.setAllChecked(true);
+ }
+ });
+
+ } else {
+ List listItemsToCheck = (List) checkedStateStore.get(treeElement);
+
+ if (listItemsToCheck != null) {
+ Iterator listItemsEnum = listItemsToCheck.iterator();
+ while (listItemsEnum.hasNext()) {
+ listViewer.setChecked(listItemsEnum.next(), true);
+ }
+ }
+ }
+ }
+
+ /**
+ * Logically gray-check all ancestors of treeItem by ensuring that they
+ * appear in the checked table. Add any elements to the selectedNodes
+ * so we can track that has been done.
+ */
+ private void primeHierarchyForSelection(Object item, Set selectedNodes) {
+
+ //Only prime it if we haven't visited yet
+ if (selectedNodes.contains(item)) {
+ return;
+ }
+
+ checkedStateStore.put(item, new ArrayList());
+
+ //mark as expanded as we are going to populate it after this
+ expandedTreeNodes.add(item);
+ selectedNodes.add(item);
+
+ Object parent = treeContentProvider.getParent(item);
+ if (parent != null) {
+ primeHierarchyForSelection(parent, selectedNodes);
+ }
+ }
+
+ /**
+ * Remove the passed listener from self's collection of clients
+ * that listen for changes to element checked states
+ *
+ * @param listener ICheckStateListener
+ */
+ public void removeCheckStateListener(ICheckStateListener listener) {
+ removeListenerObject(listener);
+ }
+
+ /**
+ * Handle the selection of an item in the tree viewer
+ *
+ * @param event SelectionChangedEvent
+ */
+ @Override
+ public void selectionChanged(SelectionChangedEvent event) {
+ IStructuredSelection selection = (IStructuredSelection) event
+ .getSelection();
+ Object selectedElement = selection.getFirstElement();
+ if (selectedElement == null) {
+ currentTreeSelection = null;
+ listViewer.setInput(currentTreeSelection);
+ return;
+ }
+
+ // ie.- if not an item deselection
+ if (selectedElement != currentTreeSelection) {
+ populateListViewer(selectedElement);
+ }
+
+ currentTreeSelection = selectedElement;
+ }
+
+ /**
+ * Select or deselect all of the elements in the tree depending on the value of the selection
+ * boolean. Be sure to update the displayed files as well.
+ * @param selection
+ */
+ public void setAllSelections(final boolean selection) {
+
+ //If there is no root there is nothing to select
+ if (root == null) {
+ return;
+ }
+
+ //Potentially long operation - show a busy cursor
+ BusyIndicator.showWhile(treeViewer.getControl().getDisplay(),
+ new Runnable() {
+ @Override
+ public void run() {
+ setTreeChecked(root, selection);
+ listViewer.setAllChecked(selection);
+ }
+ });
+ }
+
+ /**
+ * The treeElement has been white selected. Get the list for the element and
+ * set it in the checked state store.
+ * @param treeElement the element being updated
+ */
+ private void setListForWhiteSelection(Object treeElement) {
+
+ Object[] listItems = listContentProvider.getElements(treeElement);
+ List listItemsChecked = new ArrayList();
+ for (int i = 0; i < listItems.length; ++i) {
+ listItemsChecked.add(listItems[i]);
+ }
+
+ checkedStateStore.put(treeElement, listItemsChecked);
+ }
+
+ /**
+ * Set the list viewer's providers to those passed
+ *
+ * @param contentProvider ITreeContentProvider
+ * @param labelProvider ILabelProvider
+ */
+ public void setListProviders(IStructuredContentProvider contentProvider,
+ ILabelProvider labelProvider) {
+ listViewer.setContentProvider(contentProvider);
+ listViewer.setLabelProvider(labelProvider);
+ }
+
+ /**
+ * Set the comparator that is to be applied to self's list viewer
+ *
+ * @param comparator the sorter for the list
+ */
+ public void setListComparator(ViewerComparator comparator) {
+ listViewer.setComparator(comparator);
+ }
+
+ /**
+ * Set the root of the widget to be new Root. Regenerate all of the tables and lists from this
+ * value.
+ * @param newRoot
+ */
+ public void setRoot(Object newRoot) {
+ this.root = newRoot;
+ initialize();
+ }
+
+ /**
+ * Set the checked state of the passed tree element appropriately, and
+ * do so recursively to all of its child tree elements as well
+ */
+ protected void setTreeChecked(Object treeElement, boolean state) {
+
+ if (treeElement.equals(currentTreeSelection)) {
+ listViewer.setAllChecked(state);
+ }
+
+ if (state) {
+ setListForWhiteSelection(treeElement);
+ } else {
+ checkedStateStore.remove(treeElement);
+ }
+
+ setWhiteChecked(treeElement, state);
+ treeViewer.setChecked(treeElement, state);
+ treeViewer.setGrayed(treeElement, false);
+
+ // now logically check/uncheck all children as well if it has been expanded
+ if (expandedTreeNodes.contains(treeElement)) {
+ Object[] children = treeContentProvider.getChildren(treeElement);
+ for (int i = 0; i < children.length; ++i) {
+ setTreeChecked(children[i], state);
+ }
+ }
+ }
+
+ /**
+ * Set the tree viewer's providers to those passed
+ *
+ * @param contentProvider ITreeContentProvider
+ * @param labelProvider ILabelProvider
+ */
+ public void setTreeProviders(ITreeContentProvider contentProvider,
+ ILabelProvider labelProvider) {
+ treeViewer.setContentProvider(contentProvider);
+ treeViewer.setLabelProvider(labelProvider);
+ }
+
+ /**
+ * Set the comparator that is to be applied to self's tree viewer
+ *
+ * @param comparator the comparator for the tree
+ */
+ public void setTreeComparator(ViewerComparator comparator) {
+ treeViewer.setComparator(comparator);
+ }
+
+ /**
+ * Adjust the collection of references to white-checked tree elements appropriately.
+ *
+ * @param treeElement java.lang.Object
+ * @param isWhiteChecked boolean
+ */
+ protected void setWhiteChecked(Object treeElement, boolean isWhiteChecked) {
+ if (isWhiteChecked) {
+ if (!whiteCheckedTreeItems.contains(treeElement)) {
+ whiteCheckedTreeItems.add(treeElement);
+ }
+ } else {
+ whiteCheckedTreeItems.remove(treeElement);
+ }
+ }
+
+ /**
+ * Handle the collapsing of an element in a tree viewer
+ */
+ @Override
+ public void treeCollapsed(TreeExpansionEvent event) {
+ // We don't need to do anything with this
+ }
+
+ /**
+ * Handle the expansionsion of an element in a tree viewer
+ */
+ @Override
+ public void treeExpanded(TreeExpansionEvent event) {
+ expandTreeElement(event.getElement());
+ }
+
+ /**
+ * Callback that's invoked when the checked status of an item in the tree
+ * is changed by the user.
+ */
+ protected void treeItemChecked(Object treeElement, boolean state) {
+
+ // recursively adjust all child tree elements appropriately
+ setTreeChecked(treeElement, state);
+
+ Object parent = treeContentProvider.getParent(treeElement);
+
+ // workspace root is not shown in the tree, so ignore it
+ if (parent == null || parent instanceof IWorkspaceRoot) {
+ return;
+ }
+
+ // now update upwards in the tree hierarchy
+ if (state) {
+ grayCheckHierarchy(parent);
+ } else {
+ ungrayCheckHierarchy(parent);
+ }
+
+ //Update the hierarchy but do not white select the parent
+ grayUpdateHierarchy(parent);
+ }
+
+ /**
+ * Logically un-gray-check all ancestors of treeItem iff appropriate.
+ */
+ protected void ungrayCheckHierarchy(Object treeElement) {
+ if (!determineShouldBeAtLeastGrayChecked(treeElement)) {
+ checkedStateStore.remove(treeElement);
+ }
+
+ Object parent = treeContentProvider.getParent(treeElement);
+ if (parent != null) {
+ ungrayCheckHierarchy(parent);
+ }
+ }
+
+ /**
+ * Set the checked state of self and all ancestors appropriately
+ */
+ protected void updateHierarchy(Object treeElement) {
+
+ boolean whiteChecked = determineShouldBeWhiteChecked(treeElement);
+ boolean shouldBeAtLeastGray = determineShouldBeAtLeastGrayChecked(treeElement);
+
+ treeViewer.setChecked(treeElement, shouldBeAtLeastGray);
+ setWhiteChecked(treeElement, whiteChecked);
+ if (whiteChecked) {
+ treeViewer.setGrayed(treeElement, false);
+ } else {
+ treeViewer.setGrayed(treeElement, shouldBeAtLeastGray);
+ }
+
+ // proceed up the tree element hierarchy but gray select all of them
+ Object parent = treeContentProvider.getParent(treeElement);
+ if (parent != null) {
+ grayUpdateHierarchy(parent);
+ }
+ }
+
+ /**
+ * Update the selections of the tree elements in items to reflect the new
+ * selections provided.
+ * @param items Map with keys of Object (the tree element) and values of List (the selected
+ * list elements).
+ * NOTE: This method does not special case keys with no values (i.e.,
+ * a tree element with an empty list). If a tree element does not have any selected
+ * items, do not include the element in the Map.
+ */
+ public void updateSelections(Map items) {
+ // We are replacing all selected items with the given selected items,
+ // so reinitialize everything.
+ this.listViewer.setAllChecked(false);
+ this.treeViewer.setCheckedElements(new Object[0]);
+ this.whiteCheckedTreeItems = new HashSet();
+ Set selectedNodes = new HashSet();
+ checkedStateStore = new HashMap();
+
+ //Update the store before the hierarchy to prevent updating parents before all of the children are done
+ Iterator keyIterator = items.keySet().iterator();
+ while (keyIterator.hasNext()) {
+ Object key = keyIterator.next();
+ List selections = (List) items.get(key);
+ //Replace the items in the checked state store with those from the supplied items
+ checkedStateStore.put(key, selections);
+ selectedNodes.add(key);
+ // proceed up the tree element hierarchy
+ Object parent = treeContentProvider.getParent(key);
+ if (parent != null) {
+ // proceed up the tree element hierarchy and make sure everything is in the table
+ primeHierarchyForSelection(parent, selectedNodes);
+ }
+ }
+
+ // Update the checked tree items. Since each tree item has a selected
+ // item, all the tree items will be gray checked.
+ treeViewer.setCheckedElements(checkedStateStore.keySet().toArray());
+ treeViewer.setGrayedElements(checkedStateStore.keySet().toArray());
+
+ // Update the listView of the currently selected tree item.
+ if (currentTreeSelection != null) {
+ Object displayItems = items.get(currentTreeSelection);
+ if (displayItems != null) {
+ listViewer.setCheckedElements(((List) displayItems).toArray());
+ }
+ }
+ }
+
+ /**
+ * Set the focus on to the list widget.
+ */
+ public void setFocus() {
+
+ treeViewer.getTree().setFocus();
+ if(treeViewer.getSelection().isEmpty()) {
+ Object[] elements = treeContentProvider.getElements(root);
+ if(elements.length > 0) {
+ StructuredSelection selection = new StructuredSelection(elements[0]);
+ treeViewer.setSelection(selection);
+ }
+ }
+
+ }
+
+}
+

Back to the top