/* * Copyright 2003-2011 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 jetbrains.mps.nodeEditor; import jetbrains.mps.editor.runtime.SideTransformInfoUtil; import jetbrains.mps.nodeEditor.cells.APICellAdapter; import jetbrains.mps.nodeEditor.sidetransform.EditorCell_STHint; import jetbrains.mps.openapi.editor.EditorComponent; import jetbrains.mps.openapi.editor.EditorComponentState; import jetbrains.mps.openapi.editor.cells.CellInfo; import jetbrains.mps.openapi.editor.cells.EditorCell; import jetbrains.mps.openapi.editor.selection.Selection; import jetbrains.mps.openapi.editor.selection.SelectionListener; import jetbrains.mps.openapi.editor.selection.SingularSelection; import jetbrains.mps.openapi.editor.update.UpdaterListener; import jetbrains.mps.openapi.editor.update.UpdaterListenerAdapter; import org.jetbrains.annotations.NotNull; import org.jetbrains.mps.openapi.model.SNode; class AutoValidator { @NotNull private final MyCellSelectionListener mySelectionListener; @NotNull private final EditorComponent myEditorComponent; @NotNull private final MyUpdaterListener myUpdaterListener; private boolean mySuppressSelectionChanges = false; private boolean myEventsBlocked; AutoValidator(@NotNull EditorComponent editorComponent) { myEditorComponent = editorComponent; myEditorComponent.getSelectionManager().addSelectionListener(mySelectionListener = new MyCellSelectionListener()); myEditorComponent.getUpdater().addListener(myUpdaterListener = new MyUpdaterListener()); } private void validateErrorCell(CellInfo cellInfo, EditorComponent editorComponent) { EditorCell cell = cellInfo.findCell(editorComponent); if (cell == null) { return; } EditorComponentState state = editorComponent.getEditorContext().getEditorComponentState(); mySuppressSelectionChanges = true; try { APICellAdapter.validate(cell, true, false); editorComponent.getUpdater().flushModelEvents(); editorComponent.getEditorContext().restoreEditorComponentState(state); } finally { mySuppressSelectionChanges = false; } } void dispose() { mySelectionListener.dispose(); myEditorComponent.getSelectionManager().removeSelectionListener(mySelectionListener); myEditorComponent.getUpdater().removeListener(myUpdaterListener); } private class MyCellSelectionListener implements SelectionListener { private boolean myDisposed; @Override public void selectionChanged(final EditorComponent editorComponent, Selection oldSelection, Selection newSelection) { if (mySuppressSelectionChanges || oldSelection == newSelection || !(oldSelection instanceof SingularSelection)) { return; } final EditorCell editorCell = ((SingularSelection) oldSelection).getEditorCell(); // Do not perform any actions on moving within same EditorCell. if (newSelection instanceof SingularSelection && ((SingularSelection) newSelection).getEditorCell() == editorCell) { return; } if (editorComponent.isReadOnly() || myEventsBlocked) { return; } final boolean wasInErrorState = editorCell.isErrorState(); final boolean wasStHint = editorCell instanceof EditorCell_STHint; if (!wasInErrorState && !wasStHint) { return; } final SNode node = editorCell.getSNode(); final CellInfo cellInfo = editorCell.getCellInfo(); myEditorComponent.getEditorContext().getRepository().getModelAccess().executeCommandInEDT(() -> { if (myDisposed) { return; } if (wasInErrorState) { validateErrorCell(cellInfo, editorComponent); } else { SideTransformInfoUtil.removeTransformInfo(node); } }); } public void dispose() { myDisposed = true; } } private class MyUpdaterListener extends UpdaterListenerAdapter implements UpdaterListener { @Override public void editorUpdateStarted(EditorComponent editorComponent) { myEventsBlocked = true; } @Override public void editorUpdated(EditorComponent editorComponent) { myEventsBlocked = false; } } }