Changeset 1895 in josm


Ignore:
Timestamp:
2009-08-03T17:21:37+02:00 (15 years ago)
Author:
Gubaer
Message:

new: only one list of layers managed by MapView. LayerListDialog is an adapter to this list.
improved delete confirmation for multi layer delete
various bug fixes in the new LayerListDialog

Location:
trunk/src/org/openstreetmap/josm
Files:
9 edited

Legend:

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

    r1857 r1895  
    4343import org.openstreetmap.josm.gui.OptionPaneUtil;
    4444import org.openstreetmap.josm.gui.SplashScreen;
     45import org.openstreetmap.josm.gui.dialogs.LayerListDialog;
    4546import org.openstreetmap.josm.gui.download.DownloadDialog.DownloadTask;
    4647import org.openstreetmap.josm.gui.layer.Layer;
     
    216217            mapFrame.setVisible(true);
    217218            mapFrame.setVisibleDialogs();
     219            // bootstrapping problem: make sure the layer list dialog is going to
     220            // listen to change events of the very first layer
     221            //
     222            layer.addPropertyChangeListener(LayerListDialog.getInstance().getModel());
    218223        }
    219224        map.mapView.addLayer(layer);
  • trunk/src/org/openstreetmap/josm/actions/AutoScaleAction.java

    r1868 r1895  
    135135                    Main.map != null
    136136                    && Main.map.mapView != null
    137                     && Main.map.mapView.getAllLayers().size() > 0
     137                    && Main.map.mapView.hasLayers()
    138138            );
    139139        }
  • trunk/src/org/openstreetmap/josm/actions/ZoomInAction.java

    r1854 r1895  
    88
    99import org.openstreetmap.josm.Main;
    10 import org.openstreetmap.josm.gui.layer.Layer;
    1110import org.openstreetmap.josm.tools.Shortcut;
    1211
     
    2827                Main.map != null
    2928                && Main.map.mapView != null
    30                 && Main.map.mapView.getAllLayers().size() > 0
     29                && Main.map.mapView.hasLayers()
    3130        );
    3231    }
  • trunk/src/org/openstreetmap/josm/actions/ZoomOutAction.java

    r1854 r1895  
    2727                Main.map != null
    2828                && Main.map.mapView != null
    29                 && Main.map.mapView.getAllLayers().size() > 0
     29                && Main.map.mapView.hasLayers()
    3030        );
    3131    }
  • trunk/src/org/openstreetmap/josm/actions/downloadtasks/DownloadOsmTask.java

    r1885 r1895  
    9595            if (Main.map == null) return null;
    9696            if (Main.map.mapView == null) return null;
    97             Collection<Layer> layers = Main.map.mapView.getAllLayers();
     97            Collection<Layer> layers = Main.map.mapView.getAllLayersAsList();
    9898            for (Layer layer : layers) {
    9999                if (layer instanceof OsmDataLayer)
  • trunk/src/org/openstreetmap/josm/gui/MapView.java

    r1890 r1895  
    2222import java.util.Enumeration;
    2323import java.util.LinkedList;
     24import java.util.List;
    2425
    2526import javax.swing.AbstractButton;
     
    209210    }
    210211
     212    protected void fireActiveLayerChanged(Layer oldLayer, Layer newLayer) {
     213        for (Layer.LayerChangeListener l : Layer.listeners) {
     214            l.activeLayerChange(oldLayer, newLayer);
     215        }
     216    }
     217
    211218    /**
    212219     * Remove the layer from the mapview. If the layer was in the list before,
     
    214221     */
    215222    public void removeLayer(Layer layer) {
     223        boolean deletedLayerWasActiveLayer = false;
     224
    216225        if (layer == activeLayer) {
    217             for (Layer.LayerChangeListener l : Layer.listeners) {
    218                 l.activeLayerChange(layer, null);
    219             }
    220226            activeLayer = null;
     227            deletedLayerWasActiveLayer = true;
     228            fireActiveLayerChanged(layer, null);
    221229        }
    222230        if (layers.remove(layer)) {
     
    228236        layer.destroy();
    229237        AudioPlayer.reset();
     238        if (layer instanceof OsmDataLayer && deletedLayerWasActiveLayer) {
     239            for (Layer l : layers) {
     240                if (l instanceof OsmDataLayer) {
     241                    activeLayer = l;
     242                    fireActiveLayerChanged(null, activeLayer);
     243                }
     244            }
     245        }
     246        repaint();
    230247    }
    231248
     
    368385    public Collection<Layer> getAllLayers() {
    369386        return Collections.unmodifiableCollection(layers);
     387    }
     388
     389    /**
     390     * @return An unmodifiable ordered list of all layers
     391     */
     392    public List<Layer> getAllLayersAsList() {
     393        return Collections.unmodifiableList(layers);
     394    }
     395
     396    /**
     397     * Replies the number of layers managed by this mav view
     398     *
     399     * @return the number of layers managed by this mav view
     400     */
     401    public int getNumLayers() {
     402        return layers.size();
     403    }
     404
     405    /**
     406     * Replies true if there is at least one layer in this map view
     407     *
     408     * @return true if there is at least one layer in this map view
     409     */
     410    public boolean hasLayers() {
     411        return getNumLayers() > 0;
    370412    }
    371413
  • trunk/src/org/openstreetmap/josm/gui/OptionPaneUtil.java

    r1865 r1895  
    1010import javax.swing.JDialog;
    1111import javax.swing.JOptionPane;
    12 import javax.swing.JRootPane;
    1312import javax.swing.UIManager;
    1413
  • trunk/src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

    r1890 r1895  
    1515import java.beans.PropertyChangeListener;
    1616import java.util.ArrayList;
    17 import java.util.Collection;
    1817import java.util.Collections;
    1918import java.util.List;
    2019import java.util.concurrent.CopyOnWriteArrayList;
     20import java.util.logging.Logger;
    2121
    2222import javax.swing.AbstractAction;
     
    3232import javax.swing.ListModel;
    3333import javax.swing.ListSelectionModel;
     34import javax.swing.SwingUtilities;
    3435import javax.swing.UIManager;
    3536import javax.swing.event.ListDataEvent;
     
    5960 */
    6061public class LayerListDialog extends ToggleDialog {
     62    static private final Logger logger = Logger.getLogger(LayerListDialog.class.getName());
    6163
    6264    /** the unique instance of the dialog */
     
    112114        ActivateLayerAction activateLayerAction = new ActivateLayerAction();
    113115        adaptTo(activateLayerAction, selectionModel);
     116        adaptToLayerChanges(activateLayerAction);
    114117        buttonPanel.add(new SideButton(activateLayerAction, "activate"));
    115118
     
    159162        //
    160163        final MapView mapView = mapFrame.mapView;
    161         model.populate(mapView.getAllLayers());
     164        model.populate();
    162165        model.setSelectedLayer(mapView.getActiveLayer());
    163166        model.addLayerListModelListener(
     
    166169                        layerList.ensureIndexIsVisible(index);
    167170                    }
     171
     172                    public void refresh() {
     173                        layerList.repaint();
     174                    }
    168175                }
    169176        );
     
    208215    }
    209216
     217    protected void adaptToLayerChanges(final IEnabledStateUpdating listener) {
     218        Layer.listeners.add(
     219                new LayerChangeListener() {
     220                    public void activeLayerChange(Layer oldLayer, Layer newLayer) {
     221                        listener.updateEnabledState();
     222                    }
     223                    public void layerAdded(Layer newLayer) {
     224                        listener.updateEnabledState();
     225                    }
     226                    public void layerRemoved(Layer oldLayer) {
     227                        listener.updateEnabledState();
     228                    }
     229                }
     230        );
     231    }
     232
     233
     234    private enum DeleteDecision {
     235        deleteCurrent,
     236        dontDeleteCurrent,
     237        deleteAll,
     238        cancel
     239    }
     240
    210241    /**
    211242     * The action to delete the currently selected layer
    212243     */
    213244    public final  class DeleteLayerAction extends AbstractAction implements IEnabledStateUpdating {
     245
     246
    214247
    215248        private  Layer layer;
     
    256289                    "delete_layer",
    257290                    Main.parent,
    258                     tr("Do you really want to delete the whole layer ''{0}''?", layer.getName()),
     291                    tr("Do you really want to delete layer ''{0}''?", layer.getName()),
    259292                    tr("Confirmation"),
    260293                    JOptionPane.YES_NO_OPTION,
     
    263296        }
    264297
    265         public void deleteLayer(Layer layer) {
     298        protected DeleteDecision confirmDeleteMultipleLayer(Layer layer, int idx, int numLayers) {
     299            String options[] = new String[] {
     300                    tr("Yes"),
     301                    tr("No"),
     302                    tr("Delete all"),
     303                    tr("Cancel")
     304            };
     305            int ret = ConditionalOptionPaneUtil.showOptionDialog(
     306                    "delete_layer",
     307                    Main.parent,
     308                    tr("Do you really want to delete layer ''{0}''?", layer.getName()),
     309                    tr("Deleting layer {0} of {1}", idx+1, numLayers),
     310                    JOptionPane.DEFAULT_OPTION,
     311                    JOptionPane.QUESTION_MESSAGE,
     312                    options,
     313                    options[0]
     314            );
     315            switch(ret) {
     316            case ConditionalOptionPaneUtil.DIALOG_DISABLED_OPTION: return DeleteDecision.deleteAll;
     317            case JOptionPane.CLOSED_OPTION: return DeleteDecision.cancel;
     318            case 0: return DeleteDecision.deleteCurrent;
     319            case 1: return DeleteDecision.dontDeleteCurrent;
     320            case 2: return DeleteDecision.deleteAll;
     321            case 3: return DeleteDecision.cancel;
     322            default:
     323                // shouldn't happen. This is the safest option.
     324                return DeleteDecision.cancel;
     325            }
     326        }
     327
     328
     329        public void deleteSingleLayer(Layer layer) {
    266330            if (layer == null)
    267331                return;
     
    282346        }
    283347
     348        public void deleteMultipleLayers(List<Layer> layers) {
     349            boolean doAskConfirmation = true;
     350            for (int i=0; i < layers.size(); i++) {
     351                Layer layer = layers.get(i);
     352                if (layer instanceof OsmDataLayer) {
     353                    OsmDataLayer dataLayer = (OsmDataLayer)layer;
     354                    if (dataLayer.isModified() && ! confirmSkipSaving(dataLayer)) {
     355                        continue;
     356                    }
     357                }
     358                if (doAskConfirmation) {
     359                    DeleteDecision decision = confirmDeleteMultipleLayer(layer, i, layers.size());
     360                    switch(decision) {
     361                    case deleteCurrent: /* do nothing */ break;
     362                    case deleteAll: doAskConfirmation = false; break;
     363                    case dontDeleteCurrent: continue;
     364                    case cancel: return;
     365                    }
     366                }
     367                // model and view are going to be updated via LayerChangeListener
     368                //
     369                Main.main.removeLayer(layer);
     370            }
     371        }
     372
    284373        public void actionPerformed(ActionEvent e) {
    285374            if (this.layer == null) {
    286375                List<Layer> selectedLayers = getModel().getSelectedLayers();
    287                 for (Layer layer: selectedLayers) {
    288                     deleteLayer(layer);
     376                if (selectedLayers.size() == 1) {
     377                    deleteSingleLayer(selectedLayers.get(0));
     378                } else {
     379                    deleteMultipleLayers(selectedLayers);
    289380                }
    290381            } else {
    291                 deleteLayer(this.layer);
     382                deleteSingleLayer(this.layer);
    292383            }
    293384        }
     
    566657    public interface LayerListModelListener {
    567658        public void makeVisible(int index, Layer layer);
     659        public void refresh();
    568660    }
    569661
     
    581673    public class LayerListModel extends DefaultListModel implements LayerChangeListener, PropertyChangeListener{
    582674
    583         private ArrayList<Layer> layers;
     675        //private ArrayList<Layer> layers;
    584676        private DefaultListSelectionModel selectionModel;
    585677        private CopyOnWriteArrayList<LayerListModelListener> listeners;
    586678
    587679        private LayerListModel(DefaultListSelectionModel selectionModel) {
    588             layers = new ArrayList<Layer>();
    589680            this.selectionModel = selectionModel;
    590681            listeners = new CopyOnWriteArrayList<LayerListModelListener>();
     
    613704        }
    614705
    615         public void populate(Collection<Layer> layers) {
    616             if (layers == null)
     706        protected void fireRefresh() {
     707            for (LayerListModelListener listener : listeners) {
     708                listener.refresh();
     709            }
     710        }
     711
     712        public void populate() {
     713            if (getLayers() != null) {
     714                for (Layer layer: getLayers()) {
     715                    // make sure the model is registered exactly once
     716                    //
     717                    layer.removePropertyChangeListener(this);
     718                    layer.addPropertyChangeListener(this);
     719                }
     720            }
     721            fireContentsChanged(this, 0, getSize());
     722        }
     723
     724        public void setSelectedLayer(Layer layer) {
     725            if (layer == null || getLayers() == null)
    617726                return;
    618             this.layers.clear();
    619             this.layers.addAll(layers);
    620             for (Layer layer: this.layers) {
    621                 layer.addPropertyChangeListener(this);
    622             }
    623             fireContentsChanged(this, 0, getSize());
    624         }
    625 
    626         public void setSelectedLayer(Layer layer) {
    627             int idx = layers.indexOf(layer);
     727            int idx = getLayers().indexOf(layer);
    628728            if (idx >= 0) {
    629729                selectionModel.setSelectionInterval(idx, idx);
     
    635735        public List<Layer> getSelectedLayers() {
    636736            ArrayList<Layer> selected = new ArrayList<Layer>();
    637             for (int i=0; i<layers.size(); i++) {
     737            if (getLayers() == null) return selected;
     738            for (int i=0; i<getLayers().size(); i++) {
    638739                if (selectionModel.isSelectedIndex(i)) {
    639                     selected.add(layers.get(i));
     740                    selected.add(getLayers().get(i));
    640741                }
    641742            }
     
    645746        public List<Integer> getSelectedRows() {
    646747            ArrayList<Integer> selected = new ArrayList<Integer>();
    647             for (int i=0; i<layers.size();i++) {
     748            if (getLayers() == null) return selected;
     749            for (int i=0; i<getLayers().size();i++) {
    648750                if (selectionModel.isSelectedIndex(i)) {
    649751                    selected.add(i);
     
    653755        }
    654756
    655         public void removeLayer(Layer layer) {
     757        protected void removeLayer(Layer layer) {
    656758            if (layer == null)
    657759                return;
    658             List<Integer> selectedRows = getSelectedRows();
    659             int deletedRow = layers.indexOf(layer);
    660             if (deletedRow < 0)
    661                 // layer not found in the list of layers
    662                 return;
    663             layers.remove(layer);
    664             fireContentsChanged(this, 0,getSize());
    665             for (int row: selectedRows) {
    666                 if (row < deletedRow) {
    667                     selectionModel.addSelectionInterval(row, row);
    668                 } else if (row == deletedRow){
    669                     // do nothing
    670                 } else {
    671                     selectionModel.addSelectionInterval(row-1, row-1);
    672                 }
    673             }
     760            fireRefresh();
    674761            ensureSelectedIsVisible();
    675762        }
    676763
    677         public void addLayer(Layer layer) {
     764        protected void addLayer(Layer layer) {
    678765            if (layer == null) return;
    679             if (layers.contains(layer)) return;
    680             layers.add(layer);
    681766            layer.addPropertyChangeListener(this);
    682767            fireContentsChanged(this, 0, getSize());
     
    685770        public Layer getFirstLayer() {
    686771            if (getSize() == 0) return null;
    687             return layers.get(0);
     772            return getLayers().get(0);
    688773        }
    689774
     
    691776            if (index < 0 || index >= getSize())
    692777                return null;
    693             return layers.get(index);
     778            return getLayers().get(index);
    694779        }
    695780
     
    703788            List<Integer> sel = getSelectedRows();
    704789            for (int row: sel) {
    705                 Layer l1 = layers.get(row);
    706                 Layer l2 = layers.get(row-1);
    707                 layers.set(row, l2);
    708                 layers.set(row-1,l1);
     790                Layer l1 = getLayers().get(row);
     791                Layer l2 = getLayers().get(row-1);
     792                Main.map.mapView.moveLayer(l2,row);
    709793                Main.map.mapView.moveLayer(l1, row-1);
    710794            }
     
    719803        public boolean canMoveDown() {
    720804            List<Integer> sel = getSelectedRows();
    721             return !sel.isEmpty() && sel.get(sel.size()-1) < layers.size()-1;
     805            return !sel.isEmpty() && sel.get(sel.size()-1) < getLayers().size()-1;
    722806        }
    723807
     
    727811            Collections.reverse(sel);
    728812            for (int row: sel) {
    729                 Layer l1 = layers.get(row);
    730                 Layer l2 = layers.get(row+1);
    731                 layers.set(row, l2);
    732                 layers.set(row+1,l1);
     813                Layer l1 = getLayers().get(row);
     814                Layer l2 = getLayers().get(row+1);
    733815                Main.map.mapView.moveLayer(l1, row+1);
     816                Main.map.mapView.moveLayer(l2, row);
    734817            }
    735818            fireContentsChanged(this, 0, getSize());
     
    744827            int index = selectionModel.getMinSelectionIndex();
    745828            if (index <0 )return;
    746             if (index >= layers.size()) return;
    747             Layer layer = layers.get(index);
     829            if (getLayers() == null) return;
     830            if (index >= getLayers().size()) return;
     831            Layer layer = getLayers().get(index);
    748832            fireMakeVisible(index, layer);
    749833        }
     
    753837            if (layer == null)
    754838                return targets;
    755             for(Layer target: layers) {
     839            for(Layer target: getLayers()) {
    756840                if (layer == target) {
    757841                    continue;
     
    765849
    766850        public void activateLayer(Layer layer) {
    767             layers.remove(layer);
    768             layers.add(0,layer);
     851            Main.map.mapView.moveLayer(layer,0);
    769852            Main.map.mapView.setActiveLayer(layer);
    770853            layer.setVisible(true);
    771854            selectionModel.setSelectionInterval(0,0);
    772855            ensureSelectedIsVisible();
     856        }
     857
     858        protected List<Layer> getLayers() {
     859            if (Main.map == null) return null;
     860            if (Main.map.mapView == null) return null;
     861            return Main.map.mapView.getAllLayersAsList();
    773862        }
    774863
     
    778867        @Override
    779868        public Object getElementAt(int index) {
    780             return layers.get(index);
     869            return getLayers().get(index);
    781870        }
    782871
    783872        @Override
    784873        public int getSize() {
     874            List<Layer> layers = getLayers();
     875            if (layers == null) return 0;
    785876            return layers.size();
    786877        }
     
    791882        public void activeLayerChange(Layer oldLayer, Layer newLayer) {
    792883            if (oldLayer != null) {
    793                 int idx = layers.indexOf(oldLayer);
     884                int idx = getLayers().indexOf(oldLayer);
    794885                if (idx >= 0) {
    795886                    fireContentsChanged(this, idx,idx);
     
    798889
    799890            if (newLayer != null) {
    800                 int idx = layers.indexOf(newLayer);
     891                int idx = getLayers().indexOf(newLayer);
    801892                if (idx >= 0) {
    802893                    fireContentsChanged(this, idx,idx);
     
    809900        }
    810901
    811         public void layerRemoved(Layer oldLayer) {
    812             removeLayer(oldLayer);
    813         }
     902        public void layerRemoved(final Layer oldLayer) {
     903            SwingUtilities.invokeLater(
     904                    new Runnable() {
     905                        public void run() {
     906                            removeLayer(oldLayer);
     907                        }
     908                    }
     909            );
     910        }
     911
    814912
    815913        /* ------------------------------------------------------------------------------ */
     
    819917            if (evt.getSource() instanceof Layer) {
    820918                Layer layer = (Layer)evt.getSource();
    821                 int idx = layers.indexOf(layer);
     919                final int idx = getLayers().indexOf(layer);
    822920                if (idx < 0) return;
    823                 fireContentsChanged(this, idx, idx);
     921                fireRefresh();
    824922            }
    825923        }
  • trunk/src/org/openstreetmap/josm/gui/dialogs/RelationListDialog.java

    r1892 r1895  
    1111import java.util.Collection;
    1212import java.util.HashSet;
     13import java.util.logging.Logger;
    1314
    1415import javax.swing.AbstractAction;
     
    4647 */
    4748public class RelationListDialog extends ToggleDialog implements LayerChangeListener, DataChangeListener {
     49    private static final Logger logger = Logger.getLogger(RelationListDialog.class.getName());
    4850    static private final PrimitiveNameFormatter NAME_FORMATTER = new PrimitiveNameFormatter();
    4951
Note: See TracChangeset for help on using the changeset viewer.