001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.preferences.advanced;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.GraphicsEnvironment;
007import java.awt.event.ActionEvent;
008import java.io.File;
009import java.util.List;
010import java.util.Locale;
011import java.util.Map;
012import java.util.stream.Collectors;
013
014import javax.swing.AbstractAction;
015import javax.swing.JFileChooser;
016import javax.swing.JOptionPane;
017import javax.swing.filechooser.FileFilter;
018
019import org.openstreetmap.josm.actions.DiskAccessAction;
020import org.openstreetmap.josm.data.Preferences;
021import org.openstreetmap.josm.gui.MainApplication;
022import org.openstreetmap.josm.gui.io.CustomConfigurator;
023import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
024import org.openstreetmap.josm.spi.preferences.Setting;
025import org.openstreetmap.josm.tools.Utils;
026import org.openstreetmap.josm.tools.ImageProvider;
027
028/**
029 * Action that exports some fragment of settings to custom configuration file
030 */
031public class ExportProfileAction extends AbstractAction {
032    private final String prefPattern;
033    private final String schemaKey;
034    private final transient Preferences prefs;
035
036    /**
037     * Constructs a new {@code ExportProfileAction}.
038     * @param prefs preferences
039     * @param schemaKey filename prefix
040     * @param prefPattern preference key pattern used to determine which entries are exported
041     */
042    public ExportProfileAction(Preferences prefs, String schemaKey, String prefPattern) {
043        super(tr("Save {0} profile", tr(schemaKey)));
044        new ImageProvider("save").getResource().attachImageIcon(this, true);
045        this.prefs = prefs;
046        this.prefPattern = prefPattern;
047        this.schemaKey = schemaKey;
048    }
049
050    @Override
051    public void actionPerformed(ActionEvent ae) {
052        Map<String, Setting<?>> all = prefs.getAllSettings();
053        List<String> keys = all.keySet().stream()
054                .filter(key -> key.matches(prefPattern))
055                .collect(Collectors.toList());
056        if (keys.isEmpty()) {
057            JOptionPane.showMessageDialog(MainApplication.getMainFrame(),
058                    tr("All the preferences of this group are default, nothing to save"), tr("Warning"), JOptionPane.WARNING_MESSAGE);
059            return;
060        }
061        File f = askUserForCustomSettingsFile();
062        if (f != null)
063           CustomConfigurator.exportPreferencesKeysToFile(f.getAbsolutePath(), false, keys);
064    }
065
066    private File askUserForCustomSettingsFile() {
067        String title = tr("Choose profile file");
068
069        FileFilter filter = new FileFilter() {
070            @Override
071            public boolean accept(File f) {
072                return f.isDirectory() || (Utils.hasExtension(f, "xml") && f.getName().toLowerCase(Locale.ENGLISH).startsWith(schemaKey));
073            }
074
075            @Override
076            public String getDescription() {
077                return tr("JOSM custom settings files (*.xml)");
078            }
079        };
080        if (!GraphicsEnvironment.isHeadless()) {
081            AbstractFileChooser fc = DiskAccessAction.createAndOpenFileChooser(false, false, title, filter,
082                    JFileChooser.FILES_ONLY, "customsettings.lastDirectory");
083            if (fc != null) {
084                File sel = fc.getSelectedFile();
085                if (!sel.getName().endsWith(".xml"))
086                    sel = new File(sel.getAbsolutePath()+".xml");
087                if (!sel.getName().startsWith(schemaKey)) {
088                    sel = new File(sel.getParentFile().getAbsolutePath()+'/'+schemaKey+'_'+sel.getName());
089                }
090                return sel;
091            }
092        }
093        return null;
094    }
095}