[4668] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.actions;
|
---|
| 3 |
|
---|
[4874] | 4 | import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
|
---|
[4668] | 5 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 6 |
|
---|
| 7 | import java.awt.event.ActionEvent;
|
---|
| 8 | import java.io.File;
|
---|
| 9 | import java.io.IOException;
|
---|
[6245] | 10 | import java.io.InputStream;
|
---|
| 11 | import java.net.URI;
|
---|
[9280] | 12 | import java.nio.file.Files;
|
---|
| 13 | import java.nio.file.StandardCopyOption;
|
---|
[5573] | 14 | import java.util.Arrays;
|
---|
[4668] | 15 | import java.util.List;
|
---|
| 16 |
|
---|
| 17 | import javax.swing.JFileChooser;
|
---|
| 18 | import javax.swing.JOptionPane;
|
---|
| 19 | import javax.swing.SwingUtilities;
|
---|
| 20 |
|
---|
[14120] | 21 | import org.openstreetmap.josm.data.projection.ProjectionRegistry;
|
---|
[4668] | 22 | import org.openstreetmap.josm.gui.HelpAwareOptionPane;
|
---|
[12630] | 23 | import org.openstreetmap.josm.gui.MainApplication;
|
---|
[4668] | 24 | import org.openstreetmap.josm.gui.PleaseWaitRunnable;
|
---|
| 25 | import org.openstreetmap.josm.gui.layer.Layer;
|
---|
[12486] | 26 | import org.openstreetmap.josm.gui.preferences.projection.ProjectionPreference;
|
---|
[4668] | 27 | import org.openstreetmap.josm.gui.progress.ProgressMonitor;
|
---|
[5573] | 28 | import org.openstreetmap.josm.gui.util.FileFilterAllFiles;
|
---|
[7578] | 29 | import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
|
---|
[4668] | 30 | import org.openstreetmap.josm.io.IllegalDataException;
|
---|
[6245] | 31 | import org.openstreetmap.josm.io.session.SessionImporter;
|
---|
[4668] | 32 | import org.openstreetmap.josm.io.session.SessionReader;
|
---|
[12486] | 33 | import org.openstreetmap.josm.io.session.SessionReader.SessionProjectionChoiceData;
|
---|
| 34 | import org.openstreetmap.josm.io.session.SessionReader.SessionViewportData;
|
---|
[6245] | 35 | import org.openstreetmap.josm.tools.CheckParameterUtil;
|
---|
[11746] | 36 | import org.openstreetmap.josm.tools.JosmRuntimeException;
|
---|
[12620] | 37 | import org.openstreetmap.josm.tools.Logging;
|
---|
[6245] | 38 | import org.openstreetmap.josm.tools.Utils;
|
---|
[4668] | 39 |
|
---|
[6245] | 40 | /**
|
---|
[7004] | 41 | * Loads a JOSM session.
|
---|
[6245] | 42 | * @since 4668
|
---|
| 43 | */
|
---|
[5438] | 44 | public class SessionLoadAction extends DiskAccessAction {
|
---|
[6069] | 45 |
|
---|
[6245] | 46 | /**
|
---|
| 47 | * Constructs a new {@code SessionLoadAction}.
|
---|
| 48 | */
|
---|
[4668] | 49 | public SessionLoadAction() {
|
---|
[4733] | 50 | super(tr("Load Session"), "open", tr("Load a session from file."), null, true, "load-session", true);
|
---|
[14397] | 51 | setHelpId(ht("/Action/SessionLoad"));
|
---|
[4668] | 52 | }
|
---|
| 53 |
|
---|
[6084] | 54 | @Override
|
---|
[4668] | 55 | public void actionPerformed(ActionEvent e) {
|
---|
[7578] | 56 | AbstractFileChooser fc = createAndOpenFileChooser(true, false, tr("Open session"),
|
---|
[6643] | 57 | Arrays.asList(SessionImporter.FILE_FILTER, FileFilterAllFiles.getInstance()),
|
---|
[6245] | 58 | SessionImporter.FILE_FILTER, JFileChooser.FILES_ONLY, "lastDirectory");
|
---|
[10192] | 59 | if (fc == null)
|
---|
| 60 | return;
|
---|
[4668] | 61 | File file = fc.getSelectedFile();
|
---|
[8404] | 62 | boolean zip = Utils.hasExtension(file, "joz");
|
---|
[12634] | 63 | MainApplication.worker.submit(new Loader(file, zip));
|
---|
[4668] | 64 | }
|
---|
| 65 |
|
---|
[6245] | 66 | /**
|
---|
| 67 | * JOSM session loader
|
---|
| 68 | */
|
---|
[4874] | 69 | public static class Loader extends PleaseWaitRunnable {
|
---|
[4668] | 70 |
|
---|
| 71 | private boolean canceled;
|
---|
| 72 | private File file;
|
---|
[6245] | 73 | private final URI uri;
|
---|
| 74 | private final InputStream is;
|
---|
| 75 | private final boolean zip;
|
---|
[4668] | 76 | private List<Layer> layers;
|
---|
[6271] | 77 | private Layer active;
|
---|
[4668] | 78 | private List<Runnable> postLoadTasks;
|
---|
[12486] | 79 | private SessionViewportData viewport;
|
---|
| 80 | private SessionProjectionChoiceData projectionChoice;
|
---|
[4668] | 81 |
|
---|
[6245] | 82 | /**
|
---|
| 83 | * Constructs a new {@code Loader} for local session file.
|
---|
| 84 | * @param file The JOSM session file
|
---|
| 85 | * @param zip {@code true} if the file is a session archive file (*.joz)
|
---|
| 86 | */
|
---|
[4668] | 87 | public Loader(File file, boolean zip) {
|
---|
| 88 | super(tr("Loading session ''{0}''", file.getName()));
|
---|
[6245] | 89 | CheckParameterUtil.ensureParameterNotNull(file, "file");
|
---|
[4668] | 90 | this.file = file;
|
---|
[6245] | 91 | this.uri = null;
|
---|
| 92 | this.is = null;
|
---|
[4668] | 93 | this.zip = zip;
|
---|
| 94 | }
|
---|
| 95 |
|
---|
[6245] | 96 | /**
|
---|
| 97 | * Constructs a new {@code Loader} for session file input stream (may be a remote file).
|
---|
| 98 | * @param is The input stream to session file
|
---|
| 99 | * @param uri The file URI
|
---|
| 100 | * @param zip {@code true} if the file is a session archive file (*.joz)
|
---|
| 101 | * @since 6245
|
---|
| 102 | */
|
---|
| 103 | public Loader(InputStream is, URI uri, boolean zip) {
|
---|
| 104 | super(tr("Loading session ''{0}''", uri));
|
---|
| 105 | CheckParameterUtil.ensureParameterNotNull(is, "is");
|
---|
| 106 | CheckParameterUtil.ensureParameterNotNull(uri, "uri");
|
---|
| 107 | this.file = null;
|
---|
| 108 | this.uri = uri;
|
---|
| 109 | this.is = is;
|
---|
| 110 | this.zip = zip;
|
---|
| 111 | }
|
---|
| 112 |
|
---|
[4668] | 113 | @Override
|
---|
[6245] | 114 | public void cancel() {
|
---|
[4668] | 115 | canceled = true;
|
---|
| 116 | }
|
---|
| 117 |
|
---|
| 118 | @Override
|
---|
| 119 | protected void finish() {
|
---|
[10601] | 120 | SwingUtilities.invokeLater(() -> {
|
---|
| 121 | if (canceled)
|
---|
| 122 | return;
|
---|
[12486] | 123 | if (projectionChoice != null) {
|
---|
| 124 | ProjectionPreference.setProjection(
|
---|
| 125 | projectionChoice.getProjectionChoiceId(),
|
---|
| 126 | projectionChoice.getSubPreferences(),
|
---|
| 127 | false);
|
---|
| 128 | }
|
---|
[10601] | 129 | addLayers();
|
---|
| 130 | runPostLoadTasks();
|
---|
[4668] | 131 | });
|
---|
| 132 | }
|
---|
| 133 |
|
---|
[10192] | 134 | private void addLayers() {
|
---|
| 135 | if (layers != null && !layers.isEmpty()) {
|
---|
[12630] | 136 | boolean noMap = MainApplication.getMap() == null;
|
---|
[10192] | 137 | for (Layer l : layers) {
|
---|
| 138 | if (canceled)
|
---|
| 139 | return;
|
---|
[13437] | 140 | // NoteImporter directly loads notes into current note layer
|
---|
| 141 | if (!MainApplication.getLayerManager().containsLayer(l)) {
|
---|
| 142 | MainApplication.getLayerManager().addLayer(l);
|
---|
| 143 | }
|
---|
[10192] | 144 | }
|
---|
| 145 | if (active != null) {
|
---|
[12636] | 146 | MainApplication.getLayerManager().setActiveLayer(active);
|
---|
[10192] | 147 | }
|
---|
[12486] | 148 | if (noMap && viewport != null) {
|
---|
[14120] | 149 | MainApplication.getMap().mapView.scheduleZoomTo(viewport.getEastNorthViewport(ProjectionRegistry.getProjection()));
|
---|
[10192] | 150 | }
|
---|
| 151 | }
|
---|
| 152 | }
|
---|
| 153 |
|
---|
| 154 | private void runPostLoadTasks() {
|
---|
[11645] | 155 | if (postLoadTasks != null) {
|
---|
| 156 | for (Runnable task : postLoadTasks) {
|
---|
| 157 | if (canceled)
|
---|
| 158 | return;
|
---|
| 159 | if (task == null) {
|
---|
| 160 | continue;
|
---|
| 161 | }
|
---|
| 162 | task.run();
|
---|
[10192] | 163 | }
|
---|
| 164 | }
|
---|
| 165 | }
|
---|
| 166 |
|
---|
[4668] | 167 | @Override
|
---|
| 168 | protected void realRun() {
|
---|
| 169 | try {
|
---|
| 170 | ProgressMonitor monitor = getProgressMonitor();
|
---|
| 171 | SessionReader reader = new SessionReader();
|
---|
[6245] | 172 | boolean tempFile = false;
|
---|
| 173 | try {
|
---|
| 174 | if (file == null) {
|
---|
| 175 | // Download and write entire joz file as a temp file on disk as we need random access later
|
---|
| 176 | file = File.createTempFile("session_", ".joz", Utils.getJosmTempDir());
|
---|
| 177 | tempFile = true;
|
---|
[9280] | 178 | Files.copy(is, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
---|
[6245] | 179 | }
|
---|
| 180 | reader.loadSession(file, zip, monitor);
|
---|
| 181 | layers = reader.getLayers();
|
---|
[6271] | 182 | active = reader.getActive();
|
---|
[6245] | 183 | postLoadTasks = reader.getPostLoadTasks();
|
---|
| 184 | viewport = reader.getViewport();
|
---|
[12486] | 185 | projectionChoice = reader.getProjectionChoice();
|
---|
[6245] | 186 | } finally {
|
---|
| 187 | if (tempFile) {
|
---|
[9296] | 188 | Utils.deleteFile(file);
|
---|
[6245] | 189 | file = null;
|
---|
| 190 | }
|
---|
| 191 | }
|
---|
[4668] | 192 | } catch (IllegalDataException e) {
|
---|
[7004] | 193 | handleException(tr("Data Error"), e);
|
---|
[4668] | 194 | } catch (IOException e) {
|
---|
[7004] | 195 | handleException(tr("IO Error"), e);
|
---|
[11746] | 196 | } catch (JosmRuntimeException | IllegalArgumentException | IllegalStateException e) {
|
---|
[4668] | 197 | cancel();
|
---|
| 198 | throw e;
|
---|
| 199 | }
|
---|
| 200 | }
|
---|
[7326] | 201 |
|
---|
[7004] | 202 | private void handleException(String dialogTitle, Exception e) {
|
---|
[12620] | 203 | Logging.error(e);
|
---|
[7004] | 204 | HelpAwareOptionPane.showMessageDialogInEDT(
|
---|
[14153] | 205 | MainApplication.getMainFrame(),
|
---|
[8540] | 206 | tr("<html>Could not load session file ''{0}''.<br>Error is:<br>{1}</html>",
|
---|
[11848] | 207 | uri != null ? uri : file.getName(), Utils.escapeReservedCharactersHTML(e.getMessage())),
|
---|
[7004] | 208 | dialogTitle,
|
---|
| 209 | JOptionPane.ERROR_MESSAGE,
|
---|
| 210 | null
|
---|
| 211 | );
|
---|
| 212 | cancel();
|
---|
| 213 | }
|
---|
[4668] | 214 | }
|
---|
| 215 | }
|
---|