/* ****************************************************************************
* CIShell: Cyberinfrastructure Shell, An Algorithm Integration Framework.
*
* All rights reserved. This program and the accompanying materials are made
* available under the terms of the Apache License v2.0 which accompanies
* this distribution, and is available at:
* http://www.apache.org/licenses/LICENSE-2.0.html
*
* Created on Aug 21, 2006 at Indiana University.
*
* Contributors:
* Indiana University -
* ***************************************************************************/
package org.cishell.reference.gui.datamanager;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Dictionary;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import org.cishell.app.service.datamanager.DataManagerListener;
import org.cishell.app.service.datamanager.DataManagerService;
import org.cishell.app.service.fileloader.FileLoaderService;
import org.cishell.framework.CIShellContext;
import org.cishell.framework.CIShellContextDelegate;
import org.cishell.framework.LocalCIShellContext;
import org.cishell.framework.algorithm.Algorithm;
import org.cishell.framework.algorithm.AlgorithmExecutionException;
import org.cishell.framework.algorithm.AlgorithmFactory;
import org.cishell.framework.algorithm.ProgressMonitor;
import org.cishell.framework.data.Data;
import org.cishell.framework.data.DataProperty;
import org.cishell.reference.gui.workspace.CIShellApplication;
import org.cishell.utilities.StringUtilities;
import org.eclipse.jface.action.ActionContributionItem;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TreeEditor;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.DropTarget;
import org.eclipse.swt.dnd.DropTargetAdapter;
import org.eclipse.swt.dnd.DropTargetEvent;
import org.eclipse.swt.dnd.FileTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.FocusAdapter;
import org.eclipse.swt.events.FocusEvent;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.part.ViewPart;
import org.osgi.framework.BundleContext;
import org.osgi.framework.BundleEvent;
import org.osgi.framework.BundleListener;
import org.osgi.framework.Constants;
import org.osgi.framework.InvalidSyntaxException;
import org.osgi.framework.ServiceReference;
import org.osgi.service.log.LogService;
public abstract class AbstractDataManagerView
extends ViewPart implements BundleListener, DataManagerListener {
private String brandPluginID;
private DataManagerService manager;
private TreeViewer viewer;
private TreeEditor editor;
private Text newEditor;
private DataGUIItem rootItem;
/*
* Flag to notify if a tree item is currently being updated so there isnt a conflict among
* various listeners.
*/
private boolean updatingTreeItem;
private Tree tree;
private Menu menu;
private Map<Data, DataGUIItem> dataToDataGUIItem;
private AlgorithmFactory saveFactory;
private AlgorithmFactory viewFactory;
private AlgorithmFactory viewWithFactory;
private DiscardListener discardListener;
private SaveListener saveListener;
private ViewListener viewListener;
private ViewWithListener viewWithListener;
private LogService logger;
public AbstractDataManagerView(String brandPluginID) {
this.brandPluginID = brandPluginID;
this.dataToDataGUIItem = new HashMap<Data, DataGUIItem>();
this.manager = Activator.getDataManagerService();
this.logger = Activator.getLogService();
if (this.manager == null) {
if (this.logger != null) {
this.logger.log(LogService.LOG_ERROR, "Data Manager Service unavailable!");
}
}
}
private String getItemID(ServiceReference serviceReference) {
return serviceReference.getProperty(
"PID:" +
Constants.SERVICE_PID) +
"-SID:" +
serviceReference.getProperty(Constants.SERVICE_ID);
}
/**
* @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
*/
public void createPartControl(Composite parent) {
this.viewer = new TreeViewer(parent);
this.viewer.setContentProvider(new DataTreeContentProvider());
this.viewer.setLabelProvider(new DataTreeLabelProvider());
this.rootItem = new DataGUIItem(null, null, this.brandPluginID);
this.viewer.setInput(this.rootItem);
this.viewer.expandAll();
// Grab the tree and add the appropriate listeners.
this.tree = this.viewer.getTree();
this.tree.addSelectionListener(new DatamodelSelectionListener());
this.tree.addMouseListener(new ContextMenuListener());
// Setup the context menu for the tree.
this.menu = new Menu(tree);
this.menu.setVisible(false);
MenuItem saveItem = new MenuItem(this.menu, SWT.PUSH);
saveItem.setText("Save");
this.saveListener = new SaveListener();
saveItem.addListener(SWT.Selection, this.saveListener);
MenuItem viewItem = new MenuItem(this.menu, SWT.PUSH);
viewItem.setText("View");
this.viewListener = new ViewListener();
viewItem.addListener(SWT.Selection, this.viewListener);
MenuItem viewWithItem = new MenuItem(this.menu, SWT.PUSH);
viewWithItem.setText("View With...");
this.viewWithListener = new ViewWithListener();
viewWithItem.addListener(SWT.Selection, this.viewWithListener);
MenuItem renameItem = new MenuItem(this.menu, SWT.PUSH);
renameItem.setText("Rename");
renameItem.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
handleInput();
}
});
MenuItem discardItem = new MenuItem(this.menu, SWT.PUSH);
discardItem.setText("Discard");
this.discardListener = new DiscardListener();
discardItem.addListener(SWT.Selection, this.discardListener);
this.tree.setMenu(this.menu);
// Allow cells to be edited on double click or when pressing enter on them.
this.editor = new TreeEditor(this.tree);
this.editor.horizontalAlignment = SWT.LEFT;
this.editor.grabHorizontal = true;
this.editor.minimumWidth = 50;
// Listen to OSGi for models being added by plugins.
if (this.manager != null) {
this.manager.addDataManagerListener(this);
} else {
Activator.getBundleContext().addBundleListener(this);
this.manager = Activator.getDataManagerService();
if (this.manager != null) {
this.manager.addDataManagerListener(this);
}
}
getSite().setSelectionProvider(new DataModelSelectionProvider());
setupDataManagerViewForDragAndDrop(parent);
}
private void setupDataManagerViewForDragAndDrop(Composite parent) {
setupDataManagerViewForDragAndDropInto(parent);
setupDataManagerViewForDragAndDropOutOf(parent);
}
private void setupDataManagerViewForDragAndDropInto(Composite parent) {
DropTarget dropTarget =
new DropTarget(parent.getParent(), DND.DROP_DEFAULT | DND.DROP_MOVE);
dropTarget.setTransfer(new Transfer[] { FileTransfer.getInstance() });
dropTarget.addDropListener(new DropTargetAdapter() {
@Override
public void drop(DropTargetEvent event) {
String fileNames[] = null;
FileTransfer fileTransfer = FileTransfer.getInstance();
if (fileTransfer.isSupportedType(event.currentDataType)) {
fileNames = (String[]) event.data;
Collection<File> flattenedFileStructure =
flattenDraggedFileStructures(fileNames);
ServiceReference fileLoaderServiceReference =
Activator.context.getServiceReference(FileLoaderService.class.getName());
FileLoaderService fileLoader =
(FileLoaderService) Activator.context.getService(
fileLoaderServiceReference);
DataManagerService dataManager =
(DataManagerService) Activator.context.getService(
Activator.context.getServiceReference(
DataManagerService.class.getName()));
ServiceReference dataManagerServiceReference =
Activator.context.getServiceReference(DataManagerService.class.getName());
for (File file : flattenedFileStructure) {
/* TODO: Eventually use the AlgorithmInvocationService for this
* kind of stuff?
*/
ServiceReference uniqueServiceReference = dataManagerServiceReference;
// ServiceReference uniqueServiceReference = new ServiceReferenceDelegate(
// dataManagerServiceReference);
CIShellContext ciShellContext = new CIShellContextDelegate(
uniqueServiceReference, new LocalCIShellContext(Activator.context));
LogService uniqueLogger =
(LogService) ciShellContext.getService(LogService.class.getName());
try {
Data[] inputData = fileLoader.loadFile(
Activator.context,
ciShellContext,
uniqueLogger,
ProgressMonitor.NULL_MONITOR,
file);
for (Data inputDatum : inputData) {
inputDatum.getMetadata().put(
DataProperty.SERVICE_REFERENCE, uniqueServiceReference);
dataManager.addData(inputDatum);
}
} catch (Throwable e) {
String format =
"An error occurred when loading your files.%n" +
"Please include the following when reporting this:%n%s";
String logMessage =
String.format(format, StringUtilities.getStackTraceAsString(e));
/* TODO: This is a spot where we might need to use a different
* LogService object (for when we want log highlighting).
*/
uniqueLogger.log(LogService.LOG_ERROR, logMessage);
}
}
}
}
});
}
private void setupDataManagerViewForDragAndDropOutOf(Composite parent) {
Transfer[] types = new Transfer[] { new CIShellDataTransfer(Activator.context) };
DragSource dragSource = new DragSource(parent, DND.DROP_DEFAULT | DND.DROP_MOVE);
dragSource.setTransfer(types);
dragSource.addDragListener(new DragSourceListener() {
private Data[] selectedData;
public void dragStart(DragSourceEvent event) {
System.err.println("dragStart");
Data[] selectedData = AbstractDataManagerView.this.manager.getSelectedData();
if ((selectedData != null) && (selectedData.length != 0)) {
event.doit = true;
this.selectedData = selectedData;
}
}
public void dragSetData(DragSourceEvent event) {
// TODO: Create the target files.
// event.data =
}
public void dragFinished(DragSourceEvent event) {
// TODO: Convert the source files, given the target files.
}
});
}
private Collection<File> flattenDraggedFileStructures(String[] fileNames) {
Collection<File> flattenedFileStructure = new ArrayList<File>();
for (String fileName : fileNames) {
flattenedFileStructure.addAll(flattenDraggedFileStructure(fileName));
}
return flattenedFileStructure;
}
private Collection<File> flattenDraggedFileStructure(String fileName) {
File file = new File(fileName);
if (file.isFile()) {
Collection<File> flattenedFileStructure = new ArrayList<File>();
flattenedFileStructure.add(file);
return flattenedFileStructure;
} else if (file.isDirectory()) {
Collection<File> flattenedFileStructure = new ArrayList<File>();
for (String childFileName : file.list()) {
String completeChildFileName = String.format(
"%s%s%s", fileName, File.separator, childFileName);
flattenedFileStructure.addAll(flattenDraggedFileStructure(completeChildFileName));
}
return flattenedFileStructure;
} else {
return new ArrayList<File>();
}
}
public void bundleChanged(BundleEvent event) {
if (event.getType() == BundleEvent.STARTED) {
this.manager = Activator.getDataManagerService();
if (this.manager != null) {
this.manager.addDataManagerListener(this);
}
}
}
/**
* @see org.eclipse.ui.part.WorkbenchPart#setFocus()
*/
public void setFocus() {
this.viewer.getControl().setFocus();
}
public void dataAdded(final Data newData, String label) {
// Get the new data's parent GUI Item (either root or another data item).
DataGUIItem parentItem = getParent(newData);
// Wrap the new data in a DataGUIItem.
final DataGUIItem newItem = new DataGUIItem(newData, parentItem, this.brandPluginID);
// Notify the parent DataModelGUIItem of its new child.
parentItem.addChild(newItem);
/* Keep a reference to the new model in the model->TreeItem mapping so that it can be used
* in the future if it has a child.
*/
this.dataToDataGUIItem.put(newData, newItem);
// update the ModelManager with the new selection
final Set<Data> selection = new HashSet<Data>();
selection.add(newData);
guiRun(new Runnable() {
public void run() {
if (!tree.isDisposed()) {
// update the TreeView
AbstractDataManagerView.this.viewer.refresh();
// context menu may need to have options enabled/disabled
// based on the new selection
updateContextMenu(newData);
// update the global selection
AbstractDataManagerView.this.viewer.expandToLevel(newItem, 0);
manager.setSelectedData((Data[]) selection.toArray(new Data[0]));
}
}
});
}
private DataGUIItem getParent(Data data) {
Dictionary<String, Object> modelDictionary = data.getMetadata();
Data parent = (Data) modelDictionary.get(DataProperty.PARENT);
DataGUIItem parentItem;
if (parent == null) {
// If it has no parent, it is a child of the root.
parentItem = this.rootItem;
} else {
// Otherwise find the associated DataModelGUIItem for the parent.
parentItem = this.dataToDataGUIItem.get(parent);
// The parent may not be in the GUI. If its not, then use root item.
if (parentItem == null) {
parentItem = this.rootItem;
}
}
return parentItem;
}
private void guiRun(Runnable run) {
if (Thread.currentThread() == Display.getDefault().getThread()) {
run.run();
} else {
Display.getDefault().syncExec(run);
}
}
public void dataLabelChanged(Data data, String label) {
if (data != null && label != null) {
TreeItem[] treeItems = this.tree.getItems();
for (int i = 0; i < treeItems.length; ++i) {
if (((DataGUIItem)treeItems[i].getData()).getModel() == data) {
updateText(label, treeItems[i]);
break;
}
}
}
}
public void dataRemoved(Data data) {
TreeItem[] treeItems = this.tree.getItems();
for (int i = 0; i < treeItems.length; ++i) {
if (((DataGUIItem)treeItems[i].getData()).getModel() == data) {
this.tree.clear(this.tree.indexOf(treeItems[i]), false);
}
}
}
public void dataSelected(final Data[] data) {
if (data != null) {
guiRun(new Runnable() {
public void run() {
// TODO: Abstract this?
Set<TreeItem> itemSet = new HashSet<TreeItem>();
for (int i = 0; i < data.length; ++i) {
TreeItem[] treeItems = tree.getItems();
// tree.getSelection()
for (int j = 0; j < treeItems.length; ++j) {
if (treeItems[j].getData() == data[i]) {
itemSet.add(treeItems[j]);
break;
}
}
}
// TODO: Add dnd listeners to itemSet elements (if necessary)
tree.setSelection(itemSet.toArray(new TreeItem[0]));
getSite().getSelectionProvider().setSelection(new StructuredSelection(data));
}
});
}
}
/*
* Enables/disables save item in the context menu based on whether or not
* their is an available Persister for the given model
*/
private void updateContextMenu(Data model) {
// throws AlgorithmCreationCanceledException, AlgorithmCreationFailedException {
this.saveFactory = enableMenuItemCheck(
this.saveFactory, "org.cishell.reference.gui.persistence.save.Save", model, 0);
this.viewFactory = enableMenuItemCheck(
this.viewFactory, "org.cishell.reference.gui.persistence.view.FileView", model, 1);
this.viewWithFactory = enableMenuItemCheck(
this.viewWithFactory,
"org.cishell.reference.gui.persistence.viewwith.FileViewWith",
model,
2);
}
private AlgorithmFactory enableMenuItemCheck(
AlgorithmFactory algorithmFactory, String service, Data model, int menuIndex) {
// throws AlgorithmCreationCanceledException, AlgorithmCreationFailedException {
boolean validSaveFactory = false;
if (algorithmFactory == null) {
algorithmFactory = Activator.getService(service);
if (algorithmFactory != null) {
validSaveFactory = true;
}
} else {
validSaveFactory = true;
}
boolean enabled = false;
if (validSaveFactory) {
Algorithm algorithm = algorithmFactory.createAlgorithm(
new Data[] { model },
new Hashtable<String, Object>(),
Activator.getCIShellContext());
if (algorithm != null) {
enabled = true;
}
}
this.menu.getItem(menuIndex).setEnabled(enabled);
return algorithmFactory;
}
/*
* Listens for selection in the GUI of data models by selecting their item
* in the tree and updates the ModelManager appropriately
*/
private class DatamodelSelectionListener extends SelectionAdapter {
public void widgetSelected(SelectionEvent e) {
Tree tree = (Tree) e.getSource();
TreeItem[] selection = tree.getSelection();
Set<Data> models = new HashSet<Data>();
Data[] modelArray = new Data[selection.length];
for (int i = 0; i < selection.length; i++) {
Data model = ((DataGUIItem) selection[i].getData()).getModel();
updateContextMenu(model);
models.add(model);
modelArray[i] = model;
}
AbstractDataManagerView.this.manager.setSelectedData(modelArray);
}
}
/*
* allows for direct text editing of the label of a DataModelGUIItem by
* using a Text control associated with a TreeEditor. This allows for
* renaming of data models without a pop-up dialog or anything
*/
private void handleInput() {
// Clean up any previous editor control
Control oldEditor = this.editor.getEditor();
if (oldEditor != null) {
oldEditor.dispose();
}
// Identify the selected row, only allow input if there is a single
// selected row
TreeItem[] selection = this.tree.getSelection();
if (selection.length != 1) {
return;
}
final TreeItem item = selection[0];
if (item == null) {
return;
}
// The control that will be the editor must be a child of the Table
this.newEditor = new Text(this.tree, SWT.NONE);
this.newEditor.setText(item.getText());
this.newEditor.addFocusListener(new FocusAdapter() {
public void focusLost(FocusEvent e) {
if (!updatingTreeItem) {
//updateText(newEditor.getText(), item);
AbstractDataManagerView.this.manager.setLabel(
((DataGUIItem) item.getData()).getModel(),
AbstractDataManagerView.this.newEditor.getText());
// FELIX. This is not > stupidness.
}
}
});
// ENTER ESC
this.newEditor.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent e) {
if ((e.character == SWT.CR) && !AbstractDataManagerView.this.updatingTreeItem) {
updateText(AbstractDataManagerView.this.newEditor.getText(), item);
} else if (e.keyCode == SWT.ESC) {
AbstractDataManagerView.this.newEditor.dispose();
}
}
});
this.newEditor.selectAll();
this.newEditor.setFocus();
this.editor.setEditor(this.newEditor, item);
}
/*
* updates the actual Label property of the DataModel that is being edited
* by the TreeEditor for renaming - only if the new name is valid though
*/
private void updateText(String newLabel, TreeItem item) {
this.updatingTreeItem = true;
if (newLabel.startsWith(">"))
newLabel = newLabel.substring(1);
this.editor.getItem().setText(newLabel);
DataGUIItem treeItem = (DataGUIItem) item.getData();
Data model = treeItem.getModel();
model.getMetadata().put(DataProperty.LABEL, newLabel);
viewer.refresh();
this.newEditor.dispose();
updatingTreeItem = false;
}
/*
* Listens for right-clicks on TreeItems and opens the context menu when
* needed.
*/
private class ContextMenuListener extends MouseAdapter {
public void mouseUp(MouseEvent event) {
if (event.button == 3) {
TreeItem item =
AbstractDataManagerView.this.tree.getItem(new Point(event.x, event.y));
if (item != null) {
AbstractDataManagerView.this.tree.getMenu().setVisible(true);
} else {
AbstractDataManagerView.this.tree.getMenu().setVisible(false);
}
}
}
}
private class SaveListener implements Listener {
public void handleEvent(Event event) {
if (AbstractDataManagerView.this.saveFactory != null) {
Data data[] = AbstractDataManagerView.this.manager.getSelectedData();
Algorithm algorithm = AbstractDataManagerView.this.saveFactory.createAlgorithm(
data, new Hashtable<String, Object>(), Activator.getCIShellContext());
try {
algorithm.execute();
} catch (AlgorithmExecutionException e) {
if (AbstractDataManagerView.this.logger != null) {
AbstractDataManagerView.this.logger.log(
LogService.LOG_ERROR, e.getMessage(), e);
e.printStackTrace();
} else {
AbstractDataManagerView.this.logger = Activator.getLogService();
if (AbstractDataManagerView.this.logger != null) {
AbstractDataManagerView.this.logger.log(
LogService.LOG_ERROR,
"org.cishell.framework.algorithm.AlgorithmExecutionException",
e);
e.printStackTrace();
}
}
}
}
}
}
private class ViewListener implements Listener {
public void handleEvent(Event event) {
if (AbstractDataManagerView.this.viewFactory != null) {
Data data[] = AbstractDataManagerView.this.manager.getSelectedData();
Algorithm algorithm = AbstractDataManagerView.this.viewFactory.createAlgorithm(
data, new Hashtable<String, Object>(), Activator.getCIShellContext());
try {
algorithm.execute();
} catch (AlgorithmExecutionException e) {
if (AbstractDataManagerView.this.logger != null) {
AbstractDataManagerView.this.logger.log(
LogService.LOG_ERROR, e.getMessage(), e);
} else {
AbstractDataManagerView.this.logger = Activator.getLogService();
// TODO: Find occurrences of this crap happening, and make it a method.
if (AbstractDataManagerView.this.logger != null) {
AbstractDataManagerView.this.logger.log(
LogService.LOG_ERROR, e.getMessage(), e);
}
}
e.printStackTrace();
}
}
}
}
private class ViewWithListener implements Listener {
public void handleEvent(Event event) {
IMenuManager topLevelMenu = CIShellApplication.getMenuManager();
IMenuManager fileMenu = topLevelMenu.findMenuUsingPath("File");
BundleContext bundleContext = Activator.getBundleContext();
try {
ServiceReference[] serviceReference = bundleContext.getAllServiceReferences(
AlgorithmFactory.class.getName(),
"(service.pid=org.cishell.reference.gui.persistence.viewwith.FileViewWith)");
if ((serviceReference != null) && (serviceReference.length > 0)) {
ActionContributionItem action =
(ActionContributionItem) fileMenu.find(getItemID(serviceReference[0]));
action.getAction().run();
}
} catch (InvalidSyntaxException e) {
e.printStackTrace();
}
}
}
private class DiscardListener implements Listener {
public void handleEvent(Event event) {
TreeItem[] selections = AbstractDataManagerView.this.tree.getSelection();
for (TreeItem selection : selections) {
// for (int i = 0; i < selections.length; i++) {
// DataGUIItem item = (DataGUIItem) selections[i].getData();
DataGUIItem item = (DataGUIItem) selection.getData();
DataGUIItem parent = item.getParent();
if (parent != null) {
parent.removeChild(item);
}
AbstractDataManagerView.this.dataToDataGUIItem.remove(item.getModel());
AbstractDataManagerView.this.manager.removeData(item.getModel());
}
AbstractDataManagerView.this.manager.setSelectedData(new Data[0]);
AbstractDataManagerView.this.viewer.refresh();
}
}
private class DataModelSelectionProvider implements ISelectionProvider {
private Set<ISelectionChangedListener> listeners =
new HashSet<ISelectionChangedListener>();
private ISelection selection;
public void addSelectionChangedListener(ISelectionChangedListener listener) {
listeners.add(listener);
}
public ISelection getSelection() {
return selection;
}
public void removeSelectionChangedListener(ISelectionChangedListener listener) {
listeners.remove(listener);
}
private TreeItem getTreeItem(Data model, TreeItem[] items) {
TreeItem result = null;
int i = 0;
while ((i < items.length) && (result == null)) {
DataGUIItem data = ((DataGUIItem) items[i].getData());
// TODO: Not sure why this happens...
if (data != null) {
Data item = data.getModel();
if (item == model)
result = items[i];
else {
// check the children recursively
result = getTreeItem(model, items[i].getItems());
}
} else {
// check the children recursively
result = getTreeItem(model, items[i].getItems());
}
i++;
}
return result;
}
public void setSelection(ISelection selection) {
if (selection != this.selection) {
this.selection = selection;
AbstractDataManagerView.this.viewer.refresh(true);
if ((selection != null) && (selection instanceof IStructuredSelection)) {
IStructuredSelection selections = (IStructuredSelection) selection;
Iterator<?> iterator = selections.iterator();
TreeItem[] newTreeSelection = new TreeItem[selections.size()];
int i = 0;
while (iterator.hasNext()) {
Object next = iterator.next();
if (next instanceof Data) {
TreeItem result = getTreeItem(
(Data) next, AbstractDataManagerView.this.tree.getItems());
newTreeSelection[i] = result;
AbstractDataManagerView.this.viewer.expandToLevel(
AbstractDataManagerView.this.dataToDataGUIItem.get(next), 0);
}
i++;
}
AbstractDataManagerView.this.tree.setSelection(newTreeSelection);
}
Iterator<ISelectionChangedListener> listenerIterator = listeners.iterator();
while (listenerIterator.hasNext()) {
ISelectionChangedListener listener = listenerIterator.next();
SelectionChangedEvent event = new SelectionChangedEvent(this, selection);
listener.selectionChanged(event);
}
}
}
}
}