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 _exportSvgItem = null;
49 private JMenuItem _undoItem = null;
50 private JMenuItem _clearUndoItem = null;
51 private JMenuItem _editPointItem = null;
52 private JMenuItem _editWaypointNameItem = null;
53 private JMenuItem _deletePointItem = null;
54 private JMenuItem _deleteRangeItem = null;
55 private JMenuItem _compressItem = null;
56 private JMenuItem _deleteMarkedPointsItem = null;
57 private JMenuItem _interpolateItem = null;
58 private JMenuItem _averageItem = null;
59 private JMenuItem _selectAllItem = null;
60 private JMenuItem _selectNoneItem = null;
61 private JMenuItem _selectStartItem = null;
62 private JMenuItem _selectEndItem = null;
63 private JMenuItem _findWaypointItem = null;
64 private JMenuItem _duplicatePointItem = null;
65 private JMenuItem _reverseItem = null;
66 private JMenuItem _addTimeOffsetItem = null;
67 private JMenuItem _addAltitudeOffsetItem = null;
68 private JMenuItem _mergeSegmentsItem = null;
69 private JMenu _rearrangeMenu = null;
70 private JMenuItem _cutAndMoveItem = null;
71 private JMenuItem _convertNamesToTimesItem = null;
72 private JMenuItem _deleteFieldValuesItem = null;
73 private JCheckBoxMenuItem _mapCheckbox = null;
74 private JMenuItem _show3dItem = null;
75 private JMenu _browserMapMenu = null;
76 private JMenuItem _chartItem = null;
77 private JMenuItem _getGpsiesItem = null;
78 private JMenuItem _uploadGpsiesItem = null;
79 private JMenuItem _lookupSrtmItem = null;
80 private JMenuItem _distanceItem = null;
81 private JMenuItem _fullRangeDetailsItem = null;
82 private JMenuItem _saveExifItem = null;
83 private JMenuItem _connectPhotoItem = null;
84 private JMenuItem _deletePhotoItem = null;
85 private JMenuItem _disconnectPhotoItem = null;
86 private JMenuItem _correlatePhotosItem = null;
87 private JMenuItem _rearrangePhotosItem = null;
88 private JMenuItem _rotatePhotoLeft = null;
89 private JMenuItem _rotatePhotoRight = null;
90 private JMenuItem _ignoreExifThumb = null;
91 private JCheckBoxMenuItem _onlineCheckbox = null;
93 // ActionListeners for reuse by menu and toolbar
94 private ActionListener _openFileAction = null;
95 private ActionListener _addPhotoAction = null;
96 private ActionListener _saveAction = null;
97 private ActionListener _undoAction = null;
98 private ActionListener _editPointAction = null;
99 private ActionListener _deletePointAction = null;
100 private ActionListener _deleteRangeAction = null;
101 private ActionListener _selectStartAction = null;
102 private ActionListener _selectEndAction = null;
103 private ActionListener _connectPhotoAction = null;
105 // Toolbar buttons which need enabling/disabling
106 private JButton _saveButton = null;
107 private JButton _undoButton = null;
108 private JButton _editPointButton = null;
109 private JButton _deletePointButton = null;
110 private JButton _deleteRangeButton = null;
111 private JButton _selectStartButton = null;
112 private JButton _selectEndButton = null;
113 private JButton _connectPhotoButton = null;
115 /** Array of key events */
116 private static final int[] KEY_EVENTS = {
117 KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.VK_C, KeyEvent.VK_D, KeyEvent.VK_E,
118 KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, KeyEvent.VK_I, KeyEvent.VK_J,
119 KeyEvent.VK_K, KeyEvent.VK_L, KeyEvent.VK_M, KeyEvent.VK_N, KeyEvent.VK_O,
120 KeyEvent.VK_P, KeyEvent.VK_Q, KeyEvent.VK_R, KeyEvent.VK_S, KeyEvent.VK_T,
121 KeyEvent.VK_U, KeyEvent.VK_V, KeyEvent.VK_W, KeyEvent.VK_X, KeyEvent.VK_Y, KeyEvent.VK_Z};
126 * @param inApp application to call on menu actions
127 * @param inTrackInfo track info object
129 public MenuManager(App inApp, TrackInfo inTrackInfo)
132 _track = inTrackInfo.getTrack();
133 _selection = inTrackInfo.getSelection();
134 _photos = inTrackInfo.getPhotoList();
139 * Create a JMenuBar containing all menu items
142 public JMenuBar createMenuBar()
144 JMenuBar menubar = new JMenuBar();
145 JMenu fileMenu = new JMenu(I18nManager.getText("menu.file"));
146 setAltKey(fileMenu, "altkey.menu.file");
148 JMenuItem openMenuItem = new JMenuItem(I18nManager.getText("function.open"));
149 setShortcut(openMenuItem, "shortcut.menu.file.open");
150 _openFileAction = new ActionListener() {
151 public void actionPerformed(ActionEvent e)
156 openMenuItem.addActionListener(_openFileAction);
157 fileMenu.add(openMenuItem);
159 JMenuItem addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
160 _addPhotoAction = new ActionListener() {
161 public void actionPerformed(ActionEvent e)
166 addPhotosMenuItem.addActionListener(_addPhotoAction);
167 fileMenu.add(addPhotosMenuItem);
168 fileMenu.addSeparator();
170 JMenuItem loadFromGpsMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSLOAD);
171 setShortcut(loadFromGpsMenuItem, "shortcut.menu.file.load");
172 fileMenu.add(loadFromGpsMenuItem);
174 _sendGpsItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSSAVE);
175 _sendGpsItem.setEnabled(false);
176 fileMenu.add(_sendGpsItem);
177 fileMenu.addSeparator();
179 _saveItem = new JMenuItem(I18nManager.getText("menu.file.save"), KeyEvent.VK_S);
180 setShortcut(_saveItem, "shortcut.menu.file.save");
181 _saveAction = new ActionListener() {
182 public void actionPerformed(ActionEvent e)
187 _saveItem.addActionListener(_saveAction);
188 _saveItem.setEnabled(false);
189 fileMenu.add(_saveItem);
191 _exportKmlItem = makeMenuItem(FunctionLibrary.FUNCTION_KMLEXPORT);
192 _exportKmlItem.setEnabled(false);
193 fileMenu.add(_exportKmlItem);
195 _exportGpxItem = makeMenuItem(FunctionLibrary.FUNCTION_GPXEXPORT);
196 _exportGpxItem.setEnabled(false);
197 fileMenu.add(_exportGpxItem);
199 _exportPovItem = makeMenuItem(FunctionLibrary.FUNCTION_POVEXPORT);
200 _exportPovItem.setEnabled(false);
201 fileMenu.add(_exportPovItem);
203 _exportSvgItem = makeMenuItem(FunctionLibrary.FUNCTION_SVGEXPORT);
204 _exportSvgItem.setEnabled(false);
205 fileMenu.add(_exportSvgItem);
206 fileMenu.addSeparator();
207 JMenuItem exitMenuItem = new JMenuItem(I18nManager.getText("menu.file.exit"));
208 exitMenuItem.addActionListener(new ActionListener() {
209 public void actionPerformed(ActionEvent e)
214 fileMenu.add(exitMenuItem);
215 menubar.add(fileMenu);
217 JMenu trackMenu = new JMenu(I18nManager.getText("menu.track"));
218 setAltKey(trackMenu, "altkey.menu.track");
219 _undoItem = new JMenuItem(I18nManager.getText("menu.track.undo"));
220 setShortcut(_undoItem, "shortcut.menu.track.undo");
221 _undoAction = new ActionListener() {
222 public void actionPerformed(ActionEvent e)
227 _undoItem.addActionListener(_undoAction);
228 _undoItem.setEnabled(false);
229 trackMenu.add(_undoItem);
230 _clearUndoItem = new JMenuItem(I18nManager.getText("menu.track.clearundo"));
231 _clearUndoItem.addActionListener(new ActionListener() {
232 public void actionPerformed(ActionEvent e)
237 _clearUndoItem.setEnabled(false);
238 trackMenu.add(_clearUndoItem);
239 trackMenu.addSeparator();
240 _compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS);
241 setShortcut(_compressItem, "shortcut.menu.edit.compress");
242 _compressItem.setEnabled(false);
243 trackMenu.add(_compressItem);
244 _deleteMarkedPointsItem = new JMenuItem(I18nManager.getText("menu.track.deletemarked"));
245 _deleteMarkedPointsItem.addActionListener(new ActionListener() {
246 public void actionPerformed(ActionEvent e)
248 _app.finishCompressTrack();
251 _deleteMarkedPointsItem.setEnabled(false);
252 trackMenu.add(_deleteMarkedPointsItem);
253 trackMenu.addSeparator();
254 // Rearrange waypoints
255 _rearrangeMenu = new JMenu(I18nManager.getText("menu.track.rearrange"));
256 _rearrangeMenu.setEnabled(false);
257 JMenuItem rearrangeStartItem = new JMenuItem(I18nManager.getText("menu.track.rearrange.start"));
258 rearrangeStartItem.addActionListener(new ActionListener() {
259 public void actionPerformed(ActionEvent e)
261 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_START);
264 rearrangeStartItem.setEnabled(true);
265 _rearrangeMenu.add(rearrangeStartItem);
266 JMenuItem rearrangeEndItem = new JMenuItem(I18nManager.getText("menu.track.rearrange.end"));
267 rearrangeEndItem.addActionListener(new ActionListener() {
268 public void actionPerformed(ActionEvent e)
270 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_END);
273 rearrangeEndItem.setEnabled(true);
274 _rearrangeMenu.add(rearrangeEndItem);
275 JMenuItem rearrangeNearestItem = new JMenuItem(I18nManager.getText("menu.track.rearrange.nearest"));
276 rearrangeNearestItem.addActionListener(new ActionListener() {
277 public void actionPerformed(ActionEvent e)
279 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_NEAREST);
282 rearrangeNearestItem.setEnabled(true);
283 _rearrangeMenu.add(rearrangeNearestItem);
284 trackMenu.add(_rearrangeMenu);
286 _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES);
287 _getGpsiesItem.setEnabled(false);
288 trackMenu.add(_getGpsiesItem);
290 _uploadGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_UPLOAD_GPSIES);
291 _uploadGpsiesItem.setEnabled(false);
292 trackMenu.add(_uploadGpsiesItem);
293 _lookupSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_LOOKUP_SRTM);
294 _lookupSrtmItem.setEnabled(false);
295 trackMenu.add(_lookupSrtmItem);
296 menubar.add(trackMenu);
299 JMenu rangeMenu = new JMenu(I18nManager.getText("menu.range"));
300 setAltKey(rangeMenu, "altkey.menu.range");
301 _selectAllItem = new JMenuItem(I18nManager.getText("menu.range.all"));
302 setShortcut(_selectAllItem, "shortcut.menu.range.all");
303 _selectAllItem.setEnabled(false);
304 _selectAllItem.addActionListener(new ActionListener() {
305 public void actionPerformed(ActionEvent e)
307 _selection.selectRange(0, _track.getNumPoints()-1);
310 rangeMenu.add(_selectAllItem);
311 _selectNoneItem = new JMenuItem(I18nManager.getText("menu.range.none"));
312 _selectNoneItem.setEnabled(false);
313 _selectNoneItem.addActionListener(new ActionListener() {
314 public void actionPerformed(ActionEvent e)
319 rangeMenu.add(_selectNoneItem);
320 rangeMenu.addSeparator();
321 _selectStartItem = new JMenuItem(I18nManager.getText("menu.range.start"));
322 _selectStartItem.setEnabled(false);
323 _selectStartAction = new ActionListener() {
324 public void actionPerformed(ActionEvent e)
326 _selection.selectRangeStart();
329 _selectStartItem.addActionListener(_selectStartAction);
330 rangeMenu.add(_selectStartItem);
331 _selectEndItem = new JMenuItem(I18nManager.getText("menu.range.end"));
332 _selectEndItem.setEnabled(false);
333 _selectEndAction = new ActionListener() {
334 public void actionPerformed(ActionEvent e)
336 _selection.selectRangeEnd();
339 _selectEndItem.addActionListener(_selectEndAction);
340 rangeMenu.add(_selectEndItem);
341 rangeMenu.addSeparator();
342 _deleteRangeItem = new JMenuItem(I18nManager.getText("menu.range.deleterange"));
343 _deleteRangeAction = new ActionListener() {
344 public void actionPerformed(ActionEvent e)
346 _app.deleteSelectedRange();
349 _deleteRangeItem.addActionListener(_deleteRangeAction);
350 _deleteRangeItem.setEnabled(false);
351 rangeMenu.add(_deleteRangeItem);
352 _reverseItem = new JMenuItem(I18nManager.getText("menu.range.reverse"));
353 _reverseItem.addActionListener(new ActionListener() {
354 public void actionPerformed(ActionEvent e)
359 _reverseItem.setEnabled(false);
360 rangeMenu.add(_reverseItem);
361 _addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET);
362 _addTimeOffsetItem.setEnabled(false);
363 rangeMenu.add(_addTimeOffsetItem);
364 _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET);
365 _addAltitudeOffsetItem.setEnabled(false);
366 rangeMenu.add(_addAltitudeOffsetItem);
367 _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.range.mergetracksegments"));
368 _mergeSegmentsItem.addActionListener(new ActionListener() {
369 public void actionPerformed(ActionEvent e)
371 _app.mergeTrackSegments();
374 _mergeSegmentsItem.setEnabled(false);
375 rangeMenu.add(_mergeSegmentsItem);
376 _deleteFieldValuesItem = makeMenuItem(FunctionLibrary.FUNCTION_DELETE_FIELD_VALUES);
377 _deleteFieldValuesItem.setEnabled(false);
378 rangeMenu.add(_deleteFieldValuesItem);
379 rangeMenu.addSeparator();
380 _interpolateItem = new JMenuItem(I18nManager.getText("menu.range.interpolate"));
381 _interpolateItem.addActionListener(new ActionListener() {
382 public void actionPerformed(ActionEvent e)
384 _app.interpolateSelection();
387 _interpolateItem.setEnabled(false);
388 rangeMenu.add(_interpolateItem);
389 _averageItem = new JMenuItem(I18nManager.getText("menu.range.average"));
390 _averageItem.addActionListener(new ActionListener() {
391 public void actionPerformed(ActionEvent e)
393 _app.averageSelection();
396 _averageItem.setEnabled(false);
397 rangeMenu.add(_averageItem);
398 _cutAndMoveItem = new JMenuItem(I18nManager.getText("menu.range.cutandmove"));
399 _cutAndMoveItem.addActionListener(new ActionListener() {
400 public void actionPerformed(ActionEvent e)
402 _app.cutAndMoveSelection();
405 _cutAndMoveItem.setEnabled(false);
406 rangeMenu.add(_cutAndMoveItem);
407 _convertNamesToTimesItem = makeMenuItem(FunctionLibrary.FUNCTION_CONVERT_NAMES_TO_TIMES);
408 _convertNamesToTimesItem.setEnabled(false);
409 rangeMenu.add(_convertNamesToTimesItem);
410 menubar.add(rangeMenu);
413 JMenu pointMenu = new JMenu(I18nManager.getText("menu.point"));
414 setAltKey(pointMenu, "altkey.menu.point");
415 _editPointItem = new JMenuItem(I18nManager.getText("menu.point.editpoint"));
416 _editPointAction = new ActionListener() {
417 public void actionPerformed(ActionEvent e)
419 _app.editCurrentPoint();
422 _editPointItem.addActionListener(_editPointAction);
423 _editPointItem.setEnabled(false);
424 pointMenu.add(_editPointItem);
425 _editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME);
426 _editWaypointNameItem.setEnabled(false);
427 pointMenu.add(_editWaypointNameItem);
428 _deletePointItem = new JMenuItem(I18nManager.getText("menu.point.deletepoint"));
429 _deletePointAction = new ActionListener() {
430 public void actionPerformed(ActionEvent e)
432 _app.deleteCurrentPoint();
435 _deletePointItem.addActionListener(_deletePointAction);
436 _deletePointItem.setEnabled(false);
437 _deletePointItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
438 pointMenu.add(_deletePointItem);
439 pointMenu.addSeparator();
441 _findWaypointItem = makeMenuItem(FunctionLibrary.FUNCTION_FIND_WAYPOINT);
442 _findWaypointItem.setEnabled(false);
443 pointMenu.add(_findWaypointItem);
444 // duplicate current point
445 _duplicatePointItem = makeMenuItem(FunctionLibrary.FUNCTION_DUPLICATE_POINT);
446 _duplicatePointItem.setEnabled(false);
447 pointMenu.add(_duplicatePointItem);
448 // paste coordinates function
449 JMenuItem pasteCoordsItem = makeMenuItem(FunctionLibrary.FUNCTION_PASTE_COORDINATES);
450 pointMenu.add(pasteCoordsItem);
451 menubar.add(pointMenu);
454 JMenu viewMenu = new JMenu(I18nManager.getText("menu.view"));
455 setAltKey(viewMenu, "altkey.menu.view");
456 // Turn map display on/off
457 _mapCheckbox = new JCheckBoxMenuItem(
458 I18nManager.getText("menu.map.showmap"), false);
459 _mapCheckbox.addActionListener(new ActionListener() {
460 public void actionPerformed(ActionEvent e) {
461 Config.setConfigBoolean(Config.KEY_SHOW_MAP, _mapCheckbox.isSelected());
462 UpdateMessageBroker.informSubscribers();
465 viewMenu.add(_mapCheckbox);
466 // Turn off the sidebars
467 JCheckBoxMenuItem sidebarsCheckbox = new JCheckBoxMenuItem(I18nManager.getText("menu.view.showsidebars"));
468 sidebarsCheckbox.setSelected(true);
469 sidebarsCheckbox.addActionListener(new ActionListener() {
470 public void actionPerformed(ActionEvent e) {
471 _app.toggleSidebars();
474 viewMenu.add(sidebarsCheckbox);
476 _show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D);
477 _show3dItem.setEnabled(false);
478 viewMenu.add(_show3dItem);
480 _browserMapMenu = new JMenu(I18nManager.getText("menu.view.browser"));
481 _browserMapMenu.setEnabled(false);
482 JMenuItem googleMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.google"));
483 googleMapsItem.addActionListener(new ActionListener() {
484 public void actionPerformed(ActionEvent e)
486 _app.showExternalMap(UrlGenerator.MAP_SOURCE_GOOGLE);
489 _browserMapMenu.add(googleMapsItem);
490 JMenuItem openMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.openstreetmap"));
491 openMapsItem.addActionListener(new ActionListener() {
492 public void actionPerformed(ActionEvent e)
494 _app.showExternalMap(UrlGenerator.MAP_SOURCE_OSM);
497 _browserMapMenu.add(openMapsItem);
498 JMenuItem mapquestMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.mapquest"));
499 mapquestMapsItem.addActionListener(new ActionListener() {
500 public void actionPerformed(ActionEvent e)
502 _app.showExternalMap(UrlGenerator.MAP_SOURCE_MAPQUEST);
505 _browserMapMenu.add(mapquestMapsItem);
506 JMenuItem yahooMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.yahoo"));
507 yahooMapsItem.addActionListener(new ActionListener() {
508 public void actionPerformed(ActionEvent e)
510 _app.showExternalMap(UrlGenerator.MAP_SOURCE_YAHOO);
513 _browserMapMenu.add(yahooMapsItem);
514 JMenuItem bingMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.bing"));
515 bingMapsItem.addActionListener(new ActionListener() {
516 public void actionPerformed(ActionEvent e)
518 _app.showExternalMap(UrlGenerator.MAP_SOURCE_BING);
521 _browserMapMenu.add(bingMapsItem);
522 viewMenu.add(_browserMapMenu);
524 _chartItem = makeMenuItem(FunctionLibrary.FUNCTION_CHARTS);
525 _chartItem.setEnabled(false);
526 viewMenu.add(_chartItem);
528 _distanceItem = makeMenuItem(FunctionLibrary.FUNCTION_DISTANCES);
529 _distanceItem.setEnabled(false);
530 viewMenu.add(_distanceItem);
531 // full range details
532 _fullRangeDetailsItem = makeMenuItem(FunctionLibrary.FUNCTION_FULL_RANGE_DETAILS);
533 _fullRangeDetailsItem.setEnabled(false);
534 viewMenu.add(_fullRangeDetailsItem);
535 menubar.add(viewMenu);
538 JMenu photoMenu = new JMenu(I18nManager.getText("menu.photo"));
539 setAltKey(photoMenu, "altkey.menu.photo");
540 addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
541 addPhotosMenuItem.addActionListener(_addPhotoAction);
542 photoMenu.add(addPhotosMenuItem);
543 _saveExifItem = new JMenuItem(I18nManager.getText("menu.photo.saveexif"));
544 _saveExifItem.addActionListener(new ActionListener() {
545 public void actionPerformed(ActionEvent e)
550 _saveExifItem.setEnabled(false);
551 photoMenu.add(_saveExifItem);
552 _connectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.connect"));
553 _connectPhotoAction = new ActionListener() {
554 public void actionPerformed(ActionEvent e)
556 _app.connectPhotoToPoint();
559 _connectPhotoItem.addActionListener(_connectPhotoAction);
560 _connectPhotoItem.setEnabled(false);
561 photoMenu.addSeparator();
562 photoMenu.add(_connectPhotoItem);
564 _disconnectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.disconnect"));
565 _disconnectPhotoItem.addActionListener(new ActionListener() {
566 public void actionPerformed(ActionEvent e)
568 _app.disconnectPhotoFromPoint();
571 _disconnectPhotoItem.setEnabled(false);
572 photoMenu.add(_disconnectPhotoItem);
573 _deletePhotoItem = new JMenuItem(I18nManager.getText("menu.photo.delete"));
574 _deletePhotoItem.addActionListener(new ActionListener() {
575 public void actionPerformed(ActionEvent e)
577 _app.deleteCurrentPhoto();
580 _deletePhotoItem.setEnabled(false);
581 photoMenu.add(_deletePhotoItem);
582 // Rotate current photo
583 _rotatePhotoLeft = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_LEFT);
584 _rotatePhotoLeft.setEnabled(false);
585 photoMenu.add(_rotatePhotoLeft);
586 _rotatePhotoRight = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_RIGHT);
587 _rotatePhotoRight.setEnabled(false);
588 photoMenu.add(_rotatePhotoRight);
589 _ignoreExifThumb = makeMenuItem(FunctionLibrary.FUNCTION_IGNORE_EXIF_THUMB);
590 _ignoreExifThumb.setEnabled(false);
591 photoMenu.add(_ignoreExifThumb);
592 photoMenu.addSeparator();
593 // correlate all photos
594 _correlatePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_PHOTOS);
595 _correlatePhotosItem.setEnabled(false);
596 photoMenu.add(_correlatePhotosItem);
597 // rearrange photo points
598 _rearrangePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_REARRANGE_PHOTOS);
599 _rearrangePhotosItem.setEnabled(false);
600 photoMenu.add(_rearrangePhotosItem);
601 menubar.add(photoMenu);
604 JMenu settingsMenu = new JMenu(I18nManager.getText("menu.settings"));
605 setAltKey(settingsMenu, "altkey.menu.settings");
606 // Set the map background
607 JMenuItem mapBgItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_MAP_BG);
608 settingsMenu.add(mapBgItem);
609 _onlineCheckbox = new JCheckBoxMenuItem(I18nManager.getText("menu.settings.onlinemode"));
610 _onlineCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_ONLINE_MODE));
611 _onlineCheckbox.addActionListener(new ActionListener() {
612 public void actionPerformed(ActionEvent e) {
613 boolean isOnline = _onlineCheckbox.isSelected();
614 Config.setConfigBoolean(Config.KEY_ONLINE_MODE, isOnline);
615 if (isOnline) {UpdateMessageBroker.informSubscribers();}
618 settingsMenu.add(_onlineCheckbox);
619 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_DISK_CACHE));
620 settingsMenu.addSeparator();
621 // Set kmz image size
622 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_KMZ_IMAGE_SIZE));
624 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_PATHS));
626 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_COLOURS));
628 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_LANGUAGE));
629 settingsMenu.addSeparator();
630 // Save configuration
631 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG));
632 menubar.add(settingsMenu);
635 JMenu helpMenu = new JMenu(I18nManager.getText("menu.help"));
636 setAltKey(helpMenu, "altkey.menu.help");
637 JMenuItem helpItem = makeMenuItem(FunctionLibrary.FUNCTION_HELP);
638 setShortcut(helpItem, "shortcut.menu.help.help");
639 helpMenu.add(helpItem);
640 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SHOW_KEYS));
641 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_ABOUT));
642 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_CHECK_VERSION));
643 menubar.add(helpMenu);
649 * Convenience method for making a menu item using a function
650 * @param inFunction function
651 * @return menu item using localized name of function
653 private static JMenuItem makeMenuItem(GenericFunction inFunction)
655 JMenuItem item = new JMenuItem(I18nManager.getText(inFunction.getNameKey()));
656 item.addActionListener(new FunctionLauncher(inFunction));
661 * Set the alt key for the given menu
662 * @param inMenu menu to set
663 * @param inKey key to lookup to get language-sensitive altkey
665 private static void setAltKey(JMenu inMenu, String inKey)
667 // Lookup the key in the properties
668 String altKey = I18nManager.getText(inKey);
669 if (altKey != null && altKey.length() == 1)
671 int code = altKey.charAt(0) - 'A';
672 if (code >= 0 && code < 26)
674 // Found a valid code between A and Z
675 inMenu.setMnemonic(KEY_EVENTS[code]);
681 * Set the shortcut key for the given menu item
682 * @param inMenuItem menu item to set
683 * @param inKey key to lookup to get language-sensitive shortcut
685 private static void setShortcut(JMenuItem inMenuItem, String inKey)
687 // Lookup the key in the properties
688 String altKey = I18nManager.getText(inKey);
689 if (altKey != null && altKey.length() == 1)
691 int code = altKey.charAt(0) - 'A';
692 if (code >= 0 && code < 26)
694 // Found a valid code between A and Z
695 inMenuItem.setAccelerator(KeyStroke.getKeyStroke(KEY_EVENTS[code],
696 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
697 // use platform-specific key mask so Ctrl on Linux/Win, Clover on Mac
703 * Create a JToolBar containing all toolbar buttons
704 * @return toolbar containing buttons
706 public JToolBar createToolBar()
708 JToolBar toolbar = new JToolBar();
710 JButton openFileButton = new JButton(IconManager.getImageIcon(IconManager.OPEN_FILE));
711 openFileButton.setToolTipText(I18nManager.getText("function.open"));
712 openFileButton.addActionListener(_openFileAction);
713 toolbar.add(openFileButton);
715 JButton addPhotoButton = new JButton(IconManager.getImageIcon(IconManager.ADD_PHOTO));
716 addPhotoButton.setToolTipText(I18nManager.getText("menu.file.addphotos"));
717 addPhotoButton.addActionListener(_addPhotoAction);
718 toolbar.add(addPhotoButton);
720 _saveButton = new JButton(IconManager.getImageIcon(IconManager.SAVE_FILE));
721 _saveButton.setToolTipText(I18nManager.getText("menu.file.save"));
722 _saveButton.addActionListener(_saveAction);
723 _saveButton.setEnabled(false);
724 toolbar.add(_saveButton);
726 _undoButton = new JButton(IconManager.getImageIcon(IconManager.UNDO));
727 _undoButton.setToolTipText(I18nManager.getText("menu.track.undo"));
728 _undoButton.addActionListener(_undoAction);
729 _undoButton.setEnabled(false);
730 toolbar.add(_undoButton);
732 _editPointButton = new JButton(IconManager.getImageIcon(IconManager.EDIT_POINT));
733 _editPointButton.setToolTipText(I18nManager.getText("menu.point.editpoint"));
734 _editPointButton.addActionListener(_editPointAction);
735 _editPointButton.setEnabled(false);
736 toolbar.add(_editPointButton);
738 _deletePointButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_POINT));
739 _deletePointButton.setToolTipText(I18nManager.getText("menu.point.deletepoint"));
740 _deletePointButton.addActionListener(_deletePointAction);
741 _deletePointButton.setEnabled(false);
742 toolbar.add(_deletePointButton);
744 _deleteRangeButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_RANGE));
745 _deleteRangeButton.setToolTipText(I18nManager.getText("menu.range.deleterange"));
746 _deleteRangeButton.addActionListener(_deleteRangeAction);
747 _deleteRangeButton.setEnabled(false);
748 toolbar.add(_deleteRangeButton);
750 _selectStartButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_START));
751 _selectStartButton.setToolTipText(I18nManager.getText("menu.range.start"));
752 _selectStartButton.addActionListener(_selectStartAction);
753 _selectStartButton.setEnabled(false);
754 toolbar.add(_selectStartButton);
755 _selectEndButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_END));
756 _selectEndButton.setToolTipText(I18nManager.getText("menu.range.end"));
757 _selectEndButton.addActionListener(_selectEndAction);
758 _selectEndButton.setEnabled(false);
759 toolbar.add(_selectEndButton);
760 _connectPhotoButton = new JButton(IconManager.getImageIcon(IconManager.CONNECT_PHOTO));
761 _connectPhotoButton.setToolTipText(I18nManager.getText("menu.photo.connect"));
762 _connectPhotoButton.addActionListener(_connectPhotoAction);
763 _connectPhotoButton.setEnabled(false);
764 toolbar.add(_connectPhotoButton);
766 toolbar.setFloatable(false);
772 * Method to update menu when file loaded
774 public void informFileLoaded()
776 // save, undo, delete enabled
777 _sendGpsItem.setEnabled(true);
778 _saveItem.setEnabled(true);
779 _undoItem.setEnabled(true);
780 _compressItem.setEnabled(true);
781 _deleteMarkedPointsItem.setEnabled(false);
786 * @see tim.prune.DataSubscriber#dataUpdated(tim.prune.data.Track)
788 public void dataUpdated(byte inUpdateType)
790 boolean hasData = (_track != null && _track.getNumPoints() > 0);
791 // set functions which require data
792 _sendGpsItem.setEnabled(hasData);
793 _saveItem.setEnabled(hasData);
794 _saveButton.setEnabled(hasData);
795 _exportKmlItem.setEnabled(hasData);
796 _exportGpxItem.setEnabled(hasData);
797 _exportPovItem.setEnabled(hasData);
798 _exportSvgItem.setEnabled(hasData);
799 _compressItem.setEnabled(hasData);
800 _deleteMarkedPointsItem.setEnabled(hasData && _track.hasMarkedPoints());
801 _rearrangeMenu.setEnabled(hasData && _track.hasTrackPoints() && _track.hasWaypoints());
802 _selectAllItem.setEnabled(hasData);
803 _selectNoneItem.setEnabled(hasData);
804 _show3dItem.setEnabled(hasData);
805 _chartItem.setEnabled(hasData);
806 _browserMapMenu.setEnabled(hasData);
807 _distanceItem.setEnabled(hasData);
808 _getGpsiesItem.setEnabled(hasData);
809 _uploadGpsiesItem.setEnabled(hasData && _track.hasTrackPoints());
810 _lookupSrtmItem.setEnabled(hasData);
811 _findWaypointItem.setEnabled(hasData && _track.hasWaypoints());
812 // is undo available?
813 boolean hasUndo = !_app.getUndoStack().isEmpty();
814 _undoItem.setEnabled(hasUndo);
815 _undoButton.setEnabled(hasUndo);
816 _clearUndoItem.setEnabled(hasUndo);
817 // is there a current point?
818 boolean hasPoint = (hasData && _selection.getCurrentPointIndex() >= 0);
819 _editPointItem.setEnabled(hasPoint);
820 _editPointButton.setEnabled(hasPoint);
821 _editWaypointNameItem.setEnabled(hasPoint);
822 _deletePointItem.setEnabled(hasPoint);
823 _deletePointButton.setEnabled(hasPoint);
824 _selectStartItem.setEnabled(hasPoint);
825 _selectStartButton.setEnabled(hasPoint);
826 _selectEndItem.setEnabled(hasPoint);
827 _selectEndButton.setEnabled(hasPoint);
828 _duplicatePointItem.setEnabled(hasPoint);
829 // are there any photos?
830 boolean anyPhotos = _photos != null && _photos.getNumPhotos() > 0;
831 _saveExifItem.setEnabled(anyPhotos);
832 // is there a current photo?
833 boolean hasPhoto = anyPhotos && _selection.getCurrentPhotoIndex() >= 0;
834 // connect is available if photo and point selected, and photo has no point
835 Photo currentPhoto = _photos.getPhoto(_selection.getCurrentPhotoIndex());
836 boolean connectAvailable = hasPhoto && hasPoint && currentPhoto != null
837 && currentPhoto.getDataPoint() == null;
838 _connectPhotoItem.setEnabled(connectAvailable);
839 _connectPhotoButton.setEnabled(connectAvailable);
840 _disconnectPhotoItem.setEnabled(hasPhoto && currentPhoto != null && currentPhoto.getDataPoint() != null);
841 _correlatePhotosItem.setEnabled(anyPhotos && hasData);
842 _rearrangePhotosItem.setEnabled(anyPhotos && hasData && _track.getNumPoints() > 1);
843 _deletePhotoItem.setEnabled(hasPhoto);
844 _rotatePhotoLeft.setEnabled(hasPhoto);
845 _rotatePhotoRight.setEnabled(hasPhoto);
846 _ignoreExifThumb.setEnabled(hasPhoto && currentPhoto != null && currentPhoto.getExifThumbnail() != null);
847 // is there a current range?
848 boolean hasRange = (hasData && _selection.hasRangeSelected());
849 _deleteRangeItem.setEnabled(hasRange);
850 _deleteRangeButton.setEnabled(hasRange);
851 _interpolateItem.setEnabled(hasRange
852 && (_selection.getEnd() - _selection.getStart()) == 1);
853 _averageItem.setEnabled(hasRange);
854 _mergeSegmentsItem.setEnabled(hasRange);
855 _reverseItem.setEnabled(hasRange);
856 _addTimeOffsetItem.setEnabled(hasRange);
857 _addAltitudeOffsetItem.setEnabled(hasRange);
858 _convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints());
859 _deleteFieldValuesItem.setEnabled(hasRange);
860 _fullRangeDetailsItem.setEnabled(hasRange);
861 // Is the currently selected point outside the current range?
862 _cutAndMoveItem.setEnabled(hasRange && hasPoint &&
863 (_selection.getCurrentPointIndex() < _selection.getStart()
864 || _selection.getCurrentPointIndex() > (_selection.getEnd()+1)));
865 // Has the map been switched on/off?
866 boolean mapsOn = Config.getConfigBoolean(Config.KEY_SHOW_MAP);
867 if (_mapCheckbox.isSelected() != mapsOn) {
868 _mapCheckbox.setSelected(mapsOn);
874 * Ignore action completed signals
875 * @see tim.prune.DataSubscriber#actionCompleted(java.lang.String)
877 public void actionCompleted(String inMessage)