// License: GPL. For details, see LICENSE file.
package org.openstreetmap.josm.plugins.graphview.plugin.dialogs;
import static org.openstreetmap.josm.tools.I18n.tr;
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Observable;
import java.util.Observer;
import java.util.Set;
import javax.swing.AbstractAction;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.openstreetmap.josm.Main;
import org.openstreetmap.josm.gui.SideButton;
import org.openstreetmap.josm.gui.dialogs.ToggleDialog;
import org.openstreetmap.josm.plugins.graphview.core.access.AccessRulesetReader;
import org.openstreetmap.josm.plugins.graphview.core.visualisation.ColorScheme;
import org.openstreetmap.josm.plugins.graphview.core.visualisation.EndNodeColorScheme;
import org.openstreetmap.josm.plugins.graphview.core.visualisation.InclineColorScheme;
import org.openstreetmap.josm.plugins.graphview.core.visualisation.MaxheightColorScheme;
import org.openstreetmap.josm.plugins.graphview.core.visualisation.MaxspeedColorScheme;
import org.openstreetmap.josm.plugins.graphview.core.visualisation.MaxweightColorScheme;
import org.openstreetmap.josm.plugins.graphview.plugin.GraphViewPlugin;
import org.openstreetmap.josm.plugins.graphview.plugin.layer.PreferencesColorScheme;
import org.openstreetmap.josm.plugins.graphview.plugin.preferences.GraphViewPreferences;
import org.openstreetmap.josm.plugins.graphview.plugin.preferences.InternalRuleset;
import org.openstreetmap.josm.tools.Shortcut;
/**
* Dialog for graph view configuration.
*/
public class GraphViewDialog extends ToggleDialog implements Observer {
private static final int HEIGHT = 150;
/** map from labels to available color schemes */
private final LinkedHashMap<String, ColorScheme> availableColorSchemes;
private final GraphViewPreferences preferences;
private final GraphViewPlugin plugin;
private final JComboBox<String> rulesetComboBox;
private final JComboBox<String> bookmarkComboBox;
private final JComboBox<String> colorSchemeComboBox;
/**
* list of ruleset files in the order currently used by rulesetComboBox;
* null if internal rulesets are used
*/
private List<File> rulesetFiles;
public GraphViewDialog(final GraphViewPlugin plugin) {
super(tr("Graph View Dialog"), "graphview",
tr("Open the dialog for graph view configuration."), (Shortcut) null, HEIGHT);
this.preferences = GraphViewPreferences.getInstance();
this.plugin = plugin;
availableColorSchemes = new LinkedHashMap<>();
availableColorSchemes.put(tr("default"),
new PreferencesColorScheme(preferences));
availableColorSchemes.put(tr("end nodes"),
new EndNodeColorScheme(Color.GRAY, Color.RED, Color.GRAY));
availableColorSchemes.put(tr("maxspeed"),
new MaxspeedColorScheme());
availableColorSchemes.put(tr("maxweight"),
new MaxweightColorScheme());
availableColorSchemes.put(tr("maxheight"),
new MaxheightColorScheme());
availableColorSchemes.put(tr("incline"),
new InclineColorScheme());
JPanel selectionPanel = new JPanel();
GridBagLayout selectionLayout = new GridBagLayout();
selectionPanel.setLayout(selectionLayout);
GridBagConstraints gbcLabel = new GridBagConstraints();
gbcLabel.gridx = 0;
gbcLabel.anchor = GridBagConstraints.WEST;
gbcLabel.insets = new Insets(0, 5, 0, 5);
GridBagConstraints gbcComboBox = new GridBagConstraints();
gbcComboBox.gridx = 1;
gbcComboBox.fill = GridBagConstraints.HORIZONTAL;
gbcComboBox.weightx = 1;
/* create ruleset label and combo box */
{
JLabel rulesetLabel = new JLabel(tr("Ruleset:"));
gbcLabel.gridy = 0;
selectionLayout.setConstraints(rulesetLabel, gbcLabel);
selectionPanel.add(rulesetLabel);
rulesetComboBox = new JComboBox<>();
rulesetComboBox.addActionListener(rulesetActionListener);
gbcComboBox.gridy = 0;
selectionLayout.setConstraints(rulesetComboBox, gbcComboBox);
selectionPanel.add(rulesetComboBox);
}
/* create bookmark label and combo box */
{
JLabel bookmarkLabel = new JLabel(tr("Parameters:"));
gbcLabel.gridy = 1;
selectionLayout.setConstraints(bookmarkLabel, gbcLabel);
selectionPanel.add(bookmarkLabel);
bookmarkComboBox = new JComboBox<>();
bookmarkComboBox.addActionListener(bookmarkActionListener);
gbcComboBox.gridy = 1;
selectionLayout.setConstraints(bookmarkComboBox, gbcComboBox);
selectionPanel.add(bookmarkComboBox);
}
/* create color scheme label and combo box */
{
JLabel colorSchemeLabel = new JLabel(tr("Coloring:"));
gbcLabel.gridy = 2;
selectionLayout.setConstraints(colorSchemeLabel, gbcLabel);
selectionPanel.add(colorSchemeLabel);
colorSchemeComboBox = new JComboBox<>();
for (String colorSchemeName : availableColorSchemes.keySet()) {
colorSchemeComboBox.addItem(colorSchemeName);
ColorScheme colorScheme = availableColorSchemes.get(colorSchemeName);
if (colorScheme.getClass().equals(preferences.getCurrentColorScheme().getClass())) {
colorSchemeComboBox.setSelectedItem(colorSchemeName);
}
}
colorSchemeComboBox.addActionListener(colorSchemeActionListener);
gbcComboBox.gridy = 2;
selectionLayout.setConstraints(colorSchemeComboBox, gbcComboBox);
selectionPanel.add(colorSchemeComboBox);
}
createLayout(selectionPanel, true, Arrays.asList(new SideButton[] {
new SideButton(new AbstractAction(tr("Create/update graph")) {
@Override
public void actionPerformed(ActionEvent e) {
plugin.createGraphViewLayer();
}
})
}));
updateSelections();
this.preferences.addObserver(this);
}
private final ActionListener rulesetActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (rulesetComboBox.getSelectedItem() != null) {
int selectedRulesetIndex = rulesetComboBox.getSelectedIndex();
if (rulesetFiles != null) {
File selectedRulesetFile = rulesetFiles.get(selectedRulesetIndex);
preferences.setCurrentRulesetFile(selectedRulesetFile);
preferences.distributeChanges();
plugin.updateGraphViewLayer();
} else {
if (selectedRulesetIndex < InternalRuleset.values().length) {
InternalRuleset selectedIRR = InternalRuleset.values()[selectedRulesetIndex];
preferences.setCurrentInternalRuleset(selectedIRR);
preferences.distributeChanges();
plugin.updateGraphViewLayer();
}
}
}
}
};
private final ActionListener bookmarkActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String selectedBookmarkName = (String) bookmarkComboBox.getSelectedItem();
if (selectedBookmarkName != null) {
preferences.setCurrentParameterBookmarkName(selectedBookmarkName);
preferences.distributeChanges();
plugin.updateGraphViewLayer();
}
}
};
private final ActionListener colorSchemeActionListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
assert availableColorSchemes.containsKey(colorSchemeComboBox.getSelectedItem());
String colorSchemeLabel = (String) colorSchemeComboBox.getSelectedItem();
preferences.setCurrentColorScheme(availableColorSchemes.get(colorSchemeLabel));
preferences.distributeChanges();
plugin.repaintGraphViewLayer();
}
};
@Override
public void update(Observable observable, Object param) {
if (observable == preferences) {
updateSelections();
}
}
protected void updateSelections() {
/* update rulesets */
rulesetComboBox.removeActionListener(rulesetActionListener);
if (preferences.getUseInternalRulesets()) {
rulesetFiles = null;
rulesetComboBox.removeAllItems();
for (int i = 0; i < InternalRuleset.values().length; i++) {
InternalRuleset ruleset = InternalRuleset.values()[i];
rulesetComboBox.addItem(ruleset.toString());
if (ruleset == preferences.getCurrentInternalRuleset()) {
rulesetComboBox.setSelectedIndex(i);
}
}
if (preferences.getCurrentInternalRuleset() == null) {
rulesetComboBox.addItem("");
rulesetComboBox.setSelectedIndex(InternalRuleset.values().length);
}
} else {
rulesetFiles = new LinkedList<>();
File[] filesInRulesetFolder = preferences.getRulesetFolder().listFiles();
if (filesInRulesetFolder != null) {
for (File possibleRulesetFile : filesInRulesetFolder) {
try {
AccessRulesetReader.readAccessRuleset(new FileInputStream(possibleRulesetFile));
rulesetFiles.add(possibleRulesetFile);
} catch (IOException ioe) {
//don't add to rulesetFiles
Main.debug(ioe);
}
}
}
Collections.sort(rulesetFiles);
rulesetComboBox.removeAllItems();
for (int i = 0; i < rulesetFiles.size(); i++) {
File rulesetFile = rulesetFiles.get(i);
rulesetComboBox.addItem(rulesetFile.getName());
if (rulesetFile.equals(preferences.getCurrentRulesetFile())) {
rulesetComboBox.setSelectedIndex(i);
}
}
}
rulesetComboBox.addActionListener(rulesetActionListener);
/* update bookmarks */
bookmarkComboBox.removeActionListener(bookmarkActionListener);
String activeBookmarkName = preferences.getCurrentParameterBookmarkName();
Set<String> bookmarkNames = new HashSet<>(preferences.getParameterBookmarks().keySet());
bookmarkComboBox.removeAllItems();
for (String bookmarkName : bookmarkNames) {
bookmarkComboBox.addItem(bookmarkName);
if (bookmarkName.equals(activeBookmarkName)) {
bookmarkComboBox.setSelectedItem(bookmarkName);
}
}
bookmarkComboBox.addActionListener(bookmarkActionListener);
}
}