source: josm/trunk/src/org/openstreetmap/josm/actions/JosmAction.java@ 3779

Last change on this file since 3779 was 3504, checked in by bastiK, 14 years ago

reworked reverseWay and combineWay such that it can be used by other actions without hack (see #5179 - Join overlapping areas rewrite)

  • Property svn:eol-style set to native
File size: 7.5 KB
Line 
1// License: GPL. Copyright 2007 by Immanuel Scholz and others
2package org.openstreetmap.josm.actions;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.util.Collection;
7
8import javax.swing.AbstractAction;
9
10import org.openstreetmap.josm.Main;
11import org.openstreetmap.josm.data.SelectionChangedListener;
12import org.openstreetmap.josm.data.osm.DataSet;
13import org.openstreetmap.josm.data.osm.OsmPrimitive;
14import org.openstreetmap.josm.gui.MapView;
15import org.openstreetmap.josm.gui.layer.Layer;
16import org.openstreetmap.josm.gui.layer.OsmDataLayer;
17import org.openstreetmap.josm.tools.Destroyable;
18import org.openstreetmap.josm.tools.ImageProvider;
19import org.openstreetmap.josm.tools.Shortcut;
20
21/**
22 * Base class helper for all Actions in JOSM. Just to make the life easier.
23 *
24 * A JosmAction is a {@see LayerChangeListener} and a {@see SelectionChangedListener}. Upon
25 * a layer change event or a selection change event it invokes {@see #updateEnabled()}.
26 * Subclasses can override {@see #updateEnabled()} in order to update the {@see #isEnabled()}-state
27 * of a JosmAction depending on the {@see #getCurrentDataSet()} and the current layers
28 * (see also {@see #getEditLayer()}).
29 *
30 * destroy() from interface Destroyable is called e.g. for MapModes, when the last layer has
31 * been removed and so the mapframe will be destroyed. For other JosmActions, destroy() may never
32 * be called (currently).
33 *
34 * @author imi
35 */
36abstract public class JosmAction extends AbstractAction implements Destroyable {
37
38 protected Shortcut sc;
39 private LayerChangeAdapter layerChangeAdapter;
40 private SelectionChangeAdapter selectionChangeAdapter;
41
42 public Shortcut getShortcut() {
43 if (sc == null) {
44 sc = Shortcut.registerShortcut("core:none", tr("No Shortcut"), 0, Shortcut.GROUP_NONE);
45 // as this shortcut is shared by all action that don't want to have a shortcut,
46 // we shouldn't allow the user to change it...
47 // this is handled by special name "core:none"
48 }
49 return sc;
50 }
51
52 /**
53 * The new super for all actions.
54 *
55 * Use this super constructor to setup your action. It takes 5 parameters:
56 *
57 * @param name the action's text as displayed on the menu (if it is added to a menu)
58 * @param iconName the filename of the icon to use
59 * @param tooltip a longer description of the action that will be displayed in the tooltip. Please note
60 * that html is not supported for menu actions on some platforms.
61 * @param shortcut a ready-created shortcut object or null if you don't want a shortcut. But you always
62 * do want a shortcut, remember you can always register it with group=none, so you
63 * won't be assigned a shortcut unless the user configures one. If you pass null here,
64 * the user CANNOT configure a shortcut for your action.
65 * @param register register this action for the toolbar preferences?
66 */
67 public JosmAction(String name, String iconName, String tooltip, Shortcut shortcut, boolean register) {
68 this(name, iconName, tooltip, shortcut, register, true);
69 }
70
71 /**
72 * Even newer super for all actions. Use if you don't want to install layer changed and selection changed adapters
73 * @param name
74 * @param iconName
75 * @param tooltip
76 * @param shortcut
77 * @param register
78 * @param installAdapters
79 */
80 public JosmAction(String name, String iconName, String tooltip, Shortcut shortcut, boolean register, boolean installAdapters) {
81 super(name, iconName == null ? null : ImageProvider.get(iconName));
82 setHelpId();
83 sc = shortcut;
84 if (sc != null) {
85 Main.registerActionShortcut(this, sc);
86 }
87 putValue(SHORT_DESCRIPTION, Main.platform.makeTooltip(tooltip, sc));
88 putValue("toolbar", iconName);
89 if (register) {
90 Main.toolbar.register(this);
91 }
92 if (installAdapters) {
93 installAdapters();
94 }
95 }
96
97 public JosmAction() {
98 this(true);
99 }
100
101 public JosmAction(boolean installAdapters) {
102 setHelpId();
103 if (installAdapters) {
104 installAdapters();
105 }
106 }
107
108 public void destroy() {
109 if (sc != null) {
110 Main.unregisterActionShortcut(this);
111 }
112 MapView.removeLayerChangeListener(layerChangeAdapter);
113 DataSet.removeSelectionListener(selectionChangeAdapter);
114 }
115
116 private void setHelpId() {
117 String helpId = "Action/"+getClass().getName().substring(getClass().getName().lastIndexOf('.')+1);
118 if (helpId.endsWith("Action")) {
119 helpId = helpId.substring(0, helpId.length()-6);
120 }
121 putValue("help", helpId);
122 }
123
124 /**
125 * Replies the current edit layer
126 *
127 * @return the current edit layer. null, if no edit layer exists
128 */
129 protected OsmDataLayer getEditLayer() {
130 return Main.main.getEditLayer();
131 }
132
133 /**
134 * Replies the current dataset
135 *
136 * @return the current dataset. null, if no current dataset exists
137 */
138 protected DataSet getCurrentDataSet() {
139 return Main.main.getCurrentDataSet();
140 }
141
142 protected void installAdapters() {
143 // make this action listen to layer change and selection change events
144 //
145 layerChangeAdapter = new LayerChangeAdapter();
146 selectionChangeAdapter = new SelectionChangeAdapter();
147 MapView.addLayerChangeListener(layerChangeAdapter);
148 DataSet.addSelectionListener(selectionChangeAdapter);
149 initEnabledState();
150 }
151
152 /**
153 * Override in subclasses to init the enabled state of an action when it is
154 * created. Default behaviour is to call {@see #updateEnabledState()}
155 *
156 * @see #updateEnabledState()
157 * @see #updateEnabledState(Collection)
158 */
159 protected void initEnabledState() {
160 updateEnabledState();
161 }
162
163 /**
164 * Override in subclasses to update the enabled state of the action when
165 * something in the JOSM state changes, i.e. when a layer is removed or added.
166 *
167 * See {@see #updateEnabledState(Collection)} to respond to changes in the collection
168 * of selected primitives.
169 *
170 * Default behavior is empty.
171 *
172 * @see #updateEnabledState(Collection)
173 * @see #initEnabledState()
174 */
175 protected void updateEnabledState() {
176 }
177
178 /**
179 * Override in subclasses to update the enabled state of the action if the
180 * collection of selected primitives changes. This method is called with the
181 * new selection.
182 *
183 * @param selection the collection of selected primitives; may be empty, but not null
184 *
185 * @see #updateEnabledState()
186 * @see #initEnabledState()
187 */
188 protected void updateEnabledState(Collection<? extends OsmPrimitive> selection) {
189 }
190
191 /**
192 * Adapter for layer change events
193 *
194 */
195 private class LayerChangeAdapter implements MapView.LayerChangeListener {
196 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
197 updateEnabledState();
198 }
199
200 public void layerAdded(Layer newLayer) {
201 updateEnabledState();
202 }
203
204 public void layerRemoved(Layer oldLayer) {
205 updateEnabledState();
206 }
207 }
208
209 /**
210 * Adapter for selection change events
211 *
212 */
213 private class SelectionChangeAdapter implements SelectionChangedListener {
214 public void selectionChanged(Collection<? extends OsmPrimitive> newSelection) {
215 updateEnabledState(newSelection);
216 }
217 }
218}
Note: See TracBrowser for help on using the repository browser.