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

Last change on this file since 10619 was 10378, checked in by Don-vip, 8 years ago

Checkstyle 6.19: enable SingleSpaceSeparator and fix violations

  • Property svn:eol-style set to native
File size: 12.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;
14
15import javax.swing.AbstractAction;
16import javax.swing.BorderFactory;
17import javax.swing.ButtonGroup;
18import javax.swing.JButton;
19import javax.swing.JCheckBox;
20import javax.swing.JPanel;
21import javax.swing.JRadioButton;
22import javax.swing.event.ListDataEvent;
23import javax.swing.event.ListDataListener;
24
25import org.openstreetmap.josm.Main;
26import org.openstreetmap.josm.data.osm.Changeset;
27import org.openstreetmap.josm.data.osm.ChangesetCache;
28import org.openstreetmap.josm.gui.widgets.JMultilineLabel;
29import org.openstreetmap.josm.gui.widgets.JosmComboBox;
30import org.openstreetmap.josm.tools.CheckParameterUtil;
31import org.openstreetmap.josm.tools.ImageProvider;
32
33/**
34 * ChangesetManagementPanel allows to configure changeset to be used in the next
35 * upload.
36 *
37 * It is displayed as one of the configuration panels in the {@link UploadDialog}.
38 *
39 * ChangesetManagementPanel is a source for {@link java.beans.PropertyChangeEvent}s. Clients can listen
40 * 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 chosed 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 ListDataListener {
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 JRadioButton rbUseNew;
54 private JRadioButton rbExisting;
55 private JosmComboBox<Changeset> cbOpenChangesets;
56 private JCheckBox cbCloseAfterUpload;
57 private OpenChangesetComboBoxModel model;
58
59 /**
60 * Constructs a new {@code ChangesetManagementPanel}.
61 *
62 * @param changesetCommentModel the changeset comment model. Must not be null.
63 * @throws IllegalArgumentException if {@code changesetCommentModel} is null
64 */
65 public ChangesetManagementPanel(ChangesetCommentModel changesetCommentModel) {
66 CheckParameterUtil.ensureParameterNotNull(changesetCommentModel, "changesetCommentModel");
67 build();
68 refreshGUI();
69 }
70
71 /**
72 * builds the GUI
73 */
74 protected void build() {
75 setLayout(new GridBagLayout());
76 GridBagConstraints gc = new GridBagConstraints();
77 setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
78
79 ButtonGroup bgUseNewOrExisting = new ButtonGroup();
80
81 gc.gridwidth = 4;
82 gc.gridx = 0;
83 gc.gridy = 0;
84 gc.fill = GridBagConstraints.HORIZONTAL;
85 gc.weightx = 1.0;
86 gc.weighty = 0.0;
87 gc.insets = new Insets(0, 0, 5, 0);
88 add(new JMultilineLabel(
89 tr("Please decide what changeset the data is uploaded to and whether to close the changeset after the next upload.")), gc);
90
91 gc.gridwidth = 4;
92 gc.gridy = 1;
93 gc.fill = GridBagConstraints.HORIZONTAL;
94 gc.weightx = 1.0;
95 gc.weighty = 0.0;
96 gc.insets = new Insets(0, 0, 0, 0);
97 gc.anchor = GridBagConstraints.FIRST_LINE_START;
98 rbUseNew = new JRadioButton(tr("Upload to a new changeset"));
99 rbUseNew.setToolTipText(tr("Open a new changeset and use it in the next upload"));
100 bgUseNewOrExisting.add(rbUseNew);
101 add(rbUseNew, gc);
102
103 gc.gridx = 0;
104 gc.gridy = 2;
105 gc.gridwidth = 1;
106 gc.weightx = 0.0;
107 gc.fill = GridBagConstraints.HORIZONTAL;
108 rbExisting = new JRadioButton(tr("Upload to an existing changeset"));
109 rbExisting.setToolTipText(tr("Upload data to an already existing and open changeset"));
110 bgUseNewOrExisting.add(rbExisting);
111 add(rbExisting, gc);
112
113 gc.gridx = 1;
114 gc.gridy = 2;
115 gc.gridwidth = 1;
116 gc.weightx = 1.0;
117 model = new OpenChangesetComboBoxModel();
118 ChangesetCache.getInstance().addChangesetCacheListener(model);
119 cbOpenChangesets = new JosmComboBox<>(model);
120 cbOpenChangesets.setToolTipText(tr("Select an open changeset"));
121 cbOpenChangesets.setRenderer(new ChangesetCellRenderer());
122 cbOpenChangesets.addItemListener(new ChangesetListItemStateListener());
123 Dimension d = cbOpenChangesets.getPreferredSize();
124 d.width = 200;
125 cbOpenChangesets.setPreferredSize(d);
126 d.width = 100;
127 cbOpenChangesets.setMinimumSize(d);
128 model.addListDataListener(this);
129 add(cbOpenChangesets, gc);
130
131 gc.gridx = 2;
132 gc.gridy = 2;
133 gc.weightx = 0.0;
134 gc.gridwidth = 1;
135 gc.weightx = 0.0;
136 JButton btnRefresh = new JButton(new RefreshAction());
137 btnRefresh.setMargin(new Insets(0, 0, 0, 0));
138 add(btnRefresh, gc);
139
140 gc.gridx = 3;
141 gc.gridy = 2;
142 gc.gridwidth = 1;
143 CloseChangesetAction closeChangesetAction = new CloseChangesetAction();
144 JButton btnClose = new JButton(closeChangesetAction);
145 btnClose.setMargin(new Insets(0, 0, 0, 0));
146 cbOpenChangesets.addItemListener(closeChangesetAction);
147 rbExisting.addItemListener(closeChangesetAction);
148 add(btnClose, gc);
149
150 gc.gridx = 0;
151 gc.gridy = 3;
152 gc.gridwidth = 4;
153 gc.weightx = 1.0;
154 cbCloseAfterUpload = new JCheckBox(tr("Close changeset after upload"));
155 cbCloseAfterUpload.setToolTipText(tr("Select to close the changeset after the next upload"));
156 add(cbCloseAfterUpload, gc);
157 cbCloseAfterUpload.setSelected(Main.pref.getBoolean("upload.changeset.close", true));
158 cbCloseAfterUpload.addItemListener(new CloseAfterUploadItemStateListener());
159
160 gc.gridx = 0;
161 gc.gridy = 5;
162 gc.gridwidth = 4;
163 gc.weightx = 1.0;
164 gc.weighty = 1.0;
165 gc.fill = GridBagConstraints.BOTH;
166 add(new JPanel(), gc);
167
168 rbUseNew.getModel().addItemListener(new RadioButtonHandler());
169 rbExisting.getModel().addItemListener(new RadioButtonHandler());
170 }
171
172 protected void refreshGUI() {
173 rbExisting.setEnabled(model.getSize() > 0);
174 if (model.getSize() == 0 && !rbUseNew.isSelected()) {
175 rbUseNew.setSelected(true);
176 }
177 cbOpenChangesets.setEnabled(model.getSize() > 0 && rbExisting.isSelected());
178 }
179
180 /**
181 * Sets the changeset to be used in the next upload
182 *
183 * @param cs the changeset
184 */
185 public void setSelectedChangesetForNextUpload(Changeset cs) {
186 int idx = model.getIndexOf(cs);
187 if (idx >= 0) {
188 rbExisting.setSelected(true);
189 model.setSelectedItem(cs);
190 }
191 }
192
193 /**
194 * Replies the currently selected changeset. null, if no changeset is
195 * selected or if the user has chosen to use a new changeset.
196 *
197 * @return the currently selected changeset. null, if no changeset is
198 * selected.
199 */
200 public Changeset getSelectedChangeset() {
201 if (rbUseNew.isSelected())
202 return null;
203 return (Changeset) cbOpenChangesets.getSelectedItem();
204 }
205
206 /**
207 * Determines if the user has chosen to close the changeset after the next upload.
208 * @return {@code true} if the user has chosen to close the changeset after the next upload
209 */
210 public boolean isCloseChangesetAfterUpload() {
211 return cbCloseAfterUpload.isSelected();
212 }
213
214 /* ---------------------------------------------------------------------------- */
215 /* Interface ListDataListener */
216 /* ---------------------------------------------------------------------------- */
217 @Override
218 public void contentsChanged(ListDataEvent e) {
219 refreshGUI();
220 }
221
222 @Override
223 public void intervalAdded(ListDataEvent e) {
224 refreshGUI();
225 }
226
227 @Override
228 public void intervalRemoved(ListDataEvent e) {
229 refreshGUI();
230 }
231
232 /**
233 * Listens to changes in the selected changeset and fires property change events.
234 */
235 class ChangesetListItemStateListener implements ItemListener {
236 @Override
237 public void itemStateChanged(ItemEvent e) {
238 Changeset cs = (Changeset) cbOpenChangesets.getSelectedItem();
239 if (cs == null) return;
240 if (rbExisting.isSelected()) {
241 firePropertyChange(SELECTED_CHANGESET_PROP, null, cs);
242 }
243 }
244 }
245
246 /**
247 * Listens to changes in "close after upload" flag and fires property change events.
248 */
249 class CloseAfterUploadItemStateListener implements ItemListener {
250 @Override
251 public void itemStateChanged(ItemEvent e) {
252 if (e.getItemSelectable() != cbCloseAfterUpload)
253 return;
254 switch(e.getStateChange()) {
255 case ItemEvent.SELECTED:
256 firePropertyChange(CLOSE_CHANGESET_AFTER_UPLOAD, false, true);
257 Main.pref.put("upload.changeset.close", true);
258 break;
259 case ItemEvent.DESELECTED:
260 firePropertyChange(CLOSE_CHANGESET_AFTER_UPLOAD, true, false);
261 Main.pref.put("upload.changeset.close", false);
262 break;
263 default: // Do nothing
264 }
265 }
266 }
267
268 /**
269 * Listens to changes in the two radio buttons rbUseNew and rbUseExisting.
270 */
271 class RadioButtonHandler implements ItemListener {
272 @Override
273 public void itemStateChanged(ItemEvent e) {
274 if (rbUseNew.isSelected()) {
275 cbOpenChangesets.setEnabled(false);
276 firePropertyChange(SELECTED_CHANGESET_PROP, null, null);
277 } else if (rbExisting.isSelected()) {
278 cbOpenChangesets.setEnabled(true);
279 if (cbOpenChangesets.getSelectedItem() == null) {
280 model.selectFirstChangeset();
281 }
282 Changeset cs = (Changeset) cbOpenChangesets.getSelectedItem();
283 if (cs == null) return;
284 firePropertyChange(SELECTED_CHANGESET_PROP, null, cs);
285 }
286 }
287 }
288
289 /**
290 * Refreshes the list of open changesets
291 *
292 */
293 class RefreshAction extends AbstractAction {
294 RefreshAction() {
295 putValue(SHORT_DESCRIPTION, tr("Load the list of your open changesets from the server"));
296 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
297 }
298
299 @Override
300 public void actionPerformed(ActionEvent e) {
301 DownloadOpenChangesetsTask task = new DownloadOpenChangesetsTask(ChangesetManagementPanel.this);
302 Main.worker.submit(task);
303 }
304 }
305
306 /**
307 * Closes the currently selected changeset
308 *
309 */
310 class CloseChangesetAction extends AbstractAction implements ItemListener {
311 CloseChangesetAction() {
312 putValue(SMALL_ICON, ImageProvider.get("closechangeset"));
313 putValue(SHORT_DESCRIPTION, tr("Close the currently selected open changeset"));
314 refreshEnabledState();
315 }
316
317 @Override
318 public void actionPerformed(ActionEvent e) {
319 Changeset cs = (Changeset) cbOpenChangesets.getSelectedItem();
320 if (cs == null) return;
321 CloseChangesetTask task = new CloseChangesetTask(Collections.singletonList(cs));
322 Main.worker.submit(task);
323 }
324
325 protected void refreshEnabledState() {
326 setEnabled(
327 cbOpenChangesets.getModel().getSize() > 0
328 && cbOpenChangesets.getSelectedItem() != null
329 && rbExisting.isSelected()
330 );
331 }
332
333 @Override
334 public void itemStateChanged(ItemEvent e) {
335 refreshEnabledState();
336 }
337 }
338}
Note: See TracBrowser for help on using the repository browser.