/*FreeMind - A Program for creating and viewing Mindmaps *Copyright (C) 2000-2011 Joerg Mueller, Daniel Polansky, Christian Foltin, Dimitri Polivaev and others. * *See COPYING for Details * *This program is free software; you can redistribute it and/or *modify it under the terms of the GNU General Public License *as published by the Free Software Foundation; either version 2 *of the License, or (at your option) any later version. * *This program is distributed in the hope that it will be useful, *but WITHOUT ANY WARRANTY; without even the implied warranty of *MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *GNU General Public License for more details. * *You should have received a copy of the GNU General Public License *along with this program; if not, write to the Free Software *Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ package plugins.map; import java.io.File; import java.io.IOException; import java.io.Writer; import java.net.MalformedURLException; import java.util.HashMap; import javax.imageio.ImageIO; import org.openstreetmap.gui.jmapviewer.Coordinate; import freemind.main.Resources; import freemind.main.Tools; import freemind.main.XMLElement; import freemind.modes.MindMapNode; import freemind.modes.common.plugins.MapNodePositionHolderBase; import freemind.modes.mindmapmode.MindMapController; import freemind.view.mindmapview.NodeView; /** * @author foltin * @date 27.10.2011 */ public class MapNodePositionHolder extends MapNodePositionHolderBase { /** * */ private static final String MAP_LOCATION = "map_location"; private Coordinate mPosition = new Coordinate(0, 0); private Coordinate mMapCenter = new Coordinate(0, 0); private String mTileSource = null; private int mZoom = 1; private static String sMapLocationGif; /* * (non-Javadoc) * * @see * freemind.extensions.NodeHookAdapter#invoke(freemind.modes.MindMapNode) */ public void invoke(MindMapNode pNode) { super.invoke(pNode); getRegistration().registerMapNode(this); } protected Registration getRegistration() { return (Registration) getPluginBaseClass(); } public void showTooltip() { if (isTooltipDesired()) { if (mTooltipLocation != null) { /* We only need the tooltip on disk. */ File tooltipFile = getTooltipFile(false); if (tooltipFile.exists()) { addTooltip(); } else { // something went wrong. Again. createToolTip(false); } } else { createToolTip(false); } } } /* * (non-Javadoc) * * @see freemind.extensions.PermanentNodeHookAdapter#shutdownMapHook() */ public void shutdownMapHook() { getRegistration().deregisterMapNode(this); super.shutdownMapHook(); } /* * (non-Javadoc) * * @see * freemind.extensions.PermanentNodeHookAdapter#save(freemind.main.XMLElement * ) */ public void save(XMLElement xml) { super.save(xml); HashMap values = new HashMap(); values.put(XML_STORAGE_POS_LON, toString(mPosition.getLon())); values.put(XML_STORAGE_POS_LAT, toString(mPosition.getLat())); values.put(XML_STORAGE_MAP_LON, toString(mMapCenter.getLon())); values.put(XML_STORAGE_MAP_LAT, toString(mMapCenter.getLat())); values.put(XML_STORAGE_ZOOM, toString(mZoom)); if (mTileSource != null) { values.put(XML_STORAGE_TILE_SOURCE, mTileSource); } if (mTooltipLocation != null) { values.put(XML_STORAGE_MAP_TOOLTIP_LOCATION, mTooltipLocation); } saveNameValuePairs(values, xml); } /** * @param pDouble * @return */ private String toString(double pDouble) { return "" + pDouble; } /** * @param pInt * @return */ private String toString(int pInt) { return "" + pInt; } /* * (non-Javadoc) * * @see freemind.extensions.PermanentNodeHookAdapter#loadFrom(freemind.main. * XMLElement) */ public void loadFrom(XMLElement pChild) { super.loadFrom(pChild); HashMap values = loadNameValuePairs(pChild); mPosition.setLat(fromString(values.get(XML_STORAGE_POS_LAT))); mPosition.setLon(fromString(values.get(XML_STORAGE_POS_LON))); mMapCenter.setLat(fromString(values.get(XML_STORAGE_MAP_LAT))); mMapCenter.setLon(fromString(values.get(XML_STORAGE_MAP_LON))); mZoom = intFromString(values.get(XML_STORAGE_ZOOM)); // is done in super implementation // // if no value stored, the get method returns null. // mTooltipLocation = (String) // values.get(XML_STORAGE_MAP_TOOLTIP_LOCATION); mTileSource = (String) values.get(XML_STORAGE_TILE_SOURCE); } /** * @param pObject * @return */ private double fromString(Object pObject) { if (pObject == null) { return 0.0; } try { return Double.parseDouble((String) pObject); } catch (Exception e) { freemind.main.Resources.getInstance().logException(e); return 0.0; } } /** * @param pObject * @return */ private int intFromString(Object pObject) { if (pObject == null) { return 1; } try { return Integer.parseInt((String) pObject); } catch (Exception e) { freemind.main.Resources.getInstance().logException(e); return 1; } } /** * Set map position. Is undoable. * * @param pTileSource * */ public void changePosition(Coordinate pPosition, Coordinate pMapCenter, int pZoom, String pTileSource) { getRegistration().changePosition(this, pPosition, pMapCenter, pZoom, pTileSource); // the changePosition recreates the tooltip... } public static interface MapNodePositionListener { void registerMapNode(MapNodePositionHolder pMapNodePositionHolder); void deregisterMapNode(MapNodePositionHolder pMapNodePositionHolder); } public Coordinate getPosition() { return mPosition; } public static MapNodePositionHolder getHook(MindMapNode node) { return (MapNodePositionHolder) getBaseHook(node); } /** * @param pTileSource */ public void setTileSource(String pTileSource) { mTileSource = pTileSource; } /** * @return */ public String getTileSource() { return mTileSource; } public void setPosition(Coordinate pPosition) { mPosition = pPosition; } public Coordinate getMapCenter() { return mMapCenter; } public void setMapCenter(Coordinate pMapCenter) { mMapCenter = pMapCenter; } public int getZoom() { return mZoom; } public void setZoom(int pZoom) { mZoom = pZoom; } public MindMapNode getNode() { return super.getNode(); } /** */ public String getImageHtml() { String imageTag = getImageTag(); String imageHtml = "<html><body>" + imageTag + "</body></html>"; logger.fine("Tooltip at " + imageTag); return imageHtml; } protected String getImageTag() { String imageTag = "ERROR"; try { imageTag = "<img src=\"" + Tools.fileToUrl(getTooltipFile(false)) + "\"/>"; } catch (MalformedURLException e) { freemind.main.Resources.getInstance().logException(e); } return imageTag; } public File getTooltipFile(boolean pForce) { if (mTooltipFile != null) { return mTooltipFile; } File mapFile = getMap().getFile(); boolean storeProperty = Resources.getInstance().getBoolProperty( NODE_MAP_STORE_TOOLTIP) || pForce; if (mapFile == null || !storeProperty) { try { if (mapFile == null) { // Houston, we have a problem logger.warning("Creating tooltip in .freemind directory, " + "as we don't know, where the map will be stored."); } mTooltipFile = File.createTempFile("node_map_tooltip_" + getNodeId(), ".png", new File(getController() .getFrame().getFreemindDirectory())); // not persistent. if (!pForce) { mTooltipFile.deleteOnExit(); } } catch (IOException e) { freemind.main.Resources.getInstance().logException(e); } } else { String createdFileName = mapFile.getAbsolutePath() + "_map_" + getNodeId() + ".png"; mTooltipFile = new File(createdFileName); if (!pForce) { // only store location, if not forced from outside. mTooltipLocation = mTooltipFile.getName(); } } return mTooltipFile; } public boolean createToolTip(boolean pForce) { boolean success = true; // order tooltip to be created. TileImage tileImage; tileImage = getRegistration().getImageForTooltip(mPosition, mZoom, mTileSource); if (!tileImage.hasErrors()) { logger.fine("Creating tooltip for " + getNode()); // save image to disk: try { File tooltipFile = getTooltipFile(pForce); ImageIO.write(tileImage.getImage(), "png", tooltipFile); addTooltip(); } catch (IOException e) { freemind.main.Resources.getInstance().logException(e); } } else { tileImage = null; logger.warning("Tooltip for node '" + getNode() + "' has errors on creation."); success = false; } return success; } public String getNodeId() { return getMindMapController().getNodeID(getNode()); } /** * @return */ private MindMapController getMindMapController() { return (MindMapController) getController(); } /** * */ public void recreateTooltip() { // remove file from disk. getTooltipFile(false).delete(); mTooltipLocation = null; showTooltip(); } /** * @return This method returns true, when a parent of the corresponding node * is folded. */ public boolean hasFoldedParents() { return getNode().hasFoldedParents(); } /* * (non-Javadoc) * * @see * freemind.extensions.PermanentNodeHookAdapter#onViewCreatedHook(freemind * .view.mindmapview.NodeView) */ public void onViewCreatedHook(NodeView pNodeView) { super.onViewCreatedHook(pNodeView); logger.fine("View created for " + this); getRegistration().fireNodeVisibilityChanged(true, this); } /* * (non-Javadoc) * * @see * freemind.extensions.PermanentNodeHookAdapter#onViewRemovedHook(freemind * .view.mindmapview.NodeView) */ public void onViewRemovedHook(NodeView pNodeView) { super.onViewRemovedHook(pNodeView); logger.fine("Removed view for " + this); getRegistration().fireNodeVisibilityChanged(false, this); } public String toString() { return "MapNodePositionHolder [mPosition=" + mPosition + ", mMapCenter=" + mMapCenter + ", mTileSource=" + mTileSource + ", mZoom=" + mZoom + ", getNode()=" + getNode() + "]"; } /* * (non-Javadoc) * * @see * freemind.extensions.PermanentNodeHookAdapter#saveHtml(java.io.Writer) */ public void saveHtml(Writer pFileout) throws IOException { super.saveHtml(pFileout); if (sMapLocationGif == null) { sMapLocationGif = getController().getFrame().getProperty( MAP_LOCATION); } String link = FreeMindMapController.getLink(mTileSource, mPosition, mMapCenter, mZoom); // to embed the original thumb nail: getImageTag() + pFileout.append("<a href=\"" + link + "\">" + "<img src=\"" + sMapLocationGif + "\"/></a>"); } }