2 * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
5 package com
.intellij
.util
.xml
.ui
;
7 import com
.intellij
.codeHighlighting
.BackgroundEditorHighlighter
;
8 import com
.intellij
.ide
.structureView
.StructureViewBuilder
;
9 import com
.intellij
.openapi
.editor
.Document
;
10 import com
.intellij
.openapi
.editor
.ScrollType
;
11 import com
.intellij
.openapi
.fileEditor
.*;
12 import com
.intellij
.openapi
.project
.Project
;
13 import com
.intellij
.openapi
.util
.UserDataHolderBase
;
14 import com
.intellij
.openapi
.vfs
.*;
15 import com
.intellij
.pom
.Navigatable
;
16 import com
.intellij
.psi
.PsiDocumentManager
;
17 import com
.intellij
.psi
.PsiElement
;
18 import com
.intellij
.psi
.PsiFile
;
19 import com
.intellij
.psi
.PsiManager
;
20 import com
.intellij
.psi
.util
.PsiTreeUtil
;
21 import com
.intellij
.psi
.xml
.XmlTag
;
22 import com
.intellij
.util
.xml
.DomElement
;
23 import com
.intellij
.util
.xml
.DomManager
;
24 import org
.jetbrains
.annotations
.NotNull
;
25 import org
.jetbrains
.annotations
.Nullable
;
28 import java
.beans
.PropertyChangeListener
;
29 import java
.beans
.PropertyChangeSupport
;
32 * User: Sergey.Vasiliev
34 abstract public class PerspectiveFileEditor
extends UserDataHolderBase
implements DocumentsEditor
, Committable
{
35 private final PropertyChangeSupport myPropertyChangeSupport
= new PropertyChangeSupport(this);
36 private final Project myProject
;
37 private final VirtualFile myFile
;
38 private final UndoHelper myUndoHelper
;
39 private boolean myInvalidated
;
41 private static final FileEditorState FILE_EDITOR_STATE
= new FileEditorState() {
42 public boolean canBeMergedWith(FileEditorState otherState
, FileEditorStateLevel level
) {
47 protected PerspectiveFileEditor(final Project project
, final VirtualFile file
) {
49 myUndoHelper
= new UndoHelper(project
, this);
52 FileEditorManager
.getInstance(myProject
).addFileEditorManagerListener(new FileEditorManagerAdapter() {
53 public void selectionChanged(FileEditorManagerEvent event
) {
54 if (PerspectiveFileEditor
.this.equals(event
.getOldEditor())) {
56 if (event
.getNewEditor() instanceof TextEditor
) {
57 setSelectionInTextEditor((TextEditor
)event
.getNewEditor(), getSelectedDomElement());
60 else if (PerspectiveFileEditor
.this.equals(event
.getNewEditor())) {
62 if (event
.getOldEditor() instanceof TextEditor
) {
63 final DomElement element
= getSelectedDomElementFromTextEditor((TextEditor
)event
.getOldEditor());
64 if (element
!= null) {
65 setSelectedDomElement(element
);
67 } else if (event
.getOldEditor() instanceof PerspectiveFileEditor
) {
68 setSelectedDomElement(((PerspectiveFileEditor
)event
.getOldEditor()).getSelectedDomElement());
73 //todo[peter] move this listener to DOM
74 VirtualFileManager
.getInstance().addVirtualFileListener(new VirtualFileAdapter() {
75 public void propertyChanged(VirtualFilePropertyEvent event
) {
79 public void contentsChanged(VirtualFileEvent event
) {
83 public void fileCreated(VirtualFileEvent event
) {
87 public void fileDeleted(VirtualFileEvent event
) {
91 public void fileMoved(VirtualFileMoveEvent event
) {
96 myUndoHelper
.startListeningDocuments();
98 final PsiFile psiFile
= getPsiFile();
99 if (psiFile
!= null) {
100 final Document document
= PsiDocumentManager
.getInstance(getProject()).getDocument(psiFile
);
101 if (document
!= null) {
102 addWatchedDocument(document
);
107 abstract protected DomElement
getSelectedDomElement();
108 abstract protected void setSelectedDomElement(DomElement domElement
);
110 protected boolean isMyFile(VirtualFile file
) {
111 return file
.equals(myFile
);
114 public final void addWatchedElement(final DomElement domElement
) {
115 addWatchedDocument(getDocumentManager().getDocument(domElement
.getRoot().getFile()));
118 public final void removeWatchedElement(final DomElement domElement
) {
119 removeWatchedDocument(getDocumentManager().getDocument(domElement
.getRoot().getFile()));
122 public final void addWatchedDocument(final Document document
) {
123 myUndoHelper
.addWatchedDocument(document
);
126 public final void removeWatchedDocument(final Document document
) {
127 myUndoHelper
.removeWatchedDocument(document
);
130 protected DomElement
getSelectedDomElementFromTextEditor(final TextEditor textEditor
) {
131 final PsiFile psiFile
= getPsiFile();
132 if (psiFile
== null) return null;
133 final PsiElement psiElement
= psiFile
.findElementAt(textEditor
.getEditor().getCaretModel().getOffset());
135 if(psiElement
== null) return null;
137 final XmlTag xmlTag
= PsiTreeUtil
.getParentOfType(psiElement
, XmlTag
.class);
139 return DomManager
.getDomManager(myProject
).getDomElement(xmlTag
);
142 public void setSelectionInTextEditor(final TextEditor textEditor
, final DomElement element
) {
143 if (element
!= null && element
.isValid()) {
144 final XmlTag tag
= element
.getXmlTag();
145 if (tag
== null) return;
147 final PsiFile file
= tag
.getContainingFile();
148 if (file
== null) return;
150 final Document document
= getDocumentManager().getDocument(file
);
151 if (document
== null || !document
.equals(textEditor
.getEditor().getDocument())) return;
153 textEditor
.getEditor().getCaretModel().moveToOffset(tag
.getTextOffset());
154 textEditor
.getEditor().getScrollingModel().scrollToCaret(ScrollType
.CENTER
);
158 protected final PsiDocumentManager
getDocumentManager() {
159 return PsiDocumentManager
.getInstance(myProject
);
163 public final PsiFile
getPsiFile() {
164 return PsiManager
.getInstance(myProject
).findFile(myFile
);
167 public final Document
[] getDocuments() {
168 return myUndoHelper
.getDocuments();
171 public final Project
getProject() {
175 public final VirtualFile
getVirtualFile() {
179 public void dispose() {
180 if (myInvalidated
) return;
181 myInvalidated
= true;
182 myUndoHelper
.stopListeningDocuments();
185 public final boolean isModified() {
186 return FileDocumentManager
.getInstance().isFileModified(getVirtualFile());
189 public boolean isValid() {
190 return getVirtualFile().isValid();
193 public void selectNotify() {
194 myUndoHelper
.setShowing(true);
198 public void deselectNotify() {
199 if (myInvalidated
) return;
200 myUndoHelper
.setShowing(false);
204 public BackgroundEditorHighlighter
getBackgroundHighlighter() {
208 public FileEditorLocation
getCurrentLocation() {
209 return new FileEditorLocation() {
210 public FileEditor
getEditor() {
211 return PerspectiveFileEditor
.this;
214 public int compareTo(final FileEditorLocation fileEditorLocation
) {
220 public StructureViewBuilder
getStructureViewBuilder() {
225 public FileEditorState
getState(FileEditorStateLevel level
) {
226 return FILE_EDITOR_STATE
;
229 public void setState(FileEditorState state
) {
232 public void addPropertyChangeListener(PropertyChangeListener listener
) {
233 myPropertyChangeSupport
.addPropertyChangeListener(listener
);
236 public void removePropertyChangeListener(PropertyChangeListener listener
) {
237 myPropertyChangeSupport
.removePropertyChangeListener(listener
);
240 protected final boolean checkIsValid() {
241 if (!myInvalidated
&& !isValid()) {
242 myInvalidated
= true;
243 myPropertyChangeSupport
.firePropertyChange(FileEditor
.PROP_VALID
, Boolean
.TRUE
, Boolean
.FALSE
);
245 return !myInvalidated
;