001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions;
003
004import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005import static org.openstreetmap.josm.tools.CheckParameterUtil.ensureParameterNotNull;
006import static org.openstreetmap.josm.tools.I18n.tr;
007
008import java.awt.event.ActionEvent;
009import java.awt.event.KeyEvent;
010import java.util.Collection;
011import java.util.Collections;
012
013import javax.swing.JOptionPane;
014
015import org.openstreetmap.josm.Main;
016import org.openstreetmap.josm.data.osm.DataSet;
017import org.openstreetmap.josm.data.osm.OsmPrimitive;
018import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
019import org.openstreetmap.josm.data.osm.PrimitiveId;
020import org.openstreetmap.josm.gui.ExceptionDialogUtil;
021import org.openstreetmap.josm.gui.io.UpdatePrimitivesTask;
022import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
023import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
024import org.openstreetmap.josm.tools.Shortcut;
025
026/**
027 * This action synchronizes a set of primitives with their state on the server.
028 *
029 */
030public class UpdateSelectionAction extends JosmAction {
031
032    /**
033     * handle an exception thrown because a primitive was deleted on the server
034     *
035     * @param id the primitive id
036     */
037    public static void handlePrimitiveGoneException(long id, OsmPrimitiveType type) {
038        MultiFetchServerObjectReader reader = new MultiFetchServerObjectReader();
039        reader.append(getCurrentDataSet(),id, type);
040        try {
041            DataSet ds = reader.parseOsm(NullProgressMonitor.INSTANCE);
042            Main.main.getEditLayer().mergeFrom(ds);
043        } catch(Exception e) {
044            ExceptionDialogUtil.explainException(e);
045        }
046    }
047
048    /**
049     * Updates the data for for the {@link OsmPrimitive}s in <code>selection</code>
050     * with the data currently kept on the server.
051     *
052     * @param selection a collection of {@link OsmPrimitive}s to update
053     *
054     */
055    public static void updatePrimitives(final Collection<OsmPrimitive> selection) {
056        UpdatePrimitivesTask task = new UpdatePrimitivesTask(Main.main.getEditLayer(),selection);
057        Main.worker.submit(task);
058    }
059
060    /**
061     * Updates the data for  the {@link OsmPrimitive}s with id <code>id</code>
062     * with the data currently kept on the server.
063     *
064     * @param id  the id of a primitive in the {@link DataSet} of the current edit layer. Must not be null.
065     * @throws IllegalArgumentException thrown if id is null
066     * @exception IllegalStateException thrown if there is no primitive with <code>id</code> in
067     *   the current dataset
068     * @exception IllegalStateException thrown if there is no current dataset
069     *
070     */
071    public static void updatePrimitive(PrimitiveId id) throws IllegalStateException, IllegalArgumentException{
072        ensureParameterNotNull(id, "id");
073        if (getEditLayer() == null)
074            throw new IllegalStateException(tr("No current dataset found"));
075        OsmPrimitive primitive = getEditLayer().data.getPrimitiveById(id);
076        if (primitive == null)
077            throw new IllegalStateException(tr("Did not find an object with id {0} in the current dataset", id));
078        updatePrimitives(Collections.singleton(primitive));
079    }
080
081    /**
082     * constructor
083     */
084    public UpdateSelectionAction() {
085        super(tr("Update selection"),
086                "updateselection",
087                tr("Updates the currently selected objects from the server (re-downloads data)"),
088                Shortcut.registerShortcut("file:updateselection",
089                        tr("File: {0}", tr("Update selection")), KeyEvent.VK_U,
090                        Shortcut.ALT_CTRL),
091                true);
092        putValue("help", ht("/Action/UpdateSelection"));
093    }
094    public UpdateSelectionAction(String name, String iconName, String tooltip,
095            Shortcut shortcut, boolean register) {
096        super(name, iconName, tooltip, shortcut, register);
097    }
098
099    @Override
100    protected void updateEnabledState() {
101        if (getCurrentDataSet() == null) {
102            setEnabled(false);
103        } else {
104            updateEnabledState(getCurrentDataSet().getAllSelected());
105        }
106    }
107
108    @Override
109    protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
110        setEnabled(selection != null && !selection.isEmpty());
111    }
112
113    /**
114     * action handler
115     */
116    @Override
117    public void actionPerformed(ActionEvent e) {
118        if (! isEnabled())
119            return;
120        Collection<OsmPrimitive> toUpdate =getData();
121        if (toUpdate.isEmpty()) {
122            JOptionPane.showMessageDialog(
123                    Main.parent,
124                    tr("There are no selected objects to update."),
125                    tr("Selection empty"),
126                    JOptionPane.INFORMATION_MESSAGE
127            );
128            return;
129        }
130        updatePrimitives(toUpdate);
131    }
132
133    public Collection<OsmPrimitive> getData() {
134        return getCurrentDataSet().getAllSelected();
135    }
136}