FileEditorManagerImpl as PersistentStateComponent

This commit is contained in:
Vladimir Krivosheev
2015-11-20 15:56:18 +01:00
parent 9c730dddbe
commit 816cdfcb13
6 changed files with 86 additions and 89 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -35,7 +35,7 @@ import com.intellij.problems.WolfTheProblemSolver;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.ui.docking.DockManager;
import com.intellij.util.messages.MessageBus;
import com.intellij.util.messages.MessageBusConnection;
import org.jetbrains.annotations.NotNull;
/**
@@ -56,10 +56,9 @@ public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl {
public PsiAwareFileEditorManagerImpl(final Project project,
final PsiManager psiManager,
final WolfTheProblemSolver problemSolver,
DockManager dockManager,
MessageBus messageBus,
EditorHistoryManager editorHistoryManager) {
super(project, dockManager, editorHistoryManager);
DockManager dockManager) {
super(project, dockManager);
myPsiManager = psiManager;
myProblemSolver = problemSolver;
myPsiTreeChangeListener = new MyPsiTreeChangeListener();
@@ -68,7 +67,7 @@ public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl {
// reinit syntax highlighter for Groovy. In power save mode keywords are highlighted by GroovySyntaxHighlighter insteadof
// GrKeywordAndDeclarationHighlighter. So we need to drop caches for token types attributes in LayeredLexerEditorHighlighter
messageBus.connect().subscribe(PowerSaveMode.TOPIC, new PowerSaveMode.Listener() {
project.getMessageBus().connect().subscribe(PowerSaveMode.TOPIC, new PowerSaveMode.Listener() {
@Override
public void powerSaveStateChanged() {
for (Editor editor : EditorFactory.getInstance().getAllEditors()) {
@@ -79,8 +78,9 @@ public class PsiAwareFileEditorManagerImpl extends FileEditorManagerImpl {
}
@Override
public void projectOpened() {
super.projectOpened(); //To change body of overridden methods use File | Settings | File Templates.
protected void projectOpened(@NotNull MessageBusConnection connection) {
super.projectOpened(connection);
myPsiManager.addPsiTreeChangeListener(myPsiTreeChangeListener);
myProblemSolver.addProblemListener(myProblemListener);
}
@@ -26,7 +26,10 @@ import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.application.ModalityState;
import com.intellij.openapi.application.ex.ApplicationManagerEx;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.ProjectComponent;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.editor.ScrollType;
@@ -43,10 +46,7 @@ import com.intellij.openapi.fileTypes.FileTypeListener;
import com.intellij.openapi.fileTypes.FileTypeManager;
import com.intellij.openapi.preview.PreviewManager;
import com.intellij.openapi.progress.ProcessCanceledException;
import com.intellij.openapi.project.DumbAwareRunnable;
import com.intellij.openapi.project.DumbService;
import com.intellij.openapi.project.PossiblyDumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.project.*;
import com.intellij.openapi.project.impl.ProjectImpl;
import com.intellij.openapi.roots.ModuleRootAdapter;
import com.intellij.openapi.roots.ModuleRootEvent;
@@ -100,7 +100,11 @@ import java.util.concurrent.atomic.AtomicInteger;
* @author Eugene Belyaev
* @author Vladimir Kondratyev
*/
public class FileEditorManagerImpl extends FileEditorManagerEx implements ProjectComponent, JDOMExternalizable {
@State(
name = "FileEditorManager",
storages = @Storage(file = StoragePathMacros.WORKSPACE_FILE)
)
public class FileEditorManagerImpl extends FileEditorManagerEx implements PersistentStateComponent<Element> {
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl");
private static final Key<Boolean> DUMB_AWARE = Key.create("DUMB_AWARE");
@@ -126,7 +130,6 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
private final PropertyChangeListener myEditorPropertyChangeListener = new MyEditorPropertyChangeListener();
private final DockManager myDockManager;
private DockableEditorContainerFactory myContentFactory;
private final EditorHistoryManager myEditorHistoryManager;
private static final AtomicInteger ourOpenFilesSetModificationCount = new AtomicInteger();
public static final ModificationTracker OPEN_FILE_SET_MODIFICATION_COUNT = new ModificationTracker() {
@@ -137,11 +140,10 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
};
public FileEditorManagerImpl(final Project project, DockManager dockManager, EditorHistoryManager editorHistoryManager) {
public FileEditorManagerImpl(@NotNull Project project, DockManager dockManager) {
/* ApplicationManager.getApplication().assertIsDispatchThread(); */
myProject = project;
myDockManager = dockManager;
myEditorHistoryManager = editorHistoryManager;
myListenerList =
new MessageListenerList<FileEditorManagerListener>(myProject.getMessageBus(), FileEditorManagerListener.FILE_EDITOR_MANAGER);
@@ -157,22 +159,41 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
myQueue.setTrackUiActivity(true);
project.getMessageBus().connect().subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
final MessageBusConnection connection = project.getMessageBus().connect();
connection.subscribe(DumbService.DUMB_MODE, new DumbService.DumbModeListener() {
@Override
public void enteredDumbMode() {
}
@Override
public void exitDumbMode() {
// can happen under write action, so postpone to avoid deadlock on FileEditorProviderManager.getProviders()
ApplicationManager.getApplication().invokeLater(new Runnable() {
@Override
public void run() {
if (!project.isDisposed())
dumbModeFinished(project);
if (!myProject.isDisposed())
dumbModeFinished(myProject);
}
});
}
});
connection.subscribe(ProjectManager.TOPIC, new ProjectManagerAdapter() {
@Override
public void projectOpened(Project project) {
if (project == myProject) {
FileEditorManagerImpl.this.projectOpened(connection);
}
}
@Override
public void projectClosed(Project project) {
if (project == myProject) {
// Dispose created editors. We do not use use closeEditor method because
// it fires event and changes history.
closeAllFiles();
}
}
});
}
private void dumbModeFinished(Project project) {
@@ -912,7 +933,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
final FileEditorProvider selectedProvider;
if (entry == null) {
selectedProvider = ((FileEditorProviderManagerImpl)FileEditorProviderManager.getInstance())
.getSelectedFileEditorProvider(myEditorHistoryManager, file, providers);
.getSelectedFileEditorProvider(EditorHistoryManager.getInstance(myProject), file, providers);
}
else {
selectedProvider = entry.getSelectedProvider();
@@ -1018,7 +1039,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
// We have to try to get state from the history only in case
// if editor is not opened. Otherwise history entry might have a state
// out of sync with the current editor state.
state = myEditorHistoryManager.getState(file, provider);
state = EditorHistoryManager.getInstance(myProject).getState(file, provider);
}
if (state != null) {
if (!isDumbAware(editor)) {
@@ -1455,15 +1476,10 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
myListenerList.remove(listener);
}
// ProjectComponent methods
@Override
public void projectOpened() {
protected void projectOpened(@NotNull MessageBusConnection connection) {
//myFocusWatcher.install(myWindows.getComponent ());
getMainSplitters().startListeningFocus();
MessageBusConnection connection = myProject.getMessageBus().connect(myProject);
final FileStatusManager fileStatusManager = FileStatusManager.getInstance(myProject);
if (fileStatusManager != null) {
/**
@@ -1510,7 +1526,7 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
}
}
}, myProject.getDisposed());
// group 1
// group 1
}
}, "", null);
}
@@ -1519,39 +1535,17 @@ public class FileEditorManagerImpl extends FileEditorManagerEx implements Projec
});
}
@Nullable
@Override
public void projectClosed() {
// Dispose created editors. We do not use use closeEditor method because
// it fires event and changes history.
closeAllFiles();
}
// BaseCompomemnt methods
@Override
@NotNull
public String getComponentName() {
return FILE_EDITOR_MANAGER;
public Element getState() {
Element state = new Element("state");
getMainSplitters().writeExternal(state);
return state;
}
@Override
public void initComponent() {
}
@Override
public void disposeComponent() { /* really do nothing */ }
//JDOMExternalizable methods
@Override
public void writeExternal(final Element element) {
getMainSplitters().writeExternal(element);
}
@Override
public void readExternal(final Element element) {
getMainSplitters().readExternal(element);
public void loadState(Element state) {
getMainSplitters().readExternal(state);
}
@Nullable
@@ -44,7 +44,6 @@
<interface-class>com.intellij.openapi.fileEditor.FileEditorManager</interface-class>
<implementation-class>com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl</implementation-class>
<headless-implementation-class>com.intellij.openapi.fileEditor.impl.TestEditorManagerImpl</headless-implementation-class>
<option name="workspace" value="true"/>
</component>
<component>
@@ -16,7 +16,6 @@
package com.intellij.openapi.fileEditor;
import com.intellij.openapi.components.impl.ComponentManagerImpl;
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
@@ -41,7 +40,7 @@ public abstract class HeavyFileEditorManagerTestCase extends CodeInsightFixtureT
public void setUp() throws Exception {
super.setUp();
myManager = new FileEditorManagerImpl(getProject(), DockManager.getInstance(getProject()), EditorHistoryManager.getInstance(getProject()));
myManager = new FileEditorManagerImpl(getProject(), DockManager.getInstance(getProject()));
((ComponentManagerImpl)getProject()).registerComponentInstance(FileEditorManager.class, myManager);
}
@@ -1,5 +1,5 @@
/*
* Copyright 2000-2014 JetBrains s.r.o.
* Copyright 2000-2015 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.
@@ -20,7 +20,6 @@ import com.intellij.openapi.components.ExpandMacroToPathMap;
import com.intellij.openapi.components.impl.ComponentManagerImpl;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.ex.FileEditorProviderManager;
import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
import com.intellij.openapi.fileEditor.impl.FileEditorManagerImpl;
import com.intellij.openapi.fileEditor.impl.FileEditorProviderManagerImpl;
import com.intellij.openapi.util.Disposer;
@@ -59,23 +58,27 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
super.setUp();
DockManager dockManager = DockManager.getInstance(getProject());
myOldDockContainers = dockManager.getContainers();
myManager = new FileEditorManagerImpl(getProject(), dockManager, EditorHistoryManager.getInstance(getProject()));
myManager = new FileEditorManagerImpl(getProject(), dockManager);
myOldManager = ((ComponentManagerImpl)getProject()).registerComponentInstance(FileEditorManager.class, myManager);
((FileEditorProviderManagerImpl)FileEditorProviderManager.getInstance()).clearSelectedProviders();
}
@Override
protected void tearDown() throws Exception {
for (DockContainer container : DockManager.getInstance(getProject()).getContainers()) {
if (!myOldDockContainers.contains(container)) {
Disposer.dispose(container);
try {
for (DockContainer container : DockManager.getInstance(getProject()).getContainers()) {
if (!myOldDockContainers.contains(container)) {
Disposer.dispose(container);
}
}
myOldDockContainers = null;
((ComponentManagerImpl)getProject()).registerComponentInstance(FileEditorManager.class, myOldManager);
myManager.closeAllFiles();
((FileEditorProviderManagerImpl)FileEditorProviderManager.getInstance()).clearSelectedProviders();
}
finally {
super.tearDown();
}
myOldDockContainers = null;
((ComponentManagerImpl)getProject()).registerComponentInstance(FileEditorManager.class, myOldManager);
myManager.closeAllFiles();
((FileEditorProviderManagerImpl)FileEditorProviderManager.getInstance()).clearSelectedProviders();
super.tearDown();
}
@Override
@@ -97,7 +100,7 @@ public abstract class FileEditorManagerTestCase extends LightPlatformCodeInsight
map.addMacroExpand(PathMacroUtil.PROJECT_DIR_MACRO_NAME, getTestDataPath());
map.substitute(rootElement, true, true);
myManager.readExternal(rootElement);
myManager.loadState(rootElement);
Future<?> future = ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
@Override
@@ -1,17 +1,17 @@
/*
* Copyright 2000-2009 JetBrains s.r.o.
* Copyright 2000-2015 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
* 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
* 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.
* 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.tasks.context;
@@ -50,17 +50,18 @@ public class OpenEditorsContextProvider extends WorkingContextProvider {
return "Open editors and positions";
}
@Override
public void saveContext(Element element) {
if (myFileEditorManager != null) {
myFileEditorManager.writeExternal(element);
myFileEditorManager.getMainSplitters().writeExternal(element);
}
Element state = myDockManager.getState();
element.addContent(state);
element.addContent(myDockManager.getState());
}
@Override
public void loadContext(Element element) {
if (myFileEditorManager != null) {
myFileEditorManager.readExternal(element);
myFileEditorManager.loadState(element);
myFileEditorManager.getMainSplitters().openFiles();
}
Element dockState = element.getChild("DockManager");
@@ -70,6 +71,7 @@ public class OpenEditorsContextProvider extends WorkingContextProvider {
}
}
@Override
public void clearContext() {
if (myFileEditorManager != null) {
myFileEditorManager.closeAllFiles();