/*
* 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.cellProviders;
import jetbrains.mps.editor.runtime.descriptor.AbstractEditorBuilder;
import jetbrains.mps.editor.runtime.descriptor.EditorBuilderEnvironment;
import jetbrains.mps.nodeEditor.cellActions.CellAction_InsertIntoCollection;
import jetbrains.mps.nodeEditor.cellLayout.CellLayout;
import jetbrains.mps.nodeEditor.cellLayout.CellLayout_Horizontal;
import jetbrains.mps.nodeEditor.cellLayout.CellLayout_Vertical;
import jetbrains.mps.nodeEditor.cells.EditorCell_Collection;
import jetbrains.mps.openapi.editor.EditorContext;
import jetbrains.mps.openapi.editor.cells.CellActionType;
import jetbrains.mps.openapi.editor.cells.EditorCell;
import jetbrains.mps.util.annotation.ToRemove;
import org.jetbrains.mps.openapi.model.SNode;
import java.util.Iterator;
import java.util.List;
public abstract class AbstractCellListHandler extends AbstractEditorBuilder implements EditorBuilderEnvironment {
public static final String ELEMENT_CELL_ACTIONS_SET = "element-cell-actions-set";
/**
* @deprecated since MPS 3.5 use {@link #getNode()} method, this field will become private in the next release
*/
@Deprecated
protected SNode myOwnerNode;
/**
* @deprecated since MPS 3.5 use {@link #getEditorContext()} method, this field will become private in the next release
*/
@Deprecated
protected EditorContext myEditorContext;
protected EditorCell_Collection myListEditorCell_Collection;
protected String myElementRole;
public AbstractCellListHandler(String elementRole, EditorContext editorContext) {
super(editorContext);
myElementRole = elementRole;
myEditorContext = editorContext;
}
/**
* @deprecated since MPS 3.5 use {@link #AbstractCellListHandler(String, EditorContext)}
*/
@Deprecated
public AbstractCellListHandler(SNode ownerNode, String elementRole, EditorContext editorContext) {
this(elementRole, editorContext);
myOwnerNode = ownerNode;
}
/**
* @deprecated since MPS 3.5 use {@link #getNode()} method
*/
@Deprecated
public SNode getOwner() {
return myOwnerNode;
}
public String getElementRole() {
return myElementRole;
}
protected abstract SNode getAnchorNode(EditorCell anchorCell);
protected abstract void doInsertNode(SNode nodeToInsert, SNode anchorNode, boolean insertBefore);
public void insertNewChild(EditorContext editorContext, EditorCell anchorCell, boolean insertBefore) {
SNode anchorNode = getAnchorNode(anchorCell);
SNode nodeToInsert = createNodeToInsert(editorContext);
doInsertNode(nodeToInsert, anchorNode, insertBefore);
}
public EditorCell createNodeCell(SNode node) {
// TODO: after MPS 3.5 make this method abstract
return createNodeCell(getEditorContext(), node);
}
/**
* @deprecated since MPS 3.5 use {@link #createNodeCell(SNode)}
*/
@Deprecated
public EditorCell createNodeCell(EditorContext editorContext, SNode node) {
return null;
}
protected EditorCell createSeparatorCell(SNode prevNode, SNode nextNode) {
return createSeparatorCell(getEditorContext(), prevNode, nextNode);
}
/**
* @deprecated since MPS 3.5 use {@link #createSeparatorCell(SNode, SNode)}
*/
@Deprecated
protected EditorCell createSeparatorCell(EditorContext editorContext, SNode prevNode, SNode nextNode) {
return null;
}
protected EditorCell createEmptyCell() {
// TODO: after MPS 3.5 make this method abstract
return createEmptyCell(getEditorContext());
}
/**
* @deprecated since MPS 3.5 use {@link #createEmptyCell()}
*/
@Deprecated
protected EditorCell createEmptyCell(EditorContext editorContext) {
return null;
}
public abstract SNode createNodeToInsert(EditorContext editorContext);
public EditorCell_Collection createCells_Vertical(EditorContext editorContext) {
return createCells(editorContext, new CellLayout_Vertical());
}
public EditorCell_Collection createCells_Horizontal(EditorContext editorContext) {
return createCells(editorContext, new CellLayout_Horizontal());
}
/**
* @deprecated since MPS 3.5 use {@link #createCells(CellLayout, boolean)}
*/
@Deprecated
public EditorCell_Collection createCells(EditorContext editorContext, CellLayout cellLayout, boolean selectable) {
return createCells(cellLayout, selectable);
}
public EditorCell_Collection createCells(CellLayout cellLayout, boolean selectable) {
EditorCell_Collection cellsCollection = createCells(cellLayout);
if (!selectable) {
return cellsCollection;
}
// if the list compartment is selectable - create wrapping cell collection around it so
// that actions intended to work for the list element do not work for the list owner.
EditorCell_Collection wrapperCell = EditorCell_Collection.create(getEditorContext(), getNode(), new CellLayout_Horizontal(), null);
wrapperCell.setSelectable(true);
wrapperCell.addEditorCell(cellsCollection);
return wrapperCell;
}
/**
* @deprecated since MPS 3.5 use {@link #createCells(CellLayout)}
*/
@Deprecated
public EditorCell_Collection createCells(EditorContext editorContext, CellLayout cellLayout) {
return createCells(cellLayout);
}
public EditorCell_Collection createCells(CellLayout cellLayout) {
myListEditorCell_Collection = EditorCell_Collection.create(getEditorContext(), getNode(), cellLayout, this);
myListEditorCell_Collection.setSelectable(false);
createInnerCells();
// add insert/insert-before actions
myListEditorCell_Collection.setAction(CellActionType.INSERT, new CellAction_InsertIntoCollection(this, false));
myListEditorCell_Collection.setAction(CellActionType.INSERT_BEFORE, new CellAction_InsertIntoCollection(this, true));
return myListEditorCell_Collection;
}
/**
* @deprecated since MPS 3.5 use {@link #createInnerCells()}
*/
protected void createInnerCells(SNode node, EditorContext editorContext) {
//TODO: after MPS 3.5 remove createInnerCells(SNode node, EditorContext editorContext) & inline it here.
createInnerCells(getNode(), getEditorContext());
}
protected void createInnerCells() {
Iterator<? extends SNode> listNodes = getNodesForList().iterator();
if (!listNodes.hasNext()) {
EditorCell emptyCell = createEmptyCell();
emptyCell.setRole(getElementRole());
myListEditorCell_Collection.addEditorCell(emptyCell);
} else {
SNode prevNode = null;
while (listNodes.hasNext()) {
SNode nextNode = listNodes.next();
addSeparatorCell(prevNode, nextNode);
myListEditorCell_Collection.addEditorCell(createNodeCell(nextNode));
prevNode = nextNode;
}
}
}
protected abstract List<? extends SNode> getNodesForList();
private void addSeparatorCell(SNode prevNode, SNode nextNode) {
if (prevNode == null) {
return;
}
EditorCell separatorCell = createSeparatorCell(prevNode, nextNode);
if (separatorCell != null) {
myListEditorCell_Collection.addEditorCell(separatorCell);
}
}
}