3 import java.awt.event.ActionEvent;
4 import java.awt.event.ActionListener;
5 import java.awt.event.InputEvent;
6 import java.awt.event.KeyEvent;
8 import javax.swing.ImageIcon;
9 import javax.swing.JButton;
10 import javax.swing.JFrame;
11 import javax.swing.JMenu;
12 import javax.swing.JMenuBar;
13 import javax.swing.JMenuItem;
14 import javax.swing.JToolBar;
15 import javax.swing.KeyStroke;
18 import tim.prune.DataSubscriber;
19 import tim.prune.I18nManager;
20 import tim.prune.browser.UrlGenerator;
21 import tim.prune.data.PhotoList;
22 import tim.prune.data.Selection;
23 import tim.prune.data.Track;
24 import tim.prune.data.TrackInfo;
27 * Class to manage the menu bar and tool bar,
28 * including enabling and disabling the items
30 public class MenuManager implements DataSubscriber
32 private JFrame _parent = null;
33 private App _app = null;
34 private Track _track = null;
35 private Selection _selection = null;
36 private PhotoList _photos = null;
38 // Menu items which need enabling/disabling
39 private JMenuItem _saveItem = null;
40 private JMenuItem _exportKmlItem = null;
41 private JMenuItem _exportGpxItem = null;
42 private JMenuItem _exportPovItem = null;
43 private JMenuItem _undoItem = null;
44 private JMenuItem _clearUndoItem = null;
45 private JMenuItem _editPointItem = null;
46 private JMenuItem _editWaypointNameItem = null;
47 private JMenuItem _deletePointItem = null;
48 private JMenuItem _deleteRangeItem = null;
49 private JMenuItem _deleteDuplicatesItem = null;
50 private JMenuItem _compressItem = null;
51 private JMenuItem _interpolateItem = null;
52 private JMenuItem _selectAllItem = null;
53 private JMenuItem _selectNoneItem = null;
54 private JMenuItem _selectStartItem = null;
55 private JMenuItem _selectEndItem = null;
56 private JMenuItem _reverseItem = null;
57 private JMenuItem _mergeSegmentsItem = null;
58 private JMenu _rearrangeMenu = null;
59 private JMenuItem _show3dItem = null;
60 private JMenuItem _showOsmMapItem = null;
61 private JMenu _browserMapMenu = null;
62 private JMenuItem _saveExifItem = null;
63 private JMenuItem _connectPhotoItem = null;
64 private JMenuItem _deletePhotoItem = null;
65 private JMenuItem _disconnectPhotoItem = null;
66 private JMenuItem _correlatePhotosItem = null;
68 // ActionListeners for reuse by menu and toolbar
69 private ActionListener _openFileAction = null;
70 private ActionListener _addPhotoAction = null;
71 private ActionListener _saveAction = null;
72 private ActionListener _undoAction = null;
73 private ActionListener _editPointAction = null;
74 private ActionListener _selectStartAction = null;
75 private ActionListener _selectEndAction = null;
76 private ActionListener _connectPhotoAction = null;
78 // Toolbar buttons which need enabling/disabling
79 private JButton _saveButton = null;
80 private JButton _undoButton = null;
81 private JButton _editPointButton = null;
82 private JButton _selectStartButton = null;
83 private JButton _selectEndButton = null;
84 private JButton _connectPhotoButton = null;
89 * @param inParent parent object for dialogs
90 * @param inApp application to call on menu actions
91 * @param inTrackInfo track info object
93 public MenuManager(JFrame inParent, App inApp, TrackInfo inTrackInfo)
97 _track = inTrackInfo.getTrack();
98 _selection = inTrackInfo.getSelection();
99 _photos = inTrackInfo.getPhotoList();
104 * Create a JMenuBar containing all menu items
107 public JMenuBar createMenuBar()
109 JMenuBar menubar = new JMenuBar();
110 JMenu fileMenu = new JMenu(I18nManager.getText("menu.file"));
112 JMenuItem openMenuItem = new JMenuItem(I18nManager.getText("menu.file.open"));
113 openMenuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, InputEvent.CTRL_DOWN_MASK));
114 _openFileAction = new ActionListener() {
115 public void actionPerformed(ActionEvent e)
120 openMenuItem.addActionListener(_openFileAction);
121 fileMenu.add(openMenuItem);
123 JMenuItem addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
124 _addPhotoAction = new ActionListener() {
125 public void actionPerformed(ActionEvent e)
130 addPhotosMenuItem.addActionListener(_addPhotoAction);
131 fileMenu.add(addPhotosMenuItem);
133 _saveItem = new JMenuItem(I18nManager.getText("menu.file.save"), KeyEvent.VK_S);
134 _saveAction = new ActionListener() {
135 public void actionPerformed(ActionEvent e)
140 _saveItem.addActionListener(_saveAction);
141 _saveItem.setEnabled(false);
142 fileMenu.add(_saveItem);
144 _exportKmlItem = new JMenuItem(I18nManager.getText("menu.file.exportkml"));
145 _exportKmlItem.addActionListener(new ActionListener() {
146 public void actionPerformed(ActionEvent e)
151 _exportKmlItem.setEnabled(false);
152 fileMenu.add(_exportKmlItem);
154 _exportGpxItem = new JMenuItem(I18nManager.getText("menu.file.exportgpx"));
155 _exportGpxItem.addActionListener(new ActionListener() {
156 public void actionPerformed(ActionEvent e)
161 _exportGpxItem.setEnabled(false);
162 fileMenu.add(_exportGpxItem);
164 _exportPovItem = new JMenuItem(I18nManager.getText("menu.file.exportpov"));
165 _exportPovItem.addActionListener(new ActionListener() {
166 public void actionPerformed(ActionEvent e)
171 _exportPovItem.setEnabled(false);
172 fileMenu.add(_exportPovItem);
173 fileMenu.addSeparator();
174 JMenuItem exitMenuItem = new JMenuItem(I18nManager.getText("menu.file.exit"));
175 exitMenuItem.addActionListener(new ActionListener() {
176 public void actionPerformed(ActionEvent e)
181 fileMenu.add(exitMenuItem);
182 menubar.add(fileMenu);
183 JMenu editMenu = new JMenu(I18nManager.getText("menu.edit"));
184 editMenu.setMnemonic(KeyEvent.VK_E);
185 _undoItem = new JMenuItem(I18nManager.getText("menu.edit.undo"));
186 _undoAction = new ActionListener() {
187 public void actionPerformed(ActionEvent e)
192 _undoItem.addActionListener(_undoAction);
193 _undoItem.setEnabled(false);
194 editMenu.add(_undoItem);
195 _clearUndoItem = new JMenuItem(I18nManager.getText("menu.edit.clearundo"));
196 _clearUndoItem.addActionListener(new ActionListener() {
197 public void actionPerformed(ActionEvent e)
202 _clearUndoItem.setEnabled(false);
203 editMenu.add(_clearUndoItem);
204 editMenu.addSeparator();
205 _editPointItem = new JMenuItem(I18nManager.getText("menu.edit.editpoint"));
206 _editPointAction = new ActionListener() {
207 public void actionPerformed(ActionEvent e)
209 _app.editCurrentPoint();
212 _editPointItem.addActionListener(_editPointAction);
213 _editPointItem.setEnabled(false);
214 editMenu.add(_editPointItem);
215 _editWaypointNameItem = new JMenuItem(I18nManager.getText("menu.edit.editwaypointname"));
216 _editWaypointNameItem.addActionListener(new ActionListener() {
217 public void actionPerformed(ActionEvent e)
219 _app.editCurrentPointName();
222 _editWaypointNameItem.setEnabled(false);
223 editMenu.add(_editWaypointNameItem);
224 _deletePointItem = new JMenuItem(I18nManager.getText("menu.edit.deletepoint"));
225 _deletePointItem.addActionListener(new ActionListener() {
226 public void actionPerformed(ActionEvent e)
228 _app.deleteCurrentPoint();
231 _deletePointItem.setEnabled(false);
232 editMenu.add(_deletePointItem);
233 _deleteRangeItem = new JMenuItem(I18nManager.getText("menu.edit.deleterange"));
234 _deleteRangeItem.addActionListener(new ActionListener() {
235 public void actionPerformed(ActionEvent e)
237 _app.deleteSelectedRange();
240 _deleteRangeItem.setEnabled(false);
241 editMenu.add(_deleteRangeItem);
242 _deleteDuplicatesItem = new JMenuItem(I18nManager.getText("menu.edit.deleteduplicates"));
243 _deleteDuplicatesItem.addActionListener(new ActionListener() {
244 public void actionPerformed(ActionEvent e)
246 _app.deleteDuplicates();
249 _deleteDuplicatesItem.setEnabled(false);
250 editMenu.add(_deleteDuplicatesItem);
251 _compressItem = new JMenuItem(I18nManager.getText("menu.edit.compress"));
252 _compressItem.addActionListener(new ActionListener() {
253 public void actionPerformed(ActionEvent e)
255 _app.compressTrack();
258 _compressItem.setEnabled(false);
259 editMenu.add(_compressItem);
260 editMenu.addSeparator();
261 _interpolateItem = new JMenuItem(I18nManager.getText("menu.edit.interpolate"));
262 _interpolateItem.addActionListener(new ActionListener() {
263 public void actionPerformed(ActionEvent e)
265 _app.interpolateSelection();
268 _interpolateItem.setEnabled(false);
269 editMenu.add(_interpolateItem);
270 _reverseItem = new JMenuItem(I18nManager.getText("menu.edit.reverse"));
271 _reverseItem.addActionListener(new ActionListener() {
272 public void actionPerformed(ActionEvent e)
277 _reverseItem.setEnabled(false);
278 editMenu.add(_reverseItem);
279 _mergeSegmentsItem = new JMenuItem(I18nManager.getText("menu.edit.mergetracksegments"));
280 _mergeSegmentsItem.addActionListener(new ActionListener() {
281 public void actionPerformed(ActionEvent e)
283 _app.mergeTrackSegments();
286 _mergeSegmentsItem.setEnabled(false);
287 editMenu.add(_mergeSegmentsItem);
288 // Rearrange waypoints
289 _rearrangeMenu = new JMenu(I18nManager.getText("menu.edit.rearrange"));
290 _rearrangeMenu.setEnabled(false);
291 JMenuItem rearrangeStartItem = new JMenuItem(I18nManager.getText("menu.edit.rearrange.start"));
292 rearrangeStartItem.addActionListener(new ActionListener() {
293 public void actionPerformed(ActionEvent e)
295 _app.rearrangeWaypoints(App.REARRANGE_TO_START);
298 rearrangeStartItem.setEnabled(true);
299 _rearrangeMenu.add(rearrangeStartItem);
300 JMenuItem rearrangeEndItem = new JMenuItem(I18nManager.getText("menu.edit.rearrange.end"));
301 rearrangeEndItem.addActionListener(new ActionListener() {
302 public void actionPerformed(ActionEvent e)
304 _app.rearrangeWaypoints(App.REARRANGE_TO_END);
307 rearrangeEndItem.setEnabled(true);
308 _rearrangeMenu.add(rearrangeEndItem);
309 JMenuItem rearrangeNearestItem = new JMenuItem(I18nManager.getText("menu.edit.rearrange.nearest"));
310 rearrangeNearestItem.addActionListener(new ActionListener() {
311 public void actionPerformed(ActionEvent e)
313 _app.rearrangeWaypoints(App.REARRANGE_TO_NEAREST);
316 rearrangeNearestItem.setEnabled(true);
317 _rearrangeMenu.add(rearrangeNearestItem);
318 editMenu.add(_rearrangeMenu);
319 menubar.add(editMenu);
322 JMenu selectMenu = new JMenu(I18nManager.getText("menu.select"));
323 _selectAllItem = new JMenuItem(I18nManager.getText("menu.select.all"));
324 _selectAllItem.setEnabled(false);
325 _selectAllItem.addActionListener(new ActionListener() {
326 public void actionPerformed(ActionEvent e)
331 selectMenu.add(_selectAllItem);
332 _selectNoneItem = new JMenuItem(I18nManager.getText("menu.select.none"));
333 _selectNoneItem.setEnabled(false);
334 _selectNoneItem.addActionListener(new ActionListener() {
335 public void actionPerformed(ActionEvent e)
340 selectMenu.add(_selectNoneItem);
341 selectMenu.addSeparator();
342 _selectStartItem = new JMenuItem(I18nManager.getText("menu.select.start"));
343 _selectStartItem.setEnabled(false);
344 _selectStartAction = new ActionListener() {
345 public void actionPerformed(ActionEvent e)
347 _selection.selectRangeStart();
350 _selectStartItem.addActionListener(_selectStartAction);
351 selectMenu.add(_selectStartItem);
352 _selectEndItem = new JMenuItem(I18nManager.getText("menu.select.end"));
353 _selectEndItem.setEnabled(false);
354 _selectEndAction = new ActionListener() {
355 public void actionPerformed(ActionEvent e)
357 _selection.selectRangeEnd();
360 _selectEndItem.addActionListener(_selectEndAction);
361 selectMenu.add(_selectEndItem);
362 menubar.add(selectMenu);
365 JMenu viewMenu = new JMenu(I18nManager.getText("menu.view"));
366 _show3dItem = new JMenuItem(I18nManager.getText("menu.view.show3d"));
367 _show3dItem.addActionListener(new ActionListener() {
368 public void actionPerformed(ActionEvent e)
373 _show3dItem.setEnabled(false);
374 viewMenu.add(_show3dItem);
376 _showOsmMapItem = new JMenuItem(I18nManager.getText("menu.view.showmap"));
377 _showOsmMapItem.addActionListener(new ActionListener() {
378 public void actionPerformed(ActionEvent e)
383 _showOsmMapItem.setEnabled(false);
384 viewMenu.add(_showOsmMapItem);
386 _browserMapMenu = new JMenu(I18nManager.getText("menu.view.browser"));
387 _browserMapMenu.setEnabled(false);
388 JMenuItem googleMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.google"));
389 googleMapsItem.addActionListener(new ActionListener() {
390 public void actionPerformed(ActionEvent e)
392 _app.showExternalMap(UrlGenerator.MAP_SOURCE_GOOGLE);
395 _browserMapMenu.add(googleMapsItem);
396 JMenuItem openMapsItem = new JMenuItem(I18nManager.getText("menu.view.browser.openstreetmap"));
397 openMapsItem.addActionListener(new ActionListener() {
398 public void actionPerformed(ActionEvent e)
400 _app.showExternalMap(UrlGenerator.MAP_SOURCE_OSM);
403 _browserMapMenu.add(openMapsItem);
404 viewMenu.add(_browserMapMenu);
405 menubar.add(viewMenu);
408 JMenu photoMenu = new JMenu(I18nManager.getText("menu.photo"));
409 addPhotosMenuItem = new JMenuItem(I18nManager.getText("menu.file.addphotos"));
410 addPhotosMenuItem.addActionListener(_addPhotoAction);
411 photoMenu.add(addPhotosMenuItem);
412 _saveExifItem = new JMenuItem(I18nManager.getText("menu.photo.saveexif"));
413 _saveExifItem.addActionListener(new ActionListener() {
414 public void actionPerformed(ActionEvent e)
419 _saveExifItem.setEnabled(false);
420 photoMenu.add(_saveExifItem);
421 _connectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.connect"));
422 _connectPhotoAction = new ActionListener() {
423 public void actionPerformed(ActionEvent e)
425 _app.connectPhotoToPoint();
428 _connectPhotoItem.addActionListener(_connectPhotoAction);
429 _connectPhotoItem.setEnabled(false);
430 photoMenu.addSeparator();
431 photoMenu.add(_connectPhotoItem);
433 _disconnectPhotoItem = new JMenuItem(I18nManager.getText("menu.photo.disconnect"));
434 _disconnectPhotoItem.addActionListener(new ActionListener() {
435 public void actionPerformed(ActionEvent e)
437 _app.disconnectPhotoFromPoint();
440 _disconnectPhotoItem.setEnabled(false);
441 photoMenu.add(_disconnectPhotoItem);
442 _deletePhotoItem = new JMenuItem(I18nManager.getText("menu.photo.delete"));
443 _deletePhotoItem.addActionListener(new ActionListener() {
444 public void actionPerformed(ActionEvent e)
446 _app.deleteCurrentPhoto();
449 _deletePhotoItem.setEnabled(false);
450 photoMenu.add(_deletePhotoItem);
451 photoMenu.addSeparator();
452 // correlate all photos
453 _correlatePhotosItem = new JMenuItem(I18nManager.getText("menu.photo.correlate"));
454 _correlatePhotosItem.addActionListener(new ActionListener() {
455 public void actionPerformed(ActionEvent e)
457 _app.beginCorrelatePhotos();
460 _correlatePhotosItem.setEnabled(false);
461 photoMenu.add(_correlatePhotosItem);
462 menubar.add(photoMenu);
465 JMenu helpMenu = new JMenu(I18nManager.getText("menu.help"));
466 JMenuItem helpItem = new JMenuItem(I18nManager.getText("menu.help"));
467 helpItem.addActionListener(new ActionListener() {
468 public void actionPerformed(ActionEvent e)
473 helpMenu.add(helpItem);
474 JMenuItem aboutItem = new JMenuItem(I18nManager.getText("menu.help.about"));
475 aboutItem.addActionListener(new ActionListener() {
476 public void actionPerformed(ActionEvent e)
478 new AboutScreen(_parent).show();
481 helpMenu.add(aboutItem);
482 menubar.add(helpMenu);
489 * Create a JToolBar containing all toolbar buttons
490 * @return toolbar containing buttons
492 public JToolBar createToolBar()
494 JToolBar toolbar = new JToolBar();
496 JButton openFileButton = new JButton(new ImageIcon(getClass().getResource("images/add_textfile_icon.png")));
497 openFileButton.setToolTipText(I18nManager.getText("menu.file.open"));
498 openFileButton.addActionListener(_openFileAction);
499 toolbar.add(openFileButton);
501 JButton addPhotoButton = new JButton(new ImageIcon(getClass().getResource("images/add_photo_icon.png")));
502 addPhotoButton.setToolTipText(I18nManager.getText("menu.file.addphotos"));
503 addPhotoButton.addActionListener(_addPhotoAction);
504 toolbar.add(addPhotoButton);
506 _saveButton = new JButton(new ImageIcon(getClass().getResource("images/save_icon.gif")));
507 _saveButton.setToolTipText(I18nManager.getText("menu.file.save"));
508 _saveButton.addActionListener(_saveAction);
509 _saveButton.setEnabled(false);
510 toolbar.add(_saveButton);
512 _undoButton = new JButton(new ImageIcon(getClass().getResource("images/undo_icon.gif")));
513 _undoButton.setToolTipText(I18nManager.getText("menu.edit.undo"));
514 _undoButton.addActionListener(_undoAction);
515 _undoButton.setEnabled(false);
516 toolbar.add(_undoButton);
518 _editPointButton = new JButton(new ImageIcon(getClass().getResource("images/edit_point_icon.gif")));
519 _editPointButton.setToolTipText(I18nManager.getText("menu.edit.editpoint"));
520 _editPointButton.addActionListener(_editPointAction);
521 _editPointButton.setEnabled(false);
522 toolbar.add(_editPointButton);
524 _selectStartButton = new JButton(new ImageIcon(getClass().getResource("images/set_start_icon.png")));
525 _selectStartButton.setToolTipText(I18nManager.getText("menu.select.start"));
526 _selectStartButton.addActionListener(_selectStartAction);
527 _selectStartButton.setEnabled(false);
528 toolbar.add(_selectStartButton);
529 _selectEndButton = new JButton(new ImageIcon(getClass().getResource("images/set_end_icon.png")));
530 _selectEndButton.setToolTipText(I18nManager.getText("menu.select.end"));
531 _selectEndButton.addActionListener(_selectEndAction);
532 _selectEndButton.setEnabled(false);
533 toolbar.add(_selectEndButton);
534 _connectPhotoButton = new JButton(new ImageIcon(getClass().getResource("images/connect_photo_icon.png")));
535 _connectPhotoButton.setToolTipText(I18nManager.getText("menu.photo.connect"));
536 _connectPhotoButton.addActionListener(_connectPhotoAction);
537 _connectPhotoButton.setEnabled(false);
538 toolbar.add(_connectPhotoButton);
540 toolbar.setFloatable(false);
546 * Method to update menu when file loaded
548 public void informFileLoaded()
550 // save, undo, delete enabled
551 _saveItem.setEnabled(true);
552 _undoItem.setEnabled(true);
553 _deleteDuplicatesItem.setEnabled(true);
554 _compressItem.setEnabled(true);
559 * @see tim.prune.DataSubscriber#dataUpdated(tim.prune.data.Track)
561 public void dataUpdated(byte inUpdateType)
563 boolean hasData = (_track != null && _track.getNumPoints() > 0);
564 // set functions which require data
565 _saveItem.setEnabled(hasData);
566 _saveButton.setEnabled(hasData);
567 _exportKmlItem.setEnabled(hasData);
568 _exportGpxItem.setEnabled(hasData);
569 _exportPovItem.setEnabled(hasData);
570 _deleteDuplicatesItem.setEnabled(hasData);
571 _compressItem.setEnabled(hasData);
572 _rearrangeMenu.setEnabled(hasData && _track.hasMixedData());
573 _selectAllItem.setEnabled(hasData);
574 _selectNoneItem.setEnabled(hasData);
575 if (_show3dItem != null)
576 _show3dItem.setEnabled(hasData);
577 _showOsmMapItem.setEnabled(hasData);
578 _browserMapMenu.setEnabled(hasData);
579 // is undo available?
580 boolean hasUndo = !_app.getUndoStack().isEmpty();
581 _undoItem.setEnabled(hasUndo);
582 _undoButton.setEnabled(hasUndo);
583 _clearUndoItem.setEnabled(hasUndo);
584 // is there a current point?
585 boolean hasPoint = (hasData && _selection.getCurrentPointIndex() >= 0);
586 _editPointItem.setEnabled(hasPoint);
587 _editPointButton.setEnabled(hasPoint);
588 _editWaypointNameItem.setEnabled(hasPoint);
589 _deletePointItem.setEnabled(hasPoint);
590 _selectStartItem.setEnabled(hasPoint);
591 _selectStartButton.setEnabled(hasPoint);
592 _selectEndItem.setEnabled(hasPoint);
593 _selectEndButton.setEnabled(hasPoint);
594 // are there any photos?
595 boolean anyPhotos = _photos != null && _photos.getNumPhotos() > 0;
596 _saveExifItem.setEnabled(anyPhotos);
597 // is there a current photo?
598 boolean hasPhoto = anyPhotos && _selection.getCurrentPhotoIndex() >= 0;
599 // connect is only available when current photo is not connected to current point
600 boolean connectAvailable = hasPhoto && hasPoint
601 && _track.getPoint(_selection.getCurrentPointIndex()).getPhoto() == null;
602 _connectPhotoItem.setEnabled(connectAvailable);
603 _connectPhotoButton.setEnabled(connectAvailable);
604 _disconnectPhotoItem.setEnabled(hasPhoto && _photos.getPhoto(_selection.getCurrentPhotoIndex()) != null
605 && _photos.getPhoto(_selection.getCurrentPhotoIndex()).getDataPoint() != null);
606 _correlatePhotosItem.setEnabled(anyPhotos && hasData);
607 _deletePhotoItem.setEnabled(hasPhoto);
608 // is there a current range?
609 boolean hasRange = (hasData && _selection.hasRangeSelected());
610 _deleteRangeItem.setEnabled(hasRange);
611 _interpolateItem.setEnabled(hasRange
612 && (_selection.getEnd() - _selection.getStart()) == 1);
613 _mergeSegmentsItem.setEnabled(hasRange);
614 _reverseItem.setEnabled(hasRange);
619 * Ignore action completed signals
620 * @see tim.prune.DataSubscriber#actionCompleted(java.lang.String)
622 public void actionCompleted(String inMessage)