001    // License: GPL. For details, see LICENSE file.
002    package org.openstreetmap.josm.actions;
003    
004    import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005    import static org.openstreetmap.josm.tools.CheckParameterUtil.ensureParameterNotNull;
006    import static org.openstreetmap.josm.tools.I18n.tr;
007    
008    import java.awt.event.ActionEvent;
009    import java.awt.event.KeyEvent;
010    import java.util.Collection;
011    import java.util.Collections;
012    
013    import javax.swing.JOptionPane;
014    
015    import org.openstreetmap.josm.Main;
016    import org.openstreetmap.josm.data.osm.DataSet;
017    import org.openstreetmap.josm.data.osm.OsmPrimitive;
018    import org.openstreetmap.josm.data.osm.OsmPrimitiveType;
019    import org.openstreetmap.josm.data.osm.PrimitiveId;
020    import org.openstreetmap.josm.gui.ExceptionDialogUtil;
021    import org.openstreetmap.josm.gui.io.UpdatePrimitivesTask;
022    import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
023    import org.openstreetmap.josm.io.MultiFetchServerObjectReader;
024    import org.openstreetmap.josm.tools.Shortcut;
025    
026    /**
027     * This action synchronizes a set of primitives with their state on the server.
028     *
029     */
030    public 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 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.map.mapView.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 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 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        public void actionPerformed(ActionEvent e) {
117            if (! isEnabled())
118                return;
119            Collection<OsmPrimitive> toUpdate =getData();
120            if (toUpdate.size() == 0) {
121                JOptionPane.showMessageDialog(
122                        Main.parent,
123                        tr("There are no selected objects to update."),
124                        tr("Selection empty"),
125                        JOptionPane.INFORMATION_MESSAGE
126                );
127                return;
128            }
129            updatePrimitives(toUpdate);
130        }
131    
132        public Collection<OsmPrimitive> getData() {
133            return getCurrentDataSet().getAllSelected();
134        }
135    }