source: josm/trunk/src/org/openstreetmap/josm/actions/mapmode/MapMode.java @ 13453

Last change on this file since 13453 was 13453, checked in by Don-vip, 7 months ago

fix #8039, fix #10456: final fixes for the read-only/locked layers:

  • rename "read-only" to "locked" (in XML and Java classes/interfaces)
  • add a new download policy (true/never) to allow private layers forbidding only to download data, but allowing everything else

This leads to:

  • normal layers: download allowed, modifications allowed, upload allowed
  • private layers: download allowed or not (download=true/never), modifications allowed, upload allowed or not (upload=true/discouraged/never)
  • locked layers: nothing allowed, the data cannot be modified in any way
  • Property svn:eol-style set to native
File size: 8.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.actions.mapmode;
3
4import java.awt.Cursor;
5import java.awt.event.ActionEvent;
6import java.awt.event.InputEvent;
7import java.awt.event.MouseEvent;
8import java.awt.event.MouseListener;
9import java.awt.event.MouseMotionListener;
10import java.util.Collection;
11import java.util.Collections;
12
13import org.openstreetmap.josm.actions.JosmAction;
14import org.openstreetmap.josm.data.osm.OsmPrimitive;
15import org.openstreetmap.josm.gui.MainApplication;
16import org.openstreetmap.josm.gui.MapFrame;
17import org.openstreetmap.josm.gui.layer.Layer;
18import org.openstreetmap.josm.gui.layer.OsmDataLayer;
19import org.openstreetmap.josm.spi.preferences.Config;
20import org.openstreetmap.josm.spi.preferences.PreferenceChangeEvent;
21import org.openstreetmap.josm.spi.preferences.PreferenceChangedListener;
22import org.openstreetmap.josm.tools.ImageProvider;
23import org.openstreetmap.josm.tools.Shortcut;
24
25/**
26 * A class implementing MapMode is able to be selected as an mode for map editing.
27 * As example scrolling the map is a MapMode, connecting Nodes to new Ways is another.
28 *
29 * MapModes should register/deregister all necessary listeners on the map's view control.
30 */
31public abstract class MapMode extends JosmAction implements MouseListener, MouseMotionListener, PreferenceChangedListener {
32    protected final Cursor cursor;
33    protected boolean ctrl;
34    protected boolean alt;
35    protected boolean shift;
36
37    /**
38     * Constructor for mapmodes without a menu
39     * @param name the action's text
40     * @param iconName icon filename in {@code mapmode} directory
41     * @param tooltip  a longer description of the action that will be displayed in the tooltip.
42     * @param shortcut a ready-created shortcut object or null if you don't want a shortcut.
43     * @param cursor cursor displayed when map mode is active
44     * @since 11713
45     */
46    public MapMode(String name, String iconName, String tooltip, Shortcut shortcut, Cursor cursor) {
47        super(name, "mapmode/"+iconName, tooltip, shortcut, false);
48        this.cursor = cursor;
49        putValue("active", Boolean.FALSE);
50    }
51
52    /**
53     * Constructor for mapmodes with a menu (no shortcut will be registered)
54     * @param name the action's text
55     * @param iconName icon filename in {@code mapmode} directory
56     * @param tooltip  a longer description of the action that will be displayed in the tooltip.
57     * @param cursor cursor displayed when map mode is active
58     * @since 11713
59     */
60    public MapMode(String name, String iconName, String tooltip, Cursor cursor) {
61        putValue(NAME, name);
62        new ImageProvider("mapmode", iconName).getResource().attachImageIcon(this);
63        putValue(SHORT_DESCRIPTION, tooltip);
64        this.cursor = cursor;
65    }
66
67    /**
68     * Makes this map mode active.
69     */
70    public void enterMode() {
71        putValue("active", Boolean.TRUE);
72        Config.getPref().addPreferenceChangeListener(this);
73        readPreferences();
74        MainApplication.getMap().mapView.setNewCursor(cursor, this);
75        updateStatusLine();
76    }
77
78    /**
79     * Makes this map mode inactive.
80     */
81    public void exitMode() {
82        putValue("active", Boolean.FALSE);
83        Config.getPref().removePreferenceChangeListener(this);
84        MainApplication.getMap().mapView.resetCursor(this);
85    }
86
87    protected void updateStatusLine() {
88        MapFrame map = MainApplication.getMap();
89        if (map != null && map.statusLine != null) {
90            map.statusLine.setHelpText(getModeHelpText());
91            map.statusLine.repaint();
92        }
93    }
94
95    /**
96     * Returns a short translated help message describing how this map mode can be used, to be displayed in status line.
97     * @return a short translated help message describing how this map mode can be used
98     */
99    public String getModeHelpText() {
100        return "";
101    }
102
103    protected void readPreferences() {}
104
105    /**
106     * Call selectMapMode(this) on the parent mapFrame.
107     */
108    @Override
109    public void actionPerformed(ActionEvent e) {
110        if (MainApplication.isDisplayingMapView()) {
111            MainApplication.getMap().selectMapMode(this);
112        }
113    }
114
115    /**
116     * Determines if layer {@code l} is supported by this map mode.
117     * By default, all tools will work with all layers.
118     * Can be overwritten to require a special type of layer
119     * @param l layer
120     * @return {@code true} if the layer is supported by this map mode
121     */
122    public boolean layerIsSupported(Layer l) {
123        return l != null;
124    }
125
126    /**
127     * Update internal ctrl, alt, shift mask from given input event.
128     * @param e input event
129     */
130    protected void updateKeyModifiers(InputEvent e) {
131        updateKeyModifiersEx(e.getModifiersEx());
132    }
133
134    /**
135     * Update internal ctrl, alt, shift mask from given mouse event.
136     * @param e mouse event
137     */
138    protected void updateKeyModifiers(MouseEvent e) {
139        updateKeyModifiersEx(e.getModifiersEx());
140    }
141
142    /**
143     * Update internal ctrl, alt, shift mask from given action event.
144     * @param e action event
145     * @since 12526
146     */
147    protected void updateKeyModifiers(ActionEvent e) {
148        // ActionEvent does not have a getModifiersEx() method like other events :(
149        updateKeyModifiersEx(mapOldModifiers(e.getModifiers()));
150    }
151
152    /**
153     * Update internal ctrl, alt, shift mask from given extended modifiers mask.
154     * @param modifiers event extended modifiers mask
155     * @since 12517
156     */
157    protected void updateKeyModifiersEx(int modifiers) {
158        ctrl = (modifiers & InputEvent.CTRL_DOWN_MASK) != 0;
159        alt = (modifiers & (InputEvent.ALT_DOWN_MASK | InputEvent.ALT_GRAPH_DOWN_MASK)) != 0;
160        shift = (modifiers & InputEvent.SHIFT_DOWN_MASK) != 0;
161    }
162
163    /**
164     * Map old (pre jdk 1.4) modifiers to extended modifiers (only for Ctrl, Alt, Shift).
165     * @param modifiers old modifiers
166     * @return extended modifiers
167     */
168    @SuppressWarnings("deprecation")
169    private static int mapOldModifiers(int modifiers) {
170        if ((modifiers & InputEvent.CTRL_MASK) != 0) {
171            modifiers |= InputEvent.CTRL_DOWN_MASK;
172        }
173        if ((modifiers & InputEvent.ALT_MASK) != 0) {
174            modifiers |= InputEvent.ALT_DOWN_MASK;
175        }
176        if ((modifiers & InputEvent.ALT_GRAPH_MASK) != 0) {
177            modifiers |= InputEvent.ALT_GRAPH_DOWN_MASK;
178        }
179        if ((modifiers & InputEvent.SHIFT_MASK) != 0) {
180            modifiers |= InputEvent.SHIFT_DOWN_MASK;
181        }
182
183        return modifiers;
184    }
185
186    protected void requestFocusInMapView() {
187        if (isEnabled()) {
188            // request focus in order to enable the expected keyboard shortcuts (see #8710)
189            MainApplication.getMap().mapView.requestFocus();
190        }
191    }
192
193    @Override
194    public void mouseReleased(MouseEvent e) {
195        requestFocusInMapView();
196    }
197
198    @Override
199    public void mouseExited(MouseEvent e) {
200        // Do nothing
201    }
202
203    @Override
204    public void mousePressed(MouseEvent e) {
205        requestFocusInMapView();
206    }
207
208    @Override
209    public void mouseClicked(MouseEvent e) {
210        // Do nothing
211    }
212
213    @Override
214    public void mouseEntered(MouseEvent e) {
215        // Do nothing
216    }
217
218    @Override
219    public void mouseMoved(MouseEvent e) {
220        // Do nothing
221    }
222
223    @Override
224    public void mouseDragged(MouseEvent e) {
225        // Do nothing
226    }
227
228    @Override
229    public void preferenceChanged(PreferenceChangeEvent e) {
230        readPreferences();
231    }
232
233    /**
234     * Gets a collection of primitives that should not be hidden by the filter.
235     * @return The primitives that the filter should not hide.
236     * @deprecated use {@link org.openstreetmap.josm.data.osm.DataSet#allPreservedPrimitives}
237     * @since 11993
238     */
239    @Deprecated
240    public Collection<? extends OsmPrimitive> getPreservedPrimitives() {
241        return Collections.emptySet();
242    }
243
244    /**
245     * Determines if the given layer is a data layer that can be modified.
246     * Useful for {@link #layerIsSupported(Layer)} implementations.
247     * @param l layer
248     * @return {@code true} if the given layer is a data layer that can be modified
249     * @since 13434
250     */
251    protected boolean isEditableDataLayer(Layer l) {
252        return l instanceof OsmDataLayer && !((OsmDataLayer) l).isLocked();
253    }
254}
Note: See TracBrowser for help on using the repository browser.