Index: trunk/src/org/openstreetmap/josm/Main.java
===================================================================
--- trunk/src/org/openstreetmap/josm/Main.java	(revision 5517)
+++ trunk/src/org/openstreetmap/josm/Main.java	(revision 5519)
@@ -628,14 +628,39 @@
     }
 
+    /**
+     * Asks user to perform "save layer" operations (save .osm on disk and/or upload osm data to server) for all {@link OsmDataLayer} before JOSM exits.
+     * @return {@code true} if there was nothing to save, or if the user wants to proceed to save operations. {@code false} if the user cancels.
+     * @since 2025
+     */
     public static boolean saveUnsavedModifications() {
-        if (map == null) return true;
-        SaveLayersDialog dialog = new SaveLayersDialog(Main.parent);
+        if (map == null || map.mapView == null) return true;
+        return saveUnsavedModifications(map.mapView.getLayersOfType(OsmDataLayer.class), true);
+    }
+
+    /**
+     * Asks user to perform "save layer" operations (save .osm on disk and/or upload osm data to server) before osm layers deletion.
+     * 
+     * @param selectedLayers The layers to check. Only instances of {@link OsmDataLayer} are considered.
+     * @param exit {@code true} if JOSM is exiting, {@code false} otherwise.
+     * @return {@code true} if there was nothing to save, or if the user wants to proceed to save operations. {@code false} if the user cancels.
+     * @since 5519
+     */
+    public static boolean saveUnsavedModifications(List<? extends Layer> selectedLayers, boolean exit) {
+        SaveLayersDialog dialog = new SaveLayersDialog(parent);
         List<OsmDataLayer> layersWithUnmodifiedChanges = new ArrayList<OsmDataLayer>();
-        for (OsmDataLayer l: Main.map.mapView.getLayersOfType(OsmDataLayer.class)) {
-            if ((l.requiresSaveToFile() || l.requiresUploadToServer()) && l.data.isModified()) {
-                layersWithUnmodifiedChanges.add(l);
-            }
-        }
-        dialog.prepareForSavingAndUpdatingLayersBeforeExit();
+        for (Layer l: selectedLayers) {
+            if (!(l instanceof OsmDataLayer)) {
+                continue;
+            }
+            OsmDataLayer odl = (OsmDataLayer)l;
+            if ((odl.requiresSaveToFile() || (odl.requiresUploadToServer() && !odl.isUploadDiscouraged())) && odl.data.isModified()) {
+                layersWithUnmodifiedChanges.add(odl);
+            }
+        }
+        if (exit) {
+            dialog.prepareForSavingAndUpdatingLayersBeforeExit();
+        } else {
+            dialog.prepareForSavingAndUpdatingLayersBeforeDelete();
+        }
         if (!layersWithUnmodifiedChanges.isEmpty()) {
             dialog.getModel().populate(layersWithUnmodifiedChanges);
Index: trunk/src/org/openstreetmap/josm/gui/MapView.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 5517)
+++ trunk/src/org/openstreetmap/josm/gui/MapView.java	(revision 5519)
@@ -69,5 +69,5 @@
  * @author imi
  */
-public class MapView extends NavigatableComponent implements PropertyChangeListener, PreferenceChangedListener {
+public class MapView extends NavigatableComponent implements PropertyChangeListener, PreferenceChangedListener, OsmDataLayer.LayerStateChangeListener {
 
     /**
@@ -312,5 +312,9 @@
         }
         fireLayerAdded(layer);
-        boolean callSetActiveLayer = layer instanceof OsmDataLayer || activeLayer == null;
+        boolean isOsmDataLayer = layer instanceof OsmDataLayer;
+        if (isOsmDataLayer) {
+            ((OsmDataLayer)layer).addLayerStateChangeListener(this);
+        }
+        boolean callSetActiveLayer = isOsmDataLayer || activeLayer == null;
         if (callSetActiveLayer) {
             // autoselect the new layer
@@ -393,4 +397,8 @@
         if (layer == activeLayer) {
             setActiveLayer(determineNextActiveLayer(layersList), false);
+        }
+        
+        if (layer instanceof OsmDataLayer) {
+            ((OsmDataLayer)layer).removeLayerPropertyChangeListener(this);
         }
 
@@ -863,5 +871,5 @@
 
     protected void refreshTitle() {
-        boolean dirty = editLayer != null && (editLayer.requiresSaveToFile() || editLayer.requiresUploadToServer());
+        boolean dirty = editLayer != null && (editLayer.requiresSaveToFile() || (editLayer.requiresUploadToServer() && !editLayer.isUploadDiscouraged()));
         if (dirty) {
             JOptionPane.getFrameForComponent(Main.parent).setTitle("* " + tr("Java OpenStreetMap Editor"));
@@ -893,3 +901,9 @@
     }
 
+    @Override
+    public void uploadDiscouragedChanged(OsmDataLayer layer, boolean newValue) {
+        if (layer == getEditLayer()) {
+            refreshTitle();
+        }
+    }
 }
Index: trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java	(revision 5517)
+++ trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java	(revision 5519)
@@ -389,29 +389,4 @@
         }
 
-        protected boolean enforceUploadOrSaveModifiedData(List<Layer> selectedLayers) {
-            SaveLayersDialog dialog = new SaveLayersDialog(Main.parent);
-            List<OsmDataLayer> layersWithUnmodifiedChanges = new ArrayList<OsmDataLayer>();
-            for (Layer l: selectedLayers) {
-                if (! (l instanceof OsmDataLayer)) {
-                    continue;
-                }
-                OsmDataLayer odl = (OsmDataLayer)l;
-                if ((odl.requiresSaveToFile() || odl.requiresUploadToServer()) && odl.data.isModified()) {
-                    layersWithUnmodifiedChanges.add(odl);
-                }
-            }
-            dialog.prepareForSavingAndUpdatingLayersBeforeDelete();
-            if (!layersWithUnmodifiedChanges.isEmpty()) {
-                dialog.getModel().populate(layersWithUnmodifiedChanges);
-                dialog.setVisible(true);
-                switch(dialog.getUserAction()) {
-                case CANCEL: return false;
-                case PROCEED: return true;
-                default: return false;
-                }
-            }
-            return true;
-        }
-
         @Override
         public void actionPerformed(ActionEvent e) {
@@ -419,7 +394,7 @@
             if (selectedLayers.isEmpty())
                 return;
-            if (! enforceUploadOrSaveModifiedData(selectedLayers))
+            if (!Main.saveUnsavedModifications(selectedLayers, false))
                 return;
-            for(Layer l: selectedLayers) {
+            for (Layer l: selectedLayers) {
                 Main.main.removeLayer(l);
             }
Index: trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java
===================================================================
--- trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 5517)
+++ trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java	(revision 5519)
@@ -28,4 +28,5 @@
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.CopyOnWriteArrayList;
 
 import javax.swing.AbstractAction;
@@ -165,4 +166,40 @@
         void commandChanged(int queueSize, int redoSize);
     }
+    
+    /**
+     * Listener called when a state of this layer has changed.
+     */
+    public interface LayerStateChangeListener {
+        /**
+         * Notifies that the "upload discouraged" (upload=no) state has changed.
+         * @param layer The layer that has been modified
+         * @param newValue The new value of the state
+         */
+        void uploadDiscouragedChanged(OsmDataLayer layer, boolean newValue);
+    }
+    
+    private final CopyOnWriteArrayList<LayerStateChangeListener> layerStateChangeListeners = new CopyOnWriteArrayList<LayerStateChangeListener>();
+    
+    /**
+     * Adds a layer state change listener
+     *
+     * @param listener the listener. Ignored if null or already registered.
+     * @since 5519
+     */
+    public void addLayerStateChangeListener(LayerStateChangeListener listener) {
+        if (listener != null) {
+            layerStateChangeListeners.addIfAbsent(listener);
+        }
+    }
+    
+    /**
+     * Removes a layer property change listener
+     *
+     * @param listener the listener. Ignored if null or already registered.
+     * @since 5519
+     */
+    public void removeLayerPropertyChangeListener(LayerStateChangeListener listener) {
+        layerStateChangeListeners.remove(listener);
+    }
 
     /**
@@ -742,5 +779,10 @@
 
     public final void setUploadDiscouraged(boolean uploadDiscouraged) {
-        data.setUploadDiscouraged(uploadDiscouraged);
+        if (uploadDiscouraged ^ isUploadDiscouraged()) {
+            data.setUploadDiscouraged(uploadDiscouraged);
+            for (LayerStateChangeListener l : layerStateChangeListeners) {
+                l.uploadDiscouragedChanged(this, uploadDiscouraged);
+            }
+        }
     }
 
