Package org.cishell.reference.gui.datamanager

Source Code of org.cishell.reference.gui.datamanager.AbstractDataManagerView$DataModelSelectionProvider

/* ****************************************************************************
* 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);
        }
      }
    }
  }
}
TOP

Related Classes of org.cishell.reference.gui.datamanager.AbstractDataManagerView$DataModelSelectionProvider

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.