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

Last change on this file since 12634 was 12634, checked in by Don-vip, 7 years ago

see #15182 - deprecate Main.worker, replace it by gui.MainApplication.worker + code refactoring to make sure only editor packages use it

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