3 import java.awt.Toolkit;
4 import java.awt.event.ActionEvent;
5 import java.awt.event.ActionListener;
6 import java.awt.event.KeyEvent;
8 import javax.swing.JButton;
9 import javax.swing.JCheckBoxMenuItem;
10 import javax.swing.JMenu;
11 import javax.swing.JMenuBar;
12 import javax.swing.JMenuItem;
13 import javax.swing.JToolBar;
14 import javax.swing.KeyStroke;
17 import tim.prune.DataSubscriber;
18 import tim.prune.FunctionLibrary;
19 import tim.prune.GenericFunction;
20 import tim.prune.I18nManager;
21 import tim.prune.UpdateMessageBroker;
22 import tim.prune.config.Config;
23 import tim.prune.data.Photo;
24 import tim.prune.data.PhotoList;
25 import tim.prune.data.Selection;
26 import tim.prune.data.Track;
27 import tim.prune.data.TrackInfo;
28 import tim.prune.function.RearrangeWaypointsFunction.Rearrange;
29 import tim.prune.function.browser.UrlGenerator;
32 * Class to manage the menu bar and tool bar,
33 * including enabling and disabling the items
35 public class MenuManager implements DataSubscriber
37 private App _app = null;
38 private Track _track = null;
39 private Selection _selection = null;
40 private PhotoList _photos = null;
42 // Menu items which need enabling/disabling
43 private JMenuItem _sendGpsItem = null;
44 private JMenuItem _saveItem = null;
45 private JMenuItem _exportKmlItem = null;
46 private JMenuItem _exportGpxItem = null;
47 private JMenuItem _exportPovItem = null;
48 private JMenuItem _undoItem = null;
49 private JMenuItem _clearUndoItem = null;
50 private JMenuItem _editPointItem = null;
51 private JMenuItem _editWaypointNameItem = null;
52 private JMenuItem _deletePointItem = null;
53 private JMenuItem _deleteRangeItem = null;
54 private JMenuItem _compressItem = null;
55 private JMenuItem _deleteMarkedPointsItem = null;
56 private JMenuItem _interpolateItem = null;
57 private JMenuItem _averageItem = null;
58 private JMenuItem _selectAllItem = null;
59 private JMenuItem _selectNoneItem = null;
60 private JMenuItem _selectStartItem = null;
61 private JMenuItem _selectEndItem = null;
62 private JMenuItem _findWaypointItem = null;
63 private JMenuItem _duplicatePointItem = null;
64 private JMenuItem _reverseItem = null;
65 private JMenuItem _addTimeOffsetItem = null;
66 private JMenuItem _addAltitudeOffsetItem = null;
67 private JMenuItem _mergeSegmentsItem = null;
68 private JMenu _rearrangeMenu = null;
69 private JMenuItem _cutAndMoveItem = null;
70 private JMenuItem _convertNamesToTimesItem = null;
71 private JCheckBoxMenuItem _mapCheckbox = null;
72 private JMenuItem _show3dItem = null;
73 private JMenu _browserMapMenu = null;
74 private JMenuItem _chartItem = null;
75 private JMenuItem _getGpsiesItem = null;
76 private JMenuItem _lookupSrtmItem = null;
77 private JMenuItem _distanceItem = null;
78 private JMenuItem _fullRangeDetailsItem = null;
79 private JMenuItem _saveExifItem = null;
80 private JMenuItem _connectPhotoItem = null;
81 private JMenuItem _deletePhotoItem = null;
82 private JMenuItem _disconnectPhotoItem = null;
83 private JMenuItem _correlatePhotosItem = null;
84 private JMenuItem _rearrangePhotosItem = null;
85 private JMenuItem _rotatePhotoLeft = null;
86 private JMenuItem _rotatePhotoRight = null;
87 private JMenuItem _ignoreExifThumb = null;
88 private JCheckBoxMenuItem _onlineCheckbox = null;
90 // ActionListeners for reuse by menu and toolbar
91 private ActionListener _openFileAction = null;
92 private ActionListener _addPhotoAction = null;
93 private ActionListener _saveAction = null;
94 private ActionListener _undoAction = null;
95 private ActionListener _editPointAction = null;
96 private ActionListener _deletePointAction = null;
97 private ActionListener _deleteRangeAction = null;
98 private ActionListener _selectStartAction = null;
99 private ActionListener _selectEndAction = null;
100 private ActionListener _connectPhotoAction = null;
102 // Toolbar buttons which need enabling/disabling
103 private JButton _saveButton = null;
104 private JButton _undoButton = null;
105 private JButton _editPointButton = null;
106 private JButton _deletePointButton = null;
107 private JButton _deleteRangeButton = null;
108 private JButton _selectStartButton = null;
109 private JButton _selectEndButton = null;
110 private JButton _connectPhotoButton = null;
112 /** Array of key events */
113 private static final int[] KEY_EVENTS = {
114 KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.VK_C, KeyEvent.VK_D, KeyEvent.VK_E,
115 KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, KeyEvent.VK_I, KeyEvent.VK_J,
116 KeyEvent.VK_K, KeyEvent.VK_L, KeyEvent.VK_M, KeyEvent.VK_N, KeyEvent.VK_O,
117 KeyEvent.VK_P, KeyEvent.VK_Q, KeyEvent.VK_R, KeyEvent.VK_S, KeyEvent.VK_T,
118 KeyEvent.VK_U, KeyEvent.VK_V, KeyEvent.VK_W, KeyEvent.VK_X, KeyEvent.VK_Y, KeyEvent.VK_Z};
123 * @param inApp application to call on menu actions
124 * @param inTrackInfo track info object
126 public MenuManager(App inApp, TrackInfo inTrackInfo)
129 _track = inTrackInfo.getTrack();
130 _selection = inTrackInfo.getSelection();
131 _photos = inTrackInfo.getPhotoList();
136 * Create a JMenuBar containing all menu items
139 public JMenuBar createMenuBar()
141 JMenuBar menubar = new JMenuBar();
142 JMenu fileMenu = new JMenu(I18nManager.getText("menu.file"));
143 setAltKey(fileMenu, "altkey.menu.file");
145 JMenuItem openMenuItem = new JMenuItem(I18nManager.getText("function.open"));
146 setShortcut(openMenuItem, "shortcut.menu.file.open");
147 _openFileAction = new ActionListener() {
148 public void actionPerformed(ActionEvent e)
153 openMenuItem.addActionListener(_openFileAction);
154 fileMenu.add(openMenuItem);
156 JMenuItem addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
157 _addPhotoAction = new ActionListener() {
158 public void actionPerformed(ActionEvent e)
163 addPhotosMenuItem.addActionListener(_addPhotoAction);
164 fileMenu.add(addPhotosMenuItem);
165 fileMenu.addSeparator();
167 JMenuItem loadFromGpsMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSLOAD);
168 setShortcut(loadFromGpsMenuItem, "shortcut.menu.file.load");
169 fileMenu.add(loadFromGpsMenuItem);
171 _sendGpsItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSSAVE);
172 _sendGpsItem.setEnabled(false);
173 fileMenu.add(_sendGpsItem);
174 fileMenu.addSeparator();
176 _saveItem = new JMenuItem(I18nManager.getText("menu.file.save"), KeyEvent.VK_S);
177 setShortcut(_saveItem, "shortcut.menu.file.save");
178 _saveAction = new ActionListener() {
179 public void actionPerformed(ActionEvent e)
184 _saveItem.addActionListener(_saveAction);
185 _saveItem.setEnabled(false);
186 fileMenu.add(_saveItem);
188 _exportKmlItem = makeMenuItem(FunctionLibrary.FUNCTION_KMLEXPORT);
189 _exportKmlItem.setEnabled(false);
190 fileMenu.add(_exportKmlItem);
192 _exportGpxItem = makeMenuItem(FunctionLibrary.FUNCTION_GPXEXPORT);
193 _exportGpxItem.setEnabled(false);
194 fileMenu.add(_exportGpxItem);
196 _exportPovItem = makeMenuItem(FunctionLibrary.FUNCTION_POVEXPORT);
197 _exportPovItem.setEnabled(false);
198 fileMenu.add(_exportPovItem);
199 fileMenu.addSeparator();
200 JMenuItem exitMenuItem = new JMenuItem(I18nManager.getText("menu.file.exit"));
201 exitMenuItem.addActionListener(new ActionListener() {
202 public void actionPerformed(ActionEvent e)
207 fileMenu.add(exitMenuItem);
208 menubar.add(fileMenu);
210 JMenu trackMenu = new JMenu(I18nManager.getText("menu.track"));
211 setAltKey(trackMenu, "altkey.menu.track");
212 _undoItem = new JMenuItem(I18nManager.getText("menu.track.undo"));
213 setShortcut(_undoItem, "shortcut.menu.track.undo");
214 _undoAction = new ActionListener() {
215 public void actionPerformed(ActionEvent e)
220 _undoItem.addActionListener(_undoAction);
221 _undoItem.setEnabled(false);
222 trackMenu.add(_undoItem);
223 _clearUndoItem = new JMenuItem(I18nManager.getText("menu.track.clearundo"));
224 _clearUndoItem.addActionListener(new ActionListener() {
225 public void actionPerformed(ActionEvent e)
230 _clearUndoItem.setEnabled(false);
231 trackMenu.add(_clearUndoItem);
232 trackMenu.addSeparator();
233 _compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS);
234 setShortcut(_compressItem, "shortcut.menu.edit.compress");
235 _compressItem.setEnabled(false);
236 trackMenu.add(_compressItem);
237 _deleteMarkedPointsItem = new JMenuItem(I18nManager.getText("menu.track.deletemarked"));
238 _deleteMarkedPointsItem.addActionListener(new ActionListener() {
239 public void actionPerformed(ActionEvent e)
241 _app.finishCompressTrack();
244 _deleteMarkedPointsItem.setEnabled(false);
245 trackMenu.add(_deleteMarkedPointsItem);
246 trackMenu.addSeparator();
247 // Rearrange waypoints
248 _rearrangeMenu = new JMenu(I18nManager.getText("menu.track.rearrange"));
249 _rearrangeMenu.setEnabled(false);
250 JMenuItem rearrangeStartItem = new JMenuItem(I18nManager.getText("menu.track.rearrange.start"));
251 rearrangeStartItem.addActionListener(new ActionListener() {
252 public void actionPerformed(ActionEvent e)
254 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_START);
257 rearrangeStartItem.setEnabled(true);
258 _rearrangeMenu.add(rearrangeStartItem);
259 JMenuItem rearrangeEndItem = new JMenuItem(I18nManager.getText("menu.track.rearrange.end"));
260 rearrangeEndItem.addActionListener(new ActionListener() {
261 public void actionPerformed(ActionEvent e)
263 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_END);
266 rearrangeEndItem.setEnabled(true);
267 _rearrangeMenu.add(rearrangeEndItem);
268 JMenuItem rearrangeNearestItem = new JMenuItem(I18nManager.getText("menu.track.rearrange.nearest"));
269 rearrangeNearestItem.addActionListener(new ActionListener() {
270 public void actionPerformed(ActionEvent e)
272 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_NEAREST);
275 rearrangeNearestItem.setEnabled(true);
276 _rearrangeMenu.add(rearrangeNearestItem);
277 trackMenu.add(_rearrangeMenu);
279 _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES);
280 _getGpsiesItem.setEnabled(false);
281 trackMenu.add(_getGpsiesItem);
282 _lookupSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_LOOKUP_SRTM);
283 _lookupSrtmItem.setEnabled(false);
284 trackMenu.add(_lookupSrtmItem);
285 menubar.add(trackMenu);
288 JMenu rangeMenu = new JMenu(I18nManager.getText("menu.range"));
289 setAltKey(rangeMenu, "altkey.menu.range");
290 _selectAllItem = new JMenuItem(I18nManager.getText("menu.range.all"));
291 setShortcut(_selectAllItem, "shortcut.menu.range.all");
292 _selectAllItem.setEnabled(false);
293 _selectAllItem.addActionListener(new ActionListener() {
294 public void actionPerformed(ActionEvent e)
296 _selection.selectRange(0, _track.getNumPoints()-1);
299 rangeMenu.add(_selectAllItem);
300 _selectNoneItem = new JMenuItem(I18nManager.getText("menu.range.none"));
301 _selectNoneItem.setEnabled(false);
302 _selectNoneItem.addActionListener(new ActionListener() {
303 public void actionPerformed(ActionEvent e)
308 rangeMenu.add(_selectNoneItem);
309 rangeMenu.addSeparator();
310 _selectStartItem = new JMenuItem(I18nManager.getText("menu.range.start"));
311 _selectStartItem.setEnabled(false);
312 _selectStartAction = new ActionListener() {
313 public void actionPerformed(ActionEvent e)
315 _selection.selectRangeStart();
318 _selectStartItem.addActionListener(_selectStartAction);
319 rangeMenu.add(_selectStartItem);
320 _selectEndItem = new JMenuItem(I18nManager.getText("menu.range.end"));
321 _selectEndItem.setEnabled(false);
322 _selectEndAction = new ActionListener() {
323 public void actionPerformed(ActionEvent e)
325 _selection.selectRangeEnd();
328 _selectEndItem.addActionListener(_selectEndAction);
329 rangeMenu.add(_selectEndItem);
330 rangeMenu.addSeparator();
331 _deleteRangeItem = new JMenuItem(I18nManager.getText("menu.range.deleterange"));
332 _deleteRangeAction = new ActionListener() {
333 public void actionPerformed(ActionEvent e)
335 _app.deleteSelectedRange();
338 _deleteRangeItem.addActionListener(_deleteRangeAction);
339 _deleteRangeItem.setEnabled(false);
340 rangeMenu.add(_deleteRangeItem);
341 _reverseItem = new JMenuItem(I18nManager.getText("menu.range.reverse"));
342 _reverseItem.addActionListener(new ActionListener() {
343 public void actionPerformed(ActionEvent e)
348 _reverseItem.setEnabled(false);
349 rangeMenu.add(_reverseItem);
350 _addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET);
351 _addTimeOffsetItem.setEnabled(false);
352 rangeMenu.add(_addTimeOffsetItem);
353 _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET);
354 _addAltitudeOffsetItem.setEnabled(false);
355 rangeMenu.add(_addAltitudeOffsetItem);
356 _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.range.mergetracksegments"));
357 _mergeSegmentsItem.addActionListener(new ActionListener() {
358 public void actionPerformed(ActionEvent e)
360 _app.mergeTrackSegments();
363 _mergeSegmentsItem.setEnabled(false);
364 rangeMenu.add(_mergeSegmentsItem);
365 rangeMenu.addSeparator();
366 _interpolateItem = new JMenuItem(I18nManager.getText("menu.range.interpolate"));
367 _interpolateItem.addActionListener(new ActionListener() {
368 public void actionPerformed(ActionEvent e)
370 _app.interpolateSelection();
373 _interpolateItem.setEnabled(false);
374 rangeMenu.add(_interpolateItem);
375 _averageItem = new JMenuItem(I18nManager.getText("menu.range.average"));
376 _averageItem.addActionListener(new ActionListener() {
377 public void actionPerformed(ActionEvent e)
379 _app.averageSelection();
382 _averageItem.setEnabled(false);
383 rangeMenu.add(_averageItem);
384 _cutAndMoveItem = new JMenuItem(I18nManager.getText("menu.range.cutandmove"));
385 _cutAndMoveItem.addActionListener(new ActionListener() {
386 public void actionPerformed(ActionEvent e)
388 _app.cutAndMoveSelection();
391 _cutAndMoveItem.setEnabled(false);
392 rangeMenu.add(_cutAndMoveItem);
393 _convertNamesToTimesItem = makeMenuItem(FunctionLibrary.FUNCTION_CONVERT_NAMES_TO_TIMES);
394 _convertNamesToTimesItem.setEnabled(false);
395 rangeMenu.add(_convertNamesToTimesItem);
396 menubar.add(rangeMenu);
399 JMenu pointMenu = new JMenu(I18nManager.getText("menu.point"));
400 setAltKey(pointMenu, "altkey.menu.point");
401 _editPointItem = new JMenuItem(I18nManager.getText("menu.point.editpoint"));
402 _editPointAction = new ActionListener() {
403 public void actionPerformed(ActionEvent e)
405 _app.editCurrentPoint();
408 _editPointItem.addActionListener(_editPointAction);
409 _editPointItem.setEnabled(false);
410 pointMenu.add(_editPointItem);
411 _editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME);
412 _editWaypointNameItem.setEnabled(false);
413 pointMenu.add(_editWaypointNameItem);
414 _deletePointItem = new JMenuItem(I18nManager.getText("menu.point.deletepoint"));
415 _deletePointAction = new ActionListener() {
416 public void actionPerformed(ActionEvent e)
418 _app.deleteCurrentPoint();
421 _deletePointItem.addActionListener(_deletePointAction);
422 _deletePointItem.setEnabled(false);
423 _deletePointItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
424 pointMenu.add(_deletePointItem);
425 pointMenu.addSeparator();
427 _findWaypointItem = makeMenuItem(FunctionLibrary.FUNCTION_FIND_WAYPOINT);
428 _findWaypointItem.setEnabled(false);
429 pointMenu.add(_findWaypointItem);
430 // duplicate current point
431 _duplicatePointItem = makeMenuItem(FunctionLibrary.FUNCTION_DUPLICATE_POINT);
432 _duplicatePointItem.setEnabled(false);
433 pointMenu.add(_duplicatePointItem);
434 // paste coordinates function
435 JMenuItem pasteCoordsItem = makeMenuItem(FunctionLibrary.FUNCTION_PASTE_COORDINATES);
436 pointMenu.add(pasteCoordsItem);
437 menubar.add(pointMenu);
440 JMenu viewMenu = new JMenu(I18nManager.getText("menu.view"));
441 setAltKey(viewMenu, "altkey.menu.view");
442 // Turn map display on/off
443 _mapCheckbox = new JCheckBoxMenuItem(
444 I18nManager.getText("menu.map.showmap"), false);
445 _mapCheckbox.addActionListener(new ActionListener() {
446 public void actionPerformed(ActionEvent e) {
447 Config.setConfigBoolean(Config.KEY_SHOW_MAP, _mapCheckbox.isSelected());
448 UpdateMessageBroker.informSubscribers();
451 viewMenu.add(_mapCheckbox);
452 _show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D);
453 _show3dItem.setEnabled(false);
454 viewMenu.add(_show3dItem);
456 _browserMapMenu = new JMenu(I18nManager.getText("menu.view.browser"));
457 _browserMapMenu.setEnabled(false);
458 JMenuItem googleMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.google"));
459 googleMapsItem.addActionListener(new ActionListener() {
460 public void actionPerformed(ActionEvent e)
462 _app.showExternalMap(UrlGenerator.MAP_SOURCE_GOOGLE);
465 _browserMapMenu.add(googleMapsItem);
466 JMenuItem openMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.openstreetmap"));
467 openMapsItem.addActionListener(new ActionListener() {
468 public void actionPerformed(ActionEvent e)
470 _app.showExternalMap(UrlGenerator.MAP_SOURCE_OSM);
473 _browserMapMenu.add(openMapsItem);
474 JMenuItem mapquestMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.mapquest"));
475 mapquestMapsItem.addActionListener(new ActionListener() {
476 public void actionPerformed(ActionEvent e)
478 _app.showExternalMap(UrlGenerator.MAP_SOURCE_MAPQUEST);
481 _browserMapMenu.add(mapquestMapsItem);
482 JMenuItem yahooMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.yahoo"));
483 yahooMapsItem.addActionListener(new ActionListener() {
484 public void actionPerformed(ActionEvent e)
486 _app.showExternalMap(UrlGenerator.MAP_SOURCE_YAHOO);
489 _browserMapMenu.add(yahooMapsItem);
490 JMenuItem bingMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.bing"));
491 bingMapsItem.addActionListener(new ActionListener() {
492 public void actionPerformed(ActionEvent e)
494 _app.showExternalMap(UrlGenerator.MAP_SOURCE_BING);
497 _browserMapMenu.add(bingMapsItem);
498 viewMenu.add(_browserMapMenu);
500 _chartItem = makeMenuItem(FunctionLibrary.FUNCTION_CHARTS);
501 _chartItem.setEnabled(false);
502 viewMenu.add(_chartItem);
504 _distanceItem = makeMenuItem(FunctionLibrary.FUNCTION_DISTANCES);
505 _distanceItem.setEnabled(false);
506 viewMenu.add(_distanceItem);
507 // full range details
508 _fullRangeDetailsItem = makeMenuItem(FunctionLibrary.FUNCTION_FULL_RANGE_DETAILS);
509 _fullRangeDetailsItem.setEnabled(false);
510 viewMenu.add(_fullRangeDetailsItem);
511 menubar.add(viewMenu);
514 JMenu photoMenu = new JMenu(I18nManager.getText("menu.photo"));
515 setAltKey(photoMenu, "altkey.menu.photo");
516 addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
517 addPhotosMenuItem.addActionListener(_addPhotoAction);
518 photoMenu.add(addPhotosMenuItem);
519 _saveExifItem = new JMenuItem(I18nManager.getText("menu.photo.saveexif"));
520 _saveExifItem.addActionListener(new ActionListener() {
521 public void actionPerformed(ActionEvent e)
526 _saveExifItem.setEnabled(false);
527 photoMenu.add(_saveExifItem);
528 _connectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.connect"));
529 _connectPhotoAction = new ActionListener() {
530 public void actionPerformed(ActionEvent e)
532 _app.connectPhotoToPoint();
535 _connectPhotoItem.addActionListener(_connectPhotoAction);
536 _connectPhotoItem.setEnabled(false);
537 photoMenu.addSeparator();
538 photoMenu.add(_connectPhotoItem);
540 _disconnectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.disconnect"));
541 _disconnectPhotoItem.addActionListener(new ActionListener() {
542 public void actionPerformed(ActionEvent e)
544 _app.disconnectPhotoFromPoint();
547 _disconnectPhotoItem.setEnabled(false);
548 photoMenu.add(_disconnectPhotoItem);
549 _deletePhotoItem = new JMenuItem(I18nManager.getText("menu.photo.delete"));
550 _deletePhotoItem.addActionListener(new ActionListener() {
551 public void actionPerformed(ActionEvent e)
553 _app.deleteCurrentPhoto();
556 _deletePhotoItem.setEnabled(false);
557 photoMenu.add(_deletePhotoItem);
558 // Rotate current photo
559 _rotatePhotoLeft = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_LEFT);
560 _rotatePhotoLeft.setEnabled(false);
561 photoMenu.add(_rotatePhotoLeft);
562 _rotatePhotoRight = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_RIGHT);
563 _rotatePhotoRight.setEnabled(false);
564 photoMenu.add(_rotatePhotoRight);
565 _ignoreExifThumb = makeMenuItem(FunctionLibrary.FUNCTION_IGNORE_EXIF_THUMB);
566 _ignoreExifThumb.setEnabled(false);
567 photoMenu.add(_ignoreExifThumb);
568 photoMenu.addSeparator();
569 // correlate all photos
570 _correlatePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_PHOTOS);
571 _correlatePhotosItem.setEnabled(false);
572 photoMenu.add(_correlatePhotosItem);
573 // rearrange photo points
574 _rearrangePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_REARRANGE_PHOTOS);
575 _rearrangePhotosItem.setEnabled(false);
576 photoMenu.add(_rearrangePhotosItem);
577 menubar.add(photoMenu);
580 JMenu settingsMenu = new JMenu(I18nManager.getText("menu.settings"));
581 setAltKey(settingsMenu, "altkey.menu.settings");
582 // Set the map background
583 JMenuItem mapBgItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_MAP_BG);
584 settingsMenu.add(mapBgItem);
585 _onlineCheckbox = new JCheckBoxMenuItem(I18nManager.getText("menu.settings.onlinemode"));
586 _onlineCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_ONLINE_MODE));
587 _onlineCheckbox.addActionListener(new ActionListener() {
588 public void actionPerformed(ActionEvent e) {
589 boolean isOnline = _onlineCheckbox.isSelected();
590 Config.setConfigBoolean(Config.KEY_ONLINE_MODE, isOnline);
591 if (isOnline) {UpdateMessageBroker.informSubscribers();}
594 settingsMenu.add(_onlineCheckbox);
595 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_DISK_CACHE));
596 settingsMenu.addSeparator();
597 // Set kmz image size
598 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_KMZ_IMAGE_SIZE));
600 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_PATHS));
602 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_COLOURS));
604 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_LANGUAGE));
605 settingsMenu.addSeparator();
606 // Save configuration
607 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG));
608 menubar.add(settingsMenu);
611 JMenu helpMenu = new JMenu(I18nManager.getText("menu.help"));
612 setAltKey(helpMenu, "altkey.menu.help");
613 JMenuItem helpItem = makeMenuItem(FunctionLibrary.FUNCTION_HELP);
614 setShortcut(helpItem, "shortcut.menu.help.help");
615 helpMenu.add(helpItem);
616 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SHOW_KEYS));
617 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_ABOUT));
618 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_CHECK_VERSION));
619 menubar.add(helpMenu);
625 * Convenience method for making a menu item using a function
626 * @param inFunction function
627 * @return menu item using localized name of function
629 private static JMenuItem makeMenuItem(GenericFunction inFunction)
631 JMenuItem item = new JMenuItem(I18nManager.getText(inFunction.getNameKey()));
632 item.addActionListener(new FunctionLauncher(inFunction));
637 * Set the alt key for the given menu
638 * @param inMenu menu to set
639 * @param inKey key to lookup to get language-sensitive altkey
641 private static void setAltKey(JMenu inMenu, String inKey)
643 // Lookup the key in the properties
644 String altKey = I18nManager.getText(inKey);
645 if (altKey != null && altKey.length() == 1)
647 int code = altKey.charAt(0) - 'A';
648 if (code >= 0 && code < 26)
650 // Found a valid code between A and Z
651 inMenu.setMnemonic(KEY_EVENTS[code]);
657 * Set the shortcut key for the given menu item
658 * @param inMenuItem menu item to set
659 * @param inKey key to lookup to get language-sensitive shortcut
661 private static void setShortcut(JMenuItem inMenuItem, String inKey)
663 // Lookup the key in the properties
664 String altKey = I18nManager.getText(inKey);
665 if (altKey != null && altKey.length() == 1)
667 int code = altKey.charAt(0) - 'A';
668 if (code >= 0 && code < 26)
670 // Found a valid code between A and Z
671 inMenuItem.setAccelerator(KeyStroke.getKeyStroke(KEY_EVENTS[code],
672 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
673 // use platform-specific key mask so Ctrl on Linux/Win, Clover on Mac
679 * Create a JToolBar containing all toolbar buttons
680 * @return toolbar containing buttons
682 public JToolBar createToolBar()
684 JToolBar toolbar = new JToolBar();
686 JButton openFileButton = new JButton(IconManager.getImageIcon(IconManager.OPEN_FILE));
687 openFileButton.setToolTipText(I18nManager.getText("function.open"));
688 openFileButton.addActionListener(_openFileAction);
689 toolbar.add(openFileButton);
691 JButton addPhotoButton = new JButton(IconManager.getImageIcon(IconManager.ADD_PHOTO));
692 addPhotoButton.setToolTipText(I18nManager.getText("menu.file.addphotos"));
693 addPhotoButton.addActionListener(_addPhotoAction);
694 toolbar.add(addPhotoButton);
696 _saveButton = new JButton(IconManager.getImageIcon(IconManager.SAVE_FILE));
697 _saveButton.setToolTipText(I18nManager.getText("menu.file.save"));
698 _saveButton.addActionListener(_saveAction);
699 _saveButton.setEnabled(false);
700 toolbar.add(_saveButton);
702 _undoButton = new JButton(IconManager.getImageIcon(IconManager.UNDO));
703 _undoButton.setToolTipText(I18nManager.getText("menu.track.undo"));
704 _undoButton.addActionListener(_undoAction);
705 _undoButton.setEnabled(false);
706 toolbar.add(_undoButton);
708 _editPointButton = new JButton(IconManager.getImageIcon(IconManager.EDIT_POINT));
709 _editPointButton.setToolTipText(I18nManager.getText("menu.point.editpoint"));
710 _editPointButton.addActionListener(_editPointAction);
711 _editPointButton.setEnabled(false);
712 toolbar.add(_editPointButton);
714 _deletePointButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_POINT));
715 _deletePointButton.setToolTipText(I18nManager.getText("menu.point.deletepoint"));
716 _deletePointButton.addActionListener(_deletePointAction);
717 _deletePointButton.setEnabled(false);
718 toolbar.add(_deletePointButton);
720 _deleteRangeButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_RANGE));
721 _deleteRangeButton.setToolTipText(I18nManager.getText("menu.range.deleterange"));
722 _deleteRangeButton.addActionListener(_deleteRangeAction);
723 _deleteRangeButton.setEnabled(false);
724 toolbar.add(_deleteRangeButton);
726 _selectStartButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_START));
727 _selectStartButton.setToolTipText(I18nManager.getText("menu.range.start"));
728 _selectStartButton.addActionListener(_selectStartAction);
729 _selectStartButton.setEnabled(false);
730 toolbar.add(_selectStartButton);
731 _selectEndButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_END));
732 _selectEndButton.setToolTipText(I18nManager.getText("menu.range.end"));
733 _selectEndButton.addActionListener(_selectEndAction);
734 _selectEndButton.setEnabled(false);
735 toolbar.add(_selectEndButton);
736 _connectPhotoButton = new JButton(IconManager.getImageIcon(IconManager.CONNECT_PHOTO));
737 _connectPhotoButton.setToolTipText(I18nManager.getText("menu.photo.connect"));
738 _connectPhotoButton.addActionListener(_connectPhotoAction);
739 _connectPhotoButton.setEnabled(false);
740 toolbar.add(_connectPhotoButton);
742 toolbar.setFloatable(false);
748 * Method to update menu when file loaded
750 public void informFileLoaded()
752 // save, undo, delete enabled
753 _sendGpsItem.setEnabled(true);
754 _saveItem.setEnabled(true);
755 _undoItem.setEnabled(true);
756 _compressItem.setEnabled(true);
757 _deleteMarkedPointsItem.setEnabled(false);
762 * @see tim.prune.DataSubscriber#dataUpdated(tim.prune.data.Track)
764 public void dataUpdated(byte inUpdateType)
766 boolean hasData = (_track != null && _track.getNumPoints() > 0);
767 // set functions which require data
768 _sendGpsItem.setEnabled(hasData);
769 _saveItem.setEnabled(hasData);
770 _saveButton.setEnabled(hasData);
771 _exportKmlItem.setEnabled(hasData);
772 _exportGpxItem.setEnabled(hasData);
773 _exportPovItem.setEnabled(hasData);
774 _compressItem.setEnabled(hasData);
775 _deleteMarkedPointsItem.setEnabled(hasData && _track.hasMarkedPoints());
776 _rearrangeMenu.setEnabled(hasData && _track.hasTrackPoints() && _track.hasWaypoints());
777 _selectAllItem.setEnabled(hasData);
778 _selectNoneItem.setEnabled(hasData);
779 _show3dItem.setEnabled(hasData);
780 _chartItem.setEnabled(hasData);
781 _browserMapMenu.setEnabled(hasData);
782 _distanceItem.setEnabled(hasData);
783 _getGpsiesItem.setEnabled(hasData);
784 _lookupSrtmItem.setEnabled(hasData);
785 _findWaypointItem.setEnabled(hasData && _track.hasWaypoints());
786 // is undo available?
787 boolean hasUndo = !_app.getUndoStack().isEmpty();
788 _undoItem.setEnabled(hasUndo);
789 _undoButton.setEnabled(hasUndo);
790 _clearUndoItem.setEnabled(hasUndo);
791 // is there a current point?
792 boolean hasPoint = (hasData && _selection.getCurrentPointIndex() >= 0);
793 _editPointItem.setEnabled(hasPoint);
794 _editPointButton.setEnabled(hasPoint);
795 _editWaypointNameItem.setEnabled(hasPoint);
796 _deletePointItem.setEnabled(hasPoint);
797 _deletePointButton.setEnabled(hasPoint);
798 _selectStartItem.setEnabled(hasPoint);
799 _selectStartButton.setEnabled(hasPoint);
800 _selectEndItem.setEnabled(hasPoint);
801 _selectEndButton.setEnabled(hasPoint);
802 _duplicatePointItem.setEnabled(hasPoint);
803 // are there any photos?
804 boolean anyPhotos = _photos != null && _photos.getNumPhotos() > 0;
805 _saveExifItem.setEnabled(anyPhotos);
806 // is there a current photo?
807 boolean hasPhoto = anyPhotos && _selection.getCurrentPhotoIndex() >= 0;
808 // connect is available if photo and point selected, and photo has no point
809 Photo currentPhoto = _photos.getPhoto(_selection.getCurrentPhotoIndex());
810 boolean connectAvailable = hasPhoto && hasPoint && currentPhoto != null
811 && currentPhoto.getDataPoint() == null;
812 _connectPhotoItem.setEnabled(connectAvailable);
813 _connectPhotoButton.setEnabled(connectAvailable);
814 _disconnectPhotoItem.setEnabled(hasPhoto && currentPhoto != null && currentPhoto.getDataPoint() != null);
815 _correlatePhotosItem.setEnabled(anyPhotos && hasData);
816 _rearrangePhotosItem.setEnabled(anyPhotos && hasData && _track.getNumPoints() > 1);
817 _deletePhotoItem.setEnabled(hasPhoto);
818 _rotatePhotoLeft.setEnabled(hasPhoto);
819 _rotatePhotoRight.setEnabled(hasPhoto);
820 _ignoreExifThumb.setEnabled(hasPhoto && currentPhoto != null && currentPhoto.getExifThumbnail() != null);
821 // is there a current range?
822 boolean hasRange = (hasData && _selection.hasRangeSelected());
823 _deleteRangeItem.setEnabled(hasRange);
824 _deleteRangeButton.setEnabled(hasRange);
825 _interpolateItem.setEnabled(hasRange
826 && (_selection.getEnd() - _selection.getStart()) == 1);
827 _averageItem.setEnabled(hasRange);
828 _mergeSegmentsItem.setEnabled(hasRange);
829 _reverseItem.setEnabled(hasRange);
830 _addTimeOffsetItem.setEnabled(hasRange);
831 _addAltitudeOffsetItem.setEnabled(hasRange);
832 _convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints());
833 _fullRangeDetailsItem.setEnabled(hasRange);
834 // Is the currently selected point outside the current range?
835 _cutAndMoveItem.setEnabled(hasRange && hasPoint &&
836 (_selection.getCurrentPointIndex() < _selection.getStart()
837 || _selection.getCurrentPointIndex() > (_selection.getEnd()+1)));
838 // Has the map been switched on/off?
839 boolean mapsOn = Config.getConfigBoolean(Config.KEY_SHOW_MAP);
840 if (_mapCheckbox.isSelected() != mapsOn) {
841 _mapCheckbox.setSelected(mapsOn);
847 * Ignore action completed signals
848 * @see tim.prune.DataSubscriber#actionCompleted(java.lang.String)
850 public void actionCompleted(String inMessage)