Logo Search packages:      
Sourcecode: uimaj version File versions  Download package

AnnotationOutline.java

/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *   http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */

package org.apache.uima.caseditor.editor.outline;

import java.util.Collection;

import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.Type;
import org.apache.uima.caseditor.CasEditorPlugin;
import org.apache.uima.caseditor.Images;
import org.apache.uima.caseditor.editor.AnnotationEditor;
import org.apache.uima.caseditor.editor.CasEditorError;
import org.apache.uima.caseditor.editor.IAnnotationEditorModifyListener;
import org.apache.uima.caseditor.editor.action.DeleteFeatureStructureAction;
import org.apache.uima.caseditor.editor.action.LowerLeftAnnotationSideAction;
import org.apache.uima.caseditor.editor.action.LowerRightAnnotationSideAction;
import org.apache.uima.caseditor.editor.action.MergeAnnotationAction;
import org.apache.uima.caseditor.editor.action.WideLeftAnnotationSideAction;
import org.apache.uima.caseditor.editor.action.WideRightAnnotationSideAction;
import org.apache.uima.caseditor.editor.util.AnnotationSelection;
import org.apache.uima.caseditor.editor.util.FeatureStructureTransfer;
import org.eclipse.core.runtime.IAdaptable;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IStatusLineManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.swt.SWT;
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.Transfer;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.swt.widgets.TreeItem;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.actions.ActionFactory;
import org.eclipse.ui.views.contentoutline.ContentOutline;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;

/**
 * This outline view displays all <code>AnnotationFS</code>s of the current
 * mode/type from the binded editor.
 */
00072 public final class AnnotationOutline extends ContentOutlinePage
            implements ISelectionListener {
  
  /**
   * This listener receive events from the bound editor.
   */
00078   protected class EditorListener implements IAnnotationEditorModifyListener {

    /**
     * Called if the editor annotation mode was changed.
     * 
     * @param newMode
     */
00085     public void annotationModeChanged(Type newMode) {
      changeAnnotationMode();
      mTableViewer.refresh();
    }

00090     public void showAnnotationsChanged(Collection<Type> shownAnnotationTypes) {
      mTableViewer.refresh();
    }
  }

  /**
   * Selects all elements in the tree viewer.
   */
00098   private class SelectAllAction extends Action {
    /**
     * Selects all elements in the tree viewer.
     */
    @Override
00103     public void run() {
      mTableViewer.getTree().selectAll();
      mTableViewer.setSelection(mTableViewer.getSelection());
    }
  }

  private OutlineStyles style = OutlineStyles.TYPE;
  
  private Composite mOutlineComposite;

  private TreeViewer mTableViewer;

  /**
   * The <code>AnnotationEditor</code> which is bound to this outline view.
   */
00118   private AnnotationEditor editor;

  /**
   * Creates a new <code>AnnotationOutline</code> object.
   *
   * @param editor -
   *          the editor to bind
   */
00126   public AnnotationOutline(AnnotationEditor editor) {
    this.editor = editor;
  }

  /**
   * Creates the outline table control.
   *
   * @param parent
   */
  @Override
00136   public void createControl(Composite parent) {
    mOutlineComposite = new Composite(parent, SWT.NONE);
    mOutlineComposite.setLayout(new FillLayout());

    createTableViewer(mOutlineComposite);
    mOutlineComposite.layout(true);

    getSite().getPage().addSelectionListener(this);
    getSite().setSelectionProvider(mTableViewer);

    changeAnnotationMode();

    // TODO: create a listener interface ... for editor listener
    editor.addAnnotationListener(new EditorListener());

    DragSource source = new DragSource(mTableViewer.getTree(), DND.DROP_COPY);

    source.setTransfer(new Transfer[] { FeatureStructureTransfer.getInstance() });

    source.addDragListener(new DragSourceListener() {
      TreeItem dragSourceItem = null;

      public void dragStart(DragSourceEvent event) {
        TreeItem[] selection = mTableViewer.getTree().getSelection();

        if (selection.length > 0) {
          event.doit = true;
          dragSourceItem = selection[0];
        } else {
          event.doit = false;
        }
      }

      public void dragSetData(DragSourceEvent event) {
        IAdaptable adaptable = (IAdaptable) dragSourceItem.getData();

        event.data = adaptable.getAdapter(FeatureStructure.class);
      }

      public void dragFinished(DragSourceEvent event) {
        // not needed
      }
    });
  }

  /**
   * Adds the actions to the tool bar.
   *
   * @param menuManager
   * @param toolBarManager
   * @param statusLineManager
   */
  @Override
00189   public void makeContributions(IMenuManager menuManager, IToolBarManager toolBarManager,
          IStatusLineManager statusLineManager) {
    // wide left annotation side action
    WideLeftAnnotationSideAction wideLeftAnnotationSideAction = new WideLeftAnnotationSideAction(
            editor.getDocument());
    wideLeftAnnotationSideAction.setText("Wides the left annotation side");
    wideLeftAnnotationSideAction.setImageDescriptor(CasEditorPlugin
            .getTaeImageDescriptor(Images.WIDE_LEFT_SIDE));

    getSite().getSelectionProvider().addSelectionChangedListener(wideLeftAnnotationSideAction);

    toolBarManager.add(wideLeftAnnotationSideAction);

    // lower left annotation side action
    LowerLeftAnnotationSideAction lowerLeftAnnotationSideAction = new LowerLeftAnnotationSideAction(
            editor.getDocument());
    lowerLeftAnnotationSideAction.setText("Lowers the left annotation side");
    lowerLeftAnnotationSideAction.setImageDescriptor(CasEditorPlugin
            .getTaeImageDescriptor(Images.LOWER_LEFT_SIDE));

    getSite().getSelectionProvider().addSelectionChangedListener(lowerLeftAnnotationSideAction);

    toolBarManager.add(lowerLeftAnnotationSideAction);

    // lower right annotation side action
    LowerRightAnnotationSideAction lowerRightAnnotionSideAction =
      new LowerRightAnnotationSideAction(editor.getDocument());
    lowerRightAnnotionSideAction.setText("Lowers the right annotation side");
    lowerRightAnnotionSideAction.setImageDescriptor(CasEditorPlugin
            .getTaeImageDescriptor(Images.LOWER_RIGHT_SIDE));

    getSite().getSelectionProvider().addSelectionChangedListener(lowerRightAnnotionSideAction);

    toolBarManager.add(lowerRightAnnotionSideAction);

    // wide right annotation side action
    WideRightAnnotationSideAction wideRightAnnotationSideAction = new WideRightAnnotationSideAction(
            editor.getDocument());
    wideRightAnnotationSideAction.setText("Wides the right annotation side");

    wideRightAnnotationSideAction.setImageDescriptor(CasEditorPlugin
            .getTaeImageDescriptor(Images.WIDE_RIGHT_SIDE));

    getSite().getSelectionProvider().addSelectionChangedListener(wideRightAnnotationSideAction);

    toolBarManager.add(wideRightAnnotationSideAction);

    // merge action
    MergeAnnotationAction mergeAction = new MergeAnnotationAction(editor.getDocument());
    getSite().getSelectionProvider().addSelectionChangedListener(mergeAction);
    mergeAction.setImageDescriptor(CasEditorPlugin.getTaeImageDescriptor(Images.MERGE));

    toolBarManager.add(mergeAction);

    // delete action
    toolBarManager.add(ActionFactory.DELETE.create(getSite().getWorkbenchWindow()));
  }

  /**
   * Retrieves the control.
   *
   * @return the control
   */
  @Override
00253   public Control getControl() {
    return mOutlineComposite;
  }

  /**
   * Adds the these actions to the global action handler: {@link DeleteFeatureStructureAction}
   * SelectAllAction
   *
   * @param actionBars
   */
  @Override
00264   public void setActionBars(IActionBars actionBars) {
    DeleteFeatureStructureAction deleteAction = new DeleteFeatureStructureAction(editor
            .getDocument());

    actionBars.setGlobalActionHandler(ActionFactory.DELETE.getId(), deleteAction);

    getSite().getSelectionProvider().addSelectionChangedListener(deleteAction);

    actionBars.setGlobalActionHandler(ActionFactory.SELECT_ALL.getId(), new SelectAllAction());
    
    Action action = new SwitchStyleAction(this);
    
    IMenuManager dropDownMenu = actionBars.getMenuManager();
    dropDownMenu.add(action);
    
    super.setActionBars(actionBars);
  }

  OutlineStyles currentStyle() {
        return style;
  }
  
  void switchStyle(OutlineStyles style) {
        
        this.style = style;
        
        if (OutlineStyles.MODE.equals(style)) {
              mTableViewer.setContentProvider(new ModeSensitiveContentProvider(
                          editor, mTableViewer));
        } else if (OutlineStyles.TYPE.equals(style)) {
              mTableViewer.setContentProvider(new TypeGroupedContentProvider(
                          editor, mTableViewer));
        } else {
              throw new CasEditorError("Unkown style!");
        }

            mTableViewer.refresh();
  }
  
  /**
   * Sets the focus.
   */
  @Override
00307   public void setFocus() {
    mOutlineComposite.setFocus();
  }

  private void changeAnnotationMode() {
    mTableViewer.setInput(editor.getDocument());
    mTableViewer.refresh();
  }

  private void createTableViewer(Composite parent) {
    int style = SWT.MULTI | SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION;

    if (mTableViewer != null) {
      mTableViewer.getTree().dispose();
    }

    mTableViewer = new TreeViewer(parent, style);

    GridData gridData = new GridData(GridData.FILL_BOTH);
    gridData.grabExcessVerticalSpace = true;
    gridData.horizontalSpan = 3;
    mTableViewer.getTree().setLayoutData(gridData);

    mTableViewer.getTree().setLinesVisible(true);
    mTableViewer.getTree().setHeaderVisible(true);

    TreeColumn textColumn = new TreeColumn(mTableViewer.getTree(), SWT.LEFT);
    textColumn.setText("Text");
    textColumn.setWidth(130);

    // performance optimization, the table can contain many items
    mTableViewer.setUseHashlookup(false);

    // Note: The type style is considered as the default
    mTableViewer.setContentProvider(new TypeGroupedContentProvider(editor, mTableViewer));
    
    mTableViewer.setFilters(new ViewerFilter[]{new ViewerFilter() {

      // TODO: Improve this filter ... it is to sloooooooooow
            @Override
            public boolean select(Viewer viewer, Object parentElement,
                        Object element) {
                  Collection<Type> shownTypes = editor.getShownAnnotationTypes();
                  
                  if (element instanceof AnnotationTypeTreeNode) {
                        AnnotationTypeTreeNode typeNode = (AnnotationTypeTreeNode) element;
                        
                        if (shownTypes.contains(typeNode.getType()))
                              return true;
                        else
                              return false;
                  }
                  else if (element instanceof AnnotationTreeNode) {
                        AnnotationTreeNode annotationNode = (AnnotationTreeNode) element;
                        
                        return shownTypes.contains(annotationNode.getAnnotation().getType());
                  }
                  else {
                        throw new CasEditorError("Unxexpected element type!");
                  }
            }}});
    
    mTableViewer.setLabelProvider(new OutlineLabelProvider());

    mTableViewer.setSorter(new OutlineTableSorter());

    mTableViewer.setAutoExpandLevel(3);

    // set input element here ... this is the document
  }

  public void selectionChanged(IWorkbenchPart part, ISelection selection) {
    boolean isForeignSelection = !(part instanceof ContentOutline && ((ContentOutline) part)
            .getCurrentPage() == this);

    if (isForeignSelection) {
      if (selection instanceof StructuredSelection) {
        AnnotationSelection annotations = new AnnotationSelection((StructuredSelection) selection);

        if (!annotations.isEmpty()) {
          ISelection tableSelection = new StructuredSelection(new AnnotationTreeNode(editor
                  .getDocument(), annotations.getFirst()));

          mTableViewer.setSelection(tableSelection, true);
        }
      }
    }
  }

  @Override
  public void dispose() {
    
    super.dispose();
    
    getSite().getPage().removeSelectionListener(this);
    
    // remove selection listener
    getSite().getWorkbenchWindow().getSelectionService().removeSelectionListener(this);
  }
}

Generated by  Doxygen 1.6.0   Back to index