Package org.cfeclipse.cfml.views.contentoutline

Source Code of org.cfeclipse.cfml.views.contentoutline.CFContentOutlineView

/*
* Created on Apr 6, 2004
*
* The MIT License
* Copyright (c) 2004 Rob Rohan
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the Software
* is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package org.cfeclipse.cfml.views.contentoutline;

//import org.eclipse.core.resources.IResource;
import java.util.Iterator;

import org.cfeclipse.cfml.editors.CFMLEditor;
import org.cfeclipse.cfml.editors.ICFDocument;
import org.cfeclipse.cfml.editors.actions.GotoFileAction;
import org.cfeclipse.cfml.parser.CFDocument;
import org.cfeclipse.cfml.parser.CFNodeList;
import org.cfeclipse.cfml.parser.docitems.DocItem;
import org.cfeclipse.cfml.parser.docitems.ScriptItem;
import org.cfeclipse.cfml.parser.docitems.TagItem;
import org.cfeclipse.cfml.util.CFPluginImages;
import org.eclipse.jface.action.Action;
import org.eclipse.jface.action.IMenuListener;
import org.eclipse.jface.action.IMenuManager;
import org.eclipse.jface.action.IToolBarManager;
import org.eclipse.jface.action.MenuManager;
import org.eclipse.jface.action.Separator;
import org.eclipse.jface.dialogs.InputDialog;
import org.eclipse.jface.text.ITextSelection;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.ui.IActionBars;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IPartListener;
import org.eclipse.ui.IPropertyListener;
import org.eclipse.ui.ISelectionListener;
import org.eclipse.ui.IWorkbenchActionConstants;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.plugin.AbstractUIPlugin;
import org.eclipse.ui.texteditor.ITextEditor;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;

/**
* @author Rob
*
*         This is the default content outline view
*/
public class CFContentOutlineView extends ContentOutlinePage implements IPartListener, IPropertyListener,
    ISelectionListener {
  public static final String ID_CONTENTOUTLINE = "org.cfeclipse.cfml.views.contentoutline.cfcontentoutlineview";
  private static final int EXPAND_TO_LEVEL= 2;
  protected Action jumpAction, selectAction, deleteItem, expandAction, collapseAction, filterOnAction, openAction,
      removeFilters;
  protected Action filters[];
  private boolean fSelectionFromEditor = false;
  private static String filter = "";
  protected static GotoFileAction gfa = new GotoFileAction();

  public void createControl(Composite parent) {
    super.createControl(parent);
    DocItem root = getRootInput();
    TreeViewer viewer = getTreeViewer();
    viewer.setContentProvider(new OutlineContentProvider(root));
    viewer.setLabelProvider(new OutlineLabelProvider());
    viewer.addSelectionChangedListener(this);
    // this listener listens to the editor (vs. this outline view)
    getSite().getPage().addPostSelectionListener(this);
    createActions();
    createToolbar();
    createContextMenu();
    hookGlobalActions();
    hookDoubleClickAction();
    reload(root);
  }
 
  protected void fireSelectionChanged(ISelection selection) {
    System.out.println("wee");
  }

  /**
   * Gets a 1 level tree of items in the document of a type. See the parser
   * for the filter syntax
   *
   * @param filter
   * @return
   */
  public DocItem getItems(String filter) {
    DocItem scratch = new TagItem(1, 1, 1, "root");

    DocItem rootItem = getRootInput();
    CFNodeList nodes = rootItem.selectNodes(filter);

    Iterator i = nodes.iterator();
    while (i.hasNext()) {
      try {
        scratch.addChild((DocItem) i.next());
      } catch (Exception e) {
        System.err.println("Tree item set error ");
        e.printStackTrace();
      }
    }

    return scratch;
  }

  /**
   * Gets the root element of the document. Saves information into a local
   * cache so if there is an error in the parser it uses the last known good
   * outline (which kind of sucks but it looks better)
   *
   * @return the root directory
   */
  public DocItem getRootInput() {
    try {
      DocItem docRoot = null;

      IEditorPart iep = getSite().getPage().getActiveEditor();

      iep.addPropertyListener(this);
      getSite().getPage().addPartListener(this);

      ITextEditor ite = (ITextEditor) iep;
      ICFDocument icfd = null;
      CFDocument cfd = null;
      if (ite.getDocumentProvider().getDocument(iep.getEditorInput()) instanceof ICFDocument) {
        icfd = (ICFDocument) ite.getDocumentProvider().getDocument(iep.getEditorInput());
        cfd = icfd.getCFDocument();
      }
      // icfd.clearAllMarkers();
      // icfd.parseDocument();

      if (cfd != null) {
        docRoot = cfd.getDocumentRoot();
        // lastDocRoot = docRoot;
      }

      if (docRoot != null) {
        return docRoot;
      } else {
        return createFakeRoot();
      }
    } catch (Exception e) {
      e.printStackTrace(System.err);
    }

    // a fake root
    return createFakeRoot();
  }

  private TagItem createFakeRoot() {
    TagItem tg = new TagItem(1, 1, 1, "Unk");
    return tg;
  }

  /**
   * gets the currently selected item in docitem form or <code>null</code> if
   * there is none
   *
   * @return
   */
  private Iterator getSelectedDocItems() {
    Iterator selecteditem = null;

    // can't do much if nothing is selected
    if (getTreeViewer().getSelection().isEmpty()) {
      return null;
    } else {
      IStructuredSelection selection = (IStructuredSelection) getTreeViewer().getSelection();
      selecteditem = selection.iterator();
    }

    return selecteditem;
  }

  /**
   * gets the currently selected item in docitem form or <code>null</code> if
   * there is none
   *
   * @return
   */
  private DocItem getSelectedDocItem() {
    Iterator selecteditems = getSelectedDocItems();

    // can't do much if nothing is selected
    if (selecteditems == null || !selecteditems.hasNext()) {
      return null;
    }
    return (DocItem) selecteditems.next();
  }

  /**
   * for recursive parent expansion in setSelectedDocItem
   *
   * @return
   */
  private void expandParentItems(DocItem item) {
    // can't do much if nothing is selected
    DocItem parentItem = item.getParent();
    if (parentItem != null) {
      TreeViewer tree = getTreeViewer();
      tree.setExpandedState(parentItem, true);
      tree.refresh(parentItem, false);
      expandParentItems(parentItem);
    }
  }

  /**
   * sets the currently selected item in docitem form or <code>null</code> if
   * there is none
   * @return
   */
  private void setSelectedDocItem(DocItem item) {
    // can't do much if nothing is selected
    if (item != null) {
      TreeViewer tree = getTreeViewer();
      fSelectionFromEditor = true;
      tree.setSelection(new StructuredSelection(item), false);
      fSelectionFromEditor = false;
      //tree.refresh(item, false);
      tree.setExpandedState(item, true);
      tree.reveal(item);
      // reveal takes care of this. Doh!
      //expandParentItems(item);
    }
  }

  /**
   * Selects the item(s) within the source code view
   */
  protected void selectItem() {
    // get a handle to the current editor and assign it to our temp action
    IEditorPart iep = getSite().getPage().getActiveEditor();
    Iterator selecteditems = getSelectedDocItems();

    if (!selecteditems.hasNext())
      return;

    ITextEditor editor = (ITextEditor) iep;
    DocItem firstItem = ((DocItem) selecteditems.next());
    int startPos = firstItem.getStartPosition();
    int endPos = firstItem.getEndPosition();
    if (!selecteditems.hasNext()) {
      // select whole tag
      if(firstItem.getClass().getName().endsWith("CfmlComment")){
        editor.selectAndReveal(firstItem.getStartPosition(), firstItem.getEndPosition() - firstItem.getStartPosition() + 1);
        return;
      }
      if (firstItem instanceof TagItem) {
        TagItem cti = (TagItem) firstItem;
        if (cti.matchingItem != null) {
          if (cti.matchingItem.getStartPosition() < cti.getStartPosition()) {
            startPos = cti.matchingItem.getStartPosition();
            endPos = cti.getEndPosition();
          } else {
            startPos = cti.getStartPosition();
            endPos = cti.matchingItem.getEndPosition();
          }
        } else {
          startPos = cti.getStartPosition();
          endPos = cti.getEndPosition();
        }
      } else {
        ScriptItem csi = (ScriptItem) firstItem;
        startPos = csi.getStartPosition();
        endPos = csi.getEndPosition();
      }
    } else {
      // otherwise select selected items
      while (selecteditems.hasNext()) {
        endPos = ((DocItem) selecteditems.next()).getEndPosition();
      }
    }
    editor.selectAndReveal(startPos, endPos - startPos + 1);
  }

  /**
   * Gets the selected item parses it, and adds the defined stuff to the
   * editor
   */
  protected void jumpToItem() {
    // get a handle to the current editor and assign it to our temp action
    IEditorPart iep = getSite().getPage().getActiveEditor();
    DocItem selecteditem = getSelectedDocItem();

    if (selecteditem == null)
      return;

    ITextEditor editor = (ITextEditor) iep;
    // editor.setHighlightRange(selecteditem.getStartPosition(),selecteditem.getMatchingItem().getEndPosition(),true);
    editor.setHighlightRange(selecteditem.getStartPosition(), 0, true);
  }

  /**
   * filters the outline on the currenly selected element
   */
  protected void filterOnSelected() {
    DocItem selecteditem = getSelectedDocItem();

    if (selecteditem == null)
      return;

    filter = "//" + selecteditem.getName();
    reload();
  }

  public void reload(DocItem root) {
    // saveExpandedElements();
    getTreeViewer().setInput(root);
    if (filter.length() == 0) {
      removeFilters.setEnabled(false);
    } else {
      removeFilters.setEnabled(true);
    }
    getControl().getDisplay().asyncExec(new Runnable() {
      public void run() {
        Control ctrl= getControl();
        if (ctrl != null && !ctrl.isDisposed()) {
          getTreeViewer().refresh();
          updateTreeExpansion();
        }
      }
    });
  }
 
  public void reload() {
    if (filter.length() == 0) {
      DocItem di = getRootInput();
      reload(di);
    } else {
      reload(getItems(filter));
    }
  }

  private void updateTreeExpansion() {
    DocItem root = getRootInput();
    if (!getTreeViewer().getExpandedState(root) && root.hasChildren() && root.getFirstChild().getName().compareToIgnoreCase("cfcomponent") == 0) {
      getTreeViewer().setExpandedState(root.getFirstChild(), true);
      getTreeViewer().refresh(root, false);
    }
//    boolean wasModelEmpty= fIsModelEmpty;
//    fIsModelEmpty= fModel == null || fModel.getProjectNode() == null;
//    if (wasModelEmpty && !fIsModelEmpty) {
//      getTreeViewer().expandToLevel(EXPAND_TO_LEVEL);
//    }
 
 
  /**
   * creates all the default actions
   */
  protected void createActions() {
    jumpAction = new Action("Jump To", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_SHOW)) {
      public void run() {
        // we only want to jump if the change came from tree viewer
        // selection
        jumpToItem();
      }
    };
    jumpAction.setToolTipText("Jump to selected tag in the editor");

    selectAction = new Action("Select", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_SHOW)) {
      public void run() {
        selectItem();
      }
    };
    selectAction.setToolTipText("Select tag in the editor");

    filterOnAction = new Action("Filter On This", CFPluginImages.getImageRegistry().getDescriptor(
        CFPluginImages.ICON_TAG)) {
      public void run() {
        filterOnSelected();
      }
    };
    filterOnAction.setToolTipText("Filter on selected tag type");

    expandAction = new Action("Expand All", AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.search",
        "$nl$/icons/full/elcl16/expandall.gif")) {
      public void run() {
        getTreeViewer().expandAll();
      }
    };
    expandAction.setToolTipText("Expand all");

    collapseAction = new Action("Collapse All", AbstractUIPlugin.imageDescriptorFromPlugin("org.eclipse.search",
        "$nl$/icons/full/elcl16/collapseall.gif")) {
      public void run() {
        getTreeViewer().collapseAll();
      }
    };
    collapseAction.setToolTipText("Collapse all");

    openAction = new Action("Open File", CFPluginImages.getImageRegistry()
        .getDescriptor(CFPluginImages.ICON_IMPORT)) {
      public void run() {
        openFile();
      }
    };

    removeFilters = new Action("Remove Filter", CFPluginImages.getImageRegistry().getDescriptor(
        CFPluginImages.ICON_DELETE)) {
      public void run() {
        filter = "";
        reload();
      }
    };
    removeFilters.setToolTipText("Remove Filter");

    deleteItem = new Action("Delete Item", CFPluginImages.getImageRegistry().getDescriptor(
        CFPluginImages.ICON_DELETE)) {
      public void run() {
        // this doesn't do nothing
        System.out.println("this should delete");
      }
    };

    // /filters
    filters = new Action[6];

    filters[0] = new Action("Include", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_TAG)) {
      public void run() {
        filter = "//cfinclude";
        reload(getItems(filter));
      }
    };

    filters[1] = new Action("Module", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_TAG)) {
      public void run() {
        filter = "//cfmodule";
        reload(getItems(filter));
      }
    };

    filters[2] = new Action("Query", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_TAG)) {
      public void run() {
        filter = "//cfquery";
        reload(getItems(filter));
      }
    };

    filters[3] = new Action("Set", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_TAG)) {
      public void run() {
        filter = "//cfset";
        reload(getItems(filter));
      }
    };

    filters[4] = new Action("Case", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_TAG)) {
      public void run() {
        filter = "//cfcase";
        reload(getItems(filter));
      }
    };

    filters[5] = new Action("Custom", CFPluginImages.getImageRegistry().getDescriptor(CFPluginImages.ICON_TAG)) {
      public void run() {
        InputDialog pathdialog = new InputDialog(getSite().getShell(), "CFML Path Filter",
            "Filter outline using path (i.e. \"//cfoutput\" for all the cfoutput tags):", "", null);

        if (pathdialog.open() == org.eclipse.jface.window.Window.OK) {
          String xpath = pathdialog.getValue();
          if (xpath.length() > 0) {
            filter = xpath;
            reload(getItems(filter));
          }
        }
      }
    };
  }

  private void createContextMenu() {
    // Create menu manager.
    MenuManager menuMgr = new MenuManager();
    menuMgr.setRemoveAllWhenShown(true);
    menuMgr.addMenuListener(new IMenuListener() {
      public void menuAboutToShow(IMenuManager mgr) {
        fillContextMenu(mgr);
      }
    });

    // Create menu.
    Menu menu = menuMgr.createContextMenu(getTreeViewer().getControl());
    getTreeViewer().getControl().setMenu(menu);
  }

  private void fillContextMenu(IMenuManager mgr) {
    mgr.add(selectAction);
    mgr.add(new Separator());
    mgr.add(filterOnAction);
    DocItem di = getSelectedDocItem();
    if (di != null) {
      String sname = di.getName();
      if (filter.length() > 0) {
        mgr.add(removeFilters);
      }
      if (sname.equals("cfinclude") || sname.equals("cfmodule")) {
        mgr.add(openAction);
      }
    }
    mgr.add(new Separator());
    int flen = filters.length;
    for (int i = 0; i < flen; i++) {
      mgr.add(filters[i]);
    }

  }

  protected void createToolbar() {
    IToolBarManager toolbarManager = super.getSite().getActionBars().getToolBarManager();
    toolbarManager.add(expandAction);
    toolbarManager.add(collapseAction);
    toolbarManager.add(selectAction);
    toolbarManager.add(filterOnAction);
    toolbarManager.add(removeFilters);
  }

  /**
   * method to open the currently selected docitem if its a include or a
   * module item
   */
  private void openFile() {
    IEditorPart iep = getSite().getPage().getActiveEditor();
    DocItem selecteditem = getSelectedDocItem();
    if (selecteditem == null)
      return;

    String si = selecteditem.getName();
    if (si.equalsIgnoreCase("cfinclude") || si.equalsIgnoreCase("cfmodule")) {
      gfa.setActiveEditor(null, iep);
      gfa.run(null);
    }
  }

  private void hookDoubleClickAction() {
    getTreeViewer().addDoubleClickListener(new IDoubleClickListener() {
      public void doubleClick(DoubleClickEvent event) {
        selectAction.run();
      }
    });
  }

  private void hookGlobalActions() {
    IActionBars bars = getSite().getActionBars();
    bars.setGlobalActionHandler(IWorkbenchActionConstants.DELETE, deleteItem);
    getTreeViewer().getControl().addKeyListener(new KeyAdapter() {
      public void keyPressed(KeyEvent event) {
        if (event.character == SWT.DEL && event.stateMask == 0 && deleteItem.isEnabled()) {
          deleteItem.run();
        }
      }
    });
  }

  public void selectionChanged(org.eclipse.jface.viewers.SelectionChangedEvent event) {
    // this fires when tree node selection changed
    if(!fSelectionFromEditor) { 
      jumpAction.run();
    }
    // getTreeViewer().refresh(new
    // StructuredSelection(event.getSelection()));
  }

  public void selectionChanged(IWorkbenchPart workbench, ISelection selection) {
    // this fires when editor is changed (thanks to addPostSelection in
    // createControl)
    if (selection != null && selection instanceof ITextSelection) {
      IEditorPart curEditor = workbench.getSite().getWorkbenchWindow().getActivePage().getActiveEditor();
      if (curEditor != null && curEditor instanceof CFMLEditor) {
        CFMLEditor curDoc = (CFMLEditor) curEditor;
        DocItem tagItem = curDoc.getSelectionCursorListener().getSelectedTag();
        if (tagItem != null) {
          setSelectedDocItem(tagItem);
        }
      }
    }
//    if (!getControl().isDisposed()) {
//      getControl().getDisplay().asyncExec(new Runnable() {
//        public void run() {
//          Control ctrl= getControl();
//          if (ctrl != null && !ctrl.isDisposed()) {
//            reload();
//            getTreeViewer().refresh();
//          }
//        }
//      });
//    }
  }

  public void partActivated(IWorkbenchPart arg0) {
    // TODO Auto-generated method stub

  }

  public void partBroughtToTop(IWorkbenchPart arg0) {
    // TODO Auto-generated method stub

  }

  public void partClosed(IWorkbenchPart arg0) {
    // TODO Auto-generated method stub

  }

  public void partDeactivated(IWorkbenchPart arg0) {
    // TODO Auto-generated method stub

  }

  public void partOpened(IWorkbenchPart arg0) {
    // TODO Auto-generated method stub

  }

  public void propertyChanged(Object arg0, int arg1) {
    // this generally comes from a save.  When we get the reconciler going, shouldn't need it
    fSelectionFromEditor = true;
    reload();
  }

}
TOP

Related Classes of org.cfeclipse.cfml.views.contentoutline.CFContentOutlineView

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.