package jetbrains.mps.vcs.changesmanager.editor;
/*Generated by MPS */
import jetbrains.mps.openapi.editor.message.EditorMessageOwner;
import jetbrains.mps.nodeEditor.EditorComponent;
import java.util.Map;
import jetbrains.mps.vcs.diff.changes.ModelChange;
import java.util.List;
import jetbrains.mps.vcs.diff.ui.common.ChangeEditorMessage;
import jetbrains.mps.internal.collections.runtime.MapSequence;
import java.util.HashMap;
import jetbrains.mps.vcs.changesmanager.CurrentDifference;
import org.jetbrains.annotations.NotNull;
import com.intellij.openapi.project.Project;
import jetbrains.mps.vcs.changesmanager.CurrentDifferenceRegistry;
import org.jetbrains.mps.openapi.module.SRepository;
import org.jetbrains.mps.openapi.model.SNode;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.mps.openapi.model.EditableSModel;
import jetbrains.mps.vcs.diff.ChangeSet;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.ide.ThreadUtils;
import jetbrains.mps.baseLanguage.closures.runtime.Wrappers;
import jetbrains.mps.vcs.diff.changes.AddRootChange;
import jetbrains.mps.vcs.diff.ui.common.ChangeEditorMessageFactory;
import java.util.ArrayList;
import jetbrains.mps.internal.collections.runtime.SetSequence;
import org.jetbrains.annotations.Nullable;
import jetbrains.mps.nodeEditor.NodeHighlightManager;
import jetbrains.mps.nodeEditor.leftHighlighter.LeftEditorHighlighter;
import jetbrains.mps.vcs.changesmanager.CurrentDifferenceAdapter;
public class EditorHighlighter implements EditorMessageOwner {
private EditorComponent myEditorComponent;
private final Map<ModelChange, List<ChangeEditorMessage>> myChangesMessages = MapSequence.fromMap(new HashMap<ModelChange, List<ChangeEditorMessage>>());
private CurrentDifference myCurrentDifference;
private ChangeStripsPainter myStripsPainter;
private EditorHighlighter.MyCurrentDifferenceListener myListener;
private final Object myDisposedLock = new Object();
private boolean myDisposed = false;
public EditorHighlighter(@NotNull final Project project, @NotNull final EditorComponent editorComponent) {
myEditorComponent = editorComponent;
CurrentDifferenceRegistry.getInstance(project).getCommandQueue().runTask(new Runnable() {
public void run() {
final SRepository repo = editorComponent.getEditorContext().getRepository();
repo.getModelAccess().runReadAction(new Runnable() {
public void run() {
synchronized (myDisposedLock) {
if (myDisposed) {
return;
}
final SNode editedNode = (editorComponent.getEditedNodePointer() == null ? null : editorComponent.getEditedNodePointer().resolve(repo));
if (editedNode == null) {
return;
}
final SModel model = editedNode.getModel();
if (model instanceof EditableSModel && !(model.isReadOnly())) {
myCurrentDifference = CurrentDifferenceRegistry.getInstance(project).getCurrentDifference((EditableSModel) model);
myListener = new EditorHighlighter.MyCurrentDifferenceListener();
}
if (myListener != null) {
myCurrentDifference.setEnabled(true);
ChangeSet changeSet = myCurrentDifference.getChangeSet();
if (changeSet != null) {
ListSequence.fromList(changeSet.getModelChanges()).where(new IWhereFilter<ModelChange>() {
public boolean accept(ModelChange c) {
return editedNode.getNodeId().equals(c.getRootId());
}
}).visitAll(new IVisitor<ModelChange>() {
public void visit(ModelChange c) {
createMessages(c);
}
});
}
synchronized (myChangesMessages) {
Sequence.fromIterable(MapSequence.fromMap(myChangesMessages).values()).visitAll(new IVisitor<List<ChangeEditorMessage>>() {
public void visit(List<ChangeEditorMessage> messages) {
ListSequence.fromList(messages).visitAll(new IVisitor<ChangeEditorMessage>() {
public void visit(ChangeEditorMessage m) {
getHighlightManager().mark(m);
}
});
}
});
}
getHighlightManager().repaintAndRebuildEditorMessages();
ThreadUtils.runInUIThreadNoWait(new Runnable() {
public void run() {
myStripsPainter = new ChangeStripsPainter(EditorHighlighter.this);
myEditorComponent.getLeftEditorHighlighter().addFoldingAreaPainter(myStripsPainter);
// .relayout() is called as a part of .addFoldingAreaPainter() method execution
}
});
myCurrentDifference.addDifferenceListener(myListener);
}
}
}
});
}
});
}
private List<ChangeEditorMessage> createMessages(final ModelChange change) {
final Wrappers._T<List<ChangeEditorMessage>> messages = new Wrappers._T<List<ChangeEditorMessage>>(null);
if (!(change instanceof AddRootChange)) {
final SRepository repo = myEditorComponent.getEditorContext().getRepository();
repo.getModelAccess().runReadAction(new Runnable() {
public void run() {
SNode editedNode = (myEditorComponent.getEditedNodePointer() == null ? null : myEditorComponent.getEditedNodePointer().resolve(repo));
if (editedNode == null) {
return;
}
SModel model = editedNode.getModel();
messages.value = ChangeEditorMessageFactory.createMessages(model, change.getChangeSet().getNewModel() != model, change, EditorHighlighter.this, null, false);
}
});
}
if (messages.value == null) {
messages.value = ListSequence.fromList(new ArrayList<ChangeEditorMessage>());
}
synchronized (myChangesMessages) {
if (MapSequence.fromMap(myChangesMessages).containsKey(change)) {
return ListSequence.fromList(new ArrayList<ChangeEditorMessage>());
}
MapSequence.fromMap(myChangesMessages).put(change, messages.value);
}
return messages.value;
}
private List<ChangeEditorMessage> removeMessages(ModelChange change) {
synchronized (myChangesMessages) {
List<ChangeEditorMessage> messages = MapSequence.fromMap(myChangesMessages).get(change);
if (messages == null || getHighlightManager() == null || ListSequence.fromList(messages).any(new IWhereFilter<ChangeEditorMessage>() {
public boolean accept(ChangeEditorMessage m) {
return m.getNode() == null;
}
})) {
return ListSequence.fromList(new ArrayList<ChangeEditorMessage>());
}
MapSequence.fromMap(myChangesMessages).removeKey(change);
return messages;
}
}
/*package*/ List<ChangeEditorMessage> getMessages(ModelChange change) {
synchronized (myChangesMessages) {
return MapSequence.fromMap(myChangesMessages).get(change);
}
}
public void dispose() {
synchronized (myDisposedLock) {
myDisposed = true;
try {
synchronized (myChangesMessages) {
SetSequence.fromSet(MapSequence.fromMap(myChangesMessages).keySet()).toListSequence().visitAll(new IVisitor<ModelChange>() {
public void visit(ModelChange ch) {
removeMessages(ch);
}
});
}
getHighlightManager().clearForOwner(this);
if (myStripsPainter != null) {
getLeftEditorHighlighter().removeFoldingAreaPainter(myStripsPainter);
myStripsPainter.dispose();
}
} finally {
if (myCurrentDifference != null) {
myCurrentDifference.removeDifferenceListener(myListener);
myListener = null;
}
}
}
}
@Nullable
/*package*/ ChangeSet getChangeSet() {
return check_urq9my_a0a21(myCurrentDifference);
}
/*package*/ ChangeStripsPainter getStripsPainter() {
return myStripsPainter;
}
/*package*/ EditorComponent getEditorComponent() {
return myEditorComponent;
}
/*package*/ NodeHighlightManager getHighlightManager() {
return myEditorComponent.getHighlightManager();
}
/*package*/ LeftEditorHighlighter getLeftEditorHighlighter() {
return myEditorComponent.getLeftEditorHighlighter();
}
public class MyCurrentDifferenceListener extends CurrentDifferenceAdapter {
private List<ChangeEditorMessage> myAddedMessages = ListSequence.fromList(new ArrayList<ChangeEditorMessage>());
private List<ChangeEditorMessage> myRemovedMessages = ListSequence.fromList(new ArrayList<ChangeEditorMessage>());
public MyCurrentDifferenceListener() {
}
@Override
public void changeAdded(@NotNull ModelChange change) {
List<ChangeEditorMessage> messages = createMessages(change);
ListSequence.fromList(myRemovedMessages).removeSequence(ListSequence.fromList(messages));
ListSequence.fromList(myAddedMessages).addSequence(ListSequence.fromList(messages));
}
@Override
public void changeRemoved(@NotNull ModelChange change) {
List<ChangeEditorMessage> messages = removeMessages(change);
ListSequence.fromList(myRemovedMessages).addSequence(ListSequence.fromList(messages));
ListSequence.fromList(myAddedMessages).removeSequence(ListSequence.fromList(messages));
}
@Override
public void changeUpdateFinished() {
if (myEditorComponent.isDisposed()) {
return;
}
if (!(ListSequence.fromList(myAddedMessages).isEmpty()) || !(ListSequence.fromList(myRemovedMessages).isEmpty())) {
NodeHighlightManager nodeHighlightManager = getHighlightManager();
for (ChangeEditorMessage removedMessage : ListSequence.fromList(myRemovedMessages)) {
nodeHighlightManager.unmark(removedMessage);
}
for (ChangeEditorMessage addedMessage : ListSequence.fromList(myAddedMessages)) {
nodeHighlightManager.mark(addedMessage);
}
check_urq9my_a3a1a5r(myStripsPainter);
nodeHighlightManager.repaintAndRebuildEditorMessages();
ListSequence.fromList(myAddedMessages).clear();
ListSequence.fromList(myRemovedMessages).clear();
}
}
}
private static ChangeSet check_urq9my_a0a21(CurrentDifference checkedDotOperand) {
if (null != checkedDotOperand) {
return checkedDotOperand.getChangeSet();
}
return null;
}
private static void check_urq9my_a3a1a5r(ChangeStripsPainter checkedDotOperand) {
if (null != checkedDotOperand) {
checkedDotOperand.relayout();
}
}
}