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 086 private 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 if (lastException != null) { 100 ExceptionDialogUtil.explainException(lastException); 101 } 102 ChangesetCache.getInstance().update(changesets); 103 if (!canceled && lastException == null) { 104 onPostDownloadOpenChangesets(); 105 } 106 }); 107 } 108 109 /** 110 * Fetch the user info from the server. This is necessary if we don't know the users id yet 111 * 112 * @return the user info 113 * @throws OsmTransferException in case of any communication exception 114 */ 115 private UserInfo fetchUserInfo() throws OsmTransferException { 116 return new OsmServerUserInfoReader().fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false)); 117 } 118 119 @Override 120 protected void realRun() throws SAXException, IOException, OsmTransferException { 121 try { 122 UserInfo userInfo = fetchUserInfo(); 123 if (canceled) 124 return; 125 reader = new OsmServerChangesetReader(); 126 ChangesetQuery query = new ChangesetQuery().forUser(userInfo.getId()).beingOpen(true); 127 changesets = reader.queryChangesets( 128 query, 129 getProgressMonitor().createSubTaskMonitor(1, false /* not internal */) 130 ); 131 } catch (OsmTransferException | IllegalArgumentException e) { 132 if (canceled) 133 return; 134 lastException = e; 135 } 136 } 137 138 public boolean isCanceled() { 139 return canceled; 140 } 141 142 public Exception getLastException() { 143 return lastException; 144 } 145 } 146}