]> gitweb.fperrin.net Git - GpsPrune.git/blob - tim/prune/gui/MenuManager.java
Version 8, September 2009
[GpsPrune.git] / tim / prune / gui / MenuManager.java
1 package tim.prune.gui;
2
3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.awt.event.InputEvent;
6 import java.awt.event.KeyEvent;
7
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;
15
16 import tim.prune.App;
17 import tim.prune.Config;
18 import tim.prune.DataSubscriber;
19 import tim.prune.FunctionLibrary;
20 import tim.prune.GenericFunction;
21 import tim.prune.I18nManager;
22 import tim.prune.UpdateMessageBroker;
23 import tim.prune.data.PhotoList;
24 import tim.prune.data.Selection;
25 import tim.prune.data.Track;
26 import tim.prune.data.TrackInfo;
27 import tim.prune.function.RearrangeWaypointsFunction.Rearrange;
28 import tim.prune.function.browser.UrlGenerator;
29
30 /**
31  * Class to manage the menu bar and tool bar,
32  * including enabling and disabling the items
33  */
34 public class MenuManager implements DataSubscriber
35 {
36         private App _app = null;
37         private Track _track = null;
38         private Selection _selection = null;
39         private PhotoList _photos = null;
40
41         // Menu items which need enabling/disabling
42         private JMenuItem _sendGpsItem = null;
43         private JMenuItem _saveItem = null;
44         private JMenuItem _exportKmlItem = null;
45         private JMenuItem _exportGpxItem = null;
46         private JMenuItem _exportPovItem = null;
47         private JMenuItem _undoItem = null;
48         private JMenuItem _clearUndoItem = null;
49         private JMenuItem _editPointItem = null;
50         private JMenuItem _editWaypointNameItem = null;
51         private JMenuItem _deletePointItem = null;
52         private JMenuItem _deleteRangeItem = null;
53         private JMenuItem _compressItem = null;
54         private JMenuItem _deleteMarkedPointsItem = null;
55         private JMenuItem _interpolateItem = null;
56         private JMenuItem _averageItem = null;
57         private JMenuItem _selectAllItem = null;
58         private JMenuItem _selectNoneItem = null;
59         private JMenuItem _selectStartItem = null;
60         private JMenuItem _selectEndItem = null;
61         private JMenuItem _findWaypointItem = null;
62         private JMenuItem _reverseItem = null;
63         private JMenuItem _addTimeOffsetItem = null;
64         private JMenuItem _addAltitudeOffsetItem = null;
65         private JMenuItem _mergeSegmentsItem = null;
66         private JMenu     _rearrangeMenu = null;
67         private JMenuItem _cutAndMoveItem = null;
68         private JMenuItem _show3dItem = null;
69         private JMenu     _browserMapMenu = null;
70         private JMenuItem _chartItem = null;
71         private JCheckBoxMenuItem _paceCheckbox = null;
72         private JMenuItem _getGpsiesItem = null;
73         private JMenuItem _distanceItem = null;
74         private JMenuItem _saveExifItem = null;
75         private JMenuItem _connectPhotoItem = null;
76         private JMenuItem _deletePhotoItem = null;
77         private JMenuItem _disconnectPhotoItem = null;
78         private JMenuItem _correlatePhotosItem = null;
79
80         // ActionListeners for reuse by menu and toolbar
81         private ActionListener _openFileAction = null;
82         private ActionListener _addPhotoAction = null;
83         private ActionListener _saveAction = null;
84         private ActionListener _undoAction = null;
85         private ActionListener _editPointAction = null;
86         private ActionListener _deletePointAction = null;
87         private ActionListener _deleteRangeAction = null;
88         private ActionListener _selectStartAction = null;
89         private ActionListener _selectEndAction = null;
90         private ActionListener _connectPhotoAction = null;
91
92         // Toolbar buttons which need enabling/disabling
93         private JButton _saveButton = null;
94         private JButton _undoButton = null;
95         private JButton _editPointButton = null;
96         private JButton _deletePointButton = null;
97         private JButton _deleteRangeButton = null;
98         private JButton _selectStartButton = null;
99         private JButton _selectEndButton = null;
100         private JButton _connectPhotoButton = null;
101
102         /** Array of key events */
103         private static final int[] KEY_EVENTS = {
104                 KeyEvent.VK_A, KeyEvent.VK_B, KeyEvent.VK_C, KeyEvent.VK_D, KeyEvent.VK_E,
105                 KeyEvent.VK_F, KeyEvent.VK_G, KeyEvent.VK_H, KeyEvent.VK_I, KeyEvent.VK_J,
106                 KeyEvent.VK_K, KeyEvent.VK_L, KeyEvent.VK_M, KeyEvent.VK_N, KeyEvent.VK_O,
107                 KeyEvent.VK_P, KeyEvent.VK_Q, KeyEvent.VK_R, KeyEvent.VK_S, KeyEvent.VK_T,
108                 KeyEvent.VK_U, KeyEvent.VK_V, KeyEvent.VK_W, KeyEvent.VK_X, KeyEvent.VK_Y, KeyEvent.VK_Z};
109
110
111         /**
112          * Constructor
113          * @param inApp application to call on menu actions
114          * @param inTrackInfo track info object
115          */
116         public MenuManager(App inApp, TrackInfo inTrackInfo)
117         {
118                 _app = inApp;
119                 _track = inTrackInfo.getTrack();
120                 _selection = inTrackInfo.getSelection();
121                 _photos = inTrackInfo.getPhotoList();
122         }
123
124
125         /**
126          * Create a JMenuBar containing all menu items
127          * @return JMenuBar
128          */
129         public JMenuBar createMenuBar()
130         {
131                 JMenuBar menubar = new JMenuBar();
132                 JMenu fileMenu = new JMenu(I18nManager.getText("menu.file"));
133                 setAltKey(fileMenu, "altkey.menu.file");
134                 // Open file
135                 JMenuItem openMenuItem = new JMenuItem(I18nManager.getText("menu.file.open"));
136                 setShortcut(openMenuItem, "shortcut.menu.file.open");
137                 _openFileAction = new ActionListener() {
138                         public void actionPerformed(ActionEvent e)
139                         {
140                                 _app.openFile();
141                         }
142                 };
143                 openMenuItem.addActionListener(_openFileAction);
144                 fileMenu.add(openMenuItem);
145                 // Add photos
146                 JMenuItem addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
147                 _addPhotoAction = new ActionListener() {
148                         public void actionPerformed(ActionEvent e)
149                         {
150                                 _app.addPhotos();
151                         }
152                 };
153                 addPhotosMenuItem.addActionListener(_addPhotoAction);
154                 fileMenu.add(addPhotosMenuItem);
155                 fileMenu.addSeparator();
156                 // Load from GPS
157                 JMenuItem loadFromGpsMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSLOAD);
158                 setShortcut(loadFromGpsMenuItem, "shortcut.menu.file.load");
159                 fileMenu.add(loadFromGpsMenuItem);
160                 // Send to GPS
161                 _sendGpsItem = makeMenuItem(FunctionLibrary.FUNCTION_GPSSAVE);
162                 _sendGpsItem.setEnabled(false);
163                 fileMenu.add(_sendGpsItem);
164                 fileMenu.addSeparator();
165                 // Save
166                 _saveItem = new JMenuItem(I18nManager.getText("menu.file.save"), KeyEvent.VK_S);
167                 setShortcut(_saveItem, "shortcut.menu.file.save");
168                 _saveAction = new ActionListener() {
169                         public void actionPerformed(ActionEvent e)
170                         {
171                                 _app.saveFile();
172                         }
173                 };
174                 _saveItem.addActionListener(_saveAction);
175                 _saveItem.setEnabled(false);
176                 fileMenu.add(_saveItem);
177                 // Export - Kml
178                 _exportKmlItem = makeMenuItem(FunctionLibrary.FUNCTION_KMLEXPORT);
179                 _exportKmlItem.setEnabled(false);
180                 fileMenu.add(_exportKmlItem);
181                 // Gpx
182                 _exportGpxItem = makeMenuItem(FunctionLibrary.FUNCTION_GPXEXPORT);
183                 _exportGpxItem.setEnabled(false);
184                 fileMenu.add(_exportGpxItem);
185                 // Pov
186                 _exportPovItem = makeMenuItem(FunctionLibrary.FUNCTION_POVEXPORT);
187                 _exportPovItem.setEnabled(false);
188                 fileMenu.add(_exportPovItem);
189                 fileMenu.addSeparator();
190                 JMenuItem exitMenuItem = new JMenuItem(I18nManager.getText("menu.file.exit"));
191                 exitMenuItem.addActionListener(new ActionListener() {
192                         public void actionPerformed(ActionEvent e)
193                         {
194                                 _app.exit();
195                         }
196                 });
197                 fileMenu.add(exitMenuItem);
198                 menubar.add(fileMenu);
199                 // Edit menu
200                 JMenu editMenu = new JMenu(I18nManager.getText("menu.edit"));
201                 setAltKey(editMenu, "altkey.menu.edit");
202                 _undoItem = new JMenuItem(I18nManager.getText("menu.edit.undo"));
203                 setShortcut(_undoItem, "shortcut.menu.edit.undo");
204                 _undoAction = new ActionListener() {
205                         public void actionPerformed(ActionEvent e)
206                         {
207                                 _app.beginUndo();
208                         }
209                 };
210                 _undoItem.addActionListener(_undoAction);
211                 _undoItem.setEnabled(false);
212                 editMenu.add(_undoItem);
213                 _clearUndoItem = new JMenuItem(I18nManager.getText("menu.edit.clearundo"));
214                 _clearUndoItem.addActionListener(new ActionListener() {
215                         public void actionPerformed(ActionEvent e)
216                         {
217                                 _app.clearUndo();
218                         }
219                 });
220                 _clearUndoItem.setEnabled(false);
221                 editMenu.add(_clearUndoItem);
222                 editMenu.addSeparator();
223                 _editPointItem = new JMenuItem(I18nManager.getText("menu.edit.editpoint"));
224                 _editPointAction = new ActionListener() {
225                         public void actionPerformed(ActionEvent e)
226                         {
227                                 _app.editCurrentPoint();
228                         }
229                 };
230                 _editPointItem.addActionListener(_editPointAction);
231                 _editPointItem.setEnabled(false);
232                 editMenu.add(_editPointItem);
233                 _editWaypointNameItem = makeMenuItem(FunctionLibrary.FUNCTION_EDIT_WAYPOINT_NAME);
234                 _editWaypointNameItem.setEnabled(false);
235                 editMenu.add(_editWaypointNameItem);
236                 _deletePointItem = new JMenuItem(I18nManager.getText("menu.edit.deletepoint"));
237                 _deletePointAction = new ActionListener() {
238                         public void actionPerformed(ActionEvent e)
239                         {
240                                 _app.deleteCurrentPoint();
241                         }
242                 };
243                 _deletePointItem.addActionListener(_deletePointAction);
244                 _deletePointItem.setEnabled(false);
245                 editMenu.add(_deletePointItem);
246                 _deleteRangeItem = new JMenuItem(I18nManager.getText("menu.edit.deleterange"));
247                 _deleteRangeAction = new ActionListener() {
248                         public void actionPerformed(ActionEvent e)
249                         {
250                                 _app.deleteSelectedRange();
251                         }
252                 };
253                 _deleteRangeItem.addActionListener(_deleteRangeAction);
254                 _deleteRangeItem.setEnabled(false);
255                 editMenu.add(_deleteRangeItem);
256                 editMenu.addSeparator();
257                 _compressItem = makeMenuItem(FunctionLibrary.FUNCTION_COMPRESS);
258                 setShortcut(_compressItem, "shortcut.menu.edit.compress");
259                 _compressItem.setEnabled(false);
260                 editMenu.add(_compressItem);
261                 _deleteMarkedPointsItem = new JMenuItem(I18nManager.getText("menu.edit.deletemarked"));
262                 _deleteMarkedPointsItem.addActionListener(new ActionListener() {
263                         public void actionPerformed(ActionEvent e)
264                         {
265                                 _app.finishCompressTrack();
266                         }
267                 });
268                 _deleteMarkedPointsItem.setEnabled(false);
269                 editMenu.add(_deleteMarkedPointsItem);
270                 editMenu.addSeparator();
271                 _interpolateItem = new JMenuItem(I18nManager.getText("menu.edit.interpolate"));
272                 _interpolateItem.addActionListener(new ActionListener() {
273                         public void actionPerformed(ActionEvent e)
274                         {
275                                 _app.interpolateSelection();
276                         }
277                 });
278                 _interpolateItem.setEnabled(false);
279                 editMenu.add(_interpolateItem);
280                 _averageItem = new JMenuItem(I18nManager.getText("menu.edit.average"));
281                 _averageItem.addActionListener(new ActionListener() {
282                         public void actionPerformed(ActionEvent e)
283                         {
284                                 _app.averageSelection();
285                         }
286                 });
287                 _averageItem.setEnabled(false);
288                 editMenu.add(_averageItem);
289                 _reverseItem = new JMenuItem(I18nManager.getText("menu.edit.reverse"));
290                 _reverseItem.addActionListener(new ActionListener() {
291                         public void actionPerformed(ActionEvent e)
292                         {
293                                 _app.reverseRange();
294                         }
295                 });
296                 _reverseItem.setEnabled(false);
297                 editMenu.add(_reverseItem);
298                 _addTimeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_TIME_OFFSET);
299                 _addTimeOffsetItem.setEnabled(false);
300                 editMenu.add(_addTimeOffsetItem);
301                 _addAltitudeOffsetItem = makeMenuItem(FunctionLibrary.FUNCTION_ADD_ALTITUDE_OFFSET);
302                 _addAltitudeOffsetItem.setEnabled(false);
303                 editMenu.add(_addAltitudeOffsetItem);
304                 _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.edit.mergetracksegments"));
305                 _mergeSegmentsItem.addActionListener(new ActionListener() {
306                         public void actionPerformed(ActionEvent e)
307                         {
308                                 _app.mergeTrackSegments();
309                         }
310                 });
311                 _mergeSegmentsItem.setEnabled(false);
312                 editMenu.add(_mergeSegmentsItem);
313                 // Rearrange waypoints
314                 _rearrangeMenu = new JMenu(I18nManager.getText("menu.edit.rearrange"));
315                 _rearrangeMenu.setEnabled(false);
316                 JMenuItem  rearrangeStartItem = new JMenuItem(I18nManager.getText("menu.edit.rearrange.start"));
317                 rearrangeStartItem.addActionListener(new ActionListener() {
318                         public void actionPerformed(ActionEvent e)
319                         {
320                                 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_START);
321                         }
322                 });
323                 rearrangeStartItem.setEnabled(true);
324                 _rearrangeMenu.add(rearrangeStartItem);
325                 JMenuItem rearrangeEndItem = new JMenuItem(I18nManager.getText("menu.edit.rearrange.end"));
326                 rearrangeEndItem.addActionListener(new ActionListener() {
327                         public void actionPerformed(ActionEvent e)
328                         {
329                                 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_END);
330                         }
331                 });
332                 rearrangeEndItem.setEnabled(true);
333                 _rearrangeMenu.add(rearrangeEndItem);
334                 JMenuItem rearrangeNearestItem = new JMenuItem(I18nManager.getText("menu.edit.rearrange.nearest"));
335                 rearrangeNearestItem.addActionListener(new ActionListener() {
336                         public void actionPerformed(ActionEvent e)
337                         {
338                                 FunctionLibrary.FUNCTION_REARRANGE_WAYPOINTS.rearrangeWaypoints(Rearrange.TO_NEAREST);
339                         }
340                 });
341                 rearrangeNearestItem.setEnabled(true);
342                 _rearrangeMenu.add(rearrangeNearestItem);
343                 editMenu.add(_rearrangeMenu);
344                 _cutAndMoveItem = new JMenuItem(I18nManager.getText("menu.edit.cutandmove"));
345                 _cutAndMoveItem.addActionListener(new ActionListener() {
346                         public void actionPerformed(ActionEvent e)
347                         {
348                                 _app.cutAndMoveSelection();
349                         }
350                 });
351                 _cutAndMoveItem.setEnabled(false);
352                 editMenu.add(_cutAndMoveItem);
353                 menubar.add(editMenu);
354
355                 // Select menu
356                 JMenu selectMenu = new JMenu(I18nManager.getText("menu.select"));
357                 setAltKey(selectMenu, "altkey.menu.select");
358                 _selectAllItem = new JMenuItem(I18nManager.getText("menu.select.all"));
359                 setShortcut(_selectAllItem, "shortcut.menu.select.all");
360                 _selectAllItem.setEnabled(false);
361                 _selectAllItem.addActionListener(new ActionListener() {
362                         public void actionPerformed(ActionEvent e)
363                         {
364                                 _selection.selectRange(0, _track.getNumPoints()-1);
365                         }
366                 });
367                 selectMenu.add(_selectAllItem);
368                 _selectNoneItem = new JMenuItem(I18nManager.getText("menu.select.none"));
369                 _selectNoneItem.setEnabled(false);
370                 _selectNoneItem.addActionListener(new ActionListener() {
371                         public void actionPerformed(ActionEvent e)
372                         {
373                                 _app.selectNone();
374                         }
375                 });
376                 selectMenu.add(_selectNoneItem);
377                 selectMenu.addSeparator();
378                 _selectStartItem = new JMenuItem(I18nManager.getText("menu.select.start"));
379                 _selectStartItem.setEnabled(false);
380                 _selectStartAction = new ActionListener() {
381                         public void actionPerformed(ActionEvent e)
382                         {
383                                 _selection.selectRangeStart();
384                         }
385                 };
386                 _selectStartItem.addActionListener(_selectStartAction);
387                 selectMenu.add(_selectStartItem);
388                 _selectEndItem = new JMenuItem(I18nManager.getText("menu.select.end"));
389                 _selectEndItem.setEnabled(false);
390                 _selectEndAction = new ActionListener() {
391                         public void actionPerformed(ActionEvent e)
392                         {
393                                 _selection.selectRangeEnd();
394                         }
395                 };
396                 _selectEndItem.addActionListener(_selectEndAction);
397                 selectMenu.add(_selectEndItem);
398                 selectMenu.addSeparator();
399                 _findWaypointItem = makeMenuItem(FunctionLibrary.FUNCTION_FIND_WAYPOINT);
400                 _findWaypointItem.setEnabled(false);
401                 selectMenu.add(_findWaypointItem);
402                 menubar.add(selectMenu);
403
404                 // Add view menu
405                 JMenu viewMenu = new JMenu(I18nManager.getText("menu.view"));
406                 setAltKey(viewMenu, "altkey.menu.view");
407                 _show3dItem = makeMenuItem(FunctionLibrary.FUNCTION_3D);
408                 _show3dItem.setEnabled(false);
409                 viewMenu.add(_show3dItem);
410                 // browser submenu
411                 _browserMapMenu = new JMenu(I18nManager.getText("menu.view.browser"));
412                 _browserMapMenu.setEnabled(false);
413                 JMenuItem googleMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.google"));
414                 googleMapsItem.addActionListener(new ActionListener() {
415                         public void actionPerformed(ActionEvent e)
416                         {
417                                 _app.showExternalMap(UrlGenerator.MAP_SOURCE_GOOGLE);
418                         }
419                 });
420                 _browserMapMenu.add(googleMapsItem);
421                 JMenuItem openMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.openstreetmap"));
422                 openMapsItem.addActionListener(new ActionListener() {
423                         public void actionPerformed(ActionEvent e)
424                         {
425                                 _app.showExternalMap(UrlGenerator.MAP_SOURCE_OSM);
426                         }
427                 });
428                 _browserMapMenu.add(openMapsItem);
429                 JMenuItem mapquestMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.mapquest"));
430                 mapquestMapsItem.addActionListener(new ActionListener() {
431                         public void actionPerformed(ActionEvent e)
432                         {
433                                 _app.showExternalMap(UrlGenerator.MAP_SOURCE_MAPQUEST);
434                         }
435                 });
436                 _browserMapMenu.add(mapquestMapsItem);
437                 JMenuItem yahooMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.yahoo"));
438                 yahooMapsItem.addActionListener(new ActionListener() {
439                         public void actionPerformed(ActionEvent e)
440                         {
441                                 _app.showExternalMap(UrlGenerator.MAP_SOURCE_YAHOO);
442                         }
443                 });
444                 _browserMapMenu.add(yahooMapsItem);
445                 viewMenu.add(_browserMapMenu);
446                 // Charts
447                 _chartItem = makeMenuItem(FunctionLibrary.FUNCTION_CHARTS);
448                 _chartItem.setEnabled(false);
449                 viewMenu.add(_chartItem);
450                 // Distances
451                 _distanceItem = makeMenuItem(FunctionLibrary.FUNCTION_DISTANCES);
452                 _distanceItem.setEnabled(false);
453                 viewMenu.add(_distanceItem);
454                 // Get gpsies tracks
455                 _getGpsiesItem = makeMenuItem(FunctionLibrary.FUNCTION_GET_GPSIES);
456                 _getGpsiesItem.setEnabled(false);
457                 viewMenu.add(_getGpsiesItem);
458                 menubar.add(viewMenu);
459
460                 // Add photo menu
461                 JMenu photoMenu = new JMenu(I18nManager.getText("menu.photo"));
462                 setAltKey(photoMenu, "altkey.menu.photo");
463                 addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
464                 addPhotosMenuItem.addActionListener(_addPhotoAction);
465                 photoMenu.add(addPhotosMenuItem);
466                 _saveExifItem = new JMenuItem(I18nManager.getText("menu.photo.saveexif"));
467                 _saveExifItem.addActionListener(new ActionListener() {
468                         public void actionPerformed(ActionEvent e)
469                         {
470                                 _app.saveExif();
471                         }
472                 });
473                 _saveExifItem.setEnabled(false);
474                 photoMenu.add(_saveExifItem);
475                 _connectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.connect"));
476                 _connectPhotoAction = new ActionListener() {
477                         public void actionPerformed(ActionEvent e)
478                         {
479                                 _app.connectPhotoToPoint();
480                         }
481                 };
482                 _connectPhotoItem.addActionListener(_connectPhotoAction);
483                 _connectPhotoItem.setEnabled(false);
484                 photoMenu.addSeparator();
485                 photoMenu.add(_connectPhotoItem);
486                 // disconnect photo
487                 _disconnectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.disconnect"));
488                 _disconnectPhotoItem.addActionListener(new ActionListener() {
489                         public void actionPerformed(ActionEvent e)
490                         {
491                                 _app.disconnectPhotoFromPoint();
492                         }
493                 });
494                 _disconnectPhotoItem.setEnabled(false);
495                 photoMenu.add(_disconnectPhotoItem);
496                 _deletePhotoItem = new JMenuItem(I18nManager.getText("menu.photo.delete"));
497                 _deletePhotoItem.addActionListener(new ActionListener() {
498                         public void actionPerformed(ActionEvent e)
499                         {
500                                 _app.deleteCurrentPhoto();
501                         }
502                 });
503                 _deletePhotoItem.setEnabled(false);
504                 photoMenu.add(_deletePhotoItem);
505                 photoMenu.addSeparator();
506                 // correlate all photos
507                 _correlatePhotosItem = makeMenuItem(FunctionLibrary.FUNCTION_CORRELATE_PHOTOS);
508                 _correlatePhotosItem.setEnabled(false);
509                 photoMenu.add(_correlatePhotosItem);
510                 menubar.add(photoMenu);
511
512                 // Settings menu
513                 JMenu settingsMenu = new JMenu(I18nManager.getText("menu.settings"));
514                 setAltKey(settingsMenu, "altkey.menu.settings");
515                 // Set the map background
516                 JMenuItem mapBgItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_MAP_BG);
517                 settingsMenu.add(mapBgItem);
518                 // Turn pace display on/off
519                 _paceCheckbox = new JCheckBoxMenuItem(
520                         I18nManager.getText("menu.settings.showpace"), false);
521                 _paceCheckbox.addActionListener(new ActionListener() {
522                         public void actionPerformed(ActionEvent e) {
523                                 Config.setConfigBoolean(Config.KEY_SHOW_PACE, _paceCheckbox.isSelected());
524                                 UpdateMessageBroker.informSubscribers();
525                         }
526                 });
527                 settingsMenu.add(_paceCheckbox);
528                 // Set kmz image size
529                 JMenuItem setKmzImageSizeItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_KMZ_IMAGE_SIZE);
530                 settingsMenu.add(setKmzImageSizeItem);
531                 // Set program paths
532                 JMenuItem setPathsItem = makeMenuItem(FunctionLibrary.FUNCTION_SET_PATHS);
533                 settingsMenu.add(setPathsItem);
534                 settingsMenu.addSeparator();
535                 // Save configuration
536                 JMenuItem saveConfigMenuItem = makeMenuItem(FunctionLibrary.FUNCTION_SAVECONFIG);
537                 settingsMenu.add(saveConfigMenuItem);
538                 menubar.add(settingsMenu);
539
540                 // Help menu
541                 JMenu helpMenu = new JMenu(I18nManager.getText("menu.help"));
542                 setAltKey(helpMenu, "altkey.menu.help");
543                 JMenuItem helpItem = makeMenuItem(FunctionLibrary.FUNCTION_HELP);
544                 setShortcut(helpItem, "shortcut.menu.help.help");
545                 helpMenu.add(helpItem);
546                 JMenuItem showKeysItem = makeMenuItem(FunctionLibrary.FUNCTION_SHOW_KEYS);
547                 helpMenu.add(showKeysItem);
548                 JMenuItem aboutItem = makeMenuItem(FunctionLibrary.FUNCTION_ABOUT);
549                 helpMenu.add(aboutItem);
550                 JMenuItem checkVersionItem = makeMenuItem(FunctionLibrary.FUNCTION_CHECK_VERSION);
551                 helpMenu.add(checkVersionItem);
552                 menubar.add(helpMenu);
553
554                 return menubar;
555         }
556
557         /**
558          * Convenience method for making a menu item using a function
559          * @param inFunction function
560          * @return menu item using localized name of function
561          */
562         private static JMenuItem makeMenuItem(GenericFunction inFunction)
563         {
564                 JMenuItem item = new JMenuItem(I18nManager.getText(inFunction.getNameKey()));
565                 item.addActionListener(new FunctionLauncher(inFunction));
566                 return item;
567         }
568
569         /**
570          * Set the alt key for the given menu
571          * @param inMenu menu to set
572          * @param inKey key to lookup to get language-sensitive altkey
573          */
574         private static void setAltKey(JMenu inMenu, String inKey)
575         {
576                 // Lookup the key in the properties
577                 String altKey = I18nManager.getText(inKey);
578                 if (altKey != null && altKey.length() == 1)
579                 {
580                         int code = altKey.charAt(0) - 'A';
581                         if (code >= 0 && code < 26)
582                         {
583                                 // Found a valid code between A and Z
584                                 inMenu.setMnemonic(KEY_EVENTS[code]);
585                         }
586                 }
587         }
588
589         /**
590          * Set the shortcut key for the given menu item
591          * @param inMenuItem menu item to set
592          * @param inKey key to lookup to get language-sensitive shortcut
593          */
594         private static void setShortcut(JMenuItem inMenuItem, String inKey)
595         {
596                 // Lookup the key in the properties
597                 String altKey = I18nManager.getText(inKey);
598                 if (altKey != null && altKey.length() == 1)
599                 {
600                         int code = altKey.charAt(0) - 'A';
601                         if (code >= 0 && code < 26)
602                         {
603                                 // Found a valid code between A and Z
604                                 inMenuItem.setAccelerator(KeyStroke.getKeyStroke(KEY_EVENTS[code], InputEvent.CTRL_DOWN_MASK));
605                         }
606                 }
607         }
608
609         /**
610          * Create a JToolBar containing all toolbar buttons
611          * @return toolbar containing buttons
612          */
613         public JToolBar createToolBar()
614         {
615                 JToolBar toolbar = new JToolBar();
616                 // Add text file
617                 JButton openFileButton = new JButton(IconManager.getImageIcon(IconManager.OPEN_FILE));
618                 openFileButton.setToolTipText(I18nManager.getText("menu.file.open"));
619                 openFileButton.addActionListener(_openFileAction);
620                 toolbar.add(openFileButton);
621                 // Add photo
622                 JButton addPhotoButton = new JButton(IconManager.getImageIcon(IconManager.ADD_PHOTO));
623                 addPhotoButton.setToolTipText(I18nManager.getText("menu.file.addphotos"));
624                 addPhotoButton.addActionListener(_addPhotoAction);
625                 toolbar.add(addPhotoButton);
626                 // Save
627                 _saveButton = new JButton(IconManager.getImageIcon(IconManager.SAVE_FILE));
628                 _saveButton.setToolTipText(I18nManager.getText("menu.file.save"));
629                 _saveButton.addActionListener(_saveAction);
630                 _saveButton.setEnabled(false);
631                 toolbar.add(_saveButton);
632                 // Undo
633                 _undoButton = new JButton(IconManager.getImageIcon(IconManager.UNDO));
634                 _undoButton.setToolTipText(I18nManager.getText("menu.edit.undo"));
635                 _undoButton.addActionListener(_undoAction);
636                 _undoButton.setEnabled(false);
637                 toolbar.add(_undoButton);
638                 // Edit point
639                 _editPointButton = new JButton(IconManager.getImageIcon(IconManager.EDIT_POINT));
640                 _editPointButton.setToolTipText(I18nManager.getText("menu.edit.editpoint"));
641                 _editPointButton.addActionListener(_editPointAction);
642                 _editPointButton.setEnabled(false);
643                 toolbar.add(_editPointButton);
644                 // Delete point
645                 _deletePointButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_POINT));
646                 _deletePointButton.setToolTipText(I18nManager.getText("menu.edit.deletepoint"));
647                 _deletePointButton.addActionListener(_deletePointAction);
648                 _deletePointButton.setEnabled(false);
649                 toolbar.add(_deletePointButton);
650                 // Delete range
651                 _deleteRangeButton = new JButton(IconManager.getImageIcon(IconManager.DELETE_RANGE));
652                 _deleteRangeButton.setToolTipText(I18nManager.getText("menu.edit.deleterange"));
653                 _deleteRangeButton.addActionListener(_deleteRangeAction);
654                 _deleteRangeButton.setEnabled(false);
655                 toolbar.add(_deleteRangeButton);
656                 // Select start, end
657                 _selectStartButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_START));
658                 _selectStartButton.setToolTipText(I18nManager.getText("menu.select.start"));
659                 _selectStartButton.addActionListener(_selectStartAction);
660                 _selectStartButton.setEnabled(false);
661                 toolbar.add(_selectStartButton);
662                 _selectEndButton = new JButton(IconManager.getImageIcon(IconManager.SET_RANGE_END));
663                 _selectEndButton.setToolTipText(I18nManager.getText("menu.select.end"));
664                 _selectEndButton.addActionListener(_selectEndAction);
665                 _selectEndButton.setEnabled(false);
666                 toolbar.add(_selectEndButton);
667                 _connectPhotoButton = new JButton(IconManager.getImageIcon(IconManager.CONNECT_PHOTO));
668                 _connectPhotoButton.setToolTipText(I18nManager.getText("menu.photo.connect"));
669                 _connectPhotoButton.addActionListener(_connectPhotoAction);
670                 _connectPhotoButton.setEnabled(false);
671                 toolbar.add(_connectPhotoButton);
672                 // finish off
673                 toolbar.setFloatable(false);
674                 return toolbar;
675         }
676
677
678         /**
679          * Method to update menu when file loaded
680          */
681         public void informFileLoaded()
682         {
683                 // save, undo, delete enabled
684                 _sendGpsItem.setEnabled(true);
685                 _saveItem.setEnabled(true);
686                 _undoItem.setEnabled(true);
687                 _compressItem.setEnabled(true);
688                 _deleteMarkedPointsItem.setEnabled(false);
689         }
690
691
692         /**
693          * @see tim.prune.DataSubscriber#dataUpdated(tim.prune.data.Track)
694          */
695         public void dataUpdated(byte inUpdateType)
696         {
697                 boolean hasData = (_track != null && _track.getNumPoints() > 0);
698                 // set functions which require data
699                 _sendGpsItem.setEnabled(hasData);
700                 _saveItem.setEnabled(hasData);
701                 _saveButton.setEnabled(hasData);
702                 _exportKmlItem.setEnabled(hasData);
703                 _exportGpxItem.setEnabled(hasData);
704                 _exportPovItem.setEnabled(hasData);
705                 _compressItem.setEnabled(hasData);
706                 _deleteMarkedPointsItem.setEnabled(hasData && _track.hasMarkedPoints());
707                 _rearrangeMenu.setEnabled(hasData && _track.hasTrackPoints() && _track.hasWaypoints());
708                 _selectAllItem.setEnabled(hasData);
709                 _selectNoneItem.setEnabled(hasData);
710                 _show3dItem.setEnabled(hasData);
711                 _chartItem.setEnabled(hasData);
712                 _browserMapMenu.setEnabled(hasData);
713                 _distanceItem.setEnabled(hasData);
714                 _getGpsiesItem.setEnabled(hasData);
715                 _findWaypointItem.setEnabled(hasData && _track.hasWaypoints());
716                 // is undo available?
717                 boolean hasUndo = !_app.getUndoStack().isEmpty();
718                 _undoItem.setEnabled(hasUndo);
719                 _undoButton.setEnabled(hasUndo);
720                 _clearUndoItem.setEnabled(hasUndo);
721                 // is there a current point?
722                 boolean hasPoint = (hasData && _selection.getCurrentPointIndex() >= 0);
723                 _editPointItem.setEnabled(hasPoint);
724                 _editPointButton.setEnabled(hasPoint);
725                 _editWaypointNameItem.setEnabled(hasPoint);
726                 _deletePointItem.setEnabled(hasPoint);
727                 _deletePointButton.setEnabled(hasPoint);
728                 _selectStartItem.setEnabled(hasPoint);
729                 _selectStartButton.setEnabled(hasPoint);
730                 _selectEndItem.setEnabled(hasPoint);
731                 _selectEndButton.setEnabled(hasPoint);
732                 // are there any photos?
733                 boolean anyPhotos = _photos != null && _photos.getNumPhotos() > 0;
734                 _saveExifItem.setEnabled(anyPhotos);
735                 // is there a current photo?
736                 boolean hasPhoto = anyPhotos && _selection.getCurrentPhotoIndex() >= 0;
737                 // connect is available if photo and point selected, and photo has no point
738                 boolean connectAvailable = hasPhoto && hasPoint && _photos.getPhoto(_selection.getCurrentPhotoIndex()) != null
739                         && _photos.getPhoto(_selection.getCurrentPhotoIndex()).getDataPoint() == null;
740                 _connectPhotoItem.setEnabled(connectAvailable);
741                 _connectPhotoButton.setEnabled(connectAvailable);
742                 _disconnectPhotoItem.setEnabled(hasPhoto && _photos.getPhoto(_selection.getCurrentPhotoIndex()) != null
743                         && _photos.getPhoto(_selection.getCurrentPhotoIndex()).getDataPoint() != null);
744                 _correlatePhotosItem.setEnabled(anyPhotos && hasData);
745                 _deletePhotoItem.setEnabled(hasPhoto);
746                 // is there a current range?
747                 boolean hasRange = (hasData && _selection.hasRangeSelected());
748                 _deleteRangeItem.setEnabled(hasRange);
749                 _deleteRangeButton.setEnabled(hasRange);
750                 _interpolateItem.setEnabled(hasRange
751                         && (_selection.getEnd() - _selection.getStart()) == 1);
752                 _averageItem.setEnabled(hasRange);
753                 _mergeSegmentsItem.setEnabled(hasRange);
754                 _reverseItem.setEnabled(hasRange);
755                 _addTimeOffsetItem.setEnabled(hasRange);
756                 _addAltitudeOffsetItem.setEnabled(hasRange);
757                 // Is the currently selected point outside the current range?
758                 _cutAndMoveItem.setEnabled(hasRange && hasPoint &&
759                         (_selection.getCurrentPointIndex() < _selection.getStart()
760                                 || _selection.getCurrentPointIndex() > (_selection.getEnd()+1)));
761         }
762
763
764         /**
765          * Ignore action completed signals
766          * @see tim.prune.DataSubscriber#actionCompleted(java.lang.String)
767          */
768         public void actionCompleted(String inMessage)
769         {}
770 }