source: josm/trunk/src/org/openstreetmap/josm/gui/MainMenu.java@ 5903

Last change on this file since 5903 was 5857, checked in by Don-vip, 11 years ago

fix #8561 - Integrate restart plugin into core. Asks for restart when needed.

  • Property svn:eol-style set to native
File size: 28.7 KB
Line 
1// License: GPL. See LICENSE file for details.
2package org.openstreetmap.josm.gui;
3
4import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
5import static org.openstreetmap.josm.tools.I18n.marktr;
6import static org.openstreetmap.josm.tools.I18n.tr;
7
8import java.awt.Component;
9import java.awt.Toolkit;
10import java.awt.event.KeyEvent;
11
12import javax.swing.JCheckBoxMenuItem;
13import javax.swing.JMenu;
14import javax.swing.JMenuBar;
15import javax.swing.JMenuItem;
16import javax.swing.JPopupMenu;
17import javax.swing.JSeparator;
18import javax.swing.KeyStroke;
19import javax.swing.event.MenuEvent;
20import javax.swing.event.MenuListener;
21
22import org.openstreetmap.josm.Main;
23import org.openstreetmap.josm.actions.AboutAction;
24import org.openstreetmap.josm.actions.AddNodeAction;
25import org.openstreetmap.josm.actions.AlignInCircleAction;
26import org.openstreetmap.josm.actions.AlignInLineAction;
27import org.openstreetmap.josm.actions.AutoScaleAction;
28import org.openstreetmap.josm.actions.ChangesetManagerToggleAction;
29import org.openstreetmap.josm.actions.CloseChangesetAction;
30import org.openstreetmap.josm.actions.CombineWayAction;
31import org.openstreetmap.josm.actions.CopyAction;
32import org.openstreetmap.josm.actions.CopyCoordinatesAction;
33import org.openstreetmap.josm.actions.CreateCircleAction;
34import org.openstreetmap.josm.actions.CreateMultipolygonAction;
35import org.openstreetmap.josm.actions.DeleteAction;
36import org.openstreetmap.josm.actions.DistributeAction;
37import org.openstreetmap.josm.actions.DownloadAction;
38import org.openstreetmap.josm.actions.DownloadPrimitiveAction;
39import org.openstreetmap.josm.actions.DownloadReferrersAction;
40import org.openstreetmap.josm.actions.DuplicateAction;
41import org.openstreetmap.josm.actions.ExitAction;
42import org.openstreetmap.josm.actions.ExpertToggleAction;
43import org.openstreetmap.josm.actions.FollowLineAction;
44import org.openstreetmap.josm.actions.FullscreenToggleAction;
45import org.openstreetmap.josm.actions.GpxExportAction;
46import org.openstreetmap.josm.actions.HelpAction;
47import org.openstreetmap.josm.actions.HistoryInfoAction;
48import org.openstreetmap.josm.actions.HistoryInfoWebAction;
49import org.openstreetmap.josm.actions.InfoAction;
50import org.openstreetmap.josm.actions.InfoWebAction;
51import org.openstreetmap.josm.actions.JoinAreasAction;
52import org.openstreetmap.josm.actions.JoinNodeWayAction;
53import org.openstreetmap.josm.actions.JosmAction;
54import org.openstreetmap.josm.actions.JumpToAction;
55import org.openstreetmap.josm.actions.MergeLayerAction;
56import org.openstreetmap.josm.actions.MergeNodesAction;
57import org.openstreetmap.josm.actions.MergeSelectionAction;
58import org.openstreetmap.josm.actions.MirrorAction;
59import org.openstreetmap.josm.actions.MoveAction;
60import org.openstreetmap.josm.actions.MoveNodeAction;
61import org.openstreetmap.josm.actions.NewAction;
62import org.openstreetmap.josm.actions.OpenFileAction;
63import org.openstreetmap.josm.actions.OpenLocationAction;
64import org.openstreetmap.josm.actions.OrthogonalizeAction;
65import org.openstreetmap.josm.actions.PasteAction;
66import org.openstreetmap.josm.actions.PasteTagsAction;
67import org.openstreetmap.josm.actions.PreferencesAction;
68import org.openstreetmap.josm.actions.PurgeAction;
69import org.openstreetmap.josm.actions.RedoAction;
70import org.openstreetmap.josm.actions.RestartAction;
71import org.openstreetmap.josm.actions.ReverseWayAction;
72import org.openstreetmap.josm.actions.SaveAction;
73import org.openstreetmap.josm.actions.SaveAsAction;
74import org.openstreetmap.josm.actions.SelectAllAction;
75import org.openstreetmap.josm.actions.SessionLoadAction;
76import org.openstreetmap.josm.actions.SessionSaveAsAction;
77import org.openstreetmap.josm.actions.ShowStatusReportAction;
78import org.openstreetmap.josm.actions.SimplifyWayAction;
79import org.openstreetmap.josm.actions.SplitWayAction;
80import org.openstreetmap.josm.actions.ToggleGPXLinesAction;
81import org.openstreetmap.josm.actions.UnGlueAction;
82import org.openstreetmap.josm.actions.UndoAction;
83import org.openstreetmap.josm.actions.UnselectAllAction;
84import org.openstreetmap.josm.actions.UpdateDataAction;
85import org.openstreetmap.josm.actions.UpdateModifiedAction;
86import org.openstreetmap.josm.actions.UpdateSelectionAction;
87import org.openstreetmap.josm.actions.UploadAction;
88import org.openstreetmap.josm.actions.UploadSelectionAction;
89import org.openstreetmap.josm.actions.ViewportFollowToggleAction;
90import org.openstreetmap.josm.actions.WireframeToggleAction;
91import org.openstreetmap.josm.actions.ZoomInAction;
92import org.openstreetmap.josm.actions.ZoomOutAction;
93import org.openstreetmap.josm.actions.OrthogonalizeAction.Undo;
94import org.openstreetmap.josm.actions.PreferenceToggleAction;
95import org.openstreetmap.josm.actions.audio.AudioBackAction;
96import org.openstreetmap.josm.actions.audio.AudioFasterAction;
97import org.openstreetmap.josm.actions.audio.AudioFwdAction;
98import org.openstreetmap.josm.actions.audio.AudioNextAction;
99import org.openstreetmap.josm.actions.audio.AudioPlayPauseAction;
100import org.openstreetmap.josm.actions.audio.AudioPrevAction;
101import org.openstreetmap.josm.actions.audio.AudioSlowerAction;
102import org.openstreetmap.josm.actions.search.SearchAction;
103import org.openstreetmap.josm.data.Preferences.PreferenceChangeEvent;
104import org.openstreetmap.josm.data.Preferences.PreferenceChangedListener;
105import org.openstreetmap.josm.gui.io.RecentlyOpenedFilesMenu;
106import org.openstreetmap.josm.gui.layer.Layer;
107import org.openstreetmap.josm.gui.mappaint.MapPaintMenu;
108import org.openstreetmap.josm.gui.tagging.TaggingPresetSearchAction;
109import org.openstreetmap.josm.tools.ImageProvider;
110import org.openstreetmap.josm.tools.Shortcut;
111
112/**
113 * This is the JOSM main menu bar. It is overwritten to initialize itself and provide all menu
114 * entries as member variables (sort of collect them).
115 *
116 * It also provides possibilities to attach new menu entries (used by plugins).
117 *
118 * @author Immanuel.Scholz
119 */
120public class MainMenu extends JMenuBar {
121
122 /* File menu */
123 public final NewAction newAction = new NewAction();
124 public final OpenFileAction openFile = new OpenFileAction();
125 public final RecentlyOpenedFilesMenu recentlyOpened = new RecentlyOpenedFilesMenu();
126 public final OpenLocationAction openLocation = new OpenLocationAction();
127 public final JosmAction save = SaveAction.getInstance();
128 public final JosmAction saveAs = SaveAsAction.getInstance();
129 public JosmAction sessionLoad;
130 public JosmAction sessionSaveAs;
131 public final JosmAction gpxExport = new GpxExportAction();
132 public final DownloadAction download = new DownloadAction();
133 public final DownloadPrimitiveAction downloadPrimitive = new DownloadPrimitiveAction();
134 public final DownloadReferrersAction downloadReferrers = new DownloadReferrersAction();
135 public final CloseChangesetAction closeChangesetAction = new CloseChangesetAction();
136 public final JosmAction update = new UpdateDataAction();
137 public final JosmAction updateSelection = new UpdateSelectionAction();
138 public final JosmAction updateModified = new UpdateModifiedAction();
139 public final JosmAction upload = new UploadAction();
140 public final JosmAction uploadSelection = new UploadSelectionAction();
141 public final JosmAction restart = new RestartAction();
142 public final JosmAction exit = new ExitAction();
143
144 /* Edit menu */
145 public final UndoAction undo = new UndoAction();
146 public final RedoAction redo = new RedoAction();
147 public final JosmAction copy = new CopyAction();
148 public final JosmAction copyCoordinates = new CopyCoordinatesAction();
149 public final PasteAction paste = new PasteAction();
150 public final JosmAction pasteTags = new PasteTagsAction();
151 public final JosmAction duplicate = new DuplicateAction();
152 public final JosmAction delete = new DeleteAction();
153 public final JosmAction purge = new PurgeAction();
154 public final JosmAction merge = new MergeLayerAction();
155 public final JosmAction mergeSelected = new MergeSelectionAction();
156 public final JosmAction selectAll = new SelectAllAction();
157 public final JosmAction unselectAll = new UnselectAllAction();
158 public final JosmAction search = new SearchAction();
159 public final JosmAction preferences = new PreferencesAction();
160
161 /* View menu */
162 public final WireframeToggleAction wireFrameToggleAction = new WireframeToggleAction();
163 public final JosmAction toggleGPXLines = new ToggleGPXLinesAction();
164 public final InfoAction info = new InfoAction();
165 public final InfoWebAction infoweb = new InfoWebAction();
166 public final HistoryInfoAction historyinfo = new HistoryInfoAction();
167 public final HistoryInfoWebAction historyinfoweb = new HistoryInfoWebAction();
168
169 /* Tools menu */
170 public final JosmAction splitWay = new SplitWayAction();
171 public final JosmAction combineWay = new CombineWayAction();
172 public final JosmAction reverseWay = new ReverseWayAction();
173 public final JosmAction alignInCircle = new AlignInCircleAction();
174 public final JosmAction alignInLine = new AlignInLineAction();
175 public final JosmAction distribute = new DistributeAction();
176 public final OrthogonalizeAction ortho = new OrthogonalizeAction();
177 public final JosmAction orthoUndo = new Undo(); // action is not shown in the menu. Only triggered by shortcut
178 public final JosmAction mirror = new MirrorAction();
179 public final AddNodeAction addnode = new AddNodeAction();
180 public final MoveNodeAction movenode = new MoveNodeAction();
181 public final JosmAction createCircle = new CreateCircleAction();
182 public final JosmAction mergeNodes = new MergeNodesAction();
183 public final JosmAction joinNodeWay = new JoinNodeWayAction();
184 public final JosmAction unglueNodes = new UnGlueAction();
185 public final JosmAction simplifyWay = new SimplifyWayAction();
186 public final JosmAction joinAreas = new JoinAreasAction();
187 public final JosmAction createMultipolygon = new CreateMultipolygonAction();
188 public final JosmAction followLine = new FollowLineAction();
189
190 /* Audio menu */
191 public final JosmAction audioPlayPause = new AudioPlayPauseAction();
192 public final JosmAction audioNext = new AudioNextAction();
193 public final JosmAction audioPrev = new AudioPrevAction();
194 public final JosmAction audioFwd = new AudioFwdAction();
195 public final JosmAction audioBack = new AudioBackAction();
196 public final JosmAction audioFaster = new AudioFasterAction();
197 public final JosmAction audioSlower = new AudioSlowerAction();
198
199 /* Help menu */
200 public final HelpAction help = new HelpAction();
201 public final JosmAction about = new AboutAction();
202 public final JosmAction statusreport = new ShowStatusReportAction();
203
204 public final JMenu fileMenu = addMenu(marktr("File"), KeyEvent.VK_F, 0, ht("/Menu/File"));
205 public final JMenu sessionMenu = new JMenu(tr("Session")); // submenu of the file menu
206 public final JMenu editMenu = addMenu(marktr("Edit"), KeyEvent.VK_E, 1, ht("/Menu/Edit"));
207 public final JMenu viewMenu = addMenu(marktr("View"), KeyEvent.VK_V, 2, ht("/Menu/View"));
208 public final JMenu toolsMenu = addMenu(marktr("Tools"), KeyEvent.VK_T, 3, ht("/Menu/Tools"));
209 public final JMenu presetsMenu = addMenu(marktr("Presets"), KeyEvent.VK_P, 4, ht("/Menu/Presets"));
210 public final ImageryMenu imageryMenu =
211 (ImageryMenu)addMenu(new ImageryMenu(), marktr("Imagery"), KeyEvent.VK_I, 5, ht("/Menu/Imagery"));
212 /** the window menu is split into several groups. The first is for windows that can be opened from
213 * this menu any time, e.g. the changeset editor. The second group is for toggle dialogs and the third
214 * group is for currently open windows that cannot be toggled, e.g. relation editors. It's recommended
215 * to use WINDOW_MENU_GROUP to determine the group integer.
216 */
217 public final JMenu windowMenu = addMenu(marktr("Windows"), KeyEvent.VK_W, 6, ht("/Menu/Windows"));
218 public static enum WINDOW_MENU_GROUP { ALWAYS, TOGGLE_DIALOG, VOLATILE }
219
220 public JMenu audioMenu = null;
221 public final JMenu helpMenu = addMenu(marktr("Help"), KeyEvent.VK_H, 7, ht("/Menu/Help"));
222
223 public final int defaultMenuPos = 7;
224
225 public final JosmAction moveUpAction = new MoveAction(MoveAction.Direction.UP);
226 public final JosmAction moveDownAction = new MoveAction(MoveAction.Direction.DOWN);
227 public final JosmAction moveLeftAction = new MoveAction(MoveAction.Direction.LEFT);
228 public final JosmAction moveRightAction = new MoveAction(MoveAction.Direction.RIGHT);
229 public final JumpToAction jumpToAct = new JumpToAction();
230
231 public final TaggingPresetSearchAction presetSearchAction = new TaggingPresetSearchAction();
232 public FullscreenToggleAction fullscreenToggleAction = null;
233
234 /** this menu listener hides unnecessary JSeparators in a menu list but does not remove them.
235 * If at a later time the separators are required, they will be made visible again. Intended
236 * usage is make menus not look broken if separators are used to group the menu and some of
237 * these groups are empty.
238 */
239 public final static MenuListener menuSeparatorHandler = new MenuListener() {
240 @Override
241 public void menuCanceled(MenuEvent arg0) {}
242 @Override
243 public void menuDeselected(MenuEvent arg0) {}
244 @Override
245 public void menuSelected(MenuEvent a) {
246 if(!(a.getSource() instanceof JMenu))
247 return;
248 final JPopupMenu m = ((JMenu) a.getSource()).getPopupMenu();
249 for(int i=0; i < m.getComponentCount()-1; i++) {
250 if(!(m.getComponent(i) instanceof JSeparator)) {
251 continue;
252 }
253 // hide separator if the next menu item is one as well
254 ((JSeparator) m.getComponent(i)).setVisible(!(m.getComponent(i+1) instanceof JSeparator));
255 }
256 // hide separator at the end of the menu
257 if(m.getComponent(m.getComponentCount()-1) instanceof JSeparator) {
258 ((JSeparator) m.getComponent(m.getComponentCount()-1)).setVisible(false);
259 }
260 }
261 };
262
263 /**
264 * Add a JosmAction at the end of a menu.
265 *
266 * This method handles all the shortcut handling. It also makes sure that actions that are
267 * handled by the OS are not duplicated on the menu.
268 * @param menu the menu to add the action to
269 * @param action the action that should get a menu item
270 * @return the created menu item
271 */
272 public static JMenuItem add(JMenu menu, JosmAction action) {
273 return add(menu, action, false);
274 }
275
276 /**
277 * Add a JosmAction at the end of a menu.
278 *
279 * This method handles all the shortcut handling. It also makes sure that actions that are
280 * handled by the OS are not duplicated on the menu.
281 * @param menu the menu to add the action to
282 * @param action the action that should get a menu item
283 * @param isExpert whether the entry should only be visible if the expert mode is activated
284 * @return the created menu item
285 */
286 public static JMenuItem add(JMenu menu, JosmAction action, boolean isExpert) {
287 return add(menu, action, isExpert, null);
288 }
289
290 /**
291 * Add a JosmAction at the end of a menu.
292 *
293 * This method handles all the shortcut handling. It also makes sure that actions that are
294 * handled by the OS are not duplicated on the menu.
295 * @param menu the menu to add the action to
296 * @param action the action that should get a menu item
297 * @param isExpert whether the entry should only be visible if the expert mode is activated
298 * @param index an integer specifying the position at which to add the action
299 * @return the created menu item
300 */
301 public static JMenuItem add(JMenu menu, JosmAction action, boolean isExpert, Integer index) {
302 if (action.getShortcut().getAutomatic())
303 return null;
304 final JMenuItem menuitem;
305 if (index == null) {
306 menuitem = menu.add(action);
307 } else {
308 menuitem = menu.insert(action, index);
309 }
310 if (isExpert) {
311 ExpertToggleAction.addVisibilitySwitcher(menuitem);
312 }
313 KeyStroke ks = action.getShortcut().getKeyStroke();
314 if (ks != null) {
315 menuitem.setAccelerator(ks);
316 }
317 return menuitem;
318 }
319
320 /**
321 * Add the JosmAction {@code actionToBeInserted} directly below {@code existingMenuEntryAction}.
322 *
323 * This method handles all the shortcut handling. It also makes sure that actions that are
324 * handled by the OS are not duplicated on the menu.
325 * @param menu the menu to add the action to
326 * @param actionToBeInserted the action that should get a menu item directly below {@code existingMenuEntryAction}
327 * @param isExpert whether the entry should only be visible if the expert mode is activated
328 * @param existingMenuEntryAction an action already added to the menu {@code menu}, the action {@code actionToBeInserted} is added directly below
329 * @return the created menu item
330 */
331 public static JMenuItem addAfter(JMenu menu, JosmAction actionToBeInserted, boolean isExpert, JosmAction existingMenuEntryAction) {
332 int i = 0;
333 for (Component c : menu.getMenuComponents()) {
334 if (c instanceof JMenuItem && ((JMenuItem) c).getAction() == existingMenuEntryAction) {
335 break;
336 }
337 i++;
338 }
339 return add(menu, actionToBeInserted, isExpert, i + 1);
340 }
341
342 /**
343 * Add a JosmAction to a menu.
344 *
345 * This method handles all the shortcut handling. It also makes sure that actions that are
346 * handled by the OS are not duplicated on the menu.
347 * @param menu to add the action to
348 * @param action the action that should get a menu item
349 * @param group the item should be added to. Groups are split by a separator.
350 * 0 is the first group, -1 will add the item to the end.
351 */
352 public static <E extends Enum<E>> JMenuItem add(JMenu menu, JosmAction action, Enum<E> group) {
353 if (action.getShortcut().getAutomatic())
354 return null;
355 int i = getInsertionIndexForGroup(menu, group.ordinal());
356 JMenuItem menuitem = (JMenuItem) menu.add(new JMenuItem(action), i);
357 KeyStroke ks = action.getShortcut().getKeyStroke();
358 if (ks != null) {
359 menuitem.setAccelerator(ks);
360 }
361 return menuitem;
362 }
363
364 /**
365 * Add a JosmAction to a menu and automatically prints accelerator if available.
366 * Also adds a checkbox that may be toggled.
367 * @param menu to add the action to
368 * @param action the action that should get a menu item
369 * @param group the item should be added to. Groups are split by a separator. Use
370 * one of the enums that are defined for some of the menus to tell in which
371 * group the item should go.
372 */
373 public static <E extends Enum<E>> JCheckBoxMenuItem addWithCheckbox(JMenu menu, JosmAction action, Enum<E> group) {
374 int i = getInsertionIndexForGroup(menu, group.ordinal());
375 final JCheckBoxMenuItem mi = (JCheckBoxMenuItem) menu.add(new JCheckBoxMenuItem(action), i);
376 final KeyStroke ks = action.getShortcut().getKeyStroke();
377 if (ks != null) {
378 mi.setAccelerator(ks);
379 }
380 return mi;
381 }
382
383 /** finds the correct insertion index for a given group and adds separators if necessary */
384 private static int getInsertionIndexForGroup(JMenu menu, int group) {
385 if(group < 0)
386 return -1;
387 // look for separator that *ends* the group (or stop at end of menu)
388 int i;
389 for(i=0; i < menu.getItemCount() && group >= 0; i++) {
390 if(menu.getItem(i) == null) {
391 group--;
392 }
393 }
394 // insert before separator that ends the group
395 if(group < 0) {
396 i--;
397 }
398 // not enough separators have been found, add them
399 while(group > 0) {
400 menu.addSeparator();
401 group--;
402 i++;
403 }
404 return i;
405 }
406
407 public JMenu addMenu(String name, int mnemonicKey, int position, String relativeHelpTopic) {
408 final JMenu menu = new JMenu(tr(name));
409 int screenHeight = Toolkit.getDefaultToolkit().getScreenSize().height;
410 int menuItemHeight = new JMenu().add(newAction).getPreferredSize().height;
411 MenuScroller.setScrollerFor(menu, screenHeight / menuItemHeight);
412 return addMenu(menu, name, mnemonicKey, position, relativeHelpTopic);
413 }
414
415 public JMenu addMenu(JMenu menu, String name, int mnemonicKey, int position, String relativeHelpTopic) {
416 Shortcut.registerShortcut("menu:" + name, tr("Menu: {0}", tr(name)), mnemonicKey,
417 Shortcut.MNEMONIC).setMnemonic(menu);
418 add(menu, position);
419 menu.putClientProperty("help", relativeHelpTopic);
420 return menu;
421 }
422
423 public MainMenu() {
424 JMenuItem current;
425
426 add(fileMenu, newAction);
427 add(fileMenu, openFile);
428 fileMenu.add(recentlyOpened);
429 add(fileMenu, openLocation);
430 fileMenu.addSeparator();
431 add(fileMenu, save);
432 add(fileMenu, saveAs);
433 if (Main.pref.getBoolean("session")) {
434 sessionMenu.setToolTipText(tr("Save and load the current session (list of layers, etc.)"));
435 sessionMenu.setIcon(ImageProvider.get("session"));
436 sessionSaveAs = new SessionSaveAsAction();
437 sessionLoad = new SessionLoadAction();
438 add(sessionMenu, sessionSaveAs);
439 add(sessionMenu, sessionLoad);
440 fileMenu.add(sessionMenu);
441 }
442 add(fileMenu, gpxExport, true);
443 fileMenu.addSeparator();
444 add(fileMenu, download);
445 add(fileMenu, downloadPrimitive);
446 add(fileMenu, downloadReferrers);
447 add(fileMenu, update);
448 add(fileMenu, updateSelection);
449 add(fileMenu, updateModified);
450 fileMenu.addSeparator();
451 add(fileMenu, upload);
452 add(fileMenu, uploadSelection);
453 Component sep = new JPopupMenu.Separator();
454 fileMenu.add(sep);
455 ExpertToggleAction.addVisibilitySwitcher(sep);
456 add(fileMenu, closeChangesetAction, true);
457 fileMenu.addSeparator();
458 add(fileMenu, restart);
459 add(fileMenu, exit);
460
461 add(editMenu, undo);
462 Main.main.undoRedo.addCommandQueueListener(undo);
463 add(editMenu, redo);
464 Main.main.undoRedo.addCommandQueueListener(redo);
465 editMenu.addSeparator();
466 add(editMenu, copy);
467 add(editMenu, copyCoordinates, true);
468 add(editMenu, paste);
469 add(editMenu, pasteTags);
470 add(editMenu, duplicate);
471 add(editMenu, delete);
472 add(editMenu, purge, true);
473 editMenu.addSeparator();
474 add(editMenu,merge);
475 add(editMenu,mergeSelected);
476 editMenu.addSeparator();
477 add(editMenu, selectAll);
478 add(editMenu, unselectAll);
479 editMenu.addSeparator();
480 add(editMenu, search);
481 editMenu.addSeparator();
482 add(editMenu, preferences);
483
484 // -- wireframe toggle action
485 final JCheckBoxMenuItem wireframe = new JCheckBoxMenuItem(wireFrameToggleAction);
486 viewMenu.add(wireframe);
487 wireframe.setAccelerator(wireFrameToggleAction.getShortcut().getKeyStroke());
488 wireFrameToggleAction.addButtonModel(wireframe.getModel());
489
490 viewMenu.add(new MapPaintMenu());
491 viewMenu.addSeparator();
492 add(viewMenu, new ZoomInAction());
493 add(viewMenu, new ZoomOutAction());
494 viewMenu.addSeparator();
495 for (String mode : AutoScaleAction.MODES) {
496 JosmAction autoScaleAction = new AutoScaleAction(mode);
497 add(viewMenu, autoScaleAction);
498 }
499
500 // -- viewport follow toggle action
501 ViewportFollowToggleAction viewportFollowToggleAction = new ViewportFollowToggleAction();
502 final JCheckBoxMenuItem vft = new JCheckBoxMenuItem(viewportFollowToggleAction);
503 ExpertToggleAction.addVisibilitySwitcher(vft);
504 viewMenu.add(vft);
505 vft.setAccelerator(viewportFollowToggleAction.getShortcut().getKeyStroke());
506 viewportFollowToggleAction.addButtonModel(vft.getModel());
507
508 if(!Main.applet && Main.platform.canFullscreen()) {
509 // -- fullscreen toggle action
510 fullscreenToggleAction = new FullscreenToggleAction();
511 final JCheckBoxMenuItem fullscreen = new JCheckBoxMenuItem(fullscreenToggleAction);
512 viewMenu.addSeparator();
513 viewMenu.add(fullscreen);
514 fullscreen.setAccelerator(fullscreenToggleAction.getShortcut().getKeyStroke());
515 fullscreenToggleAction.addButtonModel(fullscreen.getModel());
516 }
517 viewMenu.addSeparator();
518 add(viewMenu, info);
519 add(viewMenu, infoweb);
520 add(viewMenu, historyinfo);
521 add(viewMenu, historyinfoweb);
522 viewMenu.addSeparator();
523 viewMenu.add(new PreferenceToggleAction(tr("Edit toolbar"),
524 tr("Toggles the visibility of the edit toolbar (i.e., the vertical tool)"),
525 "sidetoolbar.visible", true).getCheckbox());
526 // -- expert mode toggle action
527 final JCheckBoxMenuItem expertItem = new JCheckBoxMenuItem(ExpertToggleAction.getInstance());
528 viewMenu.add(expertItem);
529 ExpertToggleAction.getInstance().addButtonModel(expertItem.getModel());
530
531 add(presetsMenu, presetSearchAction);
532 presetsMenu.addSeparator();
533
534 add(toolsMenu, splitWay);
535 add(toolsMenu, combineWay);
536 toolsMenu.addSeparator();
537 add(toolsMenu, reverseWay);
538 add(toolsMenu, simplifyWay);
539 toolsMenu.addSeparator();
540 add(toolsMenu, alignInCircle);
541 add(toolsMenu, alignInLine);
542 add(toolsMenu, distribute);
543 add(toolsMenu, ortho);
544 add(toolsMenu, mirror, true);
545 toolsMenu.addSeparator();
546 add(toolsMenu, followLine, true);
547 add(toolsMenu, addnode, true);
548 add(toolsMenu, movenode, true);
549 add(toolsMenu, createCircle);
550 toolsMenu.addSeparator();
551 add(toolsMenu, mergeNodes);
552 add(toolsMenu, joinNodeWay);
553 add(toolsMenu, unglueNodes);
554 toolsMenu.addSeparator();
555 add(toolsMenu, joinAreas);
556 add(toolsMenu, createMultipolygon);
557
558 // -- changeset manager toggle action
559 ChangesetManagerToggleAction changesetManagerToggleAction = new ChangesetManagerToggleAction();
560 final JCheckBoxMenuItem mi = MainMenu.addWithCheckbox(windowMenu, changesetManagerToggleAction,
561 MainMenu.WINDOW_MENU_GROUP.ALWAYS);
562 changesetManagerToggleAction.addButtonModel(mi.getModel());
563
564 if (!Main.pref.getBoolean("audio.menuinvisible", false)) {
565 showAudioMenu(true);
566 }
567
568 Main.pref.addPreferenceChangeListener(new PreferenceChangedListener() {
569 @Override
570 public void preferenceChanged(PreferenceChangeEvent e) {
571 if (e.getKey().equals("audio.menuinvisible")) {
572 showAudioMenu(!Boolean.parseBoolean(e.getNewValue().toString()));
573 }
574 }
575 });
576
577 helpMenu.add(statusreport);
578
579 current = helpMenu.add(help); // FIXME why is help not a JosmAction?
580 current.setAccelerator(Shortcut.registerShortcut("system:help", tr("Help"), KeyEvent.VK_F1,
581 Shortcut.DIRECT).getKeyStroke());
582 add(helpMenu, about);
583
584
585 windowMenu.addMenuListener(menuSeparatorHandler);
586
587 new PresetsMenuEnabler(presetsMenu).refreshEnabled();
588 }
589
590 protected void showAudioMenu(boolean showMenu) {
591 if (showMenu && audioMenu == null) {
592 audioMenu = addMenu(marktr("Audio"), KeyEvent.VK_U, defaultMenuPos, ht("/Menu/Audio"));
593 add(audioMenu, audioPlayPause);
594 add(audioMenu, audioNext);
595 add(audioMenu, audioPrev);
596 add(audioMenu, audioFwd);
597 add(audioMenu, audioBack);
598 add(audioMenu, audioSlower);
599 add(audioMenu, audioFaster);
600 validate();
601 } else if (!showMenu && audioMenu != null) {
602 remove(audioMenu);
603 audioMenu.removeAll();
604 audioMenu = null;
605 validate();
606 }
607 }
608
609 static class PresetsMenuEnabler implements MapView.LayerChangeListener {
610 private JMenu presetsMenu;
611 public PresetsMenuEnabler(JMenu presetsMenu) {
612 MapView.addLayerChangeListener(this);
613 this.presetsMenu = presetsMenu;
614 }
615 /**
616 * Refreshes the enabled state
617 *
618 */
619 protected void refreshEnabled() {
620 presetsMenu.setEnabled(Main.isDisplayingMapView()
621 && Main.map.mapView.getEditLayer() != null
622 );
623 }
624
625 public void activeLayerChange(Layer oldLayer, Layer newLayer) {
626 refreshEnabled();
627 }
628
629 public void layerAdded(Layer newLayer) {
630 refreshEnabled();
631 }
632
633 public void layerRemoved(Layer oldLayer) {
634 refreshEnabled();
635 }
636 }
637}
Note: See TracBrowser for help on using the repository browser.