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

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

refactor of some GUI/widgets classes (impacts some plugins):

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