001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.actions;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.Component;
007import java.awt.GraphicsEnvironment;
008import java.awt.GridBagLayout;
009import java.util.List;
010
011import javax.swing.DefaultListCellRenderer;
012import javax.swing.Icon;
013import javax.swing.JLabel;
014import javax.swing.JList;
015import javax.swing.JOptionPane;
016import javax.swing.JPanel;
017
018import org.openstreetmap.josm.Main;
019import org.openstreetmap.josm.gui.ExtendedDialog;
020import org.openstreetmap.josm.gui.layer.Layer;
021import org.openstreetmap.josm.gui.widgets.JosmComboBox;
022import org.openstreetmap.josm.tools.GBC;
023import org.openstreetmap.josm.tools.Shortcut;
024
025public abstract class AbstractMergeAction extends JosmAction {
026
027    /**
028     * the list cell renderer used to render layer list entries
029     *
030     */
031    public static class LayerListCellRenderer extends DefaultListCellRenderer {
032
033        @Override
034        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
035            Layer layer = (Layer) value;
036            JLabel label = (JLabel) super.getListCellRendererComponent(list, layer.getName(), index, isSelected, cellHasFocus);
037            Icon icon = layer.getIcon();
038            label.setIcon(icon);
039            label.setToolTipText(layer.getToolTipText());
040            return label;
041        }
042    }
043
044    /**
045     * Constructs a new {@code AbstractMergeAction}.
046     */
047    public AbstractMergeAction() {
048        super();
049    }
050
051    public AbstractMergeAction(String name, String iconName, String tooltip, Shortcut shortcut, boolean register) {
052        super(name, iconName, tooltip, shortcut, register);
053    }
054
055    public AbstractMergeAction(String name, String iconName, String tooltip, Shortcut shortcut,
056    boolean register, String toolbar, boolean installAdapters) {
057        super(name, iconName, tooltip, shortcut, register, toolbar, installAdapters);
058    }
059
060    protected static Layer askTargetLayer(List<Layer> targetLayers) {
061        return askTargetLayer(targetLayers.toArray(new Layer[targetLayers.size()]),
062                tr("Please select the target layer."),
063                tr("Select target layer"),
064                tr("Merge"), "dialogs/mergedown");
065    }
066
067    /**
068     * Asks a target layer.
069     * @param <T> type of layer
070     * @param targetLayers array of proposed target layers
071     * @param label label displayed in dialog
072     * @param title title of dialog
073     * @param buttonText text of button used to select target layer
074     * @param buttonIcon icon name of button used to select target layer
075     * @return choosen target layer
076     */
077    @SuppressWarnings("unchecked")
078    public static <T extends Layer> T askTargetLayer(T[] targetLayers, String label, String title, String buttonText, String buttonIcon) {
079        JosmComboBox<T> layerList = new JosmComboBox<>(targetLayers);
080        layerList.setRenderer(new LayerListCellRenderer());
081        layerList.setSelectedIndex(0);
082
083        JPanel pnl = new JPanel(new GridBagLayout());
084        pnl.add(new JLabel(label), GBC.eol());
085        pnl.add(layerList, GBC.eol());
086        if (GraphicsEnvironment.isHeadless()) {
087            // return first layer in headless mode, for unit tests
088            return targetLayers[0];
089        }
090        ExtendedDialog ed = new ExtendedDialog(Main.parent, title, new String[] {buttonText, tr("Cancel")});
091        ed.setButtonIcons(new String[] {buttonIcon, "cancel"});
092        ed.setContent(pnl);
093        ed.showDialog();
094        if (ed.getValue() != 1) {
095            return null;
096        }
097        return (T) layerList.getSelectedItem();
098    }
099
100    protected void warnNoTargetLayersForSourceLayer(Layer sourceLayer) {
101        JOptionPane.showMessageDialog(Main.parent,
102                tr("<html>There are no layers the source layer<br>''{0}''<br>could be merged to.</html>", sourceLayer.getName()),
103                tr("No target layers"), JOptionPane.WARNING_MESSAGE);
104    }
105}