Package com.intellij.ide.structureView

Source Code of com.intellij.ide.structureView.TextEditorBasedStructureViewModel

/*
* Copyright 2000-2007 JetBrains s.r.o.
*
* Licensed 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 com.intellij.ide.structureView;

import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.EditorFactory;
import com.intellij.openapi.editor.event.CaretEvent;
import com.intellij.openapi.editor.event.CaretListener;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.FileViewProvider;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ReflectionCache;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

/**
* The standard {@link StructureViewModel} implementation which is linked to a text editor.
*
* @see com.intellij.ide.structureView.TreeBasedStructureViewBuilder#createStructureViewModel()
*/

public abstract class TextEditorBasedStructureViewModel implements StructureViewModel {
  private final Editor myEditor;
  private final CaretListener myCaretListener;
  private final List<FileEditorPositionListener> myListeners = new CopyOnWriteArrayList<FileEditorPositionListener>();

  /**
   * Creates a structure view model instance linked to a text editor displaying the specified
   * file.
   *
   * @param psiFile the file for which the structure view model is requested.
   */
  protected TextEditorBasedStructureViewModel(@NotNull PsiFile psiFile) {
    this(getEditorForFile(psiFile));
  }

  /**
   * Creates a structure view model instance linked to the specified text editor.
   *
   * @param editor the editor for which the structure view model is requested.
   */
  protected TextEditorBasedStructureViewModel(final Editor editor) {
    myEditor = editor;
    myCaretListener = new CaretListener() {
      public void caretPositionChanged(CaretEvent e) {
        if (Comparing.equal(e.getEditor(), myEditor)) {
          fireCaretPositionChanged();
        }
      }

      private void fireCaretPositionChanged() {
        for (FileEditorPositionListener listener : myListeners) {
          listener.onCurrentElementChanged();
        }
      }
    };

    EditorFactory.getInstance().getEventMulticaster().addCaretListener(myCaretListener);
  }

  @Nullable
  private static Editor getEditorForFile(@NotNull final PsiFile psiFile) {
    VirtualFile virtualFile = psiFile.getVirtualFile();
    if (virtualFile == null) {
      PsiFile originalFile = psiFile.getOriginalFile();
      if (originalFile == null) return null;
      virtualFile = originalFile.getVirtualFile();
      if (virtualFile == null) return null;
    }
    final FileEditor[] editors = FileEditorManager.getInstance(psiFile.getProject()).getEditors(virtualFile);
    for (FileEditor editor : editors) {
      if (editor instanceof TextEditor) {
        return ((TextEditor)editor).getEditor();
      }
    }
    return null;
  }

  public final void addEditorPositionListener(FileEditorPositionListener listener) {
    myListeners.add(listener);
  }

  public final void removeEditorPositionListener(FileEditorPositionListener listener) {
    myListeners.remove(listener);
  }

  public void dispose() {
    EditorFactory.getInstance().getEventMulticaster().removeCaretListener(myCaretListener);
  }

  public Object getCurrentEditorElement() {
    if (myEditor == null) return null;
    final int offset = myEditor.getCaretModel().getOffset();
    FileViewProvider viewProvider = getPsiFile().getViewProvider();
    PsiElement element = viewProvider.findElementAt(offset, getPsiFile().getLanguage());
    while (element != null && !(element instanceof PsiFile)) {
      if (isSuitable(element)) return element;
      element = element.getParent();
    }
    return null;
  }

  protected abstract PsiFile getPsiFile();   // TODO: change abstract method to constructor parameter?

  protected boolean isSuitable(final PsiElement element) {
    if (element == null) return false;
    final Class[] suitableClasses = getSuitableClasses();
    for (Class suitableClass : suitableClasses) {
      if (ReflectionCache.isAssignable(suitableClass, element.getClass())) return true;
    }
    return false;
  }

  public void addModelListener(ModelListener modelListener) {

  }

  public void removeModelListener(ModelListener modelListener) {

  }

  /**
   * Returns the list of PSI element classes which are shown as structure view elements.
   * When determining the current editor element, the PSI tree is walked up until an element
   * matching one of these classes is found.
   *
   * @return the list of classes
   */
  @NotNull protected Class[] getSuitableClasses() {
    return ArrayUtil.EMPTY_CLASS_ARRAY;
  }

  protected Editor getEditor() {
    return myEditor;
  }
}
TOP

Related Classes of com.intellij.ide.structureView.TextEditorBasedStructureViewModel

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.