001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions;
003
004import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
005import static org.openstreetmap.josm.tools.I18n.tr;
006
007import java.awt.Dialog.ModalityType;
008import java.awt.event.ActionEvent;
009import java.io.File;
010
011import javax.swing.AbstractAction;
012import javax.swing.Box;
013import javax.swing.JCheckBox;
014import javax.swing.JDialog;
015import javax.swing.JOptionPane;
016
017import org.openstreetmap.josm.Main;
018import org.openstreetmap.josm.gui.layer.Layer;
019import org.openstreetmap.josm.gui.widgets.JosmTextField;
020import org.openstreetmap.josm.spi.preferences.Config;
021import org.openstreetmap.josm.tools.ImageProvider;
022
023/**
024 * Action to rename an specific layer. Provides the option to rename the
025 * file, this layer was loaded from as well (if it was loaded from a file).
026 *
027 * @author Imi
028 */
029public class RenameLayerAction extends AbstractAction {
030
031    private final File file;
032    private final transient Layer layer;
033
034    /**
035     * Constructs a new {@code RenameLayerAction}.
036     * @param file The file of the original location of this layer.
037     *      If null, no possibility to "rename the file as well" is provided.
038     * @param layer layer to rename
039     */
040    public RenameLayerAction(File file, Layer layer) {
041        super(tr("Rename layer"));
042        new ImageProvider("dialogs", "edit").getResource().attachImageIcon(this, true);
043        this.file = file;
044        this.layer = layer;
045        this.putValue("help", ht("/Action/RenameLayer"));
046    }
047
048    static class InitialValueOptionPane extends JOptionPane {
049        InitialValueOptionPane(Box panel, JosmTextField initial) {
050            super(panel, JOptionPane.QUESTION_MESSAGE, JOptionPane.OK_CANCEL_OPTION, null, null, initial);
051        }
052
053        @Override
054        public void selectInitialValue() {
055            JosmTextField initial = (JosmTextField) getInitialValue();
056            initial.requestFocusInWindow();
057            initial.selectAll();
058        }
059    }
060
061    @Override
062    public void actionPerformed(ActionEvent e) {
063        Box panel = Box.createVerticalBox();
064        final JosmTextField name = new JosmTextField(layer.getName());
065        panel.add(name);
066        JCheckBox filerename = new JCheckBox(tr("Also rename the file"));
067        panel.add(filerename);
068        filerename.setEnabled(file != null);
069        if (filerename.isEnabled()) {
070            filerename.setSelected(Config.getPref().getBoolean("layer.rename-file", true));
071        }
072
073        final JOptionPane optionPane = new InitialValueOptionPane(panel, name);
074        final JDialog dlg = optionPane.createDialog(Main.parent, tr("Rename layer"));
075        dlg.setModalityType(ModalityType.DOCUMENT_MODAL);
076        dlg.setVisible(true);
077
078        Object answer = optionPane.getValue();
079        if (answer == null || answer == JOptionPane.UNINITIALIZED_VALUE ||
080                (answer instanceof Integer && (Integer) answer != JOptionPane.OK_OPTION))
081            return;
082
083        String nameText = name.getText();
084        if (filerename.isEnabled()) {
085            Config.getPref().putBoolean("layer.rename-file", filerename.isSelected());
086            if (filerename.isSelected()) {
087                String newname = nameText;
088                if (newname.indexOf('/') == -1 && newname.indexOf('\\') == -1) {
089                    newname = file.getParent() + File.separator + newname;
090                }
091                String oldname = file.getName();
092                if (name.getText().indexOf('.') == -1 && oldname.indexOf('.') >= 0) {
093                    newname += oldname.substring(oldname.lastIndexOf('.'));
094                }
095                File newFile = new File(newname);
096                if (!SaveActionBase.confirmOverwrite(newFile))
097                    return;
098                if (Main.platform.rename(file, newFile)) {
099                    layer.setAssociatedFile(newFile);
100                    if (!layer.isRenamed()) {
101                        nameText = newFile.getName();
102                    }
103                } else {
104                    JOptionPane.showMessageDialog(
105                            Main.parent,
106                            tr("Could not rename file ''{0}''", file.getPath()),
107                            tr("Error"),
108                            JOptionPane.ERROR_MESSAGE
109                    );
110                    return;
111                }
112            }
113        }
114        layer.rename(nameText);
115        Main.parent.repaint();
116    }
117}