/*******************************************************************************
* Copyright (c) 2000, 2015 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
*******************************************************************************/
package org.eclipse.linuxtools.internal.docker.ui;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.commands.common.EventManager;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.util.SafeRunnable;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
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.TreeViewer;
import org.eclipse.jface.viewers.ViewerComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Tree;
/**
* Workbench-level composite that shows a dynamic tree. All viewer
* selection-driven interactions are handled within this object
*/
@SuppressWarnings("rawtypes")
public class ContainerTreeGroup extends EventManager implements
ISelectionChangedListener, ITreeViewerListener {
private Object root;
private Object currentTreeSelection;
private List expandedTreeNodes = new ArrayList();
private ITreeContentProvider treeContentProvider;
private ITreeContentProvider dynamicTreeContentProvider;
private ILabelProvider treeLabelProvider;
// widgets
private TreeViewer treeViewer;
/**
* 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 width
* @param height
*/
public ContainerTreeGroup(Composite parent, Object rootObject,
ITreeContentProvider treeContentProvider,
ITreeContentProvider dynamicTreeContentProvider,
ILabelProvider treeLabelProvider,
int style, int width,
int height) {
root = rootObject;
this.treeContentProvider = treeContentProvider;
this.dynamicTreeContentProvider = dynamicTreeContentProvider;
this.treeLabelProvider = treeLabelProvider;
createContents(parent, width, height, style);
}
/**
* This method must be called just before this window becomes visible.
*/
public void aboutToOpen() {
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();
}
/**
* Lay out and initialize self's visual components.
*
* @param parent
* org.eclipse.swt.widgets.Composite
* @param width
* int
* @param height
* int
*/
protected void createContents(Composite parent, int width, int height,
int style) {
// group pane
Composite composite = new Composite(parent, style);
GridLayout layout = new GridLayout();
layout.numColumns = 1;
layout.makeColumnsEqualWidth = true;
layout.marginHeight = 0;
layout.marginWidth = 0;
composite.setLayout(layout);
composite.setLayoutData(new GridData(GridData.FILL_BOTH));
composite.setFont(parent.getFont());
createTreeViewer(composite, width, height);
initialize();
}
/**
* Create this group's tree viewer.
*/
protected void createTreeViewer(Composite parent, int width, int height) {
Tree tree = new Tree(parent, SWT.BORDER | SWT.SINGLE);
GridData data = new GridData(GridData.FILL_BOTH);
data.widthHint = width;
data.heightHint = height;
tree.setLayoutData(data);
tree.setFont(parent.getFont());
treeViewer = new DynamicTreeViewer(tree,
dynamicTreeContentProvider);
treeViewer.setContentProvider(treeContentProvider);
treeViewer.setLabelProvider(treeLabelProvider);
treeViewer.addTreeListener(this);
treeViewer.addSelectionChangedListener(this);
}
/**
* Cause the tree viewer to expand all its items
*/
public void expandAll() {
treeViewer.expandAll();
}
/**
* Initialize this group's viewers after they have been laid out.
*/
protected void initialize() {
treeViewer.setInput(root);
}
/**
* Notify all selection state listeners that a selection has been made
*/
protected void notifySelectionChangeListeners(
final SelectionChangedEvent event) {
Object[] array = getListeners();
for (int i = 0; i < array.length; i++) {
final ISelectionChangedListener l = (ISelectionChangedListener) array[i];
SafeRunner.run(new SafeRunnable() {
@Override
public void run() {
l.selectionChanged(event);
}
});
}
}
/**
* Add the passed listener to self's collection of clients that listen for
* changes to selection
*
* @param listener
* ISelectionChangedListener
*/
public void addSelectionChangedListener(
ISelectionChangedListener listener) {
addListenerObject(listener);
}
/**
* Remove the passed listener from self's collection of clients that listen
* for changes to selection
*
* @param listener
* ISelectionChangedListener
*/
public void removeSelectionChangedListener(
ISelectionChangedListener 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();
currentTreeSelection = selectedElement;
notifySelectionChangeListeners(event);
}
public Object getCurrentSelection() {
return currentTreeSelection;
}
/**
* 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 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);
}
/**
* 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
*/
@SuppressWarnings("unchecked")
@Override
public void treeExpanded(TreeExpansionEvent event) {
Object item = event.getElement();
// 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)) {
expandedTreeNodes.add(item);
dynamicTreeContentProvider.getChildren(item);
Object[] children = treeContentProvider.getElements(item);
for (int i = 0; i < children.length; ++i) {
dynamicTreeContentProvider.getElements(children[i]);
}
}
}
}