// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.plugins.tracer2; import static org.openstreetmap.josm.tools.I18n.tr; //import static org.openstreetmap.josm.tools.I18n.trn; import java.awt.Cursor; import java.awt.Point; import java.awt.event.ActionEvent; import java.awt.event.InputEvent; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.Collection; import java.util.LinkedList; import java.util.List; import javax.swing.JDialog; import javax.swing.JOptionPane; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.actions.mapmode.MapMode; import org.openstreetmap.josm.command.ChangePropertyCommand; import org.openstreetmap.josm.command.Command; import org.openstreetmap.josm.command.SequenceCommand; import org.openstreetmap.josm.data.coor.LatLon; import org.openstreetmap.josm.data.osm.Node; import org.openstreetmap.josm.data.osm.OsmPrimitive; import org.openstreetmap.josm.data.osm.Way; import org.openstreetmap.josm.gui.MapFrame; import org.openstreetmap.josm.gui.PleaseWaitRunnable; import org.openstreetmap.josm.gui.progress.ProgressMonitor; import org.openstreetmap.josm.plugins.tracer2.preferences.ServerParam; import org.openstreetmap.josm.plugins.tracer2.preferences.ServerParamList; import org.openstreetmap.josm.plugins.tracer2.preferences.ServerParamSelectDialog; import org.openstreetmap.josm.plugins.tracer2.server.GetTrace; import org.openstreetmap.josm.plugins.tracer2.server.GetVersion; import org.openstreetmap.josm.tools.ImageProvider; import org.openstreetmap.josm.tools.Shortcut; import org.xml.sax.SAXException; class TracerAction extends MapMode implements MouseListener, KeyListener { private static final long serialVersionUID = 1L; private static boolean s_bServerVersionOK = false; protected boolean m_bCancel; private boolean m_bCtrl; // if pressed no tag is added + changes and connection are made to ways without tag private boolean m_bAlt; // private boolean m_bShift; // if pressed the new way will be add to the current selected private boolean m_bEnter = false; private TagValues m_oTagValues = new TagValues(); TracerPlugin m_oPlugin; TracerAction(MapFrame mapFrame) { super(tr("Tracer2"), "tracer2-sml", tr("Tracer2."), Shortcut.registerShortcut("tools:tracer2", tr("Tool: {0}", tr("Tracer2")), KeyEvent.VK_T, Shortcut.DIRECT), mapFrame, getCursor()); } @Override public void keyPressed(KeyEvent e) { Collection<OsmPrimitive> selection = getLayerManager().getEditDataSet().getSelected(); List<Command> commands = new ArrayList<>(); if (checkActiveServerParam() == false) return; switch (e.getKeyCode()) { case 37: // left m_oTagValues.left(); break; case 38: // up m_oTagValues.up(); break; case 39: // right m_oTagValues.right(); break; case 40: // down m_oTagValues.down(); break; default: return; } if (selection.isEmpty()) { return; } String strTag = m_oTagValues.getTag(); String strTagValue = m_oTagValues.getTagValue(); if (strTag != null && strTagValue != null) { commands.add(new ChangePropertyCommand(selection, strTag, strTagValue)); if (!commands.isEmpty()) { Main.main.undoRedo.add(new SequenceCommand(tr("Change tag {0} to {1}", strTag, strTagValue), commands)); } } } @Override public void keyReleased(KeyEvent e) { } @Override public void keyTyped(KeyEvent e) { } @Override public void enterMode() { m_bEnter = true; // is not working hear // because if JOSM exit it is called too //checkActiveServerParam(); if (!isEnabled()) { return; } super.enterMode(); Main.map.mapView.setCursor(getCursor()); Main.map.mapView.addMouseListener(this); Main.map.mapView.addKeyListener(this); } @Override public void exitMode() { m_bEnter = false; super.exitMode(); Main.map.mapView.removeMouseListener(this); Main.map.mapView.removeKeyListener(this); } private static Cursor getCursor() { return ImageProvider.getCursor("crosshair", "tracer2-sml"); } protected void traceAsync(Point clickPoint) { m_bCancel = false; /** * Positional data */ final LatLon pos = Main.map.mapView.getLatLon(clickPoint.x, clickPoint.y); try { PleaseWaitRunnable tracerTask = new PleaseWaitRunnable(tr("Tracing")) { @Override protected void realRun() throws SAXException { traceSync(pos, progressMonitor.createSubTaskMonitor(ProgressMonitor.ALL_TICKS, false)); } @Override protected void finish() { } @Override protected void cancel() { TracerAction.this.cancel(); } }; Thread executeTraceThread = new Thread(tracerTask); executeTraceThread.start(); } catch (Exception e) { e.printStackTrace(); } } private void tagBuilding(Way way) { String strTag = m_oTagValues.getTag(); String strTagValue = m_oTagValues.getTagValue(); if (strTag != null && strTagValue != null && !m_bCtrl) { way.put(strTag, strTagValue); } } private boolean checkServerVersion() { int nMajor = 1; int nMinor = 1; if (s_bServerVersionOK == false) { GetVersion oGetVersion = new GetVersion(); oGetVersion.start(); int nRetray = 500; // 5 seconds while (oGetVersion.isAlive() && nRetray > 0) { try { Thread.sleep(10); } catch (Exception e) { break; } nRetray--; } if (oGetVersion.m_nVersionMajor < 0 || oGetVersion.m_nVersionMinor < 0) { return false; } if (oGetVersion.m_nVersionMajor != nMajor) { JOptionPane.showMessageDialog(Main.parent, tr("The Tracer2Server version isn''t compatible with this plugin. Please download version {0} from\n{1}.", nMajor + ".x", "http://sourceforge.net/projects/tracer2server/"), tr("Error"), JOptionPane.ERROR_MESSAGE); return false; } if (oGetVersion.m_nVersionMinor < nMinor) { JOptionPane.showMessageDialog(Main.parent, tr("New version of Tracer2Server is available. For best results please upgrade to version {0}.", nMajor + "." + nMinor), tr("Information"), JOptionPane.INFORMATION_MESSAGE); } s_bServerVersionOK = true; } return true; } private boolean checkActiveServerParam() { if (checkServerVersion() == false) { return false; } if (m_bEnter == true || TracerPlugin.s_oPlugin.m_oParamList.getActivParam() == null) { ServerParamList listParam = TracerPlugin.s_oPlugin.m_oParamList; List<ServerParam> listEnableParam = listParam.getEnableParamList(); if (listEnableParam == null || listEnableParam.size() == 0) { listParam.setActivParam(null); JOptionPane.showMessageDialog(Main.parent, tr("No set of parameter is active!"), tr("Error"), JOptionPane.ERROR_MESSAGE); return false; } if (listEnableParam.size() == 1) { ServerParam param = listEnableParam.get(0); listParam.setActivParam(param); m_oTagValues.readBuildingTags(param); return true; } ServerParamSelectDialog dialog = new ServerParamSelectDialog(listEnableParam, listParam.getActivParam()); if (dialog.getShow()) { JOptionPane pane = new JOptionPane(dialog, JOptionPane.PLAIN_MESSAGE, JOptionPane.OK_CANCEL_OPTION); JDialog dlg = pane.createDialog(Main.parent, tr("Tracer2") + " - " + tr("Select parameter")); dlg.setVisible(true); Object obj = pane.getValue(); dlg.dispose(); if (obj != null && ((Integer) obj) == JOptionPane.OK_OPTION) { TracerPlugin.s_oPlugin.m_oParamList.setActivParam(dialog.getSelectedParam()); } else { return false; } } } ServerParam param = TracerPlugin.s_oPlugin.m_oParamList.getActivParam(); if (param == null) { return false; } m_bEnter = false; m_oTagValues.readBuildingTags(param); return true; } private void traceSync(LatLon pos, ProgressMonitor progressMonitor) { Collection<Command> commands = new LinkedList<>(); progressMonitor.beginTask(null, 3); try { ArrayList<LatLon> coordList; if (checkActiveServerParam() == false) return; ServerParam param = TracerPlugin.s_oPlugin.m_oParamList.getActivParam(); GetTrace oTraceSimple = new GetTrace(pos, param); oTraceSimple.start(); try { while (oTraceSimple.isAlive()) { Thread.sleep(50); if (m_bCancel == true) { oTraceSimple.interrupt(); break; } } coordList = oTraceSimple.m_listLatLon; } catch (Exception e) { coordList = new ArrayList<>(); } if (m_bCancel == true || coordList.size() == 0) { return; } // make nodes a way Way way = new Way(); Node firstNode = null; for (LatLon coord : coordList) { Node node = new Node(coord); if (firstNode == null) { firstNode = node; } //commands.add(new AddCommand(node)); way.addNode(node); } way.addNode(firstNode); tagBuilding(way); // connect to other buildings commands.add(ConnectWays.connect(way, pos, param, m_bCtrl, m_bAlt)); if (!commands.isEmpty()) { String strCommand; if (ConnectWays.s_bAddNewWay == true) { strCommand = tr("Tracer2: add a way with {0} points", coordList.size()); } else { strCommand = tr("Tracer2: modify way to {0} points", coordList.size()); } Main.main.undoRedo.add(new SequenceCommand(strCommand, commands)); if (m_bShift) { getLayerManager().getEditDataSet().addSelected(ConnectWays.s_oWay); } else { getLayerManager().getEditDataSet().setSelected(ConnectWays.s_oWay); } } else { System.out.println("Failed"); } } finally { progressMonitor.finishTask(); } } public void cancel() { m_bCancel = true; } @Override public void mouseClicked(MouseEvent e) { } @Override public void mouseEntered(MouseEvent e) { } @Override public void mouseExited(MouseEvent e) { } @Override public void mousePressed(MouseEvent e) { if (!Main.map.mapView.isActiveLayerDrawable()) { return; } requestFocusInMapView(); updateKeyModifiers(e); if (e.getButton() == MouseEvent.BUTTON1) { traceAsync(e.getPoint()); } } @Override protected void updateKeyModifiers(MouseEvent e) { m_bCtrl = (e.getModifiers() & ActionEvent.CTRL_MASK) != 0; m_bAlt = (e.getModifiers() & (ActionEvent.ALT_MASK | InputEvent.ALT_GRAPH_MASK)) != 0; m_bShift = (e.getModifiers() & ActionEvent.SHIFT_MASK) != 0; } @Override public void mouseReleased(MouseEvent e) { } }