001// License: GPL. For details, see LICENSE file. 002package org.openstreetmap.josm.actions; 003 004import static org.openstreetmap.josm.gui.help.HelpUtil.ht; 005import static org.openstreetmap.josm.tools.I18n.tr; 006 007import java.awt.event.ActionEvent; 008import java.awt.event.KeyEvent; 009import java.io.IOException; 010import java.util.Collection; 011import java.util.List; 012 013import javax.swing.JOptionPane; 014import javax.swing.SwingUtilities; 015 016import org.openstreetmap.josm.Main; 017import org.openstreetmap.josm.data.osm.Changeset; 018import org.openstreetmap.josm.data.osm.ChangesetCache; 019import org.openstreetmap.josm.data.osm.UserInfo; 020import org.openstreetmap.josm.gui.ExceptionDialogUtil; 021import org.openstreetmap.josm.gui.PleaseWaitRunnable; 022import org.openstreetmap.josm.gui.io.CloseChangesetDialog; 023import org.openstreetmap.josm.gui.io.CloseChangesetTask; 024import org.openstreetmap.josm.io.ChangesetQuery; 025import org.openstreetmap.josm.io.OnlineResource; 026import org.openstreetmap.josm.io.OsmServerChangesetReader; 027import org.openstreetmap.josm.io.OsmServerUserInfoReader; 028import org.openstreetmap.josm.io.OsmTransferException; 029import org.openstreetmap.josm.tools.Shortcut; 030import org.xml.sax.SAXException; 031 032public class CloseChangesetAction extends JosmAction { 033 034 /** 035 * Constructs a new {@code CloseChangesetAction}. 036 */ 037 public CloseChangesetAction() { 038 super(tr("Close open changesets"), 039 "closechangeset", 040 tr("Closes open changesets"), 041 Shortcut.registerShortcut("system:closechangeset", 042 tr("File: {0}", tr("Closes open changesets")), 043 KeyEvent.VK_Q, Shortcut.ALT_CTRL), 044 true 045 ); 046 putValue("help", ht("/Action/CloseChangeset")); 047 setEnabled(!Main.isOffline(OnlineResource.OSM_API)); 048 049 } 050 @Override 051 public void actionPerformed(ActionEvent e) { 052 Main.worker.submit(new DownloadOpenChangesetsTask()); 053 } 054 055 protected void onPostDownloadOpenChangesets() { 056 List<Changeset> openChangesets = ChangesetCache.getInstance().getOpenChangesets(); 057 if (openChangesets.isEmpty()) { 058 JOptionPane.showMessageDialog( 059 Main.parent, 060 tr("There are no open changesets"), 061 tr("No open changesets"), 062 JOptionPane.INFORMATION_MESSAGE 063 ); 064 return; 065 } 066 067 CloseChangesetDialog dialog = new CloseChangesetDialog(); 068 dialog.setChangesets(openChangesets); 069 dialog.setVisible(true); 070 if (dialog.isCanceled()) 071 return; 072 073 Collection<Changeset> changesetsToClose = dialog.getSelectedChangesets(); 074 CloseChangesetTask closeChangesetTask = new CloseChangesetTask(changesetsToClose); 075 Main.worker.submit(closeChangesetTask); 076 } 077 078 private class DownloadOpenChangesetsTask extends PleaseWaitRunnable { 079 080 private boolean canceled; 081 private OsmServerChangesetReader reader; 082 private List<Changeset> changesets; 083 private Exception lastException; 084 private UserInfo userInfo; 085 086 public DownloadOpenChangesetsTask() { 087 super(tr("Downloading open changesets ...", false /* don't ignore exceptions */)); 088 } 089 090 @Override 091 protected void cancel() { 092 this.canceled = true; 093 reader.cancel(); 094 } 095 096 @Override 097 protected void finish() { 098 SwingUtilities.invokeLater( 099 new Runnable() { 100 @Override 101 public void run() { 102 if (lastException != null) { 103 ExceptionDialogUtil.explainException(lastException); 104 } 105 ChangesetCache.getInstance().update(changesets); 106 if (!canceled && lastException == null) { 107 onPostDownloadOpenChangesets(); 108 } 109 } 110 } 111 ); 112 } 113 114 /** 115 * Fetch the user info from the server. This is necessary if we don't know 116 * the users id yet 117 * 118 * @return the user info 119 * @throws OsmTransferException thrown in case of any communication exception 120 */ 121 protected UserInfo fetchUserInfo() throws OsmTransferException { 122 OsmServerUserInfoReader reader = new OsmServerUserInfoReader(); 123 return reader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false)); 124 } 125 126 @Override 127 protected void realRun() throws SAXException, IOException, OsmTransferException { 128 try { 129 userInfo = fetchUserInfo(); 130 if (canceled) 131 return; 132 reader = new OsmServerChangesetReader(); 133 ChangesetQuery query = new ChangesetQuery().forUser(userInfo.getId()).beingOpen(true); 134 changesets = reader.queryChangesets( 135 query, 136 getProgressMonitor().createSubTaskMonitor(1, false /* not internal */) 137 ); 138 } catch(Exception e) { 139 if (canceled) 140 return; 141 lastException = e; 142 } 143 } 144 145 public boolean isCanceled() { 146 return canceled; 147 } 148 149 public Exception getLastException() { 150 return lastException; 151 } 152 } 153}