package org.freeplane.plugin.remote.client.listeners; import java.awt.Container; import java.util.HashMap; import java.util.Map; import javax.swing.JComponent; import org.freeplane.core.util.LogUtils; import org.freeplane.features.map.INodeView; import org.freeplane.features.map.MapChangeEvent; import org.freeplane.features.map.NodeChangeEvent; import org.freeplane.features.map.NodeModel; import org.freeplane.plugin.remote.client.ClientController; import org.freeplane.plugin.remote.client.User; import org.freeplane.plugin.remote.client.services.WS; import org.freeplane.plugin.remote.v10.model.NodeModelDefault; import org.freeplane.view.swing.features.filepreview.ExternalResource; import org.freeplane.view.swing.map.MapView; import org.freeplane.view.swing.map.NodeView; @SuppressWarnings("serial") public class NodeViewListener extends NodeView implements INodeView { private final ClientController clientController; private NodeModelDefault lastNodeState; private final NodeModel model; public NodeViewListener(ClientController clientController, NodeModel model, MapView map, Container parent) { super(model, map, parent); lastNodeState = new NodeModelDefault(model, false); this.model = model; this.clientController = clientController; } @Override public void addContent(JComponent component, int pos) { // override to do nothing } @Override public void onPreNodeMoved(NodeModel oldParent, int oldIndex, NodeModel newParent, NodeModel child, int newIndex) { // not important } @Override public void onPreNodeDelete(NodeModel oldParent, NodeModel selectedNode, int index) { // not important } @Override public void onNodeMoved(NodeModel oldParent, int oldIndex, NodeModel newParent, NodeModel child, int newIndex) { // not important } @Override public void onNodeInserted(NodeModel parent, NodeModel child, int newIndex) { // not important } @Override public void onNodeDeleted(NodeModel parent, NodeModel child, int index) { // not important } @Override public void mapChanged(MapChangeEvent event) { // not important } @Override public void nodeChanged(final NodeChangeEvent event) { LogUtils.info("nodeChange called"); if (!isUpdating()) { if (event != null && event.getProperty() != null) LogUtils.info("attribute: " + event.getProperty().toString()); if (event != null && event.getNewValue() != null) LogUtils.info("value: " + event.getNewValue().toString()); if (event.getProperty() != null) { final Object property = event.getProperty(); if (property.toString().contains("FOLDING")) { LogUtils.info("folding"); webservice().changeNode(user().getUsername(), user().getAccessToken(), "5", event.getNode().getID(), "folded", event.getNewValue()); // final ListenableFuture<Boolean> future = webservice().changeNode("5", event.getNode().getID(), "folded", event.getNewValue()); // Futures.addCallback(future, new FutureCallback<Boolean>() { // // @Override // public void onFailure(Throwable t) { // t.printStackTrace(); // } // // @Override // public void onSuccess(Boolean success) { // if (!success) { // isUpdating(true); // event.getNode().setFolded(!(Boolean) event.getNewValue()); // isUpdating(false); // } // } // }); } // note else if(property.equals("note_text")) { LogUtils.info("note_text"); webservice().changeNode(user().getUsername(), user().getAccessToken(), "5", event.getNode().getID(), "note", event.getNewValue()); } // images else if (property.equals(ExternalResource.class)) { LogUtils.info("image"); // TODO is not handled by the server side, yet. // use this code when handling is implemented //final ExternalResource resource = (ExternalResource) event.getNewValue(); //webservice().changeNode("5", event.getNode().getID(), "image", resource.getUri().toString()); } // send all because real change is unknown (only every 5 // seconds) else if (property.equals(NodeModel.UNKNOWN_PROPERTY)) { // Do nothing, because logic has changed // long nowMillis = System.currentTimeMillis(); // if (lastMillis < 0 || nowMillis - lastMillis > 5000) { // lastMillis = nowMillis; // LogUtils.info("unkown property changed, creating diff"); // NodeModelDefault now = new NodeModelDefault(event.getNode(), false); // Map<String, Object> attributeValueMap = getChangedAttributes(lastNodeState, now); // lastNodeState = now; // } } } } } // private long lastMillis = -1; public void updateCurrentState() { lastNodeState = new NodeModelDefault(model,false); } public Map<String, Object> getChangedAttributes() { final Map<String, Object> attributes = new HashMap<String, Object>(); NodeModelDefault now = new NodeModelDefault(model,false); // nodeText is a recognized change // fold is a recognized change // moving is not recognized if (!lastNodeState.hGap.equals(now.hGap)) { LogUtils.info("hGap changed to " + now.hGap); attributes.put("hGap", now.hGap); } // if (!lastNodeState.shiftY.equals(now.shiftY)) { LogUtils.info("hGap changed to " + now.shiftY); attributes.put("shiftY", now.shiftY); } //links are not recognized if(lastNodeState.link == null && now.link != null) { attributes.put("link",now.link); } else if (lastNodeState.link != null && now.link != null && !lastNodeState.link.equals(now.link)) { attributes.put("link",now.link); } else if(lastNodeState.link != null && now.link == null) { attributes.put("link", null); } //EdgeStyles are not recognized lastNodeState = now; return attributes; } private WS webservice() { return clientController.webservice(); } private boolean isUpdating() { return clientController.isUpdating(); } private User user() { return clientController.getUser(); } }