| 1 | // License: GPL. For details, see LICENSE file.
|
|---|
| 2 | package org.openstreetmap.josm.actions;
|
|---|
| 3 |
|
|---|
| 4 | import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
|
|---|
| 5 | import static org.openstreetmap.josm.tools.I18n.tr;
|
|---|
| 6 |
|
|---|
| 7 | import java.awt.event.ActionEvent;
|
|---|
| 8 | import java.awt.event.KeyEvent;
|
|---|
| 9 | import java.io.IOException;
|
|---|
| 10 | import java.util.Collection;
|
|---|
| 11 | import java.util.List;
|
|---|
| 12 |
|
|---|
| 13 | import javax.swing.JOptionPane;
|
|---|
| 14 | import javax.swing.SwingUtilities;
|
|---|
| 15 |
|
|---|
| 16 | import org.openstreetmap.josm.data.osm.Changeset;
|
|---|
| 17 | import org.openstreetmap.josm.data.osm.ChangesetCache;
|
|---|
| 18 | import org.openstreetmap.josm.data.osm.UserInfo;
|
|---|
| 19 | import org.openstreetmap.josm.gui.ExceptionDialogUtil;
|
|---|
| 20 | import org.openstreetmap.josm.gui.MainApplication;
|
|---|
| 21 | import org.openstreetmap.josm.gui.PleaseWaitRunnable;
|
|---|
| 22 | import org.openstreetmap.josm.gui.io.CloseChangesetDialog;
|
|---|
| 23 | import org.openstreetmap.josm.gui.io.CloseChangesetTask;
|
|---|
| 24 | import org.openstreetmap.josm.io.ChangesetQuery;
|
|---|
| 25 | import org.openstreetmap.josm.io.ChangesetUpdater;
|
|---|
| 26 | import org.openstreetmap.josm.io.NetworkManager;
|
|---|
| 27 | import org.openstreetmap.josm.io.OnlineResource;
|
|---|
| 28 | import org.openstreetmap.josm.io.OsmServerChangesetReader;
|
|---|
| 29 | import org.openstreetmap.josm.io.OsmServerUserInfoReader;
|
|---|
| 30 | import org.openstreetmap.josm.io.OsmTransferCanceledException;
|
|---|
| 31 | import org.openstreetmap.josm.io.OsmTransferException;
|
|---|
| 32 | import org.openstreetmap.josm.tools.Logging;
|
|---|
| 33 | import org.openstreetmap.josm.tools.Shortcut;
|
|---|
| 34 | import org.xml.sax.SAXException;
|
|---|
| 35 |
|
|---|
| 36 | /**
|
|---|
| 37 | * User action to close open changesets.
|
|---|
| 38 | * <p>
|
|---|
| 39 | * The list of open changesets will be downloaded from the server and presented
|
|---|
| 40 | * to the user.
|
|---|
| 41 | */
|
|---|
| 42 | public class CloseChangesetAction extends JosmAction {
|
|---|
| 43 |
|
|---|
| 44 | /**
|
|---|
| 45 | * Constructs a new {@code CloseChangesetAction}.
|
|---|
| 46 | */
|
|---|
| 47 | public CloseChangesetAction() {
|
|---|
| 48 | super(tr("Close open changesets..."),
|
|---|
| 49 | "closechangeset",
|
|---|
| 50 | tr("Close open changesets"),
|
|---|
| 51 | Shortcut.registerShortcut("system:closechangeset",
|
|---|
| 52 | tr("File: {0}", tr("Close open changesets")),
|
|---|
| 53 | KeyEvent.VK_Q, Shortcut.ALT_CTRL),
|
|---|
| 54 | true, false
|
|---|
| 55 | );
|
|---|
| 56 | setHelpId(ht("/Action/CloseChangeset"));
|
|---|
| 57 | setEnabled(!NetworkManager.isOffline(OnlineResource.OSM_API));
|
|---|
| 58 |
|
|---|
| 59 | }
|
|---|
| 60 |
|
|---|
| 61 | @Override
|
|---|
| 62 | public void actionPerformed(ActionEvent e) {
|
|---|
| 63 | MainApplication.worker.submit(new DownloadOpenChangesetsTask());
|
|---|
| 64 | }
|
|---|
| 65 |
|
|---|
| 66 | protected void onPostDownloadOpenChangesets() {
|
|---|
| 67 | ChangesetUpdater.check();
|
|---|
| 68 | List<Changeset> openChangesets = ChangesetCache.getInstance().getOpenChangesetsForCurrentUser();
|
|---|
| 69 | if (openChangesets.isEmpty()) {
|
|---|
| 70 | JOptionPane.showMessageDialog(
|
|---|
| 71 | MainApplication.getMainFrame(),
|
|---|
| 72 | tr("There are no open changesets"),
|
|---|
| 73 | tr("No open changesets"),
|
|---|
| 74 | JOptionPane.INFORMATION_MESSAGE
|
|---|
| 75 | );
|
|---|
| 76 | return;
|
|---|
| 77 | }
|
|---|
| 78 |
|
|---|
| 79 | CloseChangesetDialog dialog = new CloseChangesetDialog();
|
|---|
| 80 | dialog.setChangesets(openChangesets);
|
|---|
| 81 | dialog.setVisible(true);
|
|---|
| 82 | if (dialog.isCanceled())
|
|---|
| 83 | return;
|
|---|
| 84 |
|
|---|
| 85 | Collection<Changeset> changesetsToClose = dialog.getSelectedChangesets();
|
|---|
| 86 | CloseChangesetTask closeChangesetTask = new CloseChangesetTask(changesetsToClose);
|
|---|
| 87 | MainApplication.worker.submit(closeChangesetTask);
|
|---|
| 88 | }
|
|---|
| 89 |
|
|---|
| 90 | private final class DownloadOpenChangesetsTask extends PleaseWaitRunnable {
|
|---|
| 91 |
|
|---|
| 92 | private boolean canceled;
|
|---|
| 93 | private OsmServerChangesetReader reader;
|
|---|
| 94 | private List<Changeset> changesets;
|
|---|
| 95 | private Exception lastException;
|
|---|
| 96 |
|
|---|
| 97 | private DownloadOpenChangesetsTask() {
|
|---|
| 98 | super(tr("Downloading open changesets ..."), false /* don't ignore exceptions */);
|
|---|
| 99 | }
|
|---|
| 100 |
|
|---|
| 101 | @Override
|
|---|
| 102 | protected void cancel() {
|
|---|
| 103 | this.canceled = true;
|
|---|
| 104 | if (reader != null) {
|
|---|
| 105 | reader.cancel();
|
|---|
| 106 | }
|
|---|
| 107 | }
|
|---|
| 108 |
|
|---|
| 109 | @Override
|
|---|
| 110 | protected void finish() {
|
|---|
| 111 | SwingUtilities.invokeLater(() -> {
|
|---|
| 112 | Exception exception = getLastException();
|
|---|
| 113 | if (exception != null) {
|
|---|
| 114 | ExceptionDialogUtil.explainException(exception);
|
|---|
| 115 | }
|
|---|
| 116 | ChangesetCache.getInstance().update(changesets);
|
|---|
| 117 | if (!isCanceled() && exception == null) {
|
|---|
| 118 | onPostDownloadOpenChangesets();
|
|---|
| 119 | }
|
|---|
| 120 | });
|
|---|
| 121 | }
|
|---|
| 122 |
|
|---|
| 123 | /**
|
|---|
| 124 | * Fetch the user info from the server. This is necessary if we don't know the users id yet
|
|---|
| 125 | *
|
|---|
| 126 | * @return the user info
|
|---|
| 127 | * @throws OsmTransferException in case of any communication exception
|
|---|
| 128 | */
|
|---|
| 129 | private UserInfo fetchUserInfo() throws OsmTransferException {
|
|---|
| 130 | return new OsmServerUserInfoReader().fetchUserInfo(getProgressMonitor().createSubTaskMonitor(1, false));
|
|---|
| 131 | }
|
|---|
| 132 |
|
|---|
| 133 | @Override
|
|---|
| 134 | protected void realRun() throws SAXException, IOException, OsmTransferException {
|
|---|
| 135 | try {
|
|---|
| 136 | UserInfo userInfo = fetchUserInfo();
|
|---|
| 137 | if (canceled)
|
|---|
| 138 | return;
|
|---|
| 139 | reader = new OsmServerChangesetReader();
|
|---|
| 140 | ChangesetQuery query = new ChangesetQuery().forUser(userInfo.getId()).beingOpen(true);
|
|---|
| 141 | changesets = reader.queryChangesets(
|
|---|
| 142 | query,
|
|---|
| 143 | getProgressMonitor().createSubTaskMonitor(1, false /* not internal */)
|
|---|
| 144 | );
|
|---|
| 145 | } catch (OsmTransferCanceledException e) {
|
|---|
| 146 | Logging.trace(e);
|
|---|
| 147 | cancel();
|
|---|
| 148 | } catch (OsmTransferException | IllegalArgumentException e) {
|
|---|
| 149 | if (canceled)
|
|---|
| 150 | return;
|
|---|
| 151 | lastException = e;
|
|---|
| 152 | }
|
|---|
| 153 | }
|
|---|
| 154 |
|
|---|
| 155 | /**
|
|---|
| 156 | * Determines if the download task has been canceled.
|
|---|
| 157 | * @return {@code true} if the download task has been canceled
|
|---|
| 158 | */
|
|---|
| 159 | public boolean isCanceled() {
|
|---|
| 160 | return canceled;
|
|---|
| 161 | }
|
|---|
| 162 |
|
|---|
| 163 | /**
|
|---|
| 164 | * Returns the last exception that occurred.
|
|---|
| 165 | * @return the last exception that occurred, or {@code null}
|
|---|
| 166 | */
|
|---|
| 167 | public Exception getLastException() {
|
|---|
| 168 | return lastException;
|
|---|
| 169 | }
|
|---|
| 170 | }
|
|---|
| 171 | }
|
|---|