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.AudioClip;
24 import tim.prune.data.DataPoint;
25 import tim.prune.data.Field;
26 import tim.prune.data.Photo;
27 import tim.prune.data.RecentFile;
28 import tim.prune.data.RecentFileList;
29 import tim.prune.data.Selection;
30 import tim.prune.data.Track;
31 import tim.prune.data.TrackInfo;
32 import tim.prune.function.ChooseSingleParameter;
33 import tim.prune.function.SearchOpenCachingDeFunction;
34 import tim.prune.function.browser.UrlGenerator;
35 import tim.prune.function.browser.WebMapFunction;
36 import tim.prune.function.search.SearchMapillaryFunction;
37 import tim.prune.function.srtm.DownloadSrtmFunction;
38 import tim.prune.function.srtm.SrtmGl1Source;
39 import tim.prune.function.srtm.Srtm3Source;
40 import tim.prune.function.srtm.SrtmViewfinderSource;
43 * Class to manage the menu bar and tool bar,
44 * including enabling and disabling the items
46 public class MenuManager implements DataSubscriber
48 private App _app = null;
49 private Track _track = null;
50 private Selection _selection = null;
52 // Menu items which need enabling/disabling
53 private JMenuItem _sendGpsItem = null;
54 private JMenuItem _saveItem = null;
55 private JMenuItem _exportKmlItem = null;
56 private JMenuItem _exportGpxItem = null;
57 private JMenuItem _exportPovItem = null;
58 private JMenuItem _exportImageItem = null;
59 private JMenu _recentFileMenu = null;
60 private JMenuItem _undoItem = null;
61 private JMenuItem _clearUndoItem = null;
62 private JMenuItem _editPointItem = null;
63 private JMenuItem _editWaypointNameItem = null;
64 private JMenuItem _deletePointItem = null;
65 private JMenuItem _deleteRangeItem = null;
66 private JMenuItem _cropTrackItem = null;
67 private JMenuItem _compressItem = null;
68 private JMenuItem _markRectangleItem = null;
69 private JMenuItem _markUphillLiftsItem = null;
70 private JMenuItem _deleteMarkedPointsItem = null;
71 private JMenuItem _deleteByDateItem = null;
72 private JMenuItem _interpolateItem = null;
73 private JMenuItem _averageItem = null;
74 private JMenuItem _selectAllItem = null;
75 private JMenuItem _selectNoneItem = null;
76 private JMenuItem _selectSegmentItem = null;
77 private JMenuItem _selectStartItem = null;
78 private JMenuItem _selectEndItem = null;
79 private JMenuItem _findWaypointItem = null;
80 private JMenuItem _duplicatePointItem = null;
81 private JMenuItem _reverseItem = null;
82 private JMenuItem _addTimeOffsetItem = null;
83 private JMenuItem _addAltitudeOffsetItem = null;
84 private JMenuItem _removeAltitudesItem = null;
85 private JMenuItem _mergeSegmentsItem = null;
86 private JMenuItem _rearrangeWaypointsItem = null;
87 private JMenuItem _splitSegmentsItem = null;
88 private JMenuItem _sewSegmentsItem = null;
89 private JMenuItem _createMarkerWaypointsItem = null;
90 private JMenuItem _cutAndMoveItem = null;
91 private JMenuItem _convertNamesToTimesItem = null;
92 private JMenuItem _deleteFieldValuesItem = null;
93 private JCheckBoxMenuItem _mapCheckbox = null;
94 private JMenuItem _show3dItem = null;
95 private JMenu _browserMapMenu = null;
96 private JMenuItem _routingGraphHopperItem = null;
97 private JMenuItem _chartItem = null;
98 private JMenuItem _getGpsiesItem = null;
99 private JMenuItem _uploadGpsiesItem = null;
100 private JMenuItem _lookupSrtmItem = null;
101 private JMenu _downloadSrtmMenu = null;
102 private JMenuItem _nearbyWikipediaItem = null;
103 private JMenuItem _nearbyOsmPoiItem = null;
104 private JMenuItem _showPeakfinderItem = null;
105 private JMenuItem _showGeohackItem = null;
106 private JMenuItem _searchOpencachingDeItem = null;
107 private JMenuItem _searchMapillaryItem = null;
108 private JMenuItem _downloadOsmItem = null;
109 private JMenuItem _getWeatherItem = null;
110 private JMenuItem _distanceItem = null;
111 private JMenuItem _fullRangeDetailsItem = null;
112 private JMenuItem _estimateTimeItem = null;
113 private JMenuItem _learnEstimationParams = null;
114 private JMenuItem _autoplayTrack = null;
115 private JMenuItem _saveExifItem = null;
116 private JMenuItem _photoPopupItem = null;
117 private JMenuItem _selectNoPhotoItem = null;
118 private JMenuItem _connectPhotoItem = null;
119 private JMenuItem _removePhotoItem = null;
120 private JMenuItem _disconnectPhotoItem = null;
121 private JMenuItem _correlatePhotosItem = null;
122 private JMenuItem _rearrangePhotosItem = null;
123 private JMenuItem _rotatePhotoLeft = null;
124 private JMenuItem _rotatePhotoRight = null;
125 private JMenuItem _ignoreExifThumb = null;
126 private JMenuItem _connectAudioItem = null;
127 private JMenuItem _disconnectAudioItem = null;
128 private JMenuItem _removeAudioItem = null;
129 private JMenuItem _correlateAudiosItem = null;
130 private JMenuItem _selectNoAudioItem = null;
131 private JCheckBoxMenuItem _onlineCheckbox = null;
132 private JCheckBoxMenuItem _autosaveSettingsCheckbox = null;
134 // ActionListeners for reuse by menu and toolbar
135 private ActionListener _openFileAction = null;
136 private ActionListener _addPhotoAction = null;
137 private ActionListener _saveAction = null;
138 private ActionListener _undoAction = null;
139 private ActionListener _editPointAction = null;
140 private ActionListener _deletePointAction = null;
141 private ActionListener _selectStartAction = null;
142 private ActionListener _selectEndAction = null;
144 // Toolbar buttons which need enabling/disabling
145 private JButton _saveButton = null;
146 private JButton _undoButton = null;
147 private JButton _editPointButton = null;
148 private JButton _deletePointButton = null;
149 private JButton _deleteRangeButton = null;
150 private JButton _cutAndMoveButton = null;
151 private JButton _selectStartButton = null;
152 private JButton _selectEndButton = null;
153 private JButton _connectButton = null;
155 /** Array of key events */
156 private static final int[] KEY_EVENTS = {
157 KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.VK_C, KeyEvent.VK_D, KeyEvent.VK_E,
158 KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, KeyEvent.VK_I, KeyEvent.VK_J,
159 KeyEvent.VK_K, KeyEvent.VK_L, KeyEvent.VK_M, KeyEvent.VK_N, KeyEvent.VK_O,
160 KeyEvent.VK_P, KeyEvent.VK_Q, KeyEvent.VK_R, KeyEvent.VK_S, KeyEvent.VK_T,
161 KeyEvent.VK_U, KeyEvent.VK_V, KeyEvent.VK_W, KeyEvent.VK_X, KeyEvent.VK_Y, KeyEvent.VK_Z};
166 * @param inApp application to call on menu actions
167 * @param inTrackInfo track info object
169 public MenuManager(App inApp, TrackInfo inTrackInfo)
172 _track = inTrackInfo.getTrack();
173 _selection = inTrackInfo.getSelection();
178 * Create a JMenuBar containing all menu items
181 public JMenuBar createMenuBar()
183 JMenuBar menubar = new JMenuBar();
184 JMenu fileMenu = new JMenu(I18nManager.getText("menu.file"));
185 setAltKey(fileMenu, "altkey.menu.file");
187 JMenuItem openMenuItem = new JMenuItem(I18nManager.getText("function.open"));
188 setShortcut(openMenuItem, "shortcut.menu.file.open");
189 _openFileAction = new ActionListener() {
190 public void actionPerformed(ActionEvent e) {
194 openMenuItem.addActionListener(_openFileAction);
195 fileMenu.add(openMenuItem);
196 // import through gpsbabel
197 JMenuItem importBabelItem = makeMenuItem(FunctionLibrary.FUNCTION_IMPORTBABEL);
198 fileMenu.add(importBabelItem);
200 JMenuItem addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
201 _addPhotoAction = new ActionListener() {
202 public void actionPerformed(ActionEvent e) {
206 addPhotosMenuItem.addActionListener(_addPhotoAction);
207 fileMenu.add(addPhotosMenuItem);
209 JMenuItem addAudioMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_LOAD_AUDIO);
210 fileMenu.add(addAudioMenuItem);
212 _recentFileMenu = new JMenu(I18nManager.getText("menu.file.recentfiles"));
213 _recentFileMenu.setEnabled(false);
214 fileMenu.add(_recentFileMenu);
215 fileMenu.addSeparator();
217 JMenuItem loadFromGpsMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSLOAD);
218 setShortcut(loadFromGpsMenuItem, "shortcut.menu.file.load");
219 fileMenu.add(loadFromGpsMenuItem);
221 _sendGpsItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSSAVE, false);
222 fileMenu.add(_sendGpsItem);
223 fileMenu.addSeparator();
225 _saveItem = new JMenuItem(I18nManager.getText("menu.file.save"), KeyEvent.VK_S);
226 setShortcut(_saveItem, "shortcut.menu.file.save");
227 _saveAction = new ActionListener() {
228 public void actionPerformed(ActionEvent e) {
232 _saveItem.addActionListener(_saveAction);
233 _saveItem.setEnabled(false);
234 fileMenu.add(_saveItem);
236 _exportKmlItem = makeMenuItem(FunctionLibrary.FUNCTION_KMLEXPORT, false);
237 fileMenu.add(_exportKmlItem);
239 _exportGpxItem = makeMenuItem(FunctionLibrary.FUNCTION_GPXEXPORT, false);
240 fileMenu.add(_exportGpxItem);
242 _exportPovItem = makeMenuItem(FunctionLibrary.FUNCTION_POVEXPORT, false);
243 fileMenu.add(_exportPovItem);
245 _exportImageItem = makeMenuItem(FunctionLibrary.FUNCTION_IMAGEEXPORT, false);
246 fileMenu.add(_exportImageItem);
247 fileMenu.addSeparator();
249 JMenuItem exitMenuItem = new JMenuItem(I18nManager.getText("menu.file.exit"));
250 exitMenuItem.addActionListener(new ActionListener() {
251 public void actionPerformed(ActionEvent e) {
255 fileMenu.add(exitMenuItem);
256 menubar.add(fileMenu);
258 ////////////////////////////////////////////////////
260 JMenu onlineMenu = new JMenu(I18nManager.getText("menu.online"));
261 setAltKey(onlineMenu, "altkey.menu.online");
263 _lookupSrtmItem = makeMenuItem(FunctionLibrary.FUNCTION_LOOKUP_SRTM, false);
264 onlineMenu.add(_lookupSrtmItem);
265 // Download SRTM sub-menu
266 _downloadSrtmMenu = new JMenu(I18nManager.getText("function.downloadsrtm"));
267 _downloadSrtmMenu.setEnabled(false);
268 JMenuItem downloadStrmGl1Item = makeMenuItem(new DownloadSrtmFunction(_app, new SrtmGl1Source()));
269 _downloadSrtmMenu.add(downloadStrmGl1Item);
270 JMenuItem downloadStrmViewfinderItem = makeMenuItem(new DownloadSrtmFunction(_app, new SrtmViewfinderSource()));
271 _downloadSrtmMenu.add(downloadStrmViewfinderItem);
272 JMenuItem downloadStrm3Item = makeMenuItem(new DownloadSrtmFunction(_app, new Srtm3Source()));
273 _downloadSrtmMenu.add(downloadStrm3Item);
274 onlineMenu.add(_downloadSrtmMenu);
277 _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES, false);
278 onlineMenu.add(_getGpsiesItem);
280 _uploadGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_UPLOAD_GPSIES, false);
281 onlineMenu.add(_uploadGpsiesItem);
283 onlineMenu.addSeparator();
285 _browserMapMenu = new JMenu(I18nManager.getText("menu.view.browser"));
286 _browserMapMenu.setEnabled(false);
287 JMenuItem googleMapsItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_GOOGLE, "menu.view.browser.google"));
288 _browserMapMenu.add(googleMapsItem);
289 JMenuItem openMapsItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_OSM, "menu.view.browser.openstreetmap"));
290 _browserMapMenu.add(openMapsItem);
291 JMenuItem mapquestMapsItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_MAPQUEST, "menu.view.browser.mapquest"));
292 _browserMapMenu.add(mapquestMapsItem);
293 JMenuItem yahooMapsItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_YAHOO, "menu.view.browser.yahoo"));
294 _browserMapMenu.add(yahooMapsItem);
295 JMenuItem bingMapsItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_BING, "menu.view.browser.bing"));
296 _browserMapMenu.add(bingMapsItem);
297 JMenuItem inlineMapItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_INLINESKATE, "menu.view.browser.inlinemap"));
298 _browserMapMenu.add(inlineMapItem);
299 _routingGraphHopperItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_GRAPHHOPPER, "menu.view.browser.graphhopper"));
300 _browserMapMenu.add(_routingGraphHopperItem);
301 onlineMenu.add(_browserMapMenu);
303 _nearbyWikipediaItem = makeMenuItem(FunctionLibrary.FUNCTION_NEARBY_WIKIPEDIA, false);
304 onlineMenu.add(_nearbyWikipediaItem);
305 JMenuItem searchWikipediaNamesItem = makeMenuItem(FunctionLibrary.FUNCTION_SEARCH_WIKIPEDIA);
306 onlineMenu.add(searchWikipediaNamesItem);
307 _nearbyOsmPoiItem = makeMenuItem(FunctionLibrary.FUNCTION_SEARCH_OSMPOIS);
308 onlineMenu.add(_nearbyOsmPoiItem);
309 _showPeakfinderItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_PEAKFINDER, "webservice.peakfinder"), false);
310 onlineMenu.add(_showPeakfinderItem);
311 _showGeohackItem = makeMenuItem(new WebMapFunction(_app, UrlGenerator.WebService.MAP_SOURCE_GEOHACK, "webservice.geohack"), false);
312 onlineMenu.add(_showGeohackItem);
314 onlineMenu.addSeparator();
315 _searchOpencachingDeItem = makeMenuItem(new SearchOpenCachingDeFunction(_app), false);
316 onlineMenu.add(_searchOpencachingDeItem);
317 _searchMapillaryItem = makeMenuItem(new SearchMapillaryFunction(_app), false);
318 onlineMenu.add(_searchMapillaryItem);
319 _downloadOsmItem = makeMenuItem(FunctionLibrary.FUNCTION_DOWNLOAD_OSM, false);
320 onlineMenu.add(_downloadOsmItem);
321 _getWeatherItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_WEATHER_FORECAST, false);
322 onlineMenu.add(_getWeatherItem);
323 menubar.add(onlineMenu);
325 ////////////////////////////////////////////////////
327 JMenu trackMenu = new JMenu(I18nManager.getText("menu.track"));
328 setAltKey(trackMenu, "altkey.menu.track");
329 _undoItem = new JMenuItem(I18nManager.getText("menu.track.undo"));
330 setShortcut(_undoItem, "shortcut.menu.track.undo");
331 _undoAction = new ActionListener() {
332 public void actionPerformed(ActionEvent e) {
336 _undoItem.addActionListener(_undoAction);
337 _undoItem.setEnabled(false);
338 trackMenu.add(_undoItem);
339 _clearUndoItem = new JMenuItem(I18nManager.getText("menu.track.clearundo"));
340 _clearUndoItem.addActionListener(new ActionListener() {
341 public void actionPerformed(ActionEvent e) {
345 _clearUndoItem.setEnabled(false);
346 trackMenu.add(_clearUndoItem);
347 trackMenu.addSeparator();
348 _compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS, false);
349 setShortcut(_compressItem, "shortcut.menu.track.compress");
350 trackMenu.add(_compressItem);
351 _markRectangleItem = new JMenuItem(I18nManager.getText("menu.track.markrectangle"));
352 _markRectangleItem.addActionListener(new ActionListener() {
353 public void actionPerformed(ActionEvent e) {
354 _app.setCurrentMode(App.AppMode.DRAWRECT);
355 UpdateMessageBroker.informSubscribers();
358 _markRectangleItem.setEnabled(false);
359 trackMenu.add(_markRectangleItem);
360 _markUphillLiftsItem = makeMenuItem(FunctionLibrary.FUNCTION_MARK_LIFTS, false);
361 trackMenu.add(_markUphillLiftsItem);
362 _deleteMarkedPointsItem = makeMenuItem(FunctionLibrary.FUNCTION_DELETE_MARKED_POINTS, false);
363 trackMenu.add(_deleteMarkedPointsItem);
364 _deleteByDateItem = makeMenuItem(FunctionLibrary.FUNCTION_DELETE_BY_DATE, false);
365 trackMenu.add(_deleteByDateItem);
366 trackMenu.addSeparator();
367 // Rearrange waypoints
368 _rearrangeWaypointsItem = makeMenuItem(FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS, false);
369 trackMenu.add(_rearrangeWaypointsItem);
370 // Split track segments
371 _splitSegmentsItem = makeMenuItem(FunctionLibrary.FUNCTION_SPLIT_SEGMENTS, false);
372 trackMenu.add(_splitSegmentsItem);
373 // Sew track segments
374 _sewSegmentsItem = makeMenuItem(FunctionLibrary.FUNCTION_SEW_SEGMENTS, false);
375 trackMenu.add(_sewSegmentsItem);
376 // Create marker waypoints
377 _createMarkerWaypointsItem = makeMenuItem(FunctionLibrary.FUNCTION_CREATE_MARKER_WAYPOINTS, false);
378 trackMenu.add(_createMarkerWaypointsItem);
379 trackMenu.addSeparator();
380 _learnEstimationParams = makeMenuItem(FunctionLibrary.FUNCTION_LEARN_ESTIMATION_PARAMS, false);
381 trackMenu.add(_learnEstimationParams);
382 menubar.add(trackMenu);
385 JMenu rangeMenu = new JMenu(I18nManager.getText("menu.range"));
386 setAltKey(rangeMenu, "altkey.menu.range");
387 _selectAllItem = new JMenuItem(I18nManager.getText("menu.range.all"));
388 setShortcut(_selectAllItem, "shortcut.menu.range.all");
389 _selectAllItem.setEnabled(false);
390 _selectAllItem.addActionListener(new ActionListener() {
391 public void actionPerformed(ActionEvent e) {
392 _selection.selectRange(0, _track.getNumPoints()-1);
395 rangeMenu.add(_selectAllItem);
396 _selectNoneItem = new JMenuItem(I18nManager.getText("menu.range.none"));
397 _selectNoneItem.setEnabled(false);
398 _selectNoneItem.addActionListener(new ActionListener() {
399 public void actionPerformed(ActionEvent e) {
403 rangeMenu.add(_selectNoneItem);
404 _selectSegmentItem = makeMenuItem(FunctionLibrary.FUNCTION_SELECT_SEGMENT);
405 rangeMenu.add(_selectSegmentItem);
406 rangeMenu.addSeparator();
407 _selectStartItem = new JMenuItem(I18nManager.getText("menu.range.start"));
408 _selectStartItem.setEnabled(false);
409 _selectStartAction = new ActionListener() {
410 public void actionPerformed(ActionEvent e) {
411 _selection.selectRangeStart();
414 _selectStartItem.addActionListener(_selectStartAction);
415 rangeMenu.add(_selectStartItem);
416 _selectEndItem = new JMenuItem(I18nManager.getText("menu.range.end"));
417 _selectEndItem.setEnabled(false);
418 _selectEndAction = new ActionListener() {
419 public void actionPerformed(ActionEvent e) {
420 _selection.selectRangeEnd();
423 _selectEndItem.addActionListener(_selectEndAction);
424 rangeMenu.add(_selectEndItem);
425 rangeMenu.addSeparator();
426 _deleteRangeItem = makeMenuItem(FunctionLibrary.FUNCTION_DELETE_RANGE, false);
427 rangeMenu.add(_deleteRangeItem);
428 _cropTrackItem = makeMenuItem(FunctionLibrary.FUNCTION_CROP_TRACK, false);
429 rangeMenu.add(_cropTrackItem);
430 _reverseItem = new JMenuItem(I18nManager.getText("menu.range.reverse"));
431 _reverseItem.addActionListener(new ActionListener() {
432 public void actionPerformed(ActionEvent e) {
436 _reverseItem.setEnabled(false);
437 rangeMenu.add(_reverseItem);
438 _addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET, false);
439 rangeMenu.add(_addTimeOffsetItem);
440 _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET, false);
441 rangeMenu.add(_addAltitudeOffsetItem);
442 _removeAltitudesItem = makeMenuItem(FunctionLibrary.FUNCTION_REMOVE_ALTITUDES, false);
443 rangeMenu.add(_removeAltitudesItem);
444 _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.range.mergetracksegments"));
445 _mergeSegmentsItem.addActionListener(new ActionListener() {
446 public void actionPerformed(ActionEvent e) {
447 _app.mergeTrackSegments();
450 _mergeSegmentsItem.setEnabled(false);
451 rangeMenu.add(_mergeSegmentsItem);
452 _deleteFieldValuesItem = makeMenuItem(FunctionLibrary.FUNCTION_DELETE_FIELD_VALUES, false);
453 rangeMenu.add(_deleteFieldValuesItem);
454 rangeMenu.addSeparator();
455 _interpolateItem = makeMenuItem(new ChooseSingleParameter(_app, FunctionLibrary.FUNCTION_INTERPOLATE), false);
456 rangeMenu.add(_interpolateItem);
457 _averageItem = new JMenuItem(I18nManager.getText("menu.range.average"));
458 _averageItem.addActionListener(new ActionListener() {
459 public void actionPerformed(ActionEvent e) {
460 _app.averageSelection();
463 _averageItem.setEnabled(false);
464 rangeMenu.add(_averageItem);
465 _cutAndMoveItem = new JMenuItem(I18nManager.getText("menu.range.cutandmove"));
466 _cutAndMoveItem.addActionListener(new ActionListener() {
467 public void actionPerformed(ActionEvent e)
469 _app.cutAndMoveSelection();
472 _cutAndMoveItem.setEnabled(false);
473 rangeMenu.add(_cutAndMoveItem);
474 _convertNamesToTimesItem = makeMenuItem(FunctionLibrary.FUNCTION_CONVERT_NAMES_TO_TIMES, false);
475 rangeMenu.add(_convertNamesToTimesItem);
476 menubar.add(rangeMenu);
479 JMenu pointMenu = new JMenu(I18nManager.getText("menu.point"));
480 setAltKey(pointMenu, "altkey.menu.point");
481 _editPointItem = new JMenuItem(I18nManager.getText("menu.point.editpoint"));
482 _editPointAction = new ActionListener() {
483 public void actionPerformed(ActionEvent e) {
484 _app.editCurrentPoint();
487 _editPointItem.addActionListener(_editPointAction);
488 _editPointItem.setEnabled(false);
489 setShortcut(_editPointItem, "shortcut.menu.point.edit");
490 pointMenu.add(_editPointItem);
491 _editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME, false);
492 pointMenu.add(_editWaypointNameItem);
493 _deletePointItem = new JMenuItem(I18nManager.getText("menu.point.deletepoint"));
494 _deletePointAction = new ActionListener() {
495 public void actionPerformed(ActionEvent e) {
496 _app.deleteCurrentPoint();
499 _deletePointItem.addActionListener(_deletePointAction);
500 _deletePointItem.setEnabled(false);
501 _deletePointItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0));
502 pointMenu.add(_deletePointItem);
503 pointMenu.addSeparator();
505 _findWaypointItem = makeMenuItem(FunctionLibrary.FUNCTION_FIND_WAYPOINT, false);
506 pointMenu.add(_findWaypointItem);
507 // duplicate current point
508 _duplicatePointItem = makeMenuItem(FunctionLibrary.FUNCTION_DUPLICATE_POINT, false);
509 pointMenu.add(_duplicatePointItem);
510 // paste coordinates function
511 JMenuItem pasteCoordsItem = makeMenuItem(FunctionLibrary.FUNCTION_PASTE_COORDINATES);
512 pointMenu.add(pasteCoordsItem);
513 menubar.add(pointMenu);
516 JMenu viewMenu = new JMenu(I18nManager.getText("menu.view"));
517 setAltKey(viewMenu, "altkey.menu.view");
518 // Turn map display on/off
519 _mapCheckbox = new JCheckBoxMenuItem(
520 I18nManager.getText("menu.map.showmap"), false);
521 _mapCheckbox.addActionListener(new ActionListener() {
522 public void actionPerformed(ActionEvent e) {
523 Config.setConfigBoolean(Config.KEY_SHOW_MAP, _mapCheckbox.isSelected());
524 UpdateMessageBroker.informSubscribers(MAPSERVER_CHANGED);
527 viewMenu.add(_mapCheckbox);
528 // Turn off the sidebars
529 JCheckBoxMenuItem sidebarsCheckbox = new JCheckBoxMenuItem(I18nManager.getText("menu.view.showsidebars"));
530 sidebarsCheckbox.setSelected(true);
531 sidebarsCheckbox.addActionListener(new ActionListener() {
532 public void actionPerformed(ActionEvent e) {
533 _app.toggleSidebars();
536 sidebarsCheckbox.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F11, 0)); // shortcut F11
537 viewMenu.add(sidebarsCheckbox);
539 _show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D, false);
540 viewMenu.add(_show3dItem);
542 _chartItem = makeMenuItem(FunctionLibrary.FUNCTION_CHARTS, false);
543 viewMenu.add(_chartItem);
544 viewMenu.addSeparator();
546 _distanceItem = makeMenuItem(FunctionLibrary.FUNCTION_DISTANCES, false);
547 viewMenu.add(_distanceItem);
548 // full range details
549 _fullRangeDetailsItem = makeMenuItem(FunctionLibrary.FUNCTION_FULL_RANGE_DETAILS, false);
550 viewMenu.add(_fullRangeDetailsItem);
552 _estimateTimeItem = makeMenuItem(FunctionLibrary.FUNCTION_ESTIMATE_TIME, false);
553 viewMenu.add(_estimateTimeItem);
554 viewMenu.addSeparator();
556 _autoplayTrack = makeMenuItem(FunctionLibrary.FUNCTION_AUTOPLAY_TRACK, false);
557 viewMenu.add(_autoplayTrack);
558 menubar.add(viewMenu);
561 JMenu photoMenu = new JMenu(I18nManager.getText("menu.photo"));
562 setAltKey(photoMenu, "altkey.menu.photo");
563 addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
564 addPhotosMenuItem.addActionListener(_addPhotoAction);
565 photoMenu.add(addPhotosMenuItem);
566 _saveExifItem = new JMenuItem(I18nManager.getText("menu.photo.saveexif"));
567 _saveExifItem.addActionListener(new ActionListener() {
568 public void actionPerformed(ActionEvent e) {
572 _saveExifItem.setEnabled(false);
573 photoMenu.add(_saveExifItem);
574 // Deselect current photo
575 _selectNoPhotoItem = new JMenuItem(I18nManager.getText("menu.range.none"));
576 _selectNoPhotoItem.setEnabled(false);
577 _selectNoPhotoItem.addActionListener(new ActionListener() {
578 public void actionPerformed(ActionEvent e) {
579 _app.getTrackInfo().selectPhoto(-1);
582 photoMenu.add(_selectNoPhotoItem);
583 photoMenu.addSeparator();
584 _connectPhotoItem = makeMenuItem(FunctionLibrary.FUNCTION_CONNECT_TO_POINT, false);
585 photoMenu.add(_connectPhotoItem);
587 _disconnectPhotoItem = makeMenuItem(FunctionLibrary.FUNCTION_DISCONNECT_PHOTO, false);
588 photoMenu.add(_disconnectPhotoItem);
589 _removePhotoItem = makeMenuItem(FunctionLibrary.FUNCTION_REMOVE_PHOTO, false);
590 photoMenu.add(_removePhotoItem);
591 // Rotate current photo
592 _rotatePhotoLeft = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_LEFT, false);
593 photoMenu.add(_rotatePhotoLeft);
594 _rotatePhotoRight = makeMenuItem(FunctionLibrary.FUNCTION_ROTATE_PHOTO_RIGHT, false);
595 photoMenu.add(_rotatePhotoRight);
597 _photoPopupItem = makeMenuItem(FunctionLibrary.FUNCTION_PHOTO_POPUP, false);
598 photoMenu.add(_photoPopupItem);
599 _ignoreExifThumb = makeMenuItem(FunctionLibrary.FUNCTION_IGNORE_EXIF_THUMB, false);
600 photoMenu.add(_ignoreExifThumb);
601 photoMenu.addSeparator();
602 // correlate all photos
603 _correlatePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_PHOTOS, false);
604 photoMenu.add(_correlatePhotosItem);
605 // rearrange photo points
606 _rearrangePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_REARRANGE_PHOTOS, false);
607 photoMenu.add(_rearrangePhotosItem);
608 menubar.add(photoMenu);
611 JMenu audioMenu = new JMenu(I18nManager.getText("menu.audio"));
612 setAltKey(audioMenu, "altkey.menu.audio");
613 addAudioMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_LOAD_AUDIO);
614 audioMenu.add(addAudioMenuItem);
615 _selectNoAudioItem = new JMenuItem(I18nManager.getText("menu.range.none"));
616 _selectNoAudioItem.setEnabled(false);
617 _selectNoAudioItem.addActionListener(new ActionListener() {
618 public void actionPerformed(ActionEvent e) {
619 _app.getTrackInfo().selectAudio(-1);
622 audioMenu.add(_selectNoAudioItem);
623 audioMenu.addSeparator();
625 _connectAudioItem = makeMenuItem(FunctionLibrary.FUNCTION_CONNECT_TO_POINT, false);
626 audioMenu.add(_connectAudioItem);
627 // Disconnect current audio clip
628 _disconnectAudioItem = makeMenuItem(FunctionLibrary.FUNCTION_DISCONNECT_AUDIO, false);
629 audioMenu.add(_disconnectAudioItem);
630 // Remove current audio clip
631 _removeAudioItem = makeMenuItem(FunctionLibrary.FUNCTION_REMOVE_AUDIO, false);
632 audioMenu.add(_removeAudioItem);
633 audioMenu.addSeparator();
634 // Correlate audio clips
635 _correlateAudiosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_AUDIOS, false);
636 audioMenu.add(_correlateAudiosItem);
637 menubar.add(audioMenu);
640 JMenu settingsMenu = new JMenu(I18nManager.getText("menu.settings"));
641 setAltKey(settingsMenu, "altkey.menu.settings");
642 // Set the map background
643 JMenuItem mapBgItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_MAP_BG);
644 settingsMenu.add(mapBgItem);
645 _onlineCheckbox = new JCheckBoxMenuItem(I18nManager.getText("menu.settings.onlinemode"));
646 _onlineCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_ONLINE_MODE));
647 _onlineCheckbox.addActionListener(new ActionListener() {
648 public void actionPerformed(ActionEvent e) {
649 boolean isOnline = _onlineCheckbox.isSelected();
650 Config.setConfigBoolean(Config.KEY_ONLINE_MODE, isOnline);
651 if (isOnline) {UpdateMessageBroker.informSubscribers();}
654 settingsMenu.add(_onlineCheckbox);
655 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_DISK_CACHE));
656 settingsMenu.addSeparator();
658 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_PATHS));
660 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_COLOURS));
662 JMenuItem setDisplaySettingsItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_DISPLAY_SETTINGS);
663 settingsMenu.add(setDisplaySettingsItem);
665 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_LANGUAGE));
666 // Set altitude tolerance
667 settingsMenu.add(makeMenuItem(new ChooseSingleParameter(_app, FunctionLibrary.FUNCTION_SET_ALTITUDE_TOLERANCE)));
669 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_TIMEZONE));
670 // Set Earthdata authentication
671 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SET_EARTHDATA_AUTH));
672 settingsMenu.addSeparator();
673 // Save configuration
674 settingsMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG));
675 _autosaveSettingsCheckbox = new JCheckBoxMenuItem(
676 I18nManager.getText("menu.settings.autosave"), false);
677 _autosaveSettingsCheckbox.setSelected(Config.getConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS));
678 _autosaveSettingsCheckbox.addActionListener(new ActionListener() {
679 public void actionPerformed(ActionEvent e) {
680 Config.setConfigBoolean(Config.KEY_AUTOSAVE_SETTINGS, _autosaveSettingsCheckbox.isSelected());
683 settingsMenu.add(_autosaveSettingsCheckbox);
684 menubar.add(settingsMenu);
687 JMenu helpMenu = new JMenu(I18nManager.getText("menu.help"));
688 setAltKey(helpMenu, "altkey.menu.help");
689 JMenuItem helpItem = makeMenuItem(FunctionLibrary.FUNCTION_HELP);
690 setShortcut(helpItem, "shortcut.menu.help.help");
691 helpMenu.add(helpItem);
692 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_SHOW_KEYS));
693 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_ABOUT));
694 helpMenu.add(makeMenuItem(FunctionLibrary.FUNCTION_CHECK_VERSION));
695 menubar.add(helpMenu);
701 * Convenience method for making a menu item using a function
702 * @param inFunction function
703 * @param inEnabled flag to specify initial enabled state
704 * @return menu item using localized name of function
706 private static JMenuItem makeMenuItem(GenericFunction inFunction, boolean inEnabled)
708 JMenuItem item = makeMenuItem(inFunction);
709 item.setEnabled(inEnabled);
714 * Convenience method for making a menu item using a function
715 * @param inFunction function
716 * @return menu item using localized name of function
718 private static JMenuItem makeMenuItem(GenericFunction inFunction)
720 JMenuItem item = new JMenuItem(I18nManager.getText(inFunction.getNameKey()));
721 item.addActionListener(new FunctionLauncher(inFunction));
726 * Set the alt key for the given menu
727 * @param inMenu menu to set
728 * @param inKey key to lookup to get language-sensitive altkey
730 private static void setAltKey(JMenu inMenu, String inKey)
732 // Lookup the key in the properties
733 String altKey = I18nManager.getText(inKey);
734 if (altKey != null && altKey.length() == 1)
736 int code = altKey.charAt(0) - 'A';
737 if (code >= 0 && code < 26)
739 // Found a valid code between A and Z
740 inMenu.setMnemonic(KEY_EVENTS[code]);
746 * Set the shortcut key for the given menu item
747 * @param inMenuItem menu item to set
748 * @param inKey key to lookup to get language-sensitive shortcut
750 private static void setShortcut(JMenuItem inMenuItem, String inKey)
752 // Lookup the key in the properties
753 String altKey = I18nManager.getText(inKey);
754 if (altKey != null && altKey.length() == 1)
756 int code = altKey.charAt(0) - 'A';
757 if (code >= 0 && code < 26)
759 // Found a valid code between A and Z
760 inMenuItem.setAccelerator(KeyStroke.getKeyStroke(KEY_EVENTS[code],
761 Toolkit.getDefaultToolkit().getMenuShortcutKeyMask()));
762 // use platform-specific key mask so Ctrl on Linux/Win, Clover on Mac
768 * Create a JToolBar containing all toolbar buttons
769 * @return toolbar containing buttons
771 public JToolBar createToolBar()
773 JToolBar toolbar = new JToolBar();
775 JButton openFileButton = new JButton(IconManager.getImageIcon(IconManager.OPEN_FILE));
776 openFileButton.setToolTipText(I18nManager.getText("function.open"));
777 openFileButton.addActionListener(_openFileAction);
778 toolbar.add(openFileButton);
780 JButton addPhotoButton = new JButton(IconManager.getImageIcon(IconManager.ADD_PHOTO));
781 addPhotoButton.setToolTipText(I18nManager.getText("menu.file.addphotos"));
782 addPhotoButton.addActionListener(_addPhotoAction);
783 toolbar.add(addPhotoButton);
785 _saveButton = new JButton(IconManager.getImageIcon(IconManager.SAVE_FILE));
786 _saveButton.setToolTipText(I18nManager.getText("menu.file.save"));
787 _saveButton.addActionListener(_saveAction);
788 _saveButton.setEnabled(false);
789 toolbar.add(_saveButton);
791 _undoButton = new JButton(IconManager.getImageIcon(IconManager.UNDO));
792 _undoButton.setToolTipText(I18nManager.getText("menu.track.undo"));
793 _undoButton.addActionListener(_undoAction);
794 _undoButton.setEnabled(false);
795 toolbar.add(_undoButton);
797 _editPointButton = new JButton(IconManager.getImageIcon(IconManager.EDIT_POINT));
798 _editPointButton.setToolTipText(I18nManager.getText("menu.point.editpoint"));
799 _editPointButton.addActionListener(_editPointAction);
800 _editPointButton.setEnabled(false);
801 toolbar.add(_editPointButton);
803 _deletePointButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_POINT));
804 _deletePointButton.setToolTipText(I18nManager.getText("menu.point.deletepoint"));
805 _deletePointButton.addActionListener(_deletePointAction);
806 _deletePointButton.setEnabled(false);
807 toolbar.add(_deletePointButton);
809 _deleteRangeButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_RANGE));
810 _deleteRangeButton.setToolTipText(I18nManager.getText("function.deleterange"));
811 _deleteRangeButton.addActionListener(new ActionListener() {
812 public void actionPerformed(ActionEvent arg0) {
813 FunctionLibrary.FUNCTION_DELETE_RANGE.begin();
816 _deleteRangeButton.setEnabled(false);
817 toolbar.add(_deleteRangeButton);
819 _cutAndMoveButton = new JButton(IconManager.getImageIcon(IconManager.CUT_AND_MOVE));
820 _cutAndMoveButton.setToolTipText(I18nManager.getText("menu.range.cutandmove"));
821 _cutAndMoveButton.addActionListener(new ActionListener() {
822 public void actionPerformed(ActionEvent arg0) {
823 _app.cutAndMoveSelection();
826 _cutAndMoveButton.setEnabled(false);
827 toolbar.add(_cutAndMoveButton);
829 _selectStartButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_START));
830 _selectStartButton.setToolTipText(I18nManager.getText("menu.range.start"));
831 _selectStartButton.addActionListener(_selectStartAction);
832 _selectStartButton.setEnabled(false);
833 toolbar.add(_selectStartButton);
834 _selectEndButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_END));
835 _selectEndButton.setToolTipText(I18nManager.getText("menu.range.end"));
836 _selectEndButton.addActionListener(_selectEndAction);
837 _selectEndButton.setEnabled(false);
838 toolbar.add(_selectEndButton);
840 _connectButton = new JButton(IconManager.getImageIcon(IconManager.CONNECT_PHOTO));
841 _connectButton.setToolTipText(I18nManager.getText(FunctionLibrary.FUNCTION_CONNECT_TO_POINT.getNameKey()));
842 _connectButton.addActionListener(new ActionListener() {
843 public void actionPerformed(ActionEvent arg0) {
844 FunctionLibrary.FUNCTION_CONNECT_TO_POINT.begin();
847 _connectButton.setEnabled(false);
848 toolbar.add(_connectButton);
850 toolbar.setFloatable(false);
856 * Method to update menu when file loaded
858 public void informFileLoaded()
860 // save, undo, delete enabled
861 _sendGpsItem.setEnabled(true);
862 _saveItem.setEnabled(true);
863 _undoItem.setEnabled(true);
864 _compressItem.setEnabled(true);
865 _deleteMarkedPointsItem.setEnabled(false);
870 * @see tim.prune.DataSubscriber#dataUpdated(tim.prune.data.Track)
872 public void dataUpdated(byte inUpdateType)
874 final boolean hasData = _track != null && _track.getNumPoints() > 0;
875 final boolean hasMultiplePoints = hasData && _track.getNumPoints() > 1;
877 // set functions which require data
878 _sendGpsItem.setEnabled(hasData);
879 _saveItem.setEnabled(hasData);
880 _saveButton.setEnabled(hasData);
881 _exportKmlItem.setEnabled(hasData);
882 _exportGpxItem.setEnabled(hasData);
883 _exportPovItem.setEnabled(hasMultiplePoints);
884 _exportImageItem.setEnabled(hasMultiplePoints);
885 _compressItem.setEnabled(hasData);
886 _markRectangleItem.setEnabled(hasData);
887 _markUphillLiftsItem.setEnabled(hasData && _track.hasAltitudeData());
888 _deleteMarkedPointsItem.setEnabled(hasData && _track.hasMarkedPoints());
889 _rearrangeWaypointsItem.setEnabled(hasData && _track.hasTrackPoints() && _track.hasWaypoints());
890 final boolean hasSeveralTrackPoints = hasData && _track.hasTrackPoints() && _track.getNumPoints() > 3;
891 _splitSegmentsItem.setEnabled(hasSeveralTrackPoints);
892 _sewSegmentsItem.setEnabled(hasSeveralTrackPoints);
893 _createMarkerWaypointsItem.setEnabled(hasSeveralTrackPoints);
894 _selectAllItem.setEnabled(hasData);
895 _selectNoneItem.setEnabled(hasData);
896 _show3dItem.setEnabled(hasMultiplePoints);
897 _chartItem.setEnabled(hasData);
898 _browserMapMenu.setEnabled(hasData);
899 _distanceItem.setEnabled(hasData);
900 _autoplayTrack.setEnabled(hasData && _track.getNumPoints() > 3);
901 _getGpsiesItem.setEnabled(hasData);
902 _uploadGpsiesItem.setEnabled(hasData && _track.hasTrackPoints());
903 _lookupSrtmItem.setEnabled(hasData);
904 _nearbyWikipediaItem.setEnabled(hasData);
905 _nearbyOsmPoiItem.setEnabled(hasData);
906 _downloadOsmItem.setEnabled(hasData);
907 _getWeatherItem.setEnabled(hasData);
908 _findWaypointItem.setEnabled(hasData && _track.hasWaypoints());
909 // have we got a cache?
910 _downloadSrtmMenu.setEnabled(hasData && Config.getConfigString(Config.KEY_DISK_CACHE) != null);
911 // have we got any timestamps?
912 _deleteByDateItem.setEnabled(hasData && _track.hasData(Field.TIMESTAMP));
914 // is undo available?
915 boolean hasUndo = !_app.getUndoStack().isEmpty();
916 _undoItem.setEnabled(hasUndo);
917 _undoButton.setEnabled(hasUndo);
918 _clearUndoItem.setEnabled(hasUndo);
919 // is there a current point?
920 DataPoint currPoint = _app.getTrackInfo().getCurrentPoint();
921 boolean hasPoint = (currPoint != null);
922 _editPointItem.setEnabled(hasPoint);
923 _editPointButton.setEnabled(hasPoint);
924 _editWaypointNameItem.setEnabled(hasPoint);
925 _deletePointItem.setEnabled(hasPoint);
926 _deletePointButton.setEnabled(hasPoint);
927 _selectStartItem.setEnabled(hasPoint);
928 _selectStartButton.setEnabled(hasPoint);
929 _selectEndItem.setEnabled(hasPoint);
930 _selectEndButton.setEnabled(hasPoint);
931 _duplicatePointItem.setEnabled(hasPoint);
932 _showPeakfinderItem.setEnabled(hasPoint);
933 _showGeohackItem.setEnabled(hasPoint);
934 _searchOpencachingDeItem.setEnabled(hasPoint);
935 _searchMapillaryItem.setEnabled(hasPoint);
937 _selectSegmentItem.setEnabled(hasPoint && !currPoint.isWaypoint());
938 // are there any photos?
939 boolean anyPhotos = _app.getTrackInfo().getPhotoList().getNumPhotos() > 0;
940 _saveExifItem.setEnabled(anyPhotos && _app.getTrackInfo().getPhotoList().hasMediaWithFile());
941 // is there a current photo, audio?
942 Photo currentPhoto = _app.getTrackInfo().getCurrentPhoto();
943 boolean hasPhoto = currentPhoto != null;
944 AudioClip currentAudio = _app.getTrackInfo().getCurrentAudio();
945 boolean hasAudio = currentAudio != null;
946 // connect is available if (photo/audio) and point selected, and media has no point
947 boolean connectAvailable = (hasPhoto && hasPoint && currentPhoto.getDataPoint() == null)
948 || (hasAudio && hasPoint && currentAudio.getDataPoint() == null);
949 _connectPhotoItem.setEnabled(hasPhoto && hasPoint && currentPhoto.getDataPoint() == null);
950 _connectButton.setEnabled(connectAvailable);
951 _disconnectPhotoItem.setEnabled(hasPhoto && currentPhoto.getDataPoint() != null);
952 _correlatePhotosItem.setEnabled(anyPhotos && hasData);
953 _rearrangePhotosItem.setEnabled(anyPhotos && hasMultiplePoints);
954 _removePhotoItem.setEnabled(hasPhoto);
955 _rotatePhotoLeft.setEnabled(hasPhoto);
956 _rotatePhotoRight.setEnabled(hasPhoto);
957 _photoPopupItem.setEnabled(hasPhoto);
958 _ignoreExifThumb.setEnabled(hasPhoto && currentPhoto.getExifThumbnail() != null);
959 _selectNoPhotoItem.setEnabled(hasPhoto);
960 boolean anyAudios = _app.getTrackInfo().getAudioList().getNumAudios() > 0;
961 _selectNoAudioItem.setEnabled(hasAudio);
962 _removeAudioItem.setEnabled(hasAudio);
963 _connectAudioItem.setEnabled(hasAudio && hasPoint && currentAudio.getDataPoint() == null);
964 _disconnectAudioItem.setEnabled(hasAudio && currentAudio.getDataPoint() != null);
965 _correlateAudiosItem.setEnabled(anyAudios && hasData);
966 // is there a current range?
967 boolean hasRange = (hasData && _selection.hasRangeSelected());
968 _deleteRangeItem.setEnabled(hasRange);
969 _deleteRangeButton.setEnabled(hasRange);
970 _cropTrackItem.setEnabled(hasRange);
971 _interpolateItem.setEnabled(hasRange);
972 _averageItem.setEnabled(hasRange);
973 _mergeSegmentsItem.setEnabled(hasRange);
974 _reverseItem.setEnabled(hasRange);
975 _addTimeOffsetItem.setEnabled(hasRange);
976 _addAltitudeOffsetItem.setEnabled(hasRange);
977 _removeAltitudesItem.setEnabled(hasRange);
978 _convertNamesToTimesItem.setEnabled(hasRange && _track.hasWaypoints());
979 _deleteFieldValuesItem.setEnabled(hasRange);
980 _fullRangeDetailsItem.setEnabled(hasRange);
981 _estimateTimeItem.setEnabled(hasRange);
982 _learnEstimationParams.setEnabled(hasData && _track.hasTrackPoints() && _track.hasData(Field.TIMESTAMP)
983 && _track.hasAltitudeData());
984 // Is the currently selected point outside the current range?
985 boolean canCutAndMove = hasRange && hasPoint &&
986 (_selection.getCurrentPointIndex() < _selection.getStart()
987 || _selection.getCurrentPointIndex() > (_selection.getEnd()+1));
988 _cutAndMoveItem.setEnabled(canCutAndMove);
989 _cutAndMoveButton.setEnabled(canCutAndMove);
990 final boolean isTrackLengthTwo = hasData && _track.getNumPoints() == 2;
991 _routingGraphHopperItem.setEnabled(isTrackLengthTwo || (hasData && hasRange));
992 // Has the map been switched on/off?
993 boolean mapsOn = Config.getConfigBoolean(Config.KEY_SHOW_MAP);
994 if (_mapCheckbox.isSelected() != mapsOn) {
995 _mapCheckbox.setSelected(mapsOn);
997 // Are there any recently-used files?
998 RecentFileList rfl = Config.getRecentFileList();
999 final int numRecentFiles = rfl.getNumEntries();
1000 final boolean hasRecentFiles = numRecentFiles > 0;
1001 _recentFileMenu.setEnabled(hasRecentFiles);
1004 int numItems = _recentFileMenu.getMenuComponentCount();
1005 if (numItems == numRecentFiles)
1007 // Right number of items, just change texts
1008 for (int i=0; i<numRecentFiles; i++)
1010 JMenuItem item = _recentFileMenu.getItem(i);
1011 RecentFile rf = rfl.getFile(i);
1012 item.setText(rf==null?"":rf.getFile().getName());
1013 item.setToolTipText(rf==null?null:rf.getFile().getAbsolutePath());
1019 _recentFileMenu.removeAll();
1020 for (int i=0; i<rfl.getSize(); i++)
1022 RecentFile rf = rfl.getFile(i);
1023 if (rf != null && rf.isValid())
1025 JMenuItem menuItem = new JMenuItem(rf.getFile().getName());
1026 menuItem.setToolTipText(rf.getFile().getAbsolutePath());
1027 menuItem.addActionListener(new RecentFileTrigger(_app, i));
1028 _recentFileMenu.add(menuItem);
1037 * Ignore action completed signals
1038 * @see tim.prune.DataSubscriber#actionCompleted(java.lang.String)
1040 public void actionCompleted(String inMessage)