Package com.googlecode.goclipse.editors

Source Code of com.googlecode.goclipse.editors.GoEditorOutlinePage$OutlinePageContentProvider

package com.googlecode.goclipse.editors;

import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import melnorme.utilbox.core.CoreUtil;

import org.eclipse.core.resources.IFile;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider;
import org.eclipse.jface.viewers.DelegatingStyledCellLabelProvider.IStyledLabelProvider;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StyledString;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.ui.IEditorInput;
import org.eclipse.ui.IFileEditorInput;
import org.eclipse.ui.ide.FileStoreEditorInput;
import org.eclipse.ui.texteditor.IDocumentProvider;
import org.eclipse.ui.texteditor.IElementStateListener;
import org.eclipse.ui.views.contentoutline.ContentOutlinePage;

import com.googlecode.goclipse.Activator;
import com.googlecode.goclipse.go.CodeContext;
import com.googlecode.goclipse.go.lang.model.Function;
import com.googlecode.goclipse.go.lang.model.Import;
import com.googlecode.goclipse.go.lang.model.Node;
import com.googlecode.goclipse.go.lang.model.Type;
import com.googlecode.goclipse.go.lang.model.TypeClass;
import com.googlecode.goclipse.ui.GoPluginImages;
import com.googlecode.goclipse.ui.views.GoImageProvider;

/**
* The outline page for the Go editor.
*/
public class GoEditorOutlinePage extends ContentOutlinePage {
  private IDocumentProvider documentProvider;
  private GoEditor editor;

  /**
   * Create a new GoEditorOutlinePage.
   *
   * @param documentProvider
   * @param editor
   */
  public GoEditorOutlinePage(IDocumentProvider documentProvider, GoEditor editor) {
    this.documentProvider = documentProvider;
    this.editor = editor;
  }

  @Override
  public void createControl(Composite parent) {
    super.createControl(parent);
   
    getTreeViewer().setContentProvider(new OutlinePageContentProvider());
    getTreeViewer().setLabelProvider(new DelegatingStyledCellLabelProvider(new NodeLabelProvider()));
    getTreeViewer().addSelectionChangedListener(this);
    getTreeViewer().addSelectionChangedListener(new ISelectionChangedListener() {
      @Override
      public void selectionChanged(SelectionChangedEvent event) {
        handleSelectionChanged();
      }
    });
   
    documentProvider.addElementStateListener(new AbstractElementStateListener() {
      @Override
      public void elementDirtyStateChanged(Object element, boolean isDirty) {
        if (!isDirty) {
          refreshAsync();
        }
      }
    });
   
    refresh();
  }

  protected void handleEditorReconcilation() {
    if (!getControl().isDisposed()) {
      refreshAsync();
    }
  }
 
  protected void handleSelectionChanged() {
    Object sel = ((IStructuredSelection)getTreeViewer().getSelection()).getFirstElement();
   
    if (sel instanceof Node) {
      IDocument document = documentProvider.getDocument(editor.getEditorInput());
     
      Node node = (Node)sel;
     
      int line = node.getLine() - 1;
     
      if (line != -1) {
        try {
          editor.selectAndReveal(document.getLineOffset(line), document.getLineLength(line));
        } catch (BadLocationException ble) {
          ble.printStackTrace();
        }
      }
    }
  }

  private void refreshAsync() {
    Display.getDefault().asyncExec(new Runnable() {
      @Override
            public void run() {
        refresh();
      }
    });
  }
 
  private void refresh() {
    try {
      if (!getTreeViewer().getControl().isDisposed()) {
        IDocument document = documentProvider.getDocument(editor.getEditorInput());
       
        if (document != null) {
          CodeContext codeContext = null;
         
          IEditorInput input = editor.getEditorInput();
         
          if (input instanceof IFileEditorInput) {
            IFile file = ((IFileEditorInput)input).getFile();
           
            codeContext = CodeContext.getCodeContext(
                file.getProject(),
                file.getLocation().toOSString(),
                document.get(), false);
           
          } else if (input instanceof FileStoreEditorInput) {
            URI uri = ((FileStoreEditorInput)input).getURI();
           
            codeContext = CodeContext.getCodeContext(
                new File(uri).getPath(), document.get(), false);
          }
         
          if (codeContext != null) {
            if (getTreeViewer().getInput() == null) {
              getTreeViewer().setInput(codeContext);
            } else {
              OutlinePageContentProvider contentProvider =
                (OutlinePageContentProvider)getTreeViewer().getContentProvider();
             
              contentProvider.setCodeContext(codeContext);
            }
          }
        }
      }
    }
    catch (Throwable exception) {
      Activator.logError(exception);
     
      getTreeViewer().setInput(null);
    }
  }
 
  private static String[] splitFunctionName(String name) {
    int index = name.indexOf(')');
   
    if (name.startsWith("(")) {
      index = name.indexOf(')', index + 1);
    }
   
    if (index + 1 < name.length()) {
      return new String[] {
        name.substring(0, index + 1),
        name.substring(index + 1)
      };
    } else {
      return new String[] { name };
    }
  }
 
  private static Object IMPORT_CONTAINER = "imports";
 
  private static class NodeLabelProvider extends LabelProvider implements IStyledLabelProvider {
   
    public NodeLabelProvider() {
     
    }
   
    @Override
    public String getText(Object element) {
      if (element instanceof Node) {
        Node node = (Node)element;
       
        return node.getName();
      } else {
        return element.toString();
      }
    }
   
    @Override
    public Image getImage(Object element) {
      if (element instanceof Node) {
        Node node = (Node)element;
        return GoImageProvider.getImage(node);
      } else if (element == IMPORT_CONTAINER) {
        return GoPluginImages.ELEMENT_IMPORT_CONTAINER.getImage();
      } else {
        return null;
      }
    }

    @Override
    public StyledString getStyledText(Object element) {
      StyledString str = new StyledString();
     
      if (element instanceof Function) {
        Function function = (Function)element;
       
        String[] strs = splitFunctionName(function.getName());
       
        str.append(strs[0]);
       
        if (strs.length > 1) {
          str.append(strs[1], StyledString.DECORATIONS_STYLER);
        }
      } else if (element instanceof Node) {
        Node node = (Node)element;
       
        if (node.getName() != null) {
          str.append(node.getName());
        } else {
          str.append(node.toString());
        }
       
        if (node instanceof Type) {
          Type type = (Type)node;
         
          if (type.getTypeClass() != TypeClass.UNKNOWN) {
            String typeName = type.getTypeClass().name().toLowerCase();
           
            str.append(" " + typeName, StyledString.DECORATIONS_STYLER);
          }
        }
       
      } else {
        str.append(element.toString());
      }
     
      return str;
    }
  }
 
  private static class OutlinePageContentProvider implements ITreeContentProvider {
    private Object[] NO_CHILDREN = new Object[0];
   
    private TreeViewer viewer;
    private CodeContext codeContext;
   
    public OutlinePageContentProvider() {
     
    }
   
    @Override
    public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
      this.viewer = (TreeViewer)viewer;
      codeContext = (CodeContext)newInput;
    }

    public void setCodeContext(CodeContext inCodeContext) {
      this.codeContext = inCodeContext;
     
      if (CoreUtil.areEqual(this.codeContext, inCodeContext)) {
        viewer.refresh();
      } else {
        viewer.setInput(this.codeContext);
      }
    }

    @Override
    public Object[] getElements(Object inputElement) {
      if (codeContext != null) {
        List<Node> nodes = new ArrayList<Node>();

        nodes.addAll(codeContext.methods);
        nodes.addAll(codeContext.types);
        nodes.addAll(codeContext.functions);
        //nodes.addAll(codeContext.vars);
       
        Collections.sort(nodes, new LineBasedComparator());
       
        List<Object> children = new ArrayList<Object>();
       
        if (codeContext.pkg != null) {
          children.add(codeContext.pkg);
        }
       
        if (codeContext.imports.size() > 0) {
          children.add(IMPORT_CONTAINER);
        }

        children.addAll(nodes);
       
        return children.toArray();
      } else {
        return NO_CHILDREN;
      }
    }

    @Override
    public boolean hasChildren(Object element) {
      return getChildren(element).length > 0;
    }
   
    @Override
    public Object[] getChildren(Object parentElement) {
      if (parentElement == IMPORT_CONTAINER) {
        return codeContext.imports.toArray();
      } else {
        return NO_CHILDREN;
      }
    }

    @Override
    public Object getParent(Object element) {
      if (element instanceof Import) {
        return IMPORT_CONTAINER;
      } else if (element instanceof CodeContext) {
        return null;
      } else {
        return codeContext;
      }
    }

    @Override
    public void dispose() {
     
    }
  }

  private static class LineBasedComparator implements Comparator<Node> {
    @Override
    public int compare(Node node1, Node node2) {
      return node1.getLine() - node2.getLine();
    }
  }
 
  private static abstract class AbstractElementStateListener implements IElementStateListener {
    @Override
    public void elementDirtyStateChanged(Object element, boolean isDirty) {
     
    }

    @Override
    public void elementContentAboutToBeReplaced(Object element) {
     
    }

    @Override
    public void elementContentReplaced(Object element) {
     
    }

    @Override
    public void elementDeleted(Object element) {
     
    }

    @Override
    public void elementMoved(Object originalElement, Object movedElement) {
     
    }
  }

}
TOP

Related Classes of com.googlecode.goclipse.editors.GoEditorOutlinePage$OutlinePageContentProvider

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.