source: josm/trunk/src/org/openstreetmap/josm/gui/io/ChangesetManagementPanel.java

Last change on this file was 19106, checked in by taylor.smock, 13 months ago

Cleanup some new PMD warnings from PMD 7.x (followup of r19101)

  • Property svn:eol-style set to native
File size: 10.1 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.io;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5
6import java.awt.Dimension;
7import java.awt.GridBagConstraints;
8import java.awt.GridBagLayout;
9import java.awt.Insets;
10import java.awt.event.ActionEvent;
11import java.awt.event.ItemEvent;
12import java.awt.event.ItemListener;
13import java.util.Collections;
14import java.util.Optional;
15
16import javax.swing.AbstractAction;
17import javax.swing.BorderFactory;
18import javax.swing.JButton;
19import javax.swing.JCheckBox;
20import javax.swing.JPanel;
21import javax.swing.SwingUtilities;
22
23import org.openstreetmap.josm.data.osm.Changeset;
24import org.openstreetmap.josm.data.osm.ChangesetCache;
25import org.openstreetmap.josm.data.osm.ChangesetCacheEvent;
26import org.openstreetmap.josm.data.osm.ChangesetCacheListener;
27import org.openstreetmap.josm.gui.MainApplication;
28import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
29import org.openstreetmap.josm.gui.widgets.JosmComboBox;
30import org.openstreetmap.josm.gui.widgets.JosmComboBoxModel;
31import org.openstreetmap.josm.io.OsmTransferException;
32import org.openstreetmap.josm.spi.preferences.Config;
33import org.openstreetmap.josm.tools.ImageProvider;
34import org.openstreetmap.josm.tools.Logging;
35
36/**
37 * ChangesetManagementPanel allows to configure changeset to be used in the next upload.
38 * <p>
39 * It is displayed as one of the configuration panels in the {@link UploadDialog}.
40 * <p>
41 * ChangesetManagementPanel is a source for {@link java.beans.PropertyChangeEvent}s. Clients can listen to
42 * <ul>
43 * <li>{@link #SELECTED_CHANGESET_PROP} - the new value in the property change event is
44 * the changeset selected by the user. The value is null if the user didn't select a
45 * a changeset or if he chose to use a new changeset.</li>
46 * <li> {@link #CLOSE_CHANGESET_AFTER_UPLOAD} - the new value is a boolean value indicating
47 * whether the changeset should be closed after the next upload</li>
48 * </ul>
49 */
50public class ChangesetManagementPanel extends JPanel implements ItemListener, ChangesetCacheListener {
51 static final String SELECTED_CHANGESET_PROP = ChangesetManagementPanel.class.getName() + ".selectedChangeset";
52 static final String CLOSE_CHANGESET_AFTER_UPLOAD = ChangesetManagementPanel.class.getName() + ".closeChangesetAfterUpload";
53 private static final String UPLOAD_CHANGESET_CLOSE = "upload.changeset.close";
54
55 private JosmComboBox<Changeset> cbOpenChangesets;
56 private JosmComboBoxModel<Changeset> model;
57 private JCheckBox cbCloseAfterUpload;
58
59 /**
60 * Constructs a new {@code ChangesetManagementPanel}.
61 *
62 * @since 18283 (signature)
63 */
64 public ChangesetManagementPanel() {
65 build();
66 }
67
68 /**
69 * Initializes this life cycle of the panel.
70 *
71 * @since 18283
72 */
73 public void initLifeCycle() {
74 refreshChangesets();
75 }
76
77 /**
78 * Returns the model in use.
79 * @return the model
80 */
81 public JosmComboBoxModel<Changeset> getModel() {
82 return model;
83 }
84
85 /**
86 * builds the GUI
87 */
88 protected void build() {
89 setLayout(new GridBagLayout());
90 setBorder(BorderFactory.createTitledBorder(tr("Please select a changeset:")));
91
92 GridBagConstraints gc = new GridBagConstraints();
93 gc.gridx = 0;
94 gc.gridy = 0;
95 gc.weightx = 1.0;
96 gc.weighty = 0.0;
97 gc.fill = GridBagConstraints.HORIZONTAL;
98 gc.anchor = GridBagConstraints.NORTHWEST;
99 gc.insets = new Insets(3, 3, 3, 3);
100
101 gc.gridwidth = 3;
102 add(new JMultilineLabel(tr(
103 "Please select which changeset the data shall be uploaded to and whether to close that changeset after the next upload."
104 )), gc);
105
106 gc.gridwidth = 1;
107 gc.gridy++;
108 model = new JosmComboBoxModel<>();
109 cbOpenChangesets = new JosmComboBox<>(model);
110 cbOpenChangesets.setToolTipText(tr("Select a changeset"));
111 cbOpenChangesets.setRenderer(new ChangesetCellRenderer());
112 Dimension d = cbOpenChangesets.getPreferredSize();
113 d.width = 200;
114 cbOpenChangesets.setPreferredSize(d);
115 d.width = 100;
116 cbOpenChangesets.setMinimumSize(d);
117 add(cbOpenChangesets, gc);
118 int h = cbOpenChangesets.getPreferredSize().height;
119 Dimension prefSize = new Dimension(h, h);
120
121 gc.gridx++;
122 gc.weightx = 0.0;
123 JButton btnRefresh = new JButton(new RefreshAction());
124 btnRefresh.setPreferredSize(prefSize);
125 btnRefresh.setMinimumSize(prefSize);
126 add(btnRefresh, gc);
127
128 gc.gridx++;
129 CloseChangesetAction closeChangesetAction = new CloseChangesetAction();
130 JButton btnClose = new JButton(closeChangesetAction);
131 btnClose.setPreferredSize(prefSize);
132 btnClose.setMinimumSize(prefSize);
133 add(btnClose, gc);
134
135 gc.gridy++;
136 gc.gridx = 0;
137 gc.gridwidth = 3;
138 gc.weightx = 1.0;
139 cbCloseAfterUpload = new JCheckBox(tr("Close changeset after upload"));
140 cbCloseAfterUpload.setToolTipText(tr("Select to close the changeset after the next upload"));
141 add(cbCloseAfterUpload, gc);
142
143 cbOpenChangesets.addItemListener(this);
144 cbOpenChangesets.addItemListener(closeChangesetAction);
145
146 cbCloseAfterUpload.setSelected(Config.getPref().getBoolean(UPLOAD_CHANGESET_CLOSE, true));
147 cbCloseAfterUpload.addItemListener(new CloseAfterUploadItemStateListener());
148
149 ChangesetCache.getInstance().addChangesetCacheListener(this);
150 }
151
152 /**
153 * Sets the changeset to be used in the next upload
154 * <p>
155 * Note: The changeset may be a new changeset that was automatically opened because the old
156 * changeset overflowed. In that case it was already added to the changeset cache and the
157 * combobox.
158 *
159 * @param cs the changeset
160 * @see UploadPrimitivesTask#handleChangesetFullResponse
161 */
162 public void setSelectedChangesetForNextUpload(Changeset cs) {
163 model.setSelectedItem(cs);
164 }
165
166 /**
167 * Returns the currently selected changeset or an empty new one.
168 *
169 * @return the currently selected changeset
170 */
171 public Changeset getSelectedChangeset() {
172 return Optional.ofNullable((Changeset) model.getSelectedItem()).orElse(new Changeset());
173 }
174
175 /**
176 * Determines if the user has chosen to close the changeset after the next upload.
177 * @return {@code true} if the user has chosen to close the changeset after the next upload
178 */
179 public boolean isCloseChangesetAfterUpload() {
180 return cbCloseAfterUpload.isSelected();
181 }
182
183 /**
184 * Listens to changes in the selected changeset and fires property change events.
185 */
186 @Override
187 public void itemStateChanged(ItemEvent e) {
188 firePropertyChange(SELECTED_CHANGESET_PROP, null, model.getSelectedItem());
189 }
190
191 /**
192 * Listens to changes in "close after upload" flag and fires property change events.
193 */
194 class CloseAfterUploadItemStateListener implements ItemListener {
195 @Override
196 public void itemStateChanged(ItemEvent e) {
197 if (e.getItemSelectable() != cbCloseAfterUpload)
198 return;
199 switch (e.getStateChange()) {
200 case ItemEvent.SELECTED:
201 firePropertyChange(CLOSE_CHANGESET_AFTER_UPLOAD, false, true);
202 Config.getPref().putBoolean(UPLOAD_CHANGESET_CLOSE, true);
203 break;
204 case ItemEvent.DESELECTED:
205 firePropertyChange(CLOSE_CHANGESET_AFTER_UPLOAD, true, false);
206 Config.getPref().putBoolean(UPLOAD_CHANGESET_CLOSE, false);
207 break;
208 default: // Do nothing
209 }
210 }
211 }
212
213 /**
214 * Refreshes the list of open changesets
215 */
216 class RefreshAction extends AbstractAction {
217 RefreshAction() {
218 putValue(SHORT_DESCRIPTION, tr("Load the list of your open changesets from the server"));
219 new ImageProvider("dialogs", "refresh").getResource().attachImageIcon(this, true);
220 }
221
222 @Override
223 public void actionPerformed(ActionEvent e) {
224 MainApplication.worker.submit(new DownloadOpenChangesetsTask(ChangesetManagementPanel.this));
225 }
226 }
227
228 /**
229 * Closes the currently selected changeset
230 */
231 class CloseChangesetAction extends AbstractAction implements ItemListener {
232 CloseChangesetAction() {
233 new ImageProvider("closechangeset").getResource().attachImageIcon(this, true);
234 putValue(SHORT_DESCRIPTION, tr("Close the currently selected open changeset"));
235 refreshEnabledState();
236 }
237
238 @Override
239 public void actionPerformed(ActionEvent e) {
240 Changeset cs = (Changeset) cbOpenChangesets.getSelectedItem();
241 if (cs == null) return;
242 MainApplication.worker.submit(new CloseChangesetTask(Collections.singletonList(cs)));
243 }
244
245 protected void refreshEnabledState() {
246 setEnabled(!getSelectedChangeset().isNew());
247 }
248
249 @Override
250 public void itemStateChanged(ItemEvent e) {
251 refreshEnabledState();
252 }
253 }
254
255 /**
256 * Refreshes the changesets combobox form the server.
257 * <p>
258 * Note: This calls into {@link #refreshCombo} through {@link #changesetCacheUpdated}
259 *
260 * @see ChangesetCache#refreshChangesetsFromServer
261 */
262 protected void refreshChangesets() {
263 try {
264 ChangesetCache.getInstance().refreshChangesetsFromServer();
265 } catch (OsmTransferException e) {
266 Logging.trace(e);
267 }
268 }
269
270 private void refreshCombo() {
271 Changeset selected = (Changeset) cbOpenChangesets.getSelectedItem();
272 model.removeAllElements();
273 model.addElement(new Changeset());
274 model.addAllElements(ChangesetCache.getInstance().getOpenChangesetsForCurrentUser());
275 cbOpenChangesets.setSelectedItem(selected != null && model.getIndexOf(selected) != -1 ? selected : model.getElementAt(0));
276 }
277
278 @Override
279 public void changesetCacheUpdated(ChangesetCacheEvent event) {
280 // This listener might have been called by a background task.
281 SwingUtilities.invokeLater(this::refreshCombo);
282 }
283}
Note: See TracBrowser for help on using the repository browser.