package jetbrains.mps.vcs.diff.ui.common;
/*Generated by MPS */
import com.intellij.ui.treeStructure.SimpleTree;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.actionSystem.DataKey;
import com.intellij.openapi.util.Ref;
import org.jetbrains.mps.openapi.model.SNodeId;
import java.util.List;
import jetbrains.mps.workbench.action.BaseAction;
import com.intellij.util.ui.tree.TreeUtil;
import jetbrains.mps.internal.collections.runtime.Sequence;
import jetbrains.mps.internal.collections.runtime.IVisitor;
import com.intellij.ui.ColoredTreeCellRenderer;
import javax.swing.JTree;
import jetbrains.mps.workbench.action.ActionUtils;
import com.intellij.openapi.actionSystem.ActionPlaces;
import javax.swing.event.TreeSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import jetbrains.mps.internal.collections.runtime.IWhereFilter;
import jetbrains.mps.internal.collections.runtime.ISelector;
import jetbrains.mps.internal.collections.runtime.ListSequence;
import java.util.Collections;
import org.jetbrains.annotations.Nullable;
import javax.swing.tree.TreePath;
import jetbrains.mps.smodel.ModelAccess;
import javax.swing.tree.DefaultTreeModel;
import org.jetbrains.mps.openapi.model.SModel;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.NonNls;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SModelOperations;
import jetbrains.mps.ide.icons.IdeIcons;
import javax.swing.Icon;
import org.jetbrains.mps.openapi.model.SNode;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SNodeOperations;
import jetbrains.mps.lang.smodel.generator.smodelAdapter.SPropertyOperations;
import jetbrains.mps.smodel.adapter.structure.MetaAdapterFactory;
import jetbrains.mps.ide.icons.IconManager;
import javax.swing.tree.DefaultMutableTreeNode;
import com.intellij.ui.SimpleTextAttributes;
import java.awt.Color;
public abstract class DiffModelTree extends SimpleTree implements DataProvider {
public static DataKey<Ref<SNodeId>> NODE_ID_DATAKEY = DataKey.create("MPS_SNodeId");
private List<DiffModelTree.RootTreeNode> myRootNodes;
private Iterable<BaseAction> myActions;
public DiffModelTree() {
rebuildNow();
TreeUtil.expandAll(this);
myActions = getRootActions();
Sequence.fromIterable(myActions).visitAll(new IVisitor<BaseAction>() {
public void visit(BaseAction a) {
a.registerCustomShortcutSet(a.getShortcutSet(), DiffModelTree.this);
}
});
setCellRenderer(new ColoredTreeCellRenderer() {
@Override
public void customizeCellRenderer(JTree p0, Object value, boolean p2, boolean p3, boolean p4, int p5, boolean p6) {
if (value instanceof DiffModelTree.TreeNode) {
((DiffModelTree.TreeNode) value).renderTreeNode(this);
}
}
});
setPopupGroup(ActionUtils.groupFromActions(Sequence.fromIterable(myActions).toGenericArray(BaseAction.class)), ActionPlaces.CHANGES_VIEW_POPUP);
// listen for selection changes
getSelectionModel().addTreeSelectionListener(new TreeSelectionListener() {
public void valueChanged(TreeSelectionEvent e) {
DiffModelTree.RootTreeNode[] node = getSelectedNodes(DiffModelTree.RootTreeNode.class, null);
if (node == null || node.length != 1) {
onUnselect();
} else {
onSelectRoot(node[0].getRootId());
}
}
});
}
protected DiffModelTree.TreeNode rebuild() {
DiffModelTree.ModelTreeNode modelNode = new DiffModelTree.ModelTreeNode();
myRootNodes = Sequence.fromIterable(getAffectedRoots()).where(new IWhereFilter<SNodeId>() {
public boolean accept(SNodeId r) {
return r != null;
}
}).select(new ISelector<SNodeId, DiffModelTree.RootTreeNode>() {
public DiffModelTree.RootTreeNode select(SNodeId r) {
return new DiffModelTree.RootTreeNode(r);
}
}).sort(new ISelector<DiffModelTree.RootTreeNode, String>() {
public String select(DiffModelTree.RootTreeNode rtn) {
return rtn.myVirtualPackage + "|" + rtn.myPresentation;
}
}, true).toListSequence();
for (DiffModelTree.RootTreeNode rtn : ListSequence.fromList(myRootNodes)) {
DiffModelTree.TreeNode parentNode = modelNode;
if (isNotEmptyString(rtn.myVirtualPackage)) {
for (final String sub : Sequence.fromArray(rtn.myVirtualPackage.split("\\."))) {
Iterable<DiffModelTree.TreeNode> children = Collections.list(parentNode.children());
DiffModelTree.TreeNode child = Sequence.fromIterable(children).findFirst(new IWhereFilter<DiffModelTree.TreeNode>() {
public boolean accept(DiffModelTree.TreeNode c) {
return c instanceof DiffModelTree.PackageTreeNode && sub.equals(c.getText());
}
});
if (child == null) {
child = new DiffModelTree.PackageTreeNode(sub);
parentNode.add(child);
}
parentNode = child;
}
}
parentNode.add(rtn);
}
if (Sequence.fromIterable(getAffectedRoots()).any(new IWhereFilter<SNodeId>() {
public boolean accept(SNodeId r) {
return r == null;
}
})) {
DiffModelTree.RootTreeNode metadataNode = new DiffModelTree.MetadataTreeNode();
ListSequence.fromList(myRootNodes).addElement(metadataNode);
modelNode.add(metadataNode);
}
return modelNode;
}
public void setSelected(@Nullable SNodeId rootId) {
// todo: find path by rootId
TreePath path = null;
for (int i = 0; i < getRowCount(); ++i) {
DiffModelTree.RootTreeNode node = as_5x0uld_a0a0a2a5(getPathForRow(i).getLastPathComponent(), DiffModelTree.RootTreeNode.class);
if (node != null && eq_5x0uld_a0a1a2a5(node.getRootId(), rootId)) {
path = getPathForRow(i);
break;
}
}
if (path != null) {
expandPath(path);
setSelectionPath(path);
scrollPathToVisible(path);
}
}
public void rebuildLater() {
rebuildNow();
}
public void rebuildNow() {
ModelAccess.instance().runReadAction(new Runnable() {
public void run() {
setModel(new DefaultTreeModel(rebuild()));
setRootVisible(true);
TreeUtil.expandAll(DiffModelTree.this);
setSelectionRow(0);
}
});
}
protected abstract Iterable<SNodeId> getAffectedRoots();
protected abstract Iterable<SModel> getModels();
protected abstract void updateRootCustomPresentation(@NotNull DiffModelTree.RootTreeNode rootTreeNode);
protected abstract Iterable<BaseAction> getRootActions();
protected boolean isMultipleRootNames() {
return false;
}
protected void onUnselect() {
}
protected void onSelectRoot(@Nullable SNodeId rootId) {
}
private DiffModelTree.RootTreeNode findRootNode(@Nullable final SNodeId nodeId) {
return ListSequence.fromList(myRootNodes).findFirst(new IWhereFilter<DiffModelTree.RootTreeNode>() {
public boolean accept(DiffModelTree.RootTreeNode r) {
return eq_5x0uld_a0a0a0a0a0a0p(nodeId, r.myRootId);
}
});
}
private int advanceIndex(int index, boolean next) {
return (next ? index + 1 : index - 1);
}
public boolean hasNeighbour(SNodeId nodeId, boolean next) {
int index = advanceIndex(ListSequence.fromList(myRootNodes).indexOf(findRootNode(nodeId)), next);
return index >= 0 && index < ListSequence.fromList(myRootNodes).count();
}
@Nullable
public SNodeId getNeighbourRoot(@Nullable SNodeId nodeId, boolean next) {
int index = advanceIndex(ListSequence.fromList(myRootNodes).indexOf(findRootNode(nodeId)), next);
assert index >= 0 && index < ListSequence.fromList(myRootNodes).count();
return ListSequence.fromList(myRootNodes).getElement(index).myRootId;
}
public String getNameForRoot(@Nullable SNodeId nodeId) {
return check_5x0uld_a0a91(findRootNode(nodeId), this);
}
@Nullable
@Override
public Object getData(@NonNls String dataId) {
if (NODE_ID_DATAKEY.is(dataId)) {
DiffModelTree.RootTreeNode[] selectedNodes = getSelectedNodes(DiffModelTree.RootTreeNode.class, null);
if (selectedNodes != null && selectedNodes.length > 0) {
return new Ref<SNodeId>(selectedNodes[0].getRootId());
}
}
return null;
}
public class ModelTreeNode extends DiffModelTree.TreeNode {
public ModelTreeNode() {
setText("model");
setText(SModelOperations.getModelName(Sequence.fromIterable(getModels()).first()));
setIcon(IdeIcons.MODEL_ICON);
}
}
private class PackageTreeNode extends DiffModelTree.TreeNode {
private PackageTreeNode(String packageName) {
setText(packageName);
}
}
public class RootTreeNode extends DiffModelTree.TreeNode {
private SNodeId myRootId;
private String myPresentation = null;
private String myVirtualPackage = null;
public RootTreeNode(SNodeId rootId) {
myRootId = rootId;
setText("" + myRootId);
doUpdatePresentation();
}
@Override
protected void doUpdatePresentation() {
myPresentation = null;
Icon icon = null;
for (SModel model : Sequence.fromIterable(getModels())) {
SNode root = model.getNode(myRootId);
if (root != null && SNodeOperations.getParent(root) == null) {
String presentation = root.getPresentation();
if (myPresentation == null) {
myPresentation = presentation;
} else if (isMultipleRootNames()) {
if (("/ " + myPresentation + " /").contains("/ " + presentation + " /")) {
} else {
myPresentation += " / " + presentation;
}
}
if (myVirtualPackage == null) {
myVirtualPackage = (SPropertyOperations.getString(root, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x10802efe25aL, 0x115eca8579fL, "virtualPackage")) == null ? "" : SPropertyOperations.getString(root, MetaAdapterFactory.getProperty(0xceab519525ea4f22L, 0x9b92103b95ca8c0cL, 0x10802efe25aL, 0x115eca8579fL, "virtualPackage")));
}
if (icon == null) {
icon = IconManager.getIconFor(root);
}
}
}
setText(myPresentation);
setIcon(icon);
updateRootCustomPresentation(this);
}
@Nullable
public SNodeId getRootId() {
return myRootId;
}
public String getPresentation() {
return myPresentation;
}
}
public class MetadataTreeNode extends DiffModelTree.RootTreeNode {
public MetadataTreeNode() {
super(null);
setText("metadata");
doUpdatePresentation();
}
@Override
protected void doUpdatePresentation() {
setText("Model Properties");
setIcon(IdeIcons.PROPERTIES_ICON);
updateRootCustomPresentation(this);
}
@Override
public String getPresentation() {
return "Model Properties";
}
}
public class TreeNode extends DefaultMutableTreeNode {
private String myText;
private int myTextStyle = SimpleTextAttributes.STYLE_PLAIN;
private String myAdditionalText;
private String myTooltipText;
private Icon myIcon;
private Color myColor;
public TreeNode() {
}
public void renderTreeNode(ColoredTreeCellRenderer coloredRenderer) {
ModelAccess.instance().runReadAction(new Runnable() {
public void run() {
doUpdatePresentation();
}
});
coloredRenderer.append(getText(), new SimpleTextAttributes(myTextStyle, getColor()));
if ((myAdditionalText != null && myAdditionalText.length() > 0)) {
coloredRenderer.append(" (" + myAdditionalText + ")", new SimpleTextAttributes(SimpleTextAttributes.STYLE_PLAIN, Color.GRAY));
}
coloredRenderer.setToolTipText(myTooltipText);
coloredRenderer.setIcon(getIcon());
}
protected void doUpdatePresentation() {
}
public String getText() {
return myText;
}
public void setText(String text) {
myText = text;
}
public String getAdditionalText() {
return myAdditionalText;
}
public void setAdditionalText(String additionalText) {
myAdditionalText = additionalText;
}
public String getTooltipText() {
return myTooltipText;
}
public void setTooltipText(String tooltipText) {
myTooltipText = tooltipText;
}
public Icon getIcon() {
return myIcon;
}
public void setIcon(Icon icon) {
myIcon = icon;
}
public Color getColor() {
return myColor;
}
public void setColor(Color color) {
myColor = color;
}
public void setTextStyle(int textStyle) {
myTextStyle = textStyle;
}
}
private static String check_5x0uld_a0a91(DiffModelTree.RootTreeNode checkedDotOperand, DiffModelTree checkedDotThisExpression) {
if (null != checkedDotOperand) {
return checkedDotOperand.getPresentation();
}
return null;
}
private static boolean isNotEmptyString(String str) {
return str != null && str.length() > 0;
}
private static <T> T as_5x0uld_a0a0a2a5(Object o, Class<T> type) {
return (type.isInstance(o) ? (T) o : null);
}
private static boolean eq_5x0uld_a0a1a2a5(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
private static boolean eq_5x0uld_a0a0a0a0a0a0p(Object a, Object b) {
return (a != null ? a.equals(b) : a == b);
}
}