001// License: GPL. For details, see LICENSE file.
002package org.openstreetmap.josm.gui.dialogs.changeset.query;
003
004import static org.openstreetmap.josm.tools.I18n.tr;
005
006import java.awt.BorderLayout;
007import java.awt.GridBagConstraints;
008import java.awt.GridBagLayout;
009import java.awt.event.ItemEvent;
010import java.awt.event.ItemListener;
011
012import javax.swing.BorderFactory;
013import javax.swing.JCheckBox;
014import javax.swing.JPanel;
015import javax.swing.JScrollPane;
016
017import org.openstreetmap.josm.gui.util.GuiHelper;
018import org.openstreetmap.josm.gui.widgets.VerticallyScrollablePanel;
019import org.openstreetmap.josm.io.ChangesetQuery;
020import org.openstreetmap.josm.spi.preferences.Config;
021import org.openstreetmap.josm.tools.GBC;
022
023/**
024 * This panel allows to specify a changeset query
025 * @since 2689
026 */
027public class AdvancedChangesetQueryPanel extends JPanel {
028
029    private final JCheckBox cbUserRestriction = new JCheckBox(tr("Select changesets owned by specific users"));
030    private final JCheckBox cbOpenAndCloseRestrictions = new JCheckBox(tr("Select changesets depending on whether they are open or closed"));
031    private final JCheckBox cbTimeRestrictions = new JCheckBox(tr("Select changesets based on the date/time they have been created or closed"));
032    private final JCheckBox cbBoundingBoxRestriction = new JCheckBox(tr("Select only changesets related to a specific bounding box"));
033    private final UserRestrictionPanel pnlUserRestriction = new UserRestrictionPanel();
034    private final OpenAndCloseStateRestrictionPanel pnlOpenAndCloseRestriction = new OpenAndCloseStateRestrictionPanel();
035    private final TimeRestrictionPanel pnlTimeRestriction = new TimeRestrictionPanel();
036    private final BBoxRestrictionPanel pnlBoundingBoxRestriction = new BBoxRestrictionPanel();
037
038    /**
039     * Constructs a new {@code AdvancedChangesetQueryPanel}.
040     */
041    public AdvancedChangesetQueryPanel() {
042        build();
043    }
044
045    protected JPanel buildQueryPanel() {
046        ItemListener stateChangeHandler = new RestrictionGroupStateChangeHandler();
047        JPanel pnl = new VerticallyScrollablePanel(new GridBagLayout());
048        pnl.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
049        GridBagConstraints gc = GBC.eol().fill(GridBagConstraints.HORIZONTAL);
050
051        // -- select changesets by a specific user
052        //
053        pnl.add(cbUserRestriction, gc);
054        cbUserRestriction.addItemListener(stateChangeHandler);
055        pnl.add(pnlUserRestriction, gc);
056
057        // -- restricting the query to open and closed changesets
058        //
059        pnl.add(cbOpenAndCloseRestrictions, gc);
060        cbOpenAndCloseRestrictions.addItemListener(stateChangeHandler);
061        pnl.add(pnlOpenAndCloseRestriction, gc);
062
063        // -- restricting the query to a specific time
064        //
065        pnl.add(cbTimeRestrictions, gc);
066        cbTimeRestrictions.addItemListener(stateChangeHandler);
067        pnl.add(pnlTimeRestriction, gc);
068
069
070        // -- restricting the query to a specific bounding box
071        //
072        pnl.add(cbBoundingBoxRestriction, gc);
073        cbBoundingBoxRestriction.addItemListener(stateChangeHandler);
074        pnl.add(pnlBoundingBoxRestriction, gc);
075
076        pnl.add(new JPanel(), gc);
077
078        return pnl;
079    }
080
081    protected final void build() {
082        setLayout(new BorderLayout());
083        JScrollPane spQueryPanel = GuiHelper.embedInVerticalScrollPane(buildQueryPanel());
084        add(spQueryPanel, BorderLayout.CENTER);
085    }
086
087    /**
088     * Initializes HMI for user input.
089     */
090    public void startUserInput() {
091        restoreFromSettings();
092        pnlBoundingBoxRestriction.setVisible(cbBoundingBoxRestriction.isSelected());
093        pnlOpenAndCloseRestriction.setVisible(cbOpenAndCloseRestrictions.isSelected());
094        pnlTimeRestriction.setVisible(cbTimeRestrictions.isSelected());
095        pnlUserRestriction.setVisible(cbUserRestriction.isSelected());
096        pnlOpenAndCloseRestriction.startUserInput();
097        pnlUserRestriction.startUserInput();
098        pnlTimeRestriction.startUserInput();
099    }
100
101    /**
102     * Display error message if a field is invalid.
103     */
104    public void displayMessageIfInvalid() {
105        if (cbUserRestriction.isSelected()) {
106            if (!pnlUserRestriction.isValidChangesetQuery()) {
107                pnlUserRestriction.displayMessageIfInvalid();
108            }
109        } else if (cbTimeRestrictions.isSelected()) {
110            if (!pnlTimeRestriction.isValidChangesetQuery()) {
111                pnlTimeRestriction.displayMessageIfInvalid();
112            }
113        } else if (cbBoundingBoxRestriction.isSelected()) {
114            if (!pnlBoundingBoxRestriction.isValidChangesetQuery()) {
115                pnlBoundingBoxRestriction.displayMessageIfInvalid();
116            }
117        }
118    }
119
120    /**
121     * Builds the changeset query based on the data entered in the form.
122     *
123     * @return the changeset query. null, if the data entered doesn't represent
124     * a valid changeset query.
125     */
126    public ChangesetQuery buildChangesetQuery() {
127        ChangesetQuery query = new ChangesetQuery();
128        if (cbUserRestriction.isSelected()) {
129            if (!pnlUserRestriction.isValidChangesetQuery())
130                return null;
131            pnlUserRestriction.fillInQuery(query);
132        }
133        if (cbOpenAndCloseRestrictions.isSelected()) {
134            // don't have to check whether it's valid. It always is.
135            pnlOpenAndCloseRestriction.fillInQuery(query);
136        }
137        if (cbBoundingBoxRestriction.isSelected()) {
138            if (!pnlBoundingBoxRestriction.isValidChangesetQuery())
139                return null;
140            pnlBoundingBoxRestriction.fillInQuery(query);
141        }
142        if (cbTimeRestrictions.isSelected()) {
143            if (!pnlTimeRestriction.isValidChangesetQuery())
144                return null;
145            pnlTimeRestriction.fillInQuery(query);
146        }
147        return query;
148    }
149
150    /**
151     * Remember settings in preferences.
152     */
153    public void rememberSettings() {
154        Config.getPref().putBoolean("changeset-query.advanced.user-restrictions", cbUserRestriction.isSelected());
155        Config.getPref().putBoolean("changeset-query.advanced.open-restrictions", cbOpenAndCloseRestrictions.isSelected());
156        Config.getPref().putBoolean("changeset-query.advanced.time-restrictions", cbTimeRestrictions.isSelected());
157        Config.getPref().putBoolean("changeset-query.advanced.bbox-restrictions", cbBoundingBoxRestriction.isSelected());
158
159        pnlUserRestriction.rememberSettings();
160        pnlOpenAndCloseRestriction.rememberSettings();
161        pnlTimeRestriction.rememberSettings();
162    }
163
164    /**
165     * Restore settings from preferences.
166     */
167    public void restoreFromSettings() {
168        cbUserRestriction.setSelected(Config.getPref().getBoolean("changeset-query.advanced.user-restrictions", false));
169        cbOpenAndCloseRestrictions.setSelected(Config.getPref().getBoolean("changeset-query.advanced.open-restrictions", false));
170        cbTimeRestrictions.setSelected(Config.getPref().getBoolean("changeset-query.advanced.time-restrictions", false));
171        cbBoundingBoxRestriction.setSelected(Config.getPref().getBoolean("changeset-query.advanced.bbox-restrictions", false));
172    }
173
174    class RestrictionGroupStateChangeHandler implements ItemListener {
175        protected void userRestrictionStateChanged() {
176            pnlUserRestriction.setVisible(cbUserRestriction.isSelected());
177        }
178
179        protected void openCloseRestrictionStateChanged() {
180            pnlOpenAndCloseRestriction.setVisible(cbOpenAndCloseRestrictions.isSelected());
181        }
182
183        protected void timeRestrictionsStateChanged() {
184            pnlTimeRestriction.setVisible(cbTimeRestrictions.isSelected());
185        }
186
187        protected void boundingBoxRestrictionChanged() {
188            pnlBoundingBoxRestriction.setVisible(cbBoundingBoxRestriction.isSelected());
189        }
190
191        @Override
192        public void itemStateChanged(ItemEvent e) {
193            if (e.getSource() == cbUserRestriction) {
194                userRestrictionStateChanged();
195            } else if (e.getSource() == cbOpenAndCloseRestrictions) {
196                openCloseRestrictionStateChanged();
197            } else if (e.getSource() == cbTimeRestrictions) {
198                timeRestrictionsStateChanged();
199            } else if (e.getSource() == cbBoundingBoxRestriction) {
200                boundingBoxRestrictionChanged();
201            }
202            validate();
203            repaint();
204        }
205    }
206}