package org.freeplane.plugin.openmaps; import org.freeplane.core.extension.IExtension; import org.freeplane.core.undo.IActor; import org.freeplane.features.icon.IStateIconProvider; import org.freeplane.features.icon.IconController; import org.freeplane.features.icon.UIIcon; import org.freeplane.features.icon.factory.IconStoreFactory; import org.freeplane.features.map.MapModel; import org.freeplane.features.map.NodeModel; import org.freeplane.features.mode.Controller; import org.freeplane.features.mode.NodeHookDescriptor; import org.freeplane.features.mode.PersistentNodeHook; import org.freeplane.n3.nanoxml.XMLElement; import org.freeplane.plugin.openmaps.mapelements.OpenMapsDialog; import org.openstreetmap.gui.jmapviewer.Coordinate; import org.freeplane.plugin.openmaps.LocationChoosenListener; /** * @author Blair Archibald */ @NodeHookDescriptor(hookName = "plugins/openmaps/OpenMapsNodeHook.propterties", onceForMap = false) public class OpenMapsNodeHook extends PersistentNodeHook implements LocationChoosenListener { private OpenMapsDialog map; public OpenMapsNodeHook() { super(); registerStateIconProvider(); } public void chooseLocation() { map = new OpenMapsDialog(); map.getController().addLocationChoosenListener(this); } public void removeLocationFromCurrentlySelectedNode() { final NodeModel node = getCurrentlySelectedNode(); OpenMapsExtension openMapsExtension = (OpenMapsExtension) node.getExtension(OpenMapsExtension.class); if (openMapsExtension != null) { super.undoableToggleHook(node, openMapsExtension); refreshNode(node); } final MapModel map = Controller.getCurrentModeController().getController().getMap(); Controller.getCurrentModeController().getMapController().setSaved(map, false); } //Called when a location is chosen in the OpenMapsDialog - Only one location may be chosen at a time public void locationChoosenAction(Coordinate locationChoosen, int zoom) { addChoosenLocationToSelectedNode(locationChoosen, zoom); map.getController().removeLocationChoosenListener(this); } public void viewCurrentlySelectedLocation() { final NodeModel node = getCurrentlySelectedNode(); OpenMapsExtension openMapsExtension = (OpenMapsExtension) node.getExtension(OpenMapsExtension.class); if (openMapsExtension != null) { map = new OpenMapsDialog(); map.showZoomToLocation(openMapsExtension.getLocation(), openMapsExtension.getZoom()); } } @Override protected HookAction createHookAction() { return null; } @Override protected IExtension createExtension(final NodeModel node, final XMLElement element) { final OpenMapsExtension extension = new OpenMapsExtension(); loadLocationFromXML(element, extension); return (IExtension) extension; } @Override protected Class<OpenMapsExtension> getExtensionClass() { return OpenMapsExtension.class; } @Override protected void saveExtension(final IExtension extension, final XMLElement element) { final OpenMapsExtension openMapsExtension = (OpenMapsExtension) extension; element.setAttribute("LAT", Double.toString(openMapsExtension.getLocation().getLat())); element.setAttribute("LON", Double.toString(openMapsExtension.getLocation().getLon())); element.setAttribute("ZOOM", Integer.toString(openMapsExtension.getZoom())); super.saveExtension(extension, element); } private void loadLocationFromXML(final XMLElement element, final OpenMapsExtension extension) { if (element != null) { final double location_x = Double.parseDouble(element.getAttribute("LAT", null)); final double location_y = Double.parseDouble(element.getAttribute("LON", null)); final int zoom = Integer.parseInt(element.getAttribute("ZOOM",null)); extension.updateLocation(location_x, location_y); extension.updateZoom(zoom); } } private void addChoosenLocationToSelectedNode(Coordinate locationChoosen, int zoom) { final NodeModel node = getCurrentlySelectedNode(); OpenMapsExtension openMapsExtension = (OpenMapsExtension) node.getExtension(OpenMapsExtension.class); if (openMapsExtension == null) { openMapsExtension = new OpenMapsExtension(); undoableActivateHook(node, openMapsExtension); } setLocationChoiceUndoable(openMapsExtension, locationChoosen, zoom); refreshNode(node); } private void setLocationChoiceUndoable(final OpenMapsExtension extension, final Coordinate locationChoosen, final int zoomChoosen) { final Coordinate currentLocation = extension.getLocation(); final int currentZoom = extension.getZoom(); if (!currentLocation.equals(locationChoosen)) { final IActor actor = createUndoActor(extension, locationChoosen, currentLocation, zoomChoosen, currentZoom); Controller.getCurrentModeController().execute(actor, Controller.getCurrentModeController().getController() .getMap()); } } private IActor createUndoActor(final OpenMapsExtension extension, final Coordinate newlyChoosenLocation, final Coordinate currentlyStoredLocation, final int newlyChoosenZoom , final int currentlyStoredZoom) { return new IActor() { private final Coordinate oldLocation = currentlyStoredLocation; private final int oldZoom = currentlyStoredZoom; public void act() { extension.updateLocation(newlyChoosenLocation); extension.updateZoom(newlyChoosenZoom); final MapModel map = Controller.getCurrentModeController() .getController().getMap(); Controller.getCurrentModeController().getMapController() .setSaved(map, false); } public String getDescription() { return "setOpenMapsLocationChoiceUndoable"; } public void undo() { if (oldLocation.getLat() == 500 && oldLocation.getLon() == 500) { removeLocationFromCurrentlySelectedNode(); } else { extension.updateLocation(oldLocation); extension.updateZoom(oldZoom); } refreshNode(getCurrentlySelectedNode()); } }; } private void refreshNode(NodeModel node) { Controller.getCurrentModeController().getMapController().nodeChanged(node, NodeModel.UNKNOWN_PROPERTY, null, null); } private NodeModel getCurrentlySelectedNode() { return Controller.getCurrentModeController().getMapController().getSelectedNode(); } private void registerStateIconProvider() { Controller.getCurrentModeController().getExtension(IconController.class).addStateIconProvider (new IStateIconProvider () { private static final String ICON_NAME = "internet"; public UIIcon getStateIcon(NodeModel node) { if (node.getExtension(OpenMapsExtension.class) != null) return IconStoreFactory.create().getUIIcon(ICON_NAME); else return null; } }); } }