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

Last change on this file was 19050, checked in by taylor.smock, 2 days ago

Revert most var changes from r19048, fix most new compile warnings and checkstyle issues

Also, document why various ErrorProne checks were originally disabled and fix
generic SonarLint issues.

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