package org.intellij.plugins.markdown.ui.split;
import com.intellij.openapi.fileEditor.*;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
public abstract class SplitTextEditorProvider implements AsyncFileEditorProvider, DumbAware {
private static final String FIRST_EDITOR = "first_editor";
private static final String SECOND_EDITOR = "second_editor";
private static final String SPLIT_LAYOUT = "split_layout";
@NotNull
protected final FileEditorProvider myFirstProvider;
@NotNull
protected final FileEditorProvider mySecondProvider;
@NotNull
private final String myEditorTypeId;
public SplitTextEditorProvider(@NotNull FileEditorProvider firstProvider, @NotNull FileEditorProvider secondProvider) {
myFirstProvider = firstProvider;
mySecondProvider = secondProvider;
myEditorTypeId = "split-provider[" + myFirstProvider.getEditorTypeId() + ";" + mySecondProvider.getEditorTypeId() + "]";
}
@Override
public boolean accept(@NotNull Project project, @NotNull VirtualFile file) {
return myFirstProvider.accept(project, file) && mySecondProvider.accept(project, file);
}
@NotNull
@Override
public FileEditor createEditor(@NotNull Project project, @NotNull VirtualFile file) {
return createEditorAsync(project, file).build();
}
@NotNull
@Override
public String getEditorTypeId() {
return myEditorTypeId;
}
@NotNull
@Override
public Builder createEditorAsync(@NotNull final Project project, @NotNull final VirtualFile file) {
final Builder firstBuilder = getBuilderFromEditorProvider(myFirstProvider, project, file);
final Builder secondBuilder = getBuilderFromEditorProvider(mySecondProvider, project, file);
return new Builder() {
@Override
public FileEditor build() {
return createSplitEditor(firstBuilder.build(), secondBuilder.build());
}
};
}
@NotNull
@Override
public FileEditorState readState(@NotNull Element sourceElement, @NotNull Project project, @NotNull VirtualFile file) {
Element child = sourceElement.getChild(FIRST_EDITOR);
FileEditorState firstState = null;
if (child != null) {
firstState = myFirstProvider.readState(child, project, file);
}
child = sourceElement.getChild(SECOND_EDITOR);
FileEditorState secondState = null;
if (child != null) {
secondState = mySecondProvider.readState(child, project, file);
}
final Attribute attribute = sourceElement.getAttribute(SPLIT_LAYOUT);
final String layoutName;
if (attribute != null) {
layoutName = attribute.getValue();
}
else {
layoutName = null;
}
return new SplitFileEditor.MyFileEditorState(layoutName, firstState, secondState);
}
@Override
public void writeState(@NotNull FileEditorState state, @NotNull Project project, @NotNull Element targetElement) {
if (!(state instanceof SplitFileEditor.MyFileEditorState)) {
return;
}
final SplitFileEditor.MyFileEditorState compositeState = (SplitFileEditor.MyFileEditorState)state;
Element child = new Element(FIRST_EDITOR);
if (compositeState.getFirstState() != null) {
myFirstProvider.writeState(compositeState.getFirstState(), project, child);
targetElement.addContent(child);
}
child = new Element(SECOND_EDITOR);
if (compositeState.getSecondState() != null) {
mySecondProvider.writeState(compositeState.getSecondState(), project, child);
targetElement.addContent(child);
}
if (compositeState.getSplitLayout() != null) {
targetElement.setAttribute(SPLIT_LAYOUT, compositeState.getSplitLayout());
}
}
protected abstract FileEditor createSplitEditor(@NotNull FileEditor firstEditor, @NotNull FileEditor secondEditor);
@NotNull
@Override
public FileEditorPolicy getPolicy() {
return FileEditorPolicy.HIDE_DEFAULT_EDITOR;
}
@NotNull
private static Builder getBuilderFromEditorProvider(@NotNull final FileEditorProvider provider,
@NotNull final Project project,
@NotNull final VirtualFile file) {
if (provider instanceof AsyncFileEditorProvider) {
return ((AsyncFileEditorProvider)provider).createEditorAsync(project, file);
}
else {
return new Builder() {
@Override
public FileEditor build() {
return provider.createEditor(project, file);
}
};
}
}
}