Changeset 5459 in josm for trunk/src/org


Ignore:
Timestamp:
2012-08-20T01:11:45+02:00 (12 years ago)
Author:
Don-vip
Message:

fix #2961 - Improve usability of WMS Layer Saving/Loading

  • Replaced the unconventional method of creating a blank layer, then loading a .wms file to a standard File->Open approach
  • Fixed memory leaks with some actions registered as listeners but never destroyed
  • Layer interface modified to allow a generic approach of layer saving in SaveActionBase rather than the previous one restricted to OSM and GPX data
  • FileImporters and FileExporters can now be enabled/disabled at runtime, for example when the active layer changes
Location:
trunk/src/org/openstreetmap/josm
Files:
20 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/actions/ExtensionFileFilter.java

    r5438 r5459  
    1212import javax.swing.filechooser.FileFilter;
    1313
     14import org.openstreetmap.josm.gui.MapView;
    1415import org.openstreetmap.josm.io.AllFormatsImporter;
    1516import org.openstreetmap.josm.io.FileExporter;
     
    5152                "org.openstreetmap.josm.io.OsmBzip2Importer",
    5253                "org.openstreetmap.josm.io.JpgImporter",
     54                "org.openstreetmap.josm.io.WMSLayerImporter",
    5355                "org.openstreetmap.josm.io.AllFormatsImporter"
    5456        };
     
    5658        for (String classname : importerNames) {
    5759            try {
    58                 Class<?> klass = Class.forName(classname);
    59                 importers.add((FileImporter) klass.newInstance());
    60             } catch (Exception e) {}
     60                FileImporter importer = (FileImporter) Class.forName(classname).newInstance();
     61                importers.add(importer);
     62                MapView.addLayerChangeListener(importer);
     63            } catch (Throwable t) { }
    6164        }
    6265
     
    6972                "org.openstreetmap.josm.io.OsmBzip2Exporter",
    7073                "org.openstreetmap.josm.io.GeoJSONExporter",
     74                "org.openstreetmap.josm.io.WMSLayerExporter"
    7175        };
    7276
    7377        for (String classname : exporterNames) {
    7478            try {
    75                 Class<?> klass = Class.forName(classname);
    76                 exporters.add((FileExporter)klass.newInstance());
    77             } catch (Exception e) {}
     79                FileExporter exporter = (FileExporter)Class.forName(classname).newInstance();
     80                exporters.add(exporter);
     81                MapView.addLayerChangeListener(exporter);
     82            } catch (Throwable t) { }
    7883        }
    7984    }
     
    134139
    135140    /**
    136      * Replies an ordered list of {@link ExtensionFileFilter}s for exporting.
     141     * Replies an ordered list of enabled {@link ExtensionFileFilter}s for exporting.
    137142     * The list is ordered according to their description, an {@link AllFormatsImporter}
    138143     * is append at the end.
    139144     *
    140      * @return an ordered list of {@link ExtensionFileFilter}s for exporting.
     145     * @return an ordered list of enabled {@link ExtensionFileFilter}s for exporting.
    141146     * @since 2029
    142147     */
     
    144149        LinkedList<ExtensionFileFilter> filters = new LinkedList<ExtensionFileFilter>();
    145150        for (FileExporter exporter : exporters) {
    146             if (filters.contains(exporter.filter)) {
     151            if (filters.contains(exporter.filter) || !exporter.isEnabled()) {
    147152                continue;
    148153            }
  • trunk/src/org/openstreetmap/josm/actions/JosmAction.java

    r5275 r5459  
    128128    }
    129129
     130    @Override
    130131    public void destroy() {
    131132        if (sc != null) {
  • trunk/src/org/openstreetmap/josm/actions/SaveAction.java

    r5014 r5459  
    3636    }
    3737
    38 
    3938    @Override public File getFile(Layer layer) {
    4039        File f = layer.getAssociatedFile();
     
    5958            }
    6059        }
    61         return f == null ? openFileDialog(layer) : f;
     60        return f == null ? layer.createAndOpenSaveFileChooser() : f;
    6261    }
    6362}
  • trunk/src/org/openstreetmap/josm/actions/SaveActionBase.java

    r5457 r5459  
    1616
    1717import org.openstreetmap.josm.Main;
    18 import org.openstreetmap.josm.data.conflict.ConflictCollection;
    19 import org.openstreetmap.josm.data.osm.OsmPrimitive;
    2018import org.openstreetmap.josm.gui.ExtendedDialog;
    21 import org.openstreetmap.josm.gui.layer.GpxLayer;
    2219import org.openstreetmap.josm.gui.layer.Layer;
    2320import org.openstreetmap.josm.gui.layer.OsmDataLayer;
    2421import org.openstreetmap.josm.io.FileExporter;
    25 import org.openstreetmap.josm.io.GpxImporter;
    2622import org.openstreetmap.josm.tools.Shortcut;
    2723
     
    4440
    4541    public boolean doSave() {
    46         Layer layer = null;
    47         if (Main.isDisplayingMapView() && (Main.map.mapView.getActiveLayer() instanceof OsmDataLayer
    48                 || Main.map.mapView.getActiveLayer() instanceof GpxLayer)) {
    49             layer = Main.map.mapView.getActiveLayer();
     42        if (Main.isDisplayingMapView()) {
     43            Layer layer = Main.map.mapView.getActiveLayer();
     44            if (layer != null && layer.isSavable()) {
     45                return doSave(layer);
     46            }
    5047        }
    51         if (layer == null)
    52             return false;
    53         return doSave(layer);
     48        return false;
    5449    }
    5550
    5651    public boolean doSave(Layer layer) {
    57         if(!checkSaveConditions(layer))
     52        if(!layer.checkSaveConditions())
    5853            return false;
    5954        file = getFile(layer);
     
    6257
    6358    public static boolean doSave(Layer layer, File file) {
    64         if(!checkSaveConditions(layer))
     59        if(!layer.checkSaveConditions())
    6560            return false;
    6661        return doInternalSave(layer, file);
     
    10196
    10297    /**
    103      * Checks whether it is ok to launch a save (whether we have data,
    104      * there is no conflict etc.)
    105      * @return <code>true</code>, if it is safe to save.
    106      */
    107     public static boolean checkSaveConditions(Layer layer) {
    108         if (layer instanceof GpxLayer)
    109             return ((GpxLayer)layer).data != null;
    110         else if (layer instanceof OsmDataLayer)  {
    111             if (isDataSetEmpty((OsmDataLayer)layer)) {
    112                 ExtendedDialog dialog = new ExtendedDialog(
    113                         Main.parent,
    114                         tr("Empty document"),
    115                         new String[] {tr("Save anyway"), tr("Cancel")}
    116                 );
    117                 dialog.setContent(tr("The document contains no data."));
    118                 dialog.setButtonIcons(new String[] {"save.png", "cancel.png"});
    119                 dialog.showDialog();
    120                 if (dialog.getValue() != 1) return false;
    121             }
    122 
    123             ConflictCollection conflicts = ((OsmDataLayer)layer).getConflicts();
    124             if (conflicts != null && !conflicts.isEmpty()) {
    125                 ExtendedDialog dialog = new ExtendedDialog(
    126                         Main.parent,
    127                         /* I18N: Display title of the window showing conflicts */
    128                         tr("Conflicts"),
    129                         new String[] {tr("Reject Conflicts and Save"), tr("Cancel")}
    130                 );
    131                 dialog.setContent(tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"));
    132                 dialog.setButtonIcons(new String[] {"save.png", "cancel.png"});
    133                 dialog.showDialog();
    134                 if (dialog.getValue() != 1) return false;
    135             }
    136             return true;
    137         }
    138         return false;
    139     }
    140 
    141     public static File openFileDialog(Layer layer) {
    142         if (layer instanceof OsmDataLayer)
    143             return createAndOpenSaveFileChooser(tr("Save OSM file"), "osm");
    144         else if (layer instanceof GpxLayer)
    145             return createAndOpenSaveFileChooser(tr("Save GPX file"), GpxImporter.FILE_FILTER);
    146         return createAndOpenSaveFileChooser(tr("Save Layer"), "lay");
    147     }
    148 
    149     /**
    150      * Check the data set if it would be empty on save. It is empty, if it contains
    151      * no objects (after all objects that are created and deleted without being
    152      * transferred to the server have been removed).
    153      *
    154      * @return <code>true</code>, if a save result in an empty data set.
    155      */
    156     private static boolean isDataSetEmpty(OsmDataLayer layer) {
    157         for (OsmPrimitive osm : layer.data.allNonDeletedPrimitives())
    158             if (!osm.isDeleted() || !osm.isNewOrUndeleted())
    159                 return false;
    160         return true;
    161     }
    162 
    163     /**
    16498     * Refreshes the enabled state
    16599     *
     
    179113        }
    180114        Layer layer = Main.map.mapView.getActiveLayer();
    181         setEnabled(layer instanceof OsmDataLayer || layer instanceof GpxLayer);
     115        setEnabled(layer != null && layer.isSavable());
    182116    }
    183117
  • trunk/src/org/openstreetmap/josm/actions/SaveAsAction.java

    r5048 r5459  
    2121    /**
    2222     * Construct the action with "Save" as label.
    23      * @param layer Save this layer.
    2423     */
    2524    public SaveAsAction() {
     
    3534
    3635    @Override protected File getFile(Layer layer) {
    37         return openFileDialog(layer);
     36        return layer.createAndOpenSaveFileChooser();
    3837    }
    3938}
  • trunk/src/org/openstreetmap/josm/actions/mapmode/DrawAction.java

    r5382 r5459  
    22package org.openstreetmap.josm.actions.mapmode;
    33
    4 import java.awt.*;
    54import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
    65import static org.openstreetmap.josm.tools.I18n.marktr;
     
    87import static org.openstreetmap.josm.tools.I18n.trn;
    98
     9import java.awt.AWTEvent;
     10import java.awt.BasicStroke;
     11import java.awt.Color;
     12import java.awt.Component;
     13import java.awt.Cursor;
     14import java.awt.Graphics2D;
     15import java.awt.KeyboardFocusManager;
     16import java.awt.Point;
     17import java.awt.Stroke;
     18import java.awt.Toolkit;
    1019import java.awt.event.AWTEventListener;
    1120import java.awt.event.ActionEvent;
     
    2938import java.util.TreeSet;
    3039
    31 import javax.swing.*;
     40import javax.swing.AbstractAction;
     41import javax.swing.JCheckBoxMenuItem;
     42import javax.swing.JFrame;
     43import javax.swing.JMenuItem;
     44import javax.swing.JOptionPane;
     45import javax.swing.JPopupMenu;
     46import javax.swing.SwingUtilities;
     47import javax.swing.Timer;
    3248
    3349import org.openstreetmap.josm.Main;
     
    91107    private EastNorth currentMouseEastNorth;
    92108
    93     private SnapHelper snapHelper = new SnapHelper();
     109    private final SnapHelper snapHelper = new SnapHelper();
    94110
    95111    private Shortcut backspaceShortcut;
    96     private Shortcut snappingShortcut;
    97 
    98     private JCheckBoxMenuItem snapCheckboxMenuItem;
     112    private final Shortcut snappingShortcut;
     113
     114    private final SnapChangeAction snapChangeAction;
     115    private final JCheckBoxMenuItem snapCheckboxMenuItem;
    99116    private boolean useRepeatedShortcut;
    100117
     
    106123        snappingShortcut = Shortcut.registerShortcut("mapmode:drawanglesnapping",
    107124            tr("Mode: Draw Angle snapping"), KeyEvent.VK_TAB, Shortcut.DIRECT);
    108         addMenuItem();
     125        snapChangeAction = new SnapChangeAction();
     126        snapCheckboxMenuItem = addMenuItem();
    109127        snapHelper.setMenuCheckBox(snapCheckboxMenuItem);
    110128        cursorJoinNode = ImageProvider.getCursor("crosshair", "joinnode");
     
    112130    }
    113131
    114     private void addMenuItem() {
     132    private JCheckBoxMenuItem addMenuItem() {
    115133        int n=Main.main.menu.editMenu.getItemCount();
    116134        for (int i=n-1;i>0;i--) {
     
    120138            }
    121139        }
    122         snapCheckboxMenuItem = MainMenu.addWithCheckbox(Main.main.menu.editMenu, new SnapChangeAction(), MainMenu.WINDOW_MENU_GROUP.VOLATILE);
     140        return MainMenu.addWithCheckbox(Main.main.menu.editMenu, snapChangeAction, MainMenu.WINDOW_MENU_GROUP.VOLATILE);
    123141    }
    124142
     
    12071225    public void destroy() {
    12081226        super.destroy();
     1227        snapChangeAction.destroy();
    12091228    }
    12101229
  • trunk/src/org/openstreetmap/josm/data/osm/visitor/paint/relations/MultipolygonCache.java

    r4732 r5459  
    2727import org.openstreetmap.josm.data.projection.Projection;
    2828import org.openstreetmap.josm.data.projection.ProjectionChangeListener;
     29import org.openstreetmap.josm.gui.MapView;
    2930import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
    3031import org.openstreetmap.josm.gui.NavigatableComponent;
     
    4950        Main.addProjectionChangeListener(this);
    5051        DataSet.addSelectionListener(this);
     52        MapView.addLayerChangeListener(this);
    5153    }
    5254
  • trunk/src/org/openstreetmap/josm/gui/ImageryMenu.java

    r5390 r5459  
    2424import org.openstreetmap.josm.gui.layer.ImageryLayer;
    2525import org.openstreetmap.josm.gui.layer.Layer;
    26 import org.openstreetmap.josm.gui.layer.WMSLayer;
    2726import org.openstreetmap.josm.tools.ImageProvider;
    2827
     
    6968    JMenuItem offsetMenuItem = singleOffset;
    7069    Map_Rectifier_WMSmenuAction rectaction = new Map_Rectifier_WMSmenuAction();
    71     JosmAction blankmenu = new JosmAction(
    72             tr("Blank Layer"), /* ICON */"blankmenu", tr("Open a blank WMS layer to load data from a file"), null, false) {
    73         @Override
    74         public void actionPerformed(ActionEvent ev) {
    75             if (!isEnabled()) return;
    76             Main.main.addLayer(new WMSLayer());
    77         }
    78 
    79         @Override
    80         protected void updateEnabledState() {
    81             setEnabled(Main.map != null && Main.map.mapView != null && !Main.map.mapView.getAllLayers().isEmpty());
    82         }
    83     };
    8470    int offsPos;
    8571
     
    10288        offsPos = getMenuComponentCount();
    10389        add(offsetMenuItem);
    104         addSeparator();
    105         add(new JMenuItem(blankmenu));
    10690    }
    10791
  • trunk/src/org/openstreetmap/josm/gui/MapFrame.java

    r5448 r5459  
    235235    }
    236236
    237     public void selectDrawTool(boolean onlyIfModeless) {
     237    public boolean selectDrawTool(boolean onlyIfModeless) {
    238238        if(onlyIfModeless && !Main.pref.getBoolean("modeless", false))
    239             return;
    240 
    241         selectMapMode(mapModeDraw);
     239            return false;
     240
     241        return selectMapMode(mapModeDraw);
    242242    }
    243243
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r5448 r5459  
    106106     * the layer listeners
    107107     */
    108     private static final CopyOnWriteArrayList<MapView.LayerChangeListener> layerChangeListeners = new CopyOnWriteArrayList<MapView.LayerChangeListener>();
     108    private static final CopyOnWriteArrayList<LayerChangeListener> layerChangeListeners = new CopyOnWriteArrayList<LayerChangeListener>();
    109109    private static final CopyOnWriteArrayList<EditLayerChangeListener> editLayerChangeListeners = new CopyOnWriteArrayList<EditLayerChangeListener>();
    110110
     
    114114     * @param listener the listener. Ignored if null or already registered.
    115115     */
    116     public static void removeLayerChangeListener(MapView.LayerChangeListener listener) {
     116    public static void removeLayerChangeListener(LayerChangeListener listener) {
    117117        layerChangeListeners.remove(listener);
    118118    }
     
    127127     * @param listener the listener. Ignored if null or already registered.
    128128     */
    129     public static void addLayerChangeListener(MapView.LayerChangeListener listener) {
     129    public static void addLayerChangeListener(LayerChangeListener listener) {
    130130        if (listener != null) {
    131131            layerChangeListeners.addIfAbsent(listener);
     
    222222    public MapView(final JPanel contentPane) {
    223223        Main.pref.addPreferenceChangeListener(this);
    224 
    225         //        new MoveAction(MoveAction.Direction.UP);
    226         //        new MoveAction(MoveAction.Direction.DOWN);
    227         //        new MoveAction(MoveAction.Direction.LEFT);
    228         //        new MoveAction(MoveAction.Direction.RIGHT);
    229224
    230225        addComponentListener(new ComponentAdapter(){
     
    265260            }
    266261        });
    267 
    268         // Add Multipolygon cache to layer listeners
    269         addLayerChangeListener(MultipolygonCache.getInstance());
    270262    }
    271263
  • trunk/src/org/openstreetmap/josm/gui/dialogs/properties/PropertiesDialog.java

    r5450 r5459  
    199199    };
    200200
    201     private DataSetListenerAdapter dataChangedAdapter = new DataSetListenerAdapter(this);
    202     private HelpAction helpAction = new HelpAction();
    203     private CopyValueAction copyValueAction = new CopyValueAction();
    204     private CopyKeyValueAction copyKeyValueAction = new CopyKeyValueAction();
    205     private CopyAllKeyValueAction copyAllKeyValueAction = new CopyAllKeyValueAction();
    206     private SearchAction searchActionSame = new SearchAction(true);
    207     private SearchAction searchActionAny = new SearchAction(false);
    208     private AddAction addAction = new AddAction();
    209     private EditAction editAction = new EditAction();
    210     private DeleteAction deleteAction = new DeleteAction();
     201    private final DataSetListenerAdapter dataChangedAdapter = new DataSetListenerAdapter(this);
     202    private final HelpAction helpAction = new HelpAction();
     203    private final CopyValueAction copyValueAction = new CopyValueAction();
     204    private final CopyKeyValueAction copyKeyValueAction = new CopyKeyValueAction();
     205    private final CopyAllKeyValueAction copyAllKeyValueAction = new CopyAllKeyValueAction();
     206    private final SearchAction searchActionSame = new SearchAction(true);
     207    private final SearchAction searchActionAny = new SearchAction(false);
     208    private final AddAction addAction = new AddAction();
     209    private final EditAction editAction = new EditAction();
     210    private final DeleteAction deleteAction = new DeleteAction();
     211    private final JosmAction[] josmActions = new JosmAction[]{addAction, editAction, deleteAction};
    211212
    212213    @Override
     
    215216        SelectionEventManager.getInstance().addSelectionListener(this, FireMode.IN_EDT_CONSOLIDATED);
    216217        MapView.addEditLayerChangeListener(this);
    217         Main.registerActionShortcut(addAction);
    218         Main.registerActionShortcut(editAction);
    219         Main.registerActionShortcut(deleteAction);
     218        for (JosmAction action : josmActions) {
     219            Main.registerActionShortcut(action);
     220        }
    220221        updateSelection();
    221222    }
     
    226227        SelectionEventManager.getInstance().removeSelectionListener(this);
    227228        MapView.removeEditLayerChangeListener(this);
    228         Main.unregisterActionShortcut(addAction);
    229         Main.unregisterActionShortcut(editAction);
    230         Main.unregisterActionShortcut(deleteAction);
     229        for (JosmAction action : josmActions) {
     230            Main.unregisterActionShortcut(action);
     231        }
    231232    }
    232233
     
    16701671        }
    16711672    }
     1673
     1674    @Override
     1675    public void destroy() {
     1676        super.destroy();
     1677        for (JosmAction action : josmActions) {
     1678            action.destroy();
     1679        }
     1680    }
    16721681}
  • trunk/src/org/openstreetmap/josm/gui/layer/GpxLayer.java

    r5450 r5459  
    6363import org.openstreetmap.josm.actions.DiskAccessAction;
    6464import org.openstreetmap.josm.actions.RenameLayerAction;
     65import org.openstreetmap.josm.actions.SaveActionBase;
    6566import org.openstreetmap.josm.actions.downloadtasks.DownloadOsmTaskList;
    6667import org.openstreetmap.josm.data.Bounds;
     
    9798import org.openstreetmap.josm.gui.widgets.JFileChooserManager;
    9899import org.openstreetmap.josm.gui.widgets.JosmComboBox;
     100import org.openstreetmap.josm.io.GpxImporter;
    99101import org.openstreetmap.josm.io.JpgImporter;
    100102import org.openstreetmap.josm.io.OsmTransferException;
     
    20422044        }
    20432045    }
     2046
     2047    @Override
     2048    public boolean isSavable() {
     2049        return true; // With GpxExporter
     2050    }
     2051
     2052    @Override
     2053    public boolean checkSaveConditions() {
     2054        return data != null;
     2055    }
     2056
     2057    @Override
     2058    public File createAndOpenSaveFileChooser() {
     2059        return SaveActionBase.createAndOpenSaveFileChooser(tr("Save GPX file"), GpxImporter.FILE_FILTER);
     2060    }
    20442061}
  • trunk/src/org/openstreetmap/josm/gui/layer/ImageryLayer.java

    r5391 r5459  
    7272    protected OffsetServerThread offsetServerThread;
    7373
     74    private final ImageryAdjustAction adjustAction = new ImageryAdjustAction(this);
     75    private final AbstractAction useServerOffsetAction = new AbstractAction(tr("(use server offset)")) {
     76        @Override
     77        public void actionPerformed(ActionEvent e) {
     78            enableOffsetServer(true);
     79        }
     80    };
     81
    7482    protected OffsetServerThread createoffsetServerThread() {
    7583        return new OffsetServerThread(new OsmosnimkiOffsetServer(
     
    179187        }
    180188    }
    181 
    182     ImageryAdjustAction adjustAction = new ImageryAdjustAction(this);
    183     AbstractAction useServerOffsetAction = new AbstractAction(tr("(use server offset)")) {
    184         @Override
    185         public void actionPerformed(ActionEvent e) {
    186             enableOffsetServer(true);
    187         }
    188     };
    189189
    190190    public void enableOffsetServer(boolean enable) {
     
    311311        }
    312312    }
     313
     314    /* (non-Javadoc)
     315     * @see org.openstreetmap.josm.gui.layer.Layer#destroy()
     316     */
     317    @Override
     318    public void destroy() {
     319        adjustAction.destroy();
     320    }
    313321}
  • trunk/src/org/openstreetmap/josm/gui/layer/Layer.java

    r5391 r5459  
    2323import org.openstreetmap.josm.actions.GpxExportAction;
    2424import org.openstreetmap.josm.actions.SaveAction;
     25import org.openstreetmap.josm.actions.SaveActionBase;
    2526import org.openstreetmap.josm.actions.SaveAsAction;
    2627import org.openstreetmap.josm.data.Bounds;
     
    427428        }
    428429    }
     430
     431    /**
     432     * Initializes the layer after a successful load of data from a file
     433     * @since 5459
     434     */
     435    public void onPostLoadFromFile() {
     436        // To be overriden if needed
     437    }
     438   
     439    /**
     440     * Replies the savable state of this layer (i.e if it can be saved through a "File->Save" dialog).
     441     * @return true if this layer can be saved to a file
     442     * @since 5459
     443     */
     444    public boolean isSavable() {
     445        return false;
     446    }
     447   
     448    /**
     449     * Checks whether it is ok to launch a save (whether we have data, there is no conflict etc.)
     450     * @return <code>true</code>, if it is safe to save.
     451     * @since 5459
     452     */
     453    public boolean checkSaveConditions() {
     454        return true;
     455    }
     456   
     457    /**
     458     * Creates a new "Save" dialog for this layer and makes it visible.<br/>
     459     * When the user has chosen a file, checks the file extension, and confirms overwrite if needed.
     460     * @return The output {@code File}
     461     * @since 5459
     462     * @see SaveActionBase#createAndOpenSaveFileChooser
     463     */
     464    public File createAndOpenSaveFileChooser() {
     465        return SaveActionBase.createAndOpenSaveFileChooser(tr("Save Layer"), "lay");
     466    }
    429467}
  • trunk/src/org/openstreetmap/josm/gui/layer/OsmDataLayer.java

    r5297 r5459  
    4242import org.openstreetmap.josm.actions.ExpertToggleAction;
    4343import org.openstreetmap.josm.actions.RenameLayerAction;
     44import org.openstreetmap.josm.actions.SaveActionBase;
    4445import org.openstreetmap.josm.actions.ToggleUploadDiscouragedLayerAction;
    4546import org.openstreetmap.josm.data.Bounds;
     
    7172import org.openstreetmap.josm.data.projection.Projection;
    7273import org.openstreetmap.josm.data.validation.TestError;
     74import org.openstreetmap.josm.gui.ExtendedDialog;
    7375import org.openstreetmap.josm.gui.HelpAwareOptionPane;
    7476import org.openstreetmap.josm.gui.HelpAwareOptionPane.ButtonSpec;
     
    655657    }
    656658
    657     /**
    658      * Initializes the layer after a successful load of OSM data from a file
    659      *
    660      */
     659    @Override
    661660    public void onPostLoadFromFile() {
    662661        setRequiresSaveToFile(false);
     
    745744        data.setUploadDiscouraged(uploadDiscouraged);
    746745    }
     746
     747    @Override
     748    public boolean isSavable() {
     749        return true; // With OsmExporter
     750    }
     751
     752    @Override
     753    public boolean checkSaveConditions() {
     754        if (isDataSetEmpty()) {
     755            ExtendedDialog dialog = new ExtendedDialog(
     756                    Main.parent,
     757                    tr("Empty document"),
     758                    new String[] {tr("Save anyway"), tr("Cancel")}
     759            );
     760            dialog.setContent(tr("The document contains no data."));
     761            dialog.setButtonIcons(new String[] {"save.png", "cancel.png"});
     762            dialog.showDialog();
     763            if (dialog.getValue() != 1) return false;
     764        }
     765
     766        ConflictCollection conflicts = getConflicts();
     767        if (conflicts != null && !conflicts.isEmpty()) {
     768            ExtendedDialog dialog = new ExtendedDialog(
     769                    Main.parent,
     770                    /* I18N: Display title of the window showing conflicts */
     771                    tr("Conflicts"),
     772                    new String[] {tr("Reject Conflicts and Save"), tr("Cancel")}
     773            );
     774            dialog.setContent(tr("There are unresolved conflicts. Conflicts will not be saved and handled as if you rejected all. Continue?"));
     775            dialog.setButtonIcons(new String[] {"save.png", "cancel.png"});
     776            dialog.showDialog();
     777            if (dialog.getValue() != 1) return false;
     778        }
     779        return true;
     780    }
     781   
     782    /**
     783     * Check the data set if it would be empty on save. It is empty, if it contains
     784     * no objects (after all objects that are created and deleted without being
     785     * transferred to the server have been removed).
     786     *
     787     * @return <code>true</code>, if a save result in an empty data set.
     788     */
     789    private boolean isDataSetEmpty() {
     790        if (data != null) {
     791            for (OsmPrimitive osm : data.allNonDeletedPrimitives())
     792                if (!osm.isDeleted() || !osm.isNewOrUndeleted())
     793                    return false;
     794        }
     795        return true;
     796    }
     797
     798    @Override
     799    public File createAndOpenSaveFileChooser() {
     800        return SaveActionBase.createAndOpenSaveFileChooser(tr("Save OSM file"), "osm");
     801    }
    747802}
  • trunk/src/org/openstreetmap/josm/gui/layer/WMSLayer.java

    r5457 r5459  
    3333import javax.swing.Action;
    3434import javax.swing.JCheckBoxMenuItem;
    35 import javax.swing.JFileChooser;
    3635import javax.swing.JMenuItem;
    3736import javax.swing.JOptionPane;
     
    3938import org.openstreetmap.gui.jmapviewer.AttributionSupport;
    4039import org.openstreetmap.josm.Main;
    41 import org.openstreetmap.josm.actions.DiskAccessAction;
    4240import org.openstreetmap.josm.actions.SaveActionBase;
    4341import org.openstreetmap.josm.data.Bounds;
     
    6260import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    6361import org.openstreetmap.josm.gui.dialogs.LayerListPopup;
    64 import org.openstreetmap.josm.gui.progress.NullProgressMonitor;
    6562import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    66 import org.openstreetmap.josm.io.WMSLayerExporter;
    6763import org.openstreetmap.josm.io.WMSLayerImporter;
    6864import org.openstreetmap.josm.io.imagery.Grabber;
     
    7066import org.openstreetmap.josm.io.imagery.WMSGrabber;
    7167import org.openstreetmap.josm.io.imagery.WMSRequest;
    72 import org.openstreetmap.josm.tools.ImageProvider;
    7368
    7469
     
    124119    protected boolean settingsChanged;
    125120    protected ImageryInfo info;
    126     protected MapView mv;
    127121    public WmsCache cache;
    128122    private AttributionSupport attribution = new AttributionSupport();
     
    178172    @Override
    179173    public void hookUpMapView() {
    180         mv = Main.map.mapView;
    181174        if (info.getUrl() != null) {
    182175            for (WMSLayer layer: Main.map.mapView.getLayersOfType(WMSLayer.class)) {
     
    194187            this.info.setPixelPerDegree(getPPD());
    195188        }
    196         resolution = mv.getDist100PixelText();
     189        resolution = Main.map.mapView.getDist100PixelText();
    197190
    198191        final MouseAdapter adapter = new MouseAdapter() {
     
    484477                SeparatorLayerAction.INSTANCE,
    485478                new OffsetAction(),
    486                 new LoadWmsAction(),
    487                 new SaveWmsAction(),
     479                new LayerSaveAction(this),
     480                new LayerSaveAsAction(this),
    488481                new BookmarkWmsAction(),
    489482                SeparatorLayerAction.INSTANCE,
     
    523516            return -1;
    524517
    525         EastNorth cursorEastNorth = mv.getEastNorth(mv.lastMEvent.getX(), mv.lastMEvent.getY());
     518        MouseEvent lastMEvent = Main.map.mapView.lastMEvent;
     519        EastNorth cursorEastNorth = Main.map.mapView.getEastNorth(lastMEvent.getX(), lastMEvent.getY());
    526520        int mouseX = getImageXIndex(cursorEastNorth.east());
    527521        int mouseY = getImageYIndex(cursorEastNorth.north());
     
    605599            if (request.getState() != null && !request.isPrecacheOnly()) {
    606600                finishedRequests.add(request);
    607                 mv.repaint();
     601                Main.map.mapView.repaint();
    608602            }
    609603        } finally {
     
    669663                        );
    670664            } else {
    671                 downloadAndPaintVisible(mv.getGraphics(), mv, true);
     665                downloadAndPaintVisible(Main.map.mapView.getGraphics(), Main.map.mapView, true);
    672666            }
    673667        }
     
    680674
    681675        private void changeResolution(WMSLayer layer) {
    682             layer.resolution = layer.mv.getDist100PixelText();
     676            layer.resolution = Main.map.mapView.getDist100PixelText();
    683677            layer.info.setPixelPerDegree(layer.getPPD());
    684678            layer.settingsChanged = true;
     
    761755                }
    762756            }
    763             mv.repaint();
     757            Main.map.mapView.repaint();
    764758        }
    765759        @Override
     
    775769    }
    776770
    777     public class SaveWmsAction extends AbstractAction {
    778         public SaveWmsAction() {
    779             super(tr("Save WMS layer to file"), ImageProvider.get("save"));
    780         }
    781         @Override
    782         public void actionPerformed(ActionEvent ev) {
    783             File f = SaveActionBase.createAndOpenSaveFileChooser(
    784                     tr("Save WMS layer"), WMSLayerImporter.FILE_FILTER);
    785             try {
    786                 new WMSLayerExporter().exportData(f, WMSLayer.this);
    787             } catch (Exception ex) {
    788                 ex.printStackTrace(System.out);
    789             }
    790         }
    791     }
    792 
    793     public class LoadWmsAction extends AbstractAction {
    794         public LoadWmsAction() {
    795             super(tr("Load WMS layer from file"), ImageProvider.get("open"));
    796         }
    797         @Override
    798         public void actionPerformed(ActionEvent ev) {
    799             JFileChooser fc = DiskAccessAction.createAndOpenFileChooser(true,
    800                     false, tr("Load WMS layer"), WMSLayerImporter.FILE_FILTER, JFileChooser.FILES_ONLY, null);
    801             if (fc == null) return;
    802             File f = fc.getSelectedFile();
    803             if (f == null) return;
    804             try {
    805                 new WMSLayerImporter(WMSLayer.this).importData(f, NullProgressMonitor.INSTANCE);
    806             } catch (InvalidClassException ex) {
    807                 JOptionPane.showMessageDialog(Main.parent, ex.getMessage(), tr("File Format Error"), JOptionPane.ERROR_MESSAGE);
    808                 return;
    809             } catch (Exception ex) {
    810                 ex.printStackTrace();
    811                 JOptionPane.showMessageDialog(Main.parent, ex.getMessage(), tr("Error loading file"), JOptionPane.ERROR_MESSAGE);
    812                 return;
    813             }
    814         }
    815     }
    816    
    817771    /**
    818772     * This action will add a WMS layer menu entry with the current WMS layer
     
    860814                    }
    861815                }
    862                 mv.repaint();
     816                Main.map.mapView.repaint();
    863817            }
    864818        }
     
    952906    }
    953907
    954     protected Grabber getGrabber(boolean localOnly){
    955         if(getInfo().getImageryType() == ImageryType.HTML)
    956             return new HTMLGrabber(mv, this, localOnly);
    957         else if(getInfo().getImageryType() == ImageryType.WMS)
    958             return new WMSGrabber(mv, this, localOnly);
     908    protected Grabber getGrabber(boolean localOnly) {
     909        if (getInfo().getImageryType() == ImageryType.HTML)
     910            return new HTMLGrabber(Main.map.mapView, this, localOnly);
     911        else if (getInfo().getImageryType() == ImageryType.WMS)
     912            return new WMSGrabber(Main.map.mapView, this, localOnly);
    959913        else throw new IllegalStateException("getGrabber() called for non-WMS layer type");
    960914    }
     
    1042996       
    1043997        settingsChanged = true;
    1044         mv.repaint();
     998        if (Main.isDisplayingMapView()) {
     999            Main.map.mapView.repaint();
     1000        }
    10451001        if (cache != null) {
    10461002            cache.saveIndex();
    10471003            cache = null;
    10481004        }
     1005    }
     1006
     1007    @Override
     1008    public void onPostLoadFromFile() {
    10491009        if (info.getUrl() != null) {
    10501010            cache = new WmsCache(info.getUrl(), imageSize);
     
    10521012        }
    10531013    }
     1014
     1015    @Override
     1016    public boolean isSavable() {
     1017        return true; // With WMSLayerExporter
     1018    }
     1019
     1020    @Override
     1021    public File createAndOpenSaveFileChooser() {
     1022        return SaveActionBase.createAndOpenSaveFileChooser(tr("Save WMS file"), WMSLayerImporter.FILE_FILTER);
     1023    }
    10541024}
  • trunk/src/org/openstreetmap/josm/io/FileExporter.java

    r3083 r5459  
    88
    99import org.openstreetmap.josm.actions.ExtensionFileFilter;
     10import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
    1011import org.openstreetmap.josm.gui.layer.Layer;
    1112
    12 public abstract class FileExporter {
    13     public ExtensionFileFilter filter;
     13public abstract class FileExporter implements LayerChangeListener {
     14   
     15    public final ExtensionFileFilter filter;
     16
     17    private boolean enabled;
    1418
    1519    public FileExporter(ExtensionFileFilter filter) {
    1620        this.filter = filter;
     21        this.enabled = true;
    1722    }
    1823
     
    2429        throw new IOException(tr("Could not export ''{0}''.", file.getName()));
    2530    }
     31
     32    /**
     33     * Returns the enabled state of this {@code FileExporter}. When enabled, it is listed and usable in "File->Save" dialogs.
     34     * @return true if this {@code FileExporter} is enabled
     35     * @since 5459
     36     */
     37    public final boolean isEnabled() {
     38        return enabled;
     39    }
     40
     41    /**
     42     * Sets the enabled state of the {@code FileExporter}. When enabled, it is listed and usable in "File->Save" dialogs.
     43     * @param enabled true to enable this {@code FileExporter}, false to disable it
     44     * @since 5459
     45     */
     46    public final void setEnabled(boolean enabled) {
     47        this.enabled = enabled;
     48    }
     49
     50    @Override
     51    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     52        // To be overriden by subclasses if their enabled state depends of the active layer nature
     53    }
     54
     55    @Override
     56    public void layerAdded(Layer newLayer) {
     57        // To be overriden by subclasses if needed
     58    }
     59
     60    @Override
     61    public void layerRemoved(Layer oldLayer) {
     62        // To be overriden by subclasses if needed
     63    }
    2664}
  • trunk/src/org/openstreetmap/josm/io/FileImporter.java

    r5361 r5459  
    1717import org.openstreetmap.josm.actions.ExtensionFileFilter;
    1818import org.openstreetmap.josm.gui.HelpAwareOptionPane;
     19import org.openstreetmap.josm.gui.MapView.LayerChangeListener;
     20import org.openstreetmap.josm.gui.layer.Layer;
    1921import org.openstreetmap.josm.gui.progress.ProgressMonitor;
    2022
    21 public abstract class FileImporter implements Comparable<FileImporter> {
     23public abstract class FileImporter implements Comparable<FileImporter>, LayerChangeListener {
    2224
    2325    public final ExtensionFileFilter filter;
     26   
     27    private boolean enabled;
    2428
    2529    public FileImporter(ExtensionFileFilter filter) {
    2630        this.filter = filter;
     31        this.enabled = true;
    2732    }
    2833
     
    122127        return new GZIPInputStream(in);
    123128    }
     129
     130    /**
     131     * Returns the enabled state of this {@code FileImporter}. When enabled, it is listed and usable in "File->Open" dialog.
     132     * @return true if this {@code FileImporter} is enabled
     133     * @since 5459
     134     */
     135    public final boolean isEnabled() {
     136        return enabled;
     137    }
     138
     139    /**
     140     * Sets the enabled state of the {@code FileImporter}. When enabled, it is listed and usable in "File->Open" dialog.
     141     * @param enabled true to enable this {@code FileImporter}, false to disable it
     142     * @since 5459
     143     */
     144    public final void setEnabled(boolean enabled) {
     145        this.enabled = enabled;
     146    }
     147
     148    @Override
     149    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     150        // To be overriden by subclasses if their enabled state depends of the active layer nature
     151    }
     152
     153    @Override
     154    public void layerAdded(Layer newLayer) {
     155        // To be overriden by subclasses if needed
     156    }
     157
     158    @Override
     159    public void layerRemoved(Layer oldLayer) {
     160        // To be overriden by subclasses if needed
     161    }
    124162}
  • trunk/src/org/openstreetmap/josm/io/WMSLayerExporter.java

    r5457 r5459  
    3838        }
    3939    }
     40
     41    @Override
     42    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     43        setEnabled(newLayer instanceof WMSLayer);
     44    }
    4045}
  • trunk/src/org/openstreetmap/josm/io/WMSLayerImporter.java

    r5457 r5459  
    99import java.io.ObjectInputStream;
    1010
     11import org.openstreetmap.josm.Main;
    1112import org.openstreetmap.josm.actions.ExtensionFileFilter;
    1213import org.openstreetmap.josm.gui.layer.WMSLayer;
    1314import org.openstreetmap.josm.gui.progress.ProgressMonitor;
     15import org.openstreetmap.josm.gui.util.GuiHelper;
    1416import org.openstreetmap.josm.tools.CheckParameterUtil;
    1517
     
    5557            ois.close();
    5658        }
     59       
     60        // FIXME: remove UI stuff from IO subsystem
     61        GuiHelper.runInEDT(new Runnable() {
     62            @Override
     63            public void run() {
     64                Main.main.addLayer(wmsLayer);
     65                wmsLayer.onPostLoadFromFile();
     66            }
     67        });
    5768    }
    5869
Note: See TracChangeset for help on using the changeset viewer.