Ticket #18801: 18801.patch

File 18801.patch, 14.5 KB (added by taylor.smock, 20 months ago)

Initial patch (pre-existing tests pass)

  • src/org/openstreetmap/josm/data/ImageData.java

     
    44import static org.openstreetmap.josm.tools.I18n.tr;
    55
    66import java.util.ArrayList;
     7import java.util.Collection;
    78import java.util.Collections;
    89import java.util.List;
    910import java.util.stream.Collectors;
     
    1617 * Class to hold {@link ImageEntry} and the current selection
    1718 * @since 14590
    1819 */
    19 public class ImageData {
     20public class ImageData implements Data {
    2021    /**
    2122     * A listener that is informed when the current selection change
    2223     */
     
    343344    public void removeImageDataUpdateListener(ImageDataUpdateListener listener) {
    344345        listeners.removeListener(listener);
    345346    }
     347
     348    @Override
     349    public Collection<DataSource> getDataSources() {
     350        return Collections.emptyList();
     351    }
    346352}
  • src/org/openstreetmap/josm/data/osm/NoteData.java

     
    99import java.util.List;
    1010import java.util.Map;
    1111
     12import org.openstreetmap.josm.data.Data;
     13import org.openstreetmap.josm.data.DataSource;
    1214import org.openstreetmap.josm.data.UserIdentityManager;
    1315import org.openstreetmap.josm.data.coor.LatLon;
    1416import org.openstreetmap.josm.data.notes.Note;
     
    2022/**
    2123 * Class to hold and perform operations on a set of notes
    2224 */
    23 public class NoteData {
     25public class NoteData implements Data {
    2426
    2527    /**
    2628     * A listener that can be informed on note data changes.
     
    5961
    6062    /**
    6163     * Construct a new note container with a given list of notes
     64     *
    6265     * @param notes The list of notes to populate the container with
    6366     */
    6467    public NoteData(Collection<Note> notes) {
     
    140143    }
    141144
    142145    /**
    143      * Add notes to the data set. It only adds a note if the ID is not already present
     146     * Add notes to the data set. It only adds a note if the ID is not already
     147     * present
     148     *
    144149     * @param newNotes A list of notes to add
    145150     */
    146151    public synchronized void addNotes(Collection<Note> newNotes) {
     
    309314    public void removeNoteDataUpdateListener(NoteDataUpdateListener listener) {
    310315        listeners.removeListener(listener);
    311316    }
     317
     318    @Override
     319    public Collection<DataSource> getDataSources() {
     320        return Collections.emptyList(); // Notes don't currently store data sources
     321    }
    312322}
  • src/org/openstreetmap/josm/gui/layer/AbstractModifiableLayer.java

     
    11// License: GPL. For details, see LICENSE file.
    22package org.openstreetmap.josm.gui.layer;
    33
     4import java.io.File;
     5import java.io.IOException;
     6
     7import org.openstreetmap.josm.data.Data;
    48import org.openstreetmap.josm.data.osm.Lockable;
    59import org.openstreetmap.josm.gui.io.AbstractIOTask;
    610import org.openstreetmap.josm.gui.io.AbstractUploadDialog;
     
    102106        // Override if needed
    103107        return false;
    104108    }
     109
     110    /**
     111     * Perform the autosave action for the layer
     112     *
     113     * @param file The file to save to
     114     * @return {@code true} if the layer was successfully saved
     115     * @throws IOException If there was an IO exception from saving
     116     * @since xxx
     117     */
     118    public boolean autosave(File file) throws IOException {
     119        // Override if needed;
     120        return false;
     121    }
     122
     123    /**
     124     * Get the data for the modifiable layer
     125     *
     126     * @return The data object
     127     * @since xxx
     128     */
     129    public abstract Data getData();
    105130}
  • src/org/openstreetmap/josm/gui/layer/AutosaveTask.java

     
    3131import java.util.regex.Pattern;
    3232
    3333import org.openstreetmap.josm.actions.OpenFileAction.OpenFileTask;
    34 import org.openstreetmap.josm.data.osm.DataSet;
     34import org.openstreetmap.josm.data.Data;
    3535import org.openstreetmap.josm.data.osm.NoteData;
    3636import org.openstreetmap.josm.data.osm.NoteData.NoteDataUpdateListener;
    3737import org.openstreetmap.josm.data.osm.event.AbstractDatasetChangedEvent;
     
    4141import org.openstreetmap.josm.data.preferences.IntegerProperty;
    4242import org.openstreetmap.josm.gui.MainApplication;
    4343import org.openstreetmap.josm.gui.Notification;
    44 import org.openstreetmap.josm.gui.io.importexport.NoteExporter;
    4544import org.openstreetmap.josm.gui.io.importexport.NoteImporter;
    46 import org.openstreetmap.josm.gui.io.importexport.OsmExporter;
    4745import org.openstreetmap.josm.gui.io.importexport.OsmImporter;
    4846import org.openstreetmap.josm.gui.layer.LayerManager.LayerAddEvent;
    4947import org.openstreetmap.josm.gui.layer.LayerManager.LayerChangeListener;
     
    116114    }
    117115
    118116    private final DataSetListenerAdapter datasetAdapter = new DataSetListenerAdapter(this);
    119     private final Set<DataSet> changedDatasets = new HashSet<>();
    120     private final Set<NoteData> changedNoteData = new HashSet<>();
     117    private final Set<Data> changedData = new HashSet<>();
    121118    private final List<AutosaveLayerInfo<?>> layersInfo = new ArrayList<>();
    122119    private final Object layersLock = new Object();
    123120    private final Deque<File> deletedLayers = new LinkedList<>();
     
    125122    private final File autosaveDir = new File(Config.getDirs().getUserDataDirectory(true), AUTOSAVE_DIR);
    126123    private final File deletedLayersDir = new File(Config.getDirs().getUserDataDirectory(true), DELETED_LAYERS_DIR);
    127124
     125    private static AutosaveTask task;
     126
    128127    /**
     128     * Initialize the AutosaveTask and set the global instance, if the global
     129     * instance is not yet set.
     130     */
     131    public AutosaveTask() {
     132        if (task == null)
     133            task = this;
     134    }
     135
     136    /**
     137     * @return The global instance for the AutosaveTask
     138     * @since xxx
     139     */
     140    public static AutosaveTask getInstance() {
     141        if (task == null)
     142            new AutosaveTask();
     143        return task;
     144    }
     145
     146    /**
    129147     * Replies the autosave directory.
    130148     * @return the autosave directory
    131149     * @since 10299
     
    236254            info.layerName = info.layer.getName();
    237255        }
    238256        try {
    239             if (info.layer instanceof OsmDataLayer) {
    240                 OsmDataLayer dataLayer = (OsmDataLayer) info.layer;
    241                 if (changedDatasets.remove(dataLayer.data)) {
    242                     File file = getNewLayerFile(info, new Date(), 0);
    243                     if (file != null) {
    244                         info.backupFiles.add(file);
    245                         new OsmExporter().exportData(file, info.layer, true /* no backup with appended ~ */);
    246                     }
     257            if (changedData.remove(info.layer.getData())) {
     258                File file = getNewLayerFile(info, new Date(), 0);
     259                if (file != null) {
     260                    info.backupFiles.add(file);
     261                    info.layer.autosave(file);
    247262                }
    248             } else if (info.layer instanceof NoteLayer) {
    249                 NoteLayer noteLayer = (NoteLayer) info.layer;
    250                 if (changedNoteData.remove(noteLayer.getNoteData())) {
    251                     File file = getNewLayerFile(info, new Date(), 0);
    252                     if (file != null) {
    253                         info.backupFiles.add(file);
    254                         new NoteExporter().exportData(file, info.layer);
    255                     }
    256                 }
    257263            }
    258264        } catch (IOException e) {
    259265            Logging.error(e);
     
    273279                for (AutosaveLayerInfo<?> info: layersInfo) {
    274280                    savelayer(info);
    275281                }
    276                 changedDatasets.clear();
    277                 changedNoteData.clear();
     282                changedData.clear();
    278283                if (PROP_NOTIFICATION.get() && !layersInfo.isEmpty()) {
    279284                    GuiHelper.runInEDT(this::displayNotification);
    280285                }
     
    317322            registerNewlayer((OsmDataLayer) e.getAddedLayer());
    318323        } else if (e.getAddedLayer() instanceof NoteLayer) {
    319324            registerNewlayer((NoteLayer) e.getAddedLayer());
     325        } else if (e.getAddedLayer() instanceof AbstractModifiableLayer) {
     326            synchronized (layersLock) {
     327                layersInfo.add(new AutosaveLayerInfo<>((AbstractModifiableLayer) e.getAddedLayer()));
     328            }
    320329        }
    321330    }
    322331
     
    361370
    362371    @Override
    363372    public void processDatasetEvent(AbstractDatasetChangedEvent event) {
    364         changedDatasets.add(event.getDataset());
     373        changedData.add(event.getDataset());
    365374    }
    366375
    367376    @Override
    368377    public void noteDataUpdated(NoteData data) {
    369         changedNoteData.add(data);
     378        changedData.add(data);
    370379    }
    371380
     381    /**
     382     * Indicate that data has changed, and it might be a good idea to autosave.
     383     *
     384     * @param data The data that has changed
     385     * @return See {@link Set#add}
     386     * @since xxx
     387     */
     388    public boolean dataUpdated(Data data) {
     389        return changedData.add(data);
     390    }
     391
    372392    @Override
    373393    public void selectedNoteChanged(NoteData noteData) {
    374394        // Do nothing
  • src/org/openstreetmap/josm/gui/layer/GpxLayer.java

     
    2727import org.openstreetmap.josm.actions.RenameLayerAction;
    2828import org.openstreetmap.josm.actions.SaveActionBase;
    2929import org.openstreetmap.josm.data.Bounds;
     30import org.openstreetmap.josm.data.Data;
    3031import org.openstreetmap.josm.data.SystemOfMeasurement;
    3132import org.openstreetmap.josm.data.gpx.GpxConstants;
    3233import org.openstreetmap.josm.data.gpx.GpxData;
     
    546547        // no i18n for international values
    547548        return isLocalFile ? "survey" : null;
    548549    }
     550
     551    @Override
     552    public Data getData() {
     553        return data;
     554    }
    549555}
  • src/org/openstreetmap/josm/gui/layer/NoteLayer.java

     
    1313import java.awt.event.MouseWheelEvent;
    1414import java.awt.event.MouseWheelListener;
    1515import java.io.File;
     16import java.io.IOException;
    1617import java.text.DateFormat;
    1718import java.util.ArrayList;
    1819import java.util.Collection;
     
    3536
    3637import org.openstreetmap.josm.actions.SaveActionBase;
    3738import org.openstreetmap.josm.data.Bounds;
     39import org.openstreetmap.josm.data.Data;
    3840import org.openstreetmap.josm.data.notes.Note;
    3941import org.openstreetmap.josm.data.notes.Note.State;
    4042import org.openstreetmap.josm.data.notes.NoteComment;
     
    9193
    9294    /**
    9395     * Create a new note layer with a set of notes
    94      * @param notes A list of notes to show in this layer
    95      * @param name The name of the layer. Typically "Notes"
     96     *
     97     * @param notes  A list of notes to show in this layer
     98     * @param name   The name of the layer. Typically "Notes"
    9699     */
    97100    public NoteLayer(Collection<Note> notes, String name) {
    98101        this(new NoteData(notes), name);
     
    478481    public String getChangesetSourceTag() {
    479482        return "Notes";
    480483    }
     484
     485    @Override
     486    public boolean autosave(File file) throws IOException {
     487        new NoteExporter().exportData(file, this);
     488        return true;
     489    }
     490
     491    @Override
     492    public Data getData() {
     493        return getNoteData();
     494    }
    481495}
  • src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

     
    5252import org.openstreetmap.josm.actions.ToggleUploadDiscouragedLayerAction;
    5353import org.openstreetmap.josm.data.APIDataSet;
    5454import org.openstreetmap.josm.data.Bounds;
     55import org.openstreetmap.josm.data.Data;
    5556import org.openstreetmap.josm.data.DataSource;
    5657import org.openstreetmap.josm.data.ProjectionBounds;
    5758import org.openstreetmap.josm.data.UndoRedoHandler;
     
    110111import org.openstreetmap.josm.gui.io.UploadDialog;
    111112import org.openstreetmap.josm.gui.io.UploadLayerTask;
    112113import org.openstreetmap.josm.gui.io.importexport.NoteExporter;
     114import org.openstreetmap.josm.gui.io.importexport.OsmExporter;
    113115import org.openstreetmap.josm.gui.io.importexport.OsmImporter;
    114116import org.openstreetmap.josm.gui.io.importexport.ValidatorErrorExporter;
    115117import org.openstreetmap.josm.gui.io.importexport.WMSLayerImporter;
     
    13351337    public boolean isUploadInProgress() {
    13361338        return isUploadInProgress.get();
    13371339    }
     1340
     1341    @Override
     1342    public Data getData() {
     1343        return getDataSet();
     1344    }
     1345
     1346    @Override
     1347    public boolean autosave(File file) throws IOException {
     1348        new OsmExporter().exportData(file, this, true /* no backup with appended ~ */);
     1349        return true;
     1350    }
    13381351}
  • src/org/openstreetmap/josm/gui/layer/geoimage/GeoImageLayer.java

     
    3636import javax.swing.JOptionPane;
    3737
    3838import org.openstreetmap.josm.actions.RenameLayerAction;
    39 import org.openstreetmap.josm.actions.mapmode.SelectLassoAction;
    4039import org.openstreetmap.josm.actions.mapmode.MapMode;
    4140import org.openstreetmap.josm.actions.mapmode.SelectAction;
     41import org.openstreetmap.josm.actions.mapmode.SelectLassoAction;
    4242import org.openstreetmap.josm.data.Bounds;
     43import org.openstreetmap.josm.data.Data;
    4344import org.openstreetmap.josm.data.ImageData;
    4445import org.openstreetmap.josm.data.ImageData.ImageDataUpdateListener;
    4546import org.openstreetmap.josm.data.gpx.GpxData;
     
    10151016    public String getChangesetSourceTag() {
    10161017        return "Geotagged Images";
    10171018    }
     1019
     1020    @Override
     1021    public Data getData() {
     1022        return data;
     1023    }
    10181024}