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 051 @Override 052 public void actionPerformed(ActionEvent e) { 053 Main.worker.submit(new DownloadOpenChangesetsTask()); 054 } 055 056 protected void onPostDownloadOpenChangesets() { 057 List<Changeset> openChangesets = ChangesetCache.getInstance().getOpenChangesetsForCurrentUser(); 058 if (openChangesets.isEmpty()) { 059 JOptionPane.showMessageDialog( 060 Main.parent, 061 tr("There are no open changesets"), 062 tr("No open changesets"), 063 JOptionPane.INFORMATION_MESSAGE 064 ); 065 return; 066 } 067 068 CloseChangesetDialog dialog = new CloseChangesetDialog(); 069 dialog.setChangesets(openChangesets); 070 dialog.setVisible(true); 071 if (dialog.isCanceled()) 072 return; 073 074 Collection<Changeset> changesetsToClose = dialog.getSelectedChangesets(); 075 CloseChangesetTask closeChangesetTask = new CloseChangesetTask(changesetsToClose); 076 Main.worker.submit(closeChangesetTask); 077 } 078 079 private final class DownloadOpenChangesetsTask extends PleaseWaitRunnable { 080 081 private boolean canceled; 082 private OsmServerChangesetReader reader; 083 private List<Changeset> changesets; 084 private Exception lastException; 085 private UserInfo userInfo; 086 087 private DownloadOpenChangesetsTask() { 088 super(tr("Downloading open changesets ..."), false /* don't ignore exceptions */); 089 } 090 091 @Override 092 protected void cancel() { 093 this.canceled = true; 094 reader.cancel(); 095 } 096 097 @Override 098 protected void finish() { 099 SwingUtilities.invokeLater( 100 new Runnable() { 101 @Override 102 public void run() { 103 if (lastException != null) { 104 ExceptionDialogUtil.explainException(lastException); 105 } 106 ChangesetCache.getInstance().update(changesets); 107 if (!canceled && lastException == null) { 108 onPostDownloadOpenChangesets(); 109 } 110 } 111 } 112 ); 113 } 114 115 /** 116 * Fetch the user info from the server. This is necessary if we don't know 117 * the users id yet 118 * 119 * @return the user info 120 * @throws OsmTransferException in case of any communication exception 121 */ 122 protected UserInfo fetchUserInfo() throws OsmTransferException { 123 OsmServerUserInfoReader reader = new OsmServerUserInfoReader(); 124 return reader.fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false)); 125 } 126 127 @Override 128 protected void realRun() throws SAXException, IOException, OsmTransferException { 129 try { 130 userInfo = fetchUserInfo(); 131 if (canceled) 132 return; 133 reader = new OsmServerChangesetReader(); 134 ChangesetQuery query = new ChangesetQuery().forUser(userInfo.getId()).beingOpen(true); 135 changesets = reader.queryChangesets( 136 query, 137 getProgressMonitor().createSubTaskMonitor(1, false /* not internal */) 138 ); 139 } catch (OsmTransferException | IllegalArgumentException e) { 140 if (canceled) 141 return; 142 lastException = e; 143 } 144 } 145 146 public boolean isCanceled() { 147 return canceled; 148 } 149 150 public Exception getLastException() { 151 return lastException; 152 } 153 } 154}