// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.io; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.Collection; import javax.swing.AbstractAction; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.KeyStroke; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.openstreetmap.josm.Main; import org.openstreetmap.josm.data.osm.Changeset; import org.openstreetmap.josm.gui.SideButton; import org.openstreetmap.josm.tools.ImageProvider; import org.openstreetmap.josm.tools.WindowGeometry; /** * This dialog lets the user select changesets from a list of changesets. * */ public class CloseChangesetDialog extends JDialog { /** the list */ private JList lstOpenChangesets; /** true if the user canceled the dialog */ private boolean canceled; /** the list model */ private DefaultListModel model; private SideButton btnCloseChangesets; protected JPanel buildTopPanel() { JPanel pnl = new JPanel(); pnl.setBorder(BorderFactory.createEmptyBorder(5,5,5,5)); pnl.setLayout(new BorderLayout()); pnl.add(new JLabel(tr("Please select the changesets you want to close")), BorderLayout.CENTER); return pnl; } protected JPanel buildCenterPanel() { JPanel pnl = new JPanel(); pnl.setLayout(new BorderLayout()); model = new DefaultListModel(); pnl.add(new JScrollPane(lstOpenChangesets = new JList(model)), BorderLayout.CENTER); lstOpenChangesets.setCellRenderer(new ChangesetCellRenderer()); return pnl; } protected JPanel buildSouthPanel() { JPanel pnl = new JPanel(); pnl.setLayout(new FlowLayout(FlowLayout.CENTER)); // -- close action CloseAction closeAction = new CloseAction(); lstOpenChangesets.addListSelectionListener(closeAction); pnl.add(btnCloseChangesets = new SideButton(closeAction)); btnCloseChangesets.setFocusable(true); btnCloseChangesets.getInputMap(JComponent.WHEN_FOCUSED).put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER,0), "enter"); btnCloseChangesets.getActionMap().put("enter",closeAction); // -- cancel action SideButton btn; pnl.add(btn = new SideButton(new CancelAction())); btn.setFocusable(true); return pnl; } protected void build() { setTitle(tr("Open changesets")); getContentPane().setLayout(new BorderLayout()); getContentPane().add(buildTopPanel(), BorderLayout.NORTH); getContentPane().add(buildCenterPanel(), BorderLayout.CENTER); getContentPane().add(buildSouthPanel(), BorderLayout.SOUTH); getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE,0), "escape"); getRootPane().getActionMap().put("escape", new CancelAction()); addWindowListener(new WindowEventHandler()); } @Override public void setVisible(boolean visible) { if (visible) { new WindowGeometry( getClass().getName() + ".geometry", WindowGeometry.centerInWindow(Main.parent, new Dimension(300,300)) ).applySafe(this); } else { new WindowGeometry(this).remember(getClass().getName() + ".geometry"); } super.setVisible(visible); } public CloseChangesetDialog() { super(JOptionPane.getFrameForComponent(Main.parent), ModalityType.DOCUMENT_MODAL); build(); } class CloseAction extends AbstractAction implements ListSelectionListener { public CloseAction() { putValue(NAME, tr("Close changesets")); putValue(SMALL_ICON, ImageProvider.get("closechangeset")); putValue(SHORT_DESCRIPTION, tr("Close the selected open changesets")); refreshEnabledState(); } public void actionPerformed(ActionEvent e) { setCanceled(false); setVisible(false); } protected void refreshEnabledState() { setEnabled(lstOpenChangesets.getSelectedValues() != null && lstOpenChangesets.getSelectedValues().length > 0); } public void valueChanged(ListSelectionEvent e) { refreshEnabledState(); } } class CancelAction extends AbstractAction { public CancelAction() { putValue(NAME, tr("Cancel")); putValue(SMALL_ICON, ImageProvider.get("cancel")); putValue(SHORT_DESCRIPTION, tr("Cancel closing of changesets")); } public void cancel() { setCanceled(true); setVisible(false); } public void actionPerformed(ActionEvent e) { cancel(); } } class WindowEventHandler extends WindowAdapter { @Override public void windowActivated(WindowEvent arg0) { btnCloseChangesets.requestFocusInWindow(); } @Override public void windowClosing(WindowEvent arg0) { new CancelAction().cancel(); } } /** * Replies true if this dialog was canceled * @return true if this dialog was canceled */ public boolean isCanceled() { return canceled; } /** * Sets whether this dialog is canceled * * @param canceled true, if this dialog is canceld */ protected void setCanceled(boolean canceled) { this.canceled = canceled; } /** * Sets the collection of changesets to be displayed * * @param changesets the collection of changesets. Assumes an empty collection if null */ public void setChangesets(Collection changesets) { if (changesets == null) { changesets = new ArrayList(); } model.removeAllElements(); for (Changeset cs: changesets) { model.addElement(cs); } if (!changesets.isEmpty()) { lstOpenChangesets.getSelectionModel().setSelectionInterval(0, changesets.size()-1); } } /** * Replies a collection with the changesets the user selected. * Never null, but may be empty. * * @return a collection with the changesets the user selected. */ public Collection getSelectedChangesets() { Object [] sel = lstOpenChangesets.getSelectedValues(); ArrayList ret = new ArrayList(); for (Object o: sel) { ret.add((Changeset)o); } return ret; } }