Ticket #18638: 18638.1.patch

File 18638.1.patch, 10.5 KB (added by taylor.smock, 4 months ago)

Switch back to [ and ] from { and } along with tests

  • src/org/openstreetmap/josm/gui/dialogs/LayerListDialog.java

     
    5454import org.openstreetmap.josm.gui.MapView;
    5555import org.openstreetmap.josm.gui.SideButton;
    5656import org.openstreetmap.josm.gui.dialogs.layer.ActivateLayerAction;
     57import org.openstreetmap.josm.gui.dialogs.layer.CycleLayerAction;
    5758import org.openstreetmap.josm.gui.dialogs.layer.DeleteLayerAction;
    5859import org.openstreetmap.josm.gui.dialogs.layer.DuplicateAction;
    5960import org.openstreetmap.josm.gui.dialogs.layer.LayerListTransferHandler;
     
    141142    private final ActivateLayerAction activateLayerAction;
    142143    private final ShowHideLayerAction showHideLayerAction;
    143144
     145    private final CycleLayerAction cycleLayerAction;
     146
    144147    //TODO This duplicates ShowHide actions functionality
    145148    /** stores which layer index to toggle and executes the ShowHide action if the layer is present */
    146149    private final class ToggleLayerIndexVisibility extends AbstractAction {
     
    329332        // Show/Activate layer on Enter key press
    330333        InputMapUtils.addSpacebarAction(layerList, showHideLayerAction);
    331334
     335        // Cycle layer action
     336        cycleLayerAction = new CycleLayerAction();
     337
    332338        createLayout(layerList, true, Arrays.asList(
    333339                new SideButton(moveUpAction, false),
    334340                new SideButton(moveDownAction, false),
     
    388394        DISPLAY_NUMBERS.removeListener(visibilityWidthListener);
    389395        ExpertToggleAction.removeExpertModeChangeListener(visibilityWidthListener);
    390396        layerManager.removeLayerChangeListener(visibilityWidthListener);
     397        cycleLayerAction.destroy();
    391398        super.destroy();
    392399        instance = null;
    393400    }
  • src/org/openstreetmap/josm/gui/dialogs/layer/CycleLayerAction.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.dialogs.layer;
     3
     4import static org.openstreetmap.josm.tools.I18n.tr;
     5
     6import java.awt.event.ActionEvent;
     7import java.awt.event.KeyEvent;
     8import java.util.ArrayList;
     9import java.util.Collections;
     10import java.util.List;
     11import java.util.stream.Collectors;
     12
     13import org.openstreetmap.josm.actions.JosmAction;
     14import org.openstreetmap.josm.gui.MainApplication;
     15import org.openstreetmap.josm.gui.layer.ImageryLayer;
     16import org.openstreetmap.josm.gui.layer.Layer;
     17import org.openstreetmap.josm.gui.layer.MainLayerManager;
     18import org.openstreetmap.josm.tools.ImageProvider;
     19import org.openstreetmap.josm.tools.Shortcut;
     20
     21/**
     22 * Allow users to cycle between adjacent layers easily
     23 *
     24 * @author Taylor Smock
     25 * @since xxx
     26 */
     27public class CycleLayerAction extends JosmAction {
     28    protected final static int KEYUP = KeyEvent.VK_OPEN_BRACKET;
     29    protected final static int KEYDOWN = KeyEvent.VK_CLOSE_BRACKET;
     30    protected final static int MODIFIER = Shortcut.SHIFT;
     31    private static Shortcut cycleUp = Shortcut.registerShortcut("core:cyclelayerup", tr("Cycle layers up"),
     32            KEYUP, MODIFIER);
     33    private static Shortcut cycleDown = Shortcut.registerShortcut("core:cyclelayerdown", tr("Cycle layers down"),
     34            KEYDOWN, MODIFIER);
     35
     36    /**
     37     * Create a CycleLayerAction that cycles through layers that are in the model
     38     */
     39    public CycleLayerAction() {
     40        super(tr("Cycle layers"), "dialogs/next", tr("Cycle through layers"), cycleDown, true,
     41                "cycle-layer", false);
     42        MainApplication.registerActionShortcut(this, cycleUp); // cycleDown gets registered by JosmAction
     43        new ImageProvider("dialogs", "next").getResource().attachImageIcon(this, true);
     44        putValue(SHORT_DESCRIPTION, tr("Cycle through visible layers."));
     45        putValue(NAME, tr("Cycle layers"));
     46    }
     47
     48    @Override
     49    public void actionPerformed(ActionEvent e) {
     50        MainLayerManager manager = MainApplication.getLayerManager();
     51        List<Layer> managerLayers = manager.getLayers().stream().filter(layer -> !(layer instanceof ImageryLayer))
     52                .collect(Collectors.toList());
     53        if (managerLayers.isEmpty())
     54            return;
     55        int key = KeyEvent.getExtendedKeyCodeForChar(e.getActionCommand().charAt(0));
     56        char character = KeyEvent.getKeyText(key).charAt(0);
     57        int realKey = KeyEvent.getExtendedKeyCodeForChar(character);
     58        Shortcut shortcut = Shortcut
     59                .findShortcut(realKey, cycleDown.getAssignedModifier())
     60                .orElse(null);
     61
     62        List<Layer> layers;
     63        if (cycleUp.equals(shortcut)) {
     64            int index = managerLayers.indexOf(manager.getActiveLayer());
     65            int sublist = index < managerLayers.size() ? index + 1 : index;
     66            if (index >= managerLayers.size() - 1) {
     67                index = 0;
     68                sublist = 0;
     69            }
     70            layers = managerLayers.subList(sublist, managerLayers.size());
     71        } else {
     72            layers = new ArrayList<>(managerLayers);
     73            Collections.reverse(layers);
     74            int index = layers.indexOf(manager.getActiveLayer());
     75            int sublist = index < managerLayers.size() - 1 ? index + 1 : 0;
     76            layers = layers.subList(sublist, layers.size());
     77        }
     78        Layer layer = layers.stream().filter(Layer::isVisible).filter(tlayer -> !(tlayer instanceof ImageryLayer))
     79                .findFirst()
     80                .orElse(manager.getActiveLayer());
     81
     82        manager.setActiveLayer(layer);
     83    }
     84
     85    @Override
     86    public void destroy() {
     87        super.destroy();
     88        MainApplication.unregisterActionShortcut(this, cycleUp);
     89    }
     90}
  • test/unit/org/openstreetmap/josm/gui/dialogs/layer/CycleLayerActionTest.java

     
     1// License: GPL. For details, see LICENSE file.
     2package org.openstreetmap.josm.gui.dialogs.layer;
     3
     4import static org.junit.Assert.assertEquals;
     5import static org.openstreetmap.josm.tools.I18n.tr;
     6
     7import java.awt.event.ActionEvent;
     8import java.awt.event.KeyEvent;
     9
     10import org.junit.Before;
     11import org.junit.Rule;
     12import org.junit.Test;
     13import org.openstreetmap.josm.data.imagery.ImageryInfo;
     14import org.openstreetmap.josm.data.imagery.ImageryLayerInfo;
     15import org.openstreetmap.josm.data.osm.DataSet;
     16import org.openstreetmap.josm.gui.MainApplication;
     17import org.openstreetmap.josm.gui.layer.ImageryLayer;
     18import org.openstreetmap.josm.gui.layer.MainLayerManager;
     19import org.openstreetmap.josm.gui.layer.OsmDataLayer;
     20import org.openstreetmap.josm.testutils.JOSMTestRules;
     21
     22import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
     23
     24/**
     25 * Test class for {@link CycleLayerAction}
     26 *
     27 * @author Taylor Smock
     28 */
     29public class CycleLayerActionTest {
     30    /** Layers need a projection */
     31    @Rule
     32    @SuppressFBWarnings(value = "URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD")
     33    public JOSMTestRules test = new JOSMTestRules().main().preferences().projection().fakeImagery();
     34
     35    CycleLayerAction cycle;
     36    MainLayerManager manager;
     37
     38    final static int MODIFIER = CycleLayerAction.MODIFIER;
     39    final static int KEYUP = CycleLayerAction.KEYUP;
     40    final static int KEYDOWN = CycleLayerAction.KEYDOWN;
     41    ActionEvent down;
     42    ActionEvent up;
     43
     44    /**
     45     * Set up common items (make layers, etc.)
     46     */
     47    @Before
     48    public void setUp() {
     49        cycle = new CycleLayerAction();
     50        manager = MainApplication.getLayerManager();
     51        for (int i = 0; i < 10; i++) {
     52            manager.addLayer(new OsmDataLayer(new DataSet(), tr("Layer {0}", i), null));
     53        }
     54        up = new ActionEvent(this, ActionEvent.ACTION_FIRST, KeyEvent.getKeyText(KEYUP), MODIFIER);
     55        down = new ActionEvent(this, ActionEvent.ACTION_FIRST, KeyEvent.getKeyText(KEYDOWN), MODIFIER);
     56    }
     57
     58    /**
     59     * Test going down from the bottom
     60     */
     61    @Test
     62    public void testDownBottom() {
     63        manager.setActiveLayer(manager.getLayers().get(0));
     64        cycle.actionPerformed(down);
     65        assertEquals(manager.getLayers().size() - 1, manager.getLayers().indexOf(manager.getActiveLayer()));
     66    }
     67
     68    /**
     69     * Check going up from the top
     70     */
     71    @Test
     72    public void testUpTop() {
     73        manager.setActiveLayer(manager.getLayers().get(manager.getLayers().size() - 1));
     74        cycle.actionPerformed(up);
     75        assertEquals(0, manager.getLayers().indexOf(manager.getActiveLayer()));
     76    }
     77
     78    /**
     79     * Check going down
     80     */
     81    @Test
     82    public void testDown() {
     83        manager.setActiveLayer(manager.getLayers().get(3));
     84        cycle.actionPerformed(down);
     85        assertEquals(2, manager.getLayers().indexOf(manager.getActiveLayer()));
     86    }
     87
     88    /**
     89     * Check going up
     90     */
     91    @Test
     92    public void testUp() {
     93        manager.setActiveLayer(manager.getLayers().get(3));
     94        cycle.actionPerformed(up);
     95        assertEquals(4, manager.getLayers().indexOf(manager.getActiveLayer()));
     96    }
     97
     98    /**
     99     * Test no layers
     100     */
     101    @Test
     102    public void testNoLayers() {
     103        manager.getLayers().forEach(manager::removeLayer);
     104        cycle.actionPerformed(up);
     105        cycle.actionPerformed(down);
     106        assertEquals(0, manager.getLayers().size());
     107    }
     108
     109    /**
     110     * Test with an aerial imagery layer
     111     */
     112    @Test
     113    public void testWithAerialImagery() {
     114        final ImageryInfo magentaTilesInfo = ImageryLayerInfo.instance.getLayers().stream()
     115                .filter(i -> i.getName().equals("Magenta Tiles")).findAny().get();
     116        ImageryLayer imageryLayer = ImageryLayer.create(magentaTilesInfo);
     117        manager.addLayer(imageryLayer);
     118        manager.moveLayer(imageryLayer, 5);
     119        manager.setActiveLayer(manager.getLayers().get(4));
     120        cycle.actionPerformed(up);
     121        assertEquals(6, manager.getLayers().indexOf(manager.getActiveLayer()));
     122        cycle.actionPerformed(down);
     123        assertEquals(4, manager.getLayers().indexOf(manager.getActiveLayer()));
     124    }
     125}