/**
* GeoDress - A program for reverse geocoding
* Copyright (C) 2010 Stefan T.
*
* See COPYING for Details.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package geodress.ui.graphical;
import geodress.main.InfoConstants;
import geodress.main.Logging;
import geodress.model.PictureBox;
import geodress.model.reader.GoogleMapsReader;
import geodress.model.writer.ExifToolWriter;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.io.IOException;
import java.net.UnknownHostException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.AbstractButton;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.KeyStroke;
/**
* This is a menu bar for the GUI.
*
* @author Stefan T.
*/
public class MenuBar extends JMenuBar {
/** Logger object */
private Logger logger;
/** current box of pictures */
private PictureBox pictureBox;
/** the parent window */
private GeoDressGui parentWindow;
/** Google Maps reader object for catching the addresses */
private GoogleMapsReader googleMapsReader;
/** EXIF writer for writing to files */
private ExifToolWriter writer;
/**
* the field where the addresses should be written to
*
* @see InfoConstants
*/
private int addressField = InfoConstants.USER_COMMENT;
/**
* Builds the menu bar.
*
* @param parent
* the parent window
*/
public MenuBar(GeoDressGui parent) {
this.parentWindow = parent;
logger = Logging.getLogger(this.getClass().getName());
/* create readers and writers */
googleMapsReader = new GoogleMapsReader();
writer = new ExifToolWriter();
/* ========== File ========== */
JMenu menu = new JMenu("File");
menu.setMnemonic(KeyEvent.VK_F);
add(menu);
/* Load directory */
JMenuItem menuItem = new JMenuItem("Load directory");
menuItem.setMnemonic(KeyEvent.VK_L);
menuItem.setToolTipText("load a directory with JPEG files");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
parentWindow.loadDirectory();
}
});
menu.add(menuItem);
/* Catch addresses */
menuItem = new JMenuItem("Catch addresses");
menuItem.setMnemonic(KeyEvent.VK_A);
menuItem
.setToolTipText("catch the addresses of geocoded pictures via Google Maps");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
catchAddresses();
}
});
menu.add(menuItem);
/* Write addresses */
menuItem = new JMenuItem("Write addresses");
menuItem.setMnemonic(KeyEvent.VK_A);
menuItem
.setToolTipText("write the caught addresses to the picture files");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
writeAddresses();
}
});
// menuItem.setEnabled(false);
menu.add(menuItem);
menu.addSeparator();
/* Export as... */
JMenu subMenu = new JMenu("Export as...");
menuItem.setMnemonic(KeyEvent.VK_E);
menu.add(subMenu);
/* TXT */
menuItem = new JMenuItem("TXT");
menuItem.setToolTipText("export the picture data as text file");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
parentWindow.exportTable(PictureBox.FORMAT_TXT_OS);
}
});
subMenu.add(menuItem);
/* CSV */
menuItem = new JMenuItem("CSV");
menuItem.setToolTipText("export the picture data as CSV table");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
parentWindow.exportTable(PictureBox.FORMAT_CSV);
}
});
subMenu.add(menuItem);
menu.addSeparator();
/* Quit */
menuItem = new JMenuItem("Quit");
menuItem.setMnemonic(KeyEvent.VK_Q);
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
});
menu.add(menuItem);
/* ========== Options ========== */
menu = new JMenu("Options");
menuItem.setMnemonic(KeyEvent.VK_O);
add(menu);
/* Change Google Maps API key */
menuItem = new JMenuItem("Change Google Maps API key");
menuItem.setToolTipText("change the Google Maps API key "
+ "that is required for catching the addresses");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
changeGoogleMapsKey();
}
});
menu.add(menuItem);
/* ExifTool Path */
menuItem = new JMenuItem("Change ExifTool path");
menuItem.setToolTipText("change the path to the ExifTool executable "
+ "that is required for writing the addresses to the files");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
changeExifToolPath();
}
});
menu.add(menuItem);
/* Backup picture files */
JCheckBoxMenuItem cbMenuItem = new JCheckBoxMenuItem(
"Backup picture files");
cbMenuItem
.setToolTipText("backup all picture files before changing EXIF data like addresses");
cbMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
boolean state = ((AbstractButton) ae.getSource()).getModel()
.isSelected();
writer.setBackupMode(state);
logger.log(Level.FINE, "Backup picture files was set to: "
+ state);
}
});
cbMenuItem.setSelected(true);
menu.add(cbMenuItem);
/* Address field */
subMenu = new JMenu("Address field");
subMenu.setToolTipText("set the picture meta data field "
+ "where the caught addresses should be written to");
menu.add(subMenu);
ButtonGroup addressGroup = new ButtonGroup();
/* User comment */
JRadioButtonMenuItem rbMenuItem = new JRadioButtonMenuItem(
"User comment");
rbMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
addressField = InfoConstants.USER_COMMENT;
logger.log(Level.FINE,
"picture meta data field was set to USER_COMMENT");
}
});
rbMenuItem.setSelected(true);
addressGroup.add(rbMenuItem);
subMenu.add(rbMenuItem);
/* Image description */
rbMenuItem = new JRadioButtonMenuItem("Image description");
rbMenuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
addressField = InfoConstants.IMAGE_DESCRIPTION;
logger.log(Level.FINE,
"picture meta data field was set to IMAGE_DESCRIPTION");
}
});
addressGroup.add(rbMenuItem);
subMenu.add(rbMenuItem);
/* ========== Help ========== */
menu = new JMenu("Help");
add(menu);
/* About */
menuItem = new JMenuItem("About");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
parentWindow.showAbout();
}
});
menu.add(menuItem);
menu.addSeparator();
/* Help */
menuItem = new JMenuItem("Help");
menuItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F1, 0));
menuItem.setToolTipText("What should I do?");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
parentWindow.showHelp();
}
});
menu.add(menuItem);
}
/**
* Gets the picture box that contains the pictures.
*
* @return the picture box
*/
public PictureBox getPictureBox() {
return pictureBox;
}
/**
* Sets a new picture box with pictures
*
* @param pictureBox
* the picture box to set
*/
public void setPictureBox(PictureBox pictureBox) {
this.pictureBox = pictureBox;
}
/**
* catches the addresses for the pictures in the box
*/
private void catchAddresses() {
if (pictureBox != null) {
Thread thread = new Thread(new Runnable() {
public void run() {
try {
pictureBox.catchAddresses(googleMapsReader,
new ProgressGui(parentWindow,
"Catching addresses from "
+ googleMapsReader));
parentWindow.createPictureList(pictureBox);
} catch (UnknownHostException uhe) {
parentWindow
.showError("An error occured while connecting to Google Maps "
+ "(maybe there is no Internet connection).");
}
}
});
thread.start();
} else {
JOptionPane.showMessageDialog(parentWindow,
"There are no pictures files.", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
/**
* save the addresses to the picture files
*/
private void writeAddresses() {
if (pictureBox != null) {
if (parentWindow.showWarningDialog(InfoConstants.WRITE_WARNING)) {
Thread thread = new Thread(new Runnable() {
public void run() {
pictureBox.writeAddresses(writer, addressField,
new ProgressGui(parentWindow,
"Saving addresses to picture files"));
parentWindow.createPictureList(pictureBox);
}
});
thread.start();
}
} else {
JOptionPane.showMessageDialog(parentWindow,
"There are no pictures files.", "Error",
JOptionPane.ERROR_MESSAGE);
}
}
/**
* changes the Google Maps API key
*/
private void changeGoogleMapsKey() {
String newKey = parentWindow.askForGoogleMapsKey();
if (newKey != null && !newKey.isEmpty()) {
googleMapsReader.setGoogleMapsKey(newKey);
logger.log(Level.FINE, "Google Maps API key was changed to "
+ newKey);
}
}
/**
* changes the path to ExifTool
*/
private void changeExifToolPath() {
String newKey = parentWindow.askForExifToolPath(writer
.getExifToolPath());
try {
if (newKey != null && !newKey.isEmpty()) {
writer.setExifToolPath(newKey);
logger
.log(Level.FINE, "ExifTool path was changed to "
+ newKey);
JOptionPane.showMessageDialog(parentWindow,
"ExifTool path was changed to \"" + newKey + "\"",
"Success", JOptionPane.INFORMATION_MESSAGE);
} else {
writer.setExifToolPath(null);
logger.log(Level.FINE, "ExifTool path was deleted by user.");
}
} catch (IOException ioe) {
logger.log(Level.INFO,
"ExifTool could not be found at the given location: "
+ newKey, ioe);
JOptionPane.showMessageDialog(parentWindow,
"ExifTool could not be found at the given location.",
"Error", JOptionPane.ERROR_MESSAGE);
}
}
}