[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 |
|
---|
| 21 | import org.openstreetmap.josm.Main;
|
---|
[6992] | 22 | import org.openstreetmap.josm.data.ViewportData;
|
---|
[4668] | 23 | import org.openstreetmap.josm.gui.HelpAwareOptionPane;
|
---|
| 24 | import org.openstreetmap.josm.gui.PleaseWaitRunnable;
|
---|
| 25 | import org.openstreetmap.josm.gui.layer.Layer;
|
---|
| 26 | import org.openstreetmap.josm.gui.progress.ProgressMonitor;
|
---|
[5573] | 27 | import org.openstreetmap.josm.gui.util.FileFilterAllFiles;
|
---|
[7578] | 28 | import org.openstreetmap.josm.gui.widgets.AbstractFileChooser;
|
---|
[4668] | 29 | import org.openstreetmap.josm.io.IllegalDataException;
|
---|
[6245] | 30 | import org.openstreetmap.josm.io.session.SessionImporter;
|
---|
[4668] | 31 | import org.openstreetmap.josm.io.session.SessionReader;
|
---|
[6245] | 32 | import org.openstreetmap.josm.tools.CheckParameterUtil;
|
---|
| 33 | import org.openstreetmap.josm.tools.Utils;
|
---|
[4668] | 34 |
|
---|
[6245] | 35 | /**
|
---|
[7004] | 36 | * Loads a JOSM session.
|
---|
[6245] | 37 | * @since 4668
|
---|
| 38 | */
|
---|
[5438] | 39 | public class SessionLoadAction extends DiskAccessAction {
|
---|
[6069] | 40 |
|
---|
[6245] | 41 | /**
|
---|
| 42 | * Constructs a new {@code SessionLoadAction}.
|
---|
| 43 | */
|
---|
[4668] | 44 | public SessionLoadAction() {
|
---|
[4733] | 45 | super(tr("Load Session"), "open", tr("Load a session from file."), null, true, "load-session", true);
|
---|
[4668] | 46 | putValue("help", ht("/Action/SessionLoad"));
|
---|
| 47 | }
|
---|
| 48 |
|
---|
[6084] | 49 | @Override
|
---|
[4668] | 50 | public void actionPerformed(ActionEvent e) {
|
---|
[7578] | 51 | AbstractFileChooser fc = createAndOpenFileChooser(true, false, tr("Open session"),
|
---|
[6643] | 52 | Arrays.asList(SessionImporter.FILE_FILTER, FileFilterAllFiles.getInstance()),
|
---|
[6245] | 53 | SessionImporter.FILE_FILTER, JFileChooser.FILES_ONLY, "lastDirectory");
|
---|
[10192] | 54 | if (fc == null)
|
---|
| 55 | return;
|
---|
[4668] | 56 | File file = fc.getSelectedFile();
|
---|
[8404] | 57 | boolean zip = Utils.hasExtension(file, "joz");
|
---|
[4668] | 58 | Main.worker.submit(new Loader(file, zip));
|
---|
| 59 | }
|
---|
| 60 |
|
---|
[6245] | 61 | /**
|
---|
| 62 | * JOSM session loader
|
---|
| 63 | */
|
---|
[4874] | 64 | public static class Loader extends PleaseWaitRunnable {
|
---|
[4668] | 65 |
|
---|
| 66 | private boolean canceled;
|
---|
| 67 | private File file;
|
---|
[6245] | 68 | private final URI uri;
|
---|
| 69 | private final InputStream is;
|
---|
| 70 | private final boolean zip;
|
---|
[4668] | 71 | private List<Layer> layers;
|
---|
[6271] | 72 | private Layer active;
|
---|
[4668] | 73 | private List<Runnable> postLoadTasks;
|
---|
[5670] | 74 | private ViewportData viewport;
|
---|
[4668] | 75 |
|
---|
[6245] | 76 | /**
|
---|
| 77 | * Constructs a new {@code Loader} for local session file.
|
---|
| 78 | * @param file The JOSM session file
|
---|
| 79 | * @param zip {@code true} if the file is a session archive file (*.joz)
|
---|
| 80 | */
|
---|
[4668] | 81 | public Loader(File file, boolean zip) {
|
---|
| 82 | super(tr("Loading session ''{0}''", file.getName()));
|
---|
[6245] | 83 | CheckParameterUtil.ensureParameterNotNull(file, "file");
|
---|
[4668] | 84 | this.file = file;
|
---|
[6245] | 85 | this.uri = null;
|
---|
| 86 | this.is = null;
|
---|
[4668] | 87 | this.zip = zip;
|
---|
| 88 | }
|
---|
| 89 |
|
---|
[6245] | 90 | /**
|
---|
| 91 | * Constructs a new {@code Loader} for session file input stream (may be a remote file).
|
---|
| 92 | * @param is The input stream to session file
|
---|
| 93 | * @param uri The file URI
|
---|
| 94 | * @param zip {@code true} if the file is a session archive file (*.joz)
|
---|
| 95 | * @since 6245
|
---|
| 96 | */
|
---|
| 97 | public Loader(InputStream is, URI uri, boolean zip) {
|
---|
| 98 | super(tr("Loading session ''{0}''", uri));
|
---|
| 99 | CheckParameterUtil.ensureParameterNotNull(is, "is");
|
---|
| 100 | CheckParameterUtil.ensureParameterNotNull(uri, "uri");
|
---|
| 101 | this.file = null;
|
---|
| 102 | this.uri = uri;
|
---|
| 103 | this.is = is;
|
---|
| 104 | this.zip = zip;
|
---|
| 105 | }
|
---|
| 106 |
|
---|
[4668] | 107 | @Override
|
---|
[6245] | 108 | public void cancel() {
|
---|
[4668] | 109 | canceled = true;
|
---|
| 110 | }
|
---|
| 111 |
|
---|
| 112 | @Override
|
---|
| 113 | protected void finish() {
|
---|
[10601] | 114 | SwingUtilities.invokeLater(() -> {
|
---|
| 115 | if (canceled)
|
---|
| 116 | return;
|
---|
| 117 | addLayers();
|
---|
| 118 | runPostLoadTasks();
|
---|
[4668] | 119 | });
|
---|
| 120 | }
|
---|
| 121 |
|
---|
[10192] | 122 | private void addLayers() {
|
---|
| 123 | if (layers != null && !layers.isEmpty()) {
|
---|
| 124 | boolean noMap = Main.map == null;
|
---|
| 125 | for (Layer l : layers) {
|
---|
| 126 | if (canceled)
|
---|
| 127 | return;
|
---|
[10432] | 128 | Main.getLayerManager().addLayer(l);
|
---|
[10192] | 129 | }
|
---|
| 130 | if (active != null) {
|
---|
[10318] | 131 | Main.getLayerManager().setActiveLayer(active);
|
---|
[10192] | 132 | }
|
---|
| 133 | if (noMap) {
|
---|
[10432] | 134 | Main.map.mapView.scheduleZoomTo(viewport);
|
---|
[10192] | 135 | }
|
---|
| 136 | }
|
---|
| 137 | }
|
---|
| 138 |
|
---|
| 139 | private void runPostLoadTasks() {
|
---|
| 140 | for (Runnable task : postLoadTasks) {
|
---|
| 141 | if (canceled)
|
---|
| 142 | return;
|
---|
| 143 | if (task == null) {
|
---|
| 144 | continue;
|
---|
| 145 | }
|
---|
| 146 | task.run();
|
---|
| 147 | }
|
---|
| 148 | }
|
---|
| 149 |
|
---|
[4668] | 150 | @Override
|
---|
| 151 | protected void realRun() {
|
---|
| 152 | try {
|
---|
| 153 | ProgressMonitor monitor = getProgressMonitor();
|
---|
| 154 | SessionReader reader = new SessionReader();
|
---|
[6245] | 155 | boolean tempFile = false;
|
---|
| 156 | try {
|
---|
| 157 | if (file == null) {
|
---|
| 158 | // Download and write entire joz file as a temp file on disk as we need random access later
|
---|
| 159 | file = File.createTempFile("session_", ".joz", Utils.getJosmTempDir());
|
---|
| 160 | tempFile = true;
|
---|
[9280] | 161 | Files.copy(is, file.toPath(), StandardCopyOption.REPLACE_EXISTING);
|
---|
[6245] | 162 | }
|
---|
| 163 | reader.loadSession(file, zip, monitor);
|
---|
| 164 | layers = reader.getLayers();
|
---|
[6271] | 165 | active = reader.getActive();
|
---|
[6245] | 166 | postLoadTasks = reader.getPostLoadTasks();
|
---|
| 167 | viewport = reader.getViewport();
|
---|
| 168 | } finally {
|
---|
| 169 | if (tempFile) {
|
---|
[9296] | 170 | Utils.deleteFile(file);
|
---|
[6245] | 171 | file = null;
|
---|
| 172 | }
|
---|
| 173 | }
|
---|
[4668] | 174 | } catch (IllegalDataException e) {
|
---|
[7004] | 175 | handleException(tr("Data Error"), e);
|
---|
[4668] | 176 | } catch (IOException e) {
|
---|
[7004] | 177 | handleException(tr("IO Error"), e);
|
---|
[10212] | 178 | } catch (RuntimeException e) {
|
---|
[4668] | 179 | cancel();
|
---|
| 180 | throw e;
|
---|
| 181 | }
|
---|
| 182 | }
|
---|
[7326] | 183 |
|
---|
[7004] | 184 | private void handleException(String dialogTitle, Exception e) {
|
---|
| 185 | Main.error(e);
|
---|
| 186 | HelpAwareOptionPane.showMessageDialogInEDT(
|
---|
| 187 | Main.parent,
|
---|
[8540] | 188 | tr("<html>Could not load session file ''{0}''.<br>Error is:<br>{1}</html>",
|
---|
| 189 | uri != null ? uri : file.getName(), e.getMessage()),
|
---|
[7004] | 190 | dialogTitle,
|
---|
| 191 | JOptionPane.ERROR_MESSAGE,
|
---|
| 192 | null
|
---|
| 193 | );
|
---|
| 194 | cancel();
|
---|
| 195 | }
|
---|
[4668] | 196 | }
|
---|
| 197 | }
|
---|