// License: GPL. For details, see LICENSE file. package org.openstreetmap.josm.gui.dialogs.changeset.query; import static org.openstreetmap.josm.tools.I18n.tr; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dialog; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.event.ActionEvent; import java.awt.event.KeyEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import javax.swing.AbstractAction; import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTabbedPane; import javax.swing.KeyStroke; import org.openstreetmap.josm.gui.HelpAwareOptionPane; import org.openstreetmap.josm.gui.SideButton; import org.openstreetmap.josm.gui.help.ContextSensitiveHelpAction; import org.openstreetmap.josm.gui.help.HelpUtil; import org.openstreetmap.josm.io.ChangesetQuery; import org.openstreetmap.josm.tools.ImageProvider; import org.openstreetmap.josm.tools.WindowGeometry; /** * This is a modal dialog for entering query criteria to search for changesets. * */ public class ChangesetQueryDialog extends JDialog { private JTabbedPane tpQueryPanels; private BasicChangesetQueryPanel pnlBasicChangesetQueries; private UrlBasedQueryPanel pnlUrlBasedQueries; private AdvancedChangesetQueryPanel pnlAdvancedQueries; private boolean canceled; protected JPanel buildContentPanel() { tpQueryPanels = new JTabbedPane(); tpQueryPanels.add(pnlBasicChangesetQueries = new BasicChangesetQueryPanel()); tpQueryPanels.add(pnlUrlBasedQueries = new UrlBasedQueryPanel()); tpQueryPanels.add(pnlAdvancedQueries = new AdvancedChangesetQueryPanel()); tpQueryPanels.setTitleAt(0, tr("Basic")); tpQueryPanels.setToolTipTextAt(0, tr("Download changesets using predefined queries")); tpQueryPanels.setTitleAt(1, tr("From URL")); tpQueryPanels.setToolTipTextAt(1, tr("Query changesets from a server URL")); tpQueryPanels.setTitleAt(2, tr("Advanced")); tpQueryPanels.setToolTipTextAt(2, tr("Use a custom changeset query")); JPanel pnl = new JPanel(new BorderLayout()); pnl.add(tpQueryPanels, BorderLayout.CENTER); return pnl; } protected JPanel buildButtonPanel() { JPanel pnl = new JPanel(new FlowLayout(FlowLayout.CENTER)); // -- query action pnl.add(new SideButton(new QueryAction())); // -- cancel action pnl.add(new SideButton(new CancelAction())); // -- help action pnl.add(new SideButton(new ContextSensitiveHelpAction(HelpUtil.ht("/Dialog/ChangesetQuery")))); return pnl; } protected void build() { setTitle(tr("Query changesets")); Container cp = getContentPane(); cp.setLayout(new BorderLayout()); cp.add(buildContentPanel(), BorderLayout.CENTER); cp.add(buildButtonPanel(), BorderLayout.SOUTH); // cancel on ESC getRootPane().getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT).put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "cancel"); getRootPane().getActionMap().put("cancel", new CancelAction()); // context sensitive help HelpUtil.setHelpContext(getRootPane(), HelpUtil.ht("/Dialog/ChangesetQuery")); addWindowListener(new WindowEventHandler()); } public ChangesetQueryDialog(Dialog parent) { super(parent, true /* modal */); build(); } public ChangesetQueryDialog(Frame parent) { super(parent, true /* modal */); build(); } public boolean isCanceled() { return canceled; } public void initForUserInput() { pnlBasicChangesetQueries.init(); } protected void setCanceled(boolean canceled) { this.canceled = canceled; } public ChangesetQuery getChangesetQuery() { if (isCanceled()) return null; switch(tpQueryPanels.getSelectedIndex()) { case 0: return pnlBasicChangesetQueries.buildChangesetQuery(); case 1: return pnlUrlBasedQueries.buildChangesetQuery(); case 2: return pnlAdvancedQueries.buildChangesetQuery(); default: // FIXME: extend with advanced queries return null; } } public void startUserInput() { pnlUrlBasedQueries.startUserInput(); pnlAdvancedQueries.startUserInput(); } @Override public void setVisible(boolean visible) { if (visible) { new WindowGeometry( getClass().getName() + ".geometry", WindowGeometry.centerInWindow( getParent(), new Dimension(400,400) ) ).applySafe(this); setCanceled(false); startUserInput(); } else if (!visible && isShowing()){ new WindowGeometry(this).remember(getClass().getName() + ".geometry"); pnlAdvancedQueries.rememberSettings(); } super.setVisible(visible); } class QueryAction extends AbstractAction { public QueryAction() { putValue(NAME, tr("Query")); putValue(SMALL_ICON, ImageProvider.get("dialogs", "search")); putValue(SHORT_DESCRIPTION, tr("Query and download changesets")); } protected void alertInvalidChangesetQuery() { HelpAwareOptionPane.showOptionDialog( ChangesetQueryDialog.this, tr("Please enter a valid changeset query URL first."), tr("Illegal changeset query URL"), JOptionPane.WARNING_MESSAGE, HelpUtil.ht("/Dialog/ChangesetQueryDialog#EnterAValidChangesetQueryUrlFirst") ); } public void actionPerformed(ActionEvent arg0) { switch(tpQueryPanels.getSelectedIndex()) { case 0: // currently, query specifications can't be invalid in the basic query panel. // We select from a couple of predefined queries and there is always a query // selected break; case 1: if (getChangesetQuery() == null) { alertInvalidChangesetQuery(); pnlUrlBasedQueries.startUserInput(); return; } break; case 2: if (getChangesetQuery() == null) { pnlAdvancedQueries.displayMessageIfInvalid(); return; } } setCanceled(false); setVisible(false); } } class CancelAction extends AbstractAction { public CancelAction() { putValue(NAME, tr("Cancel")); putValue(SMALL_ICON, ImageProvider.get("cancel")); putValue(SHORT_DESCRIPTION, tr("Close the dialog and abort querying of changesets")); } public void cancel() { setCanceled(true); setVisible(false); } public void actionPerformed(ActionEvent arg0) { cancel(); } } class WindowEventHandler extends WindowAdapter { @Override public void windowClosing(WindowEvent arg0) { new CancelAction().cancel(); } } }