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

Last change on this file since 13434 was 13434, checked in by Don-vip, 6 years ago

see #8039, see #10456 - support read-only data layers

  • 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).isReadOnly();
253 }
254}
Note: See TracBrowser for help on using the repository browser.