Subject: [PATCH] 23808
---
Index: src/org/openstreetmap/josm/actions/AlignInCircleAction.java
IDEA additional info:
Subsystem: com.intellij.openapi.diff.impl.patch.CharsetEP
<+>UTF-8
===================================================================
diff --git a/src/org/openstreetmap/josm/actions/AlignInCircleAction.java b/src/org/openstreetmap/josm/actions/AlignInCircleAction.java
--- a/src/org/openstreetmap/josm/actions/AlignInCircleAction.java	(revision 19144)
+++ b/src/org/openstreetmap/josm/actions/AlignInCircleAction.java	(date 1721140769272)
@@ -5,6 +5,9 @@
 import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
 import static org.openstreetmap.josm.tools.I18n.tr;
 
+import java.awt.Color;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
 import java.awt.event.ActionEvent;
 import java.awt.event.KeyEvent;
 import java.util.ArrayList;
@@ -18,7 +21,12 @@
 import java.util.TreeMap;
 import java.util.stream.Collectors;
 
+import javax.swing.AbstractAction;
+import javax.swing.Action;
+import javax.swing.JButton;
+import javax.swing.JEditorPane;
 import javax.swing.JOptionPane;
+import javax.swing.JPanel;
 
 import org.openstreetmap.josm.command.Command;
 import org.openstreetmap.josm.command.MoveCommand;
@@ -29,12 +37,16 @@
 import org.openstreetmap.josm.data.osm.DataSet;
 import org.openstreetmap.josm.data.osm.Node;
 import org.openstreetmap.josm.data.osm.OsmPrimitive;
+import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
 import org.openstreetmap.josm.data.osm.Way;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon;
 import org.openstreetmap.josm.data.osm.visitor.paint.relations.Multipolygon.JoinedWay;
 import org.openstreetmap.josm.data.validation.tests.CrossingWays;
 import org.openstreetmap.josm.data.validation.tests.SelfIntersectingWay;
+import org.openstreetmap.josm.gui.MainApplication;
 import org.openstreetmap.josm.gui.Notification;
+import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
+import org.openstreetmap.josm.tools.GBC;
 import org.openstreetmap.josm.tools.Geometry;
 import org.openstreetmap.josm.tools.Logging;
 import org.openstreetmap.josm.tools.Shortcut;
@@ -82,6 +94,28 @@
             super(msg);
         }
     }
+
+    /**
+     * IncompleteReferrers exception has to be raised when action can't be performed due to objects without
+     * referrer information
+     */
+    public static class IncompleteReferrers extends InvalidSelection {
+        private final long[] nodeIds;
+
+        /**
+         * Create an IncompleteReferrers exception with specific message
+         * @param msg Message that will be displayed to the user
+         * @param nodeIds The nodes that are missing referrers
+         */
+        IncompleteReferrers(String msg, long... nodeIds) {
+            super(msg);
+            this.nodeIds = nodeIds;
+        }
+
+        public long[] getNodeIds() {
+            return this.nodeIds;
+        }
+    }
 
     /**
      * Add a {@link MoveCommand} to move a node to a PolarCoor if there is a significant move.
@@ -120,6 +154,38 @@
                 .show();
 
             }
+        } catch (IncompleteReferrers except) {
+            Logging.debug(except);
+            final JPanel panel = new JPanel(new GridBagLayout());
+            final JMultilineLabel lbl = new JMultilineLabel(except.getMessage());
+            final DataSet editDataSet = getLayerManager().getEditDataSet();
+            final Action downloadReferrers = new AbstractAction(tr("Download Referrers ({0} nodes)", except.getNodeIds().length)) {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    Collection<OsmPrimitive> toDownload = new ArrayList<>(except.getNodeIds().length);
+                    for (long nodeId : except.getNodeIds()) {
+                        toDownload.add(editDataSet.getPrimitiveById(nodeId, OsmPrimitiveType.NODE));
+                    }
+                    DownloadReferrersAction.downloadReferrers(getLayerManager().getEditLayer(), toDownload);
+                }
+            };
+            final Action downloadAlong = new AbstractAction("Download Along") {
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    MainApplication.getMenu().downloadAlongWay.actionPerformed(e);
+                }
+            };
+            lbl.setMaxWidth(Notification.DEFAULT_CONTENT_WIDTH);
+            lbl.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
+            lbl.setForeground(Color.BLACK);
+            panel.setOpaque(false);
+            panel.add(lbl, GBC.eol().fill(GridBagConstraints.HORIZONTAL));
+            panel.add(new JButton(downloadReferrers));
+            panel.add(new JButton(downloadAlong), GBC.eol().fill(GridBagConstraints.HORIZONTAL));
+            new Notification().setContent(panel)
+                    .setIcon(JOptionPane.INFORMATION_MESSAGE)
+                    .setDuration(Notification.TIME_SHORT)
+                    .show();
         } catch (InvalidSelection except) {
             Logging.debug(except);
             new Notification(except.getMessage())
@@ -274,7 +340,8 @@
 
         // Check if one or more nodes does not have all parents available
         if (nodes.stream().anyMatch(not(Node::isReferrersDownloaded)))
-            throw new InvalidSelection(tr("One or more nodes involved in this action may have additional referrers."));
+            throw new IncompleteReferrers(tr("One or more nodes involved in this action may have additional referrers."),
+                    nodes.stream().filter(not(Node::isReferrersDownloaded)).mapToLong(Node::getUniqueId).toArray());
 
 
         if (center == null) {
