[1146] | 1 | // License: GPL. Copyright 2007 by Immanuel Scholz and others
|
---|
| 2 | package org.openstreetmap.josm.actions;
|
---|
| 3 |
|
---|
[2563] | 4 | import static org.openstreetmap.josm.gui.help.HelpUtil.ht;
|
---|
[1146] | 5 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
[2842] | 6 | import static org.openstreetmap.josm.tools.I18n.trn;
|
---|
[1146] | 7 |
|
---|
| 8 | import java.awt.event.ActionEvent;
|
---|
| 9 | import java.awt.event.KeyEvent;
|
---|
| 10 | import java.io.File;
|
---|
| 11 | import java.io.IOException;
|
---|
[2702] | 12 | import java.util.ArrayList;
|
---|
[2047] | 13 | import java.util.Arrays;
|
---|
[2980] | 14 | import java.util.Collection;
|
---|
[2702] | 15 | import java.util.Collections;
|
---|
[2980] | 16 | import java.util.LinkedList;
|
---|
[2047] | 17 | import java.util.List;
|
---|
[1146] | 18 |
|
---|
| 19 | import javax.swing.JFileChooser;
|
---|
| 20 | import javax.swing.JOptionPane;
|
---|
[2994] | 21 | import javax.swing.SwingUtilities;
|
---|
[2702] | 22 | import javax.swing.filechooser.FileFilter;
|
---|
[1146] | 23 |
|
---|
| 24 | import org.openstreetmap.josm.Main;
|
---|
[2980] | 25 | import org.openstreetmap.josm.gui.HelpAwareOptionPane;
|
---|
[2047] | 26 | import org.openstreetmap.josm.gui.PleaseWaitRunnable;
|
---|
[2980] | 27 | import org.openstreetmap.josm.gui.help.HelpUtil;
|
---|
[2702] | 28 | import org.openstreetmap.josm.io.AllFormatsImporter;
|
---|
[1637] | 29 | import org.openstreetmap.josm.io.FileImporter;
|
---|
[2047] | 30 | import org.openstreetmap.josm.io.OsmTransferException;
|
---|
[2702] | 31 | import org.openstreetmap.josm.tools.MultiMap;
|
---|
[1146] | 32 | import org.openstreetmap.josm.tools.Shortcut;
|
---|
[2047] | 33 | import org.xml.sax.SAXException;
|
---|
[1146] | 34 |
|
---|
| 35 | /**
|
---|
[1637] | 36 | * Open a file chooser dialog and select an file to import. Then call the gpx-import driver. Finally
|
---|
| 37 | * open an internal frame into the main window with the gpx data shown.
|
---|
[1146] | 38 | *
|
---|
| 39 | * @author imi
|
---|
| 40 | */
|
---|
| 41 | public class OpenFileAction extends DiskAccessAction {
|
---|
| 42 |
|
---|
[1169] | 43 | /**
|
---|
| 44 | * Create an open action. The name is "Open a file".
|
---|
| 45 | */
|
---|
| 46 | public OpenFileAction() {
|
---|
[1212] | 47 | super(tr("Open..."), "open", tr("Open a file."),
|
---|
[1847] | 48 | Shortcut.registerShortcut("system:open", tr("File: {0}", tr("Open...")), KeyEvent.VK_O, Shortcut.GROUP_MENU));
|
---|
[2323] | 49 | putValue("help", ht("/Action/OpenFile"));
|
---|
[2512] | 50 |
|
---|
[1169] | 51 | }
|
---|
[1146] | 52 |
|
---|
[1169] | 53 | public void actionPerformed(ActionEvent e) {
|
---|
| 54 | JFileChooser fc = createAndOpenFileChooser(true, true, null);
|
---|
| 55 | if (fc == null)
|
---|
| 56 | return;
|
---|
| 57 | File[] files = fc.getSelectedFiles();
|
---|
[2702] | 58 | OpenFileTask task = new OpenFileTask(Arrays.asList(files), fc.getFileFilter());
|
---|
[2047] | 59 | Main.worker.submit(task);
|
---|
[1169] | 60 | }
|
---|
[1146] | 61 |
|
---|
[1879] | 62 | @Override
|
---|
| 63 | protected void updateEnabledState() {
|
---|
| 64 | setEnabled(! Main.applet);
|
---|
| 65 | }
|
---|
[2047] | 66 |
|
---|
[2798] | 67 | /**
|
---|
| 68 | * Open a list of files. The complete list will be passed to batch importers.
|
---|
| 69 | * @param fileList A list of files
|
---|
| 70 | */
|
---|
| 71 | static public void openFiles(List<File> fileList) {
|
---|
| 72 | OpenFileTask task = new OpenFileTask(fileList, null);
|
---|
| 73 | Main.worker.submit(task);
|
---|
[2703] | 74 | }
|
---|
| 75 |
|
---|
[2047] | 76 | static public class OpenFileTask extends PleaseWaitRunnable {
|
---|
| 77 | private List<File> files;
|
---|
[2702] | 78 | private FileFilter fileFilter;
|
---|
[2047] | 79 | private boolean cancelled;
|
---|
| 80 |
|
---|
[2702] | 81 | public OpenFileTask(List<File> files, FileFilter fileFilter) {
|
---|
[2047] | 82 | super(tr("Opening files"), false /* don't ignore exception */);
|
---|
[2702] | 83 | this.files = new ArrayList<File>(files);
|
---|
| 84 | this.fileFilter = fileFilter;
|
---|
[2047] | 85 | }
|
---|
| 86 | @Override
|
---|
| 87 | protected void cancel() {
|
---|
| 88 | this.cancelled = true;
|
---|
| 89 | }
|
---|
| 90 |
|
---|
| 91 | @Override
|
---|
| 92 | protected void finish() {
|
---|
| 93 | // do nothing
|
---|
| 94 | }
|
---|
| 95 |
|
---|
[2980] | 96 | protected void alertFilesNotMatchingWithImporter(Collection<File> files, FileImporter importer) {
|
---|
[2994] | 97 | final StringBuffer msg = new StringBuffer();
|
---|
[2980] | 98 | msg.append("<html>");
|
---|
| 99 | msg.append(
|
---|
| 100 | trn(
|
---|
[2994] | 101 | "Cannot open {0} file with the file importer ''{1}''.",
|
---|
| 102 | "Cannot open {0} files with the file importer ''{1}''.",
|
---|
[2980] | 103 | files.size(),
|
---|
| 104 | files.size(),
|
---|
| 105 | importer.filter.getDescription()
|
---|
| 106 | )
|
---|
| 107 | ).append("<br>");
|
---|
| 108 | msg.append("<ul>");
|
---|
| 109 | for (File f: files) {
|
---|
| 110 | msg.append("<li>").append(f.getAbsolutePath()).append("</li>");
|
---|
| 111 | }
|
---|
| 112 | msg.append("</ul>");
|
---|
| 113 |
|
---|
[3501] | 114 | HelpAwareOptionPane.showMessageDialogInEDT(
|
---|
| 115 | Main.parent,
|
---|
| 116 | msg.toString(),
|
---|
| 117 | tr("Warning"),
|
---|
| 118 | JOptionPane.WARNING_MESSAGE,
|
---|
| 119 | HelpUtil.ht("/Action/OpenFile#ImporterCantImportFiles")
|
---|
| 120 | );
|
---|
[2980] | 121 | }
|
---|
| 122 |
|
---|
| 123 | protected void alertFilesWithUnknownImporter(Collection<File> files) {
|
---|
[2994] | 124 | final StringBuffer msg = new StringBuffer();
|
---|
[2980] | 125 | msg.append("<html>");
|
---|
| 126 | msg.append(
|
---|
| 127 | trn(
|
---|
[2994] | 128 | "Cannot open {0} file because no suitable file importer is available.",
|
---|
| 129 | "Cannot open {0} files because no suitable file importer is available.",
|
---|
[2980] | 130 | files.size(),
|
---|
| 131 | files.size()
|
---|
| 132 | )
|
---|
| 133 | ).append("<br>");
|
---|
| 134 | msg.append("<ul>");
|
---|
| 135 | for (File f: files) {
|
---|
| 136 | msg.append("<li>").append(f.getAbsolutePath()).append("</li>");
|
---|
| 137 | }
|
---|
| 138 | msg.append("</ul>");
|
---|
[3530] | 139 |
|
---|
[3501] | 140 | HelpAwareOptionPane.showMessageDialogInEDT(
|
---|
| 141 | Main.parent,
|
---|
| 142 | msg.toString(),
|
---|
| 143 | tr("Warning"),
|
---|
| 144 | JOptionPane.WARNING_MESSAGE,
|
---|
| 145 | HelpUtil.ht("/Action/OpenFile#MissingImporterForFiles")
|
---|
| 146 | );
|
---|
[2980] | 147 | }
|
---|
| 148 |
|
---|
[2047] | 149 | @Override
|
---|
| 150 | protected void realRun() throws SAXException, IOException, OsmTransferException {
|
---|
| 151 | if (files == null || files.isEmpty()) return;
|
---|
[2702] | 152 |
|
---|
| 153 | /**
|
---|
| 154 | * Find the importer with the chosen file filter
|
---|
| 155 | */
|
---|
| 156 | FileImporter chosenImporter = null;
|
---|
| 157 | for (FileImporter importer : ExtensionFileFilter.importers) {
|
---|
| 158 | if (fileFilter == importer.filter) {
|
---|
| 159 | chosenImporter = importer;
|
---|
| 160 | }
|
---|
| 161 | }
|
---|
| 162 | /**
|
---|
| 163 | * If the filter wasn't changed in the dialog, chosenImporter is null now.
|
---|
[2703] | 164 | * When the filter was explicitly set to AllFormatsImporter, treat this the same.
|
---|
[2702] | 165 | */
|
---|
| 166 | if (chosenImporter instanceof AllFormatsImporter) {
|
---|
| 167 | chosenImporter = null;
|
---|
| 168 | }
|
---|
[2851] | 169 | getProgressMonitor().setTicksCount(files.size());
|
---|
[2702] | 170 |
|
---|
[2980] | 171 | if (chosenImporter != null) {
|
---|
| 172 | // The importer was expicitely chosen, so use it.
|
---|
| 173 | List<File> filesNotMatchingWithImporter = new LinkedList<File>();
|
---|
| 174 | List<File> filesMatchingWithImporter = new LinkedList<File>();
|
---|
[2994] | 175 | for (final File f : files) {
|
---|
[2702] | 176 | if (!chosenImporter.acceptFile(f)) {
|
---|
| 177 | if (f.isDirectory()) {
|
---|
[2994] | 178 | SwingUtilities.invokeLater(new Runnable() {
|
---|
| 179 | public void run() {
|
---|
| 180 | JOptionPane.showMessageDialog(Main.parent, tr(
|
---|
[3530] | 181 | "<html>Cannot open directory ''{0}''.<br>Please select a file.</html>",
|
---|
[2994] | 182 | f.getAbsolutePath()), tr("Open file"), JOptionPane.ERROR_MESSAGE);
|
---|
| 183 | }
|
---|
| 184 | });
|
---|
[3530] | 185 | // TODO when changing to Java 6: Don't cancel the
|
---|
[2994] | 186 | // task here but use different modality. (Currently 2 dialogs
|
---|
| 187 | // would block each other.)
|
---|
| 188 | return;
|
---|
[2980] | 189 | } else {
|
---|
| 190 | filesNotMatchingWithImporter.add(f);
|
---|
| 191 | }
|
---|
| 192 | } else {
|
---|
| 193 | filesMatchingWithImporter.add(f);
|
---|
[2702] | 194 | }
|
---|
| 195 | }
|
---|
[2980] | 196 |
|
---|
| 197 | if (!filesNotMatchingWithImporter.isEmpty()) {
|
---|
| 198 | alertFilesNotMatchingWithImporter(filesNotMatchingWithImporter, chosenImporter);
|
---|
| 199 | }
|
---|
[2994] | 200 | if (!filesMatchingWithImporter.isEmpty()) {
|
---|
[2980] | 201 | importData(chosenImporter, filesMatchingWithImporter);
|
---|
| 202 | }
|
---|
| 203 | } else {
|
---|
| 204 | // find appropriate importer
|
---|
[2702] | 205 | MultiMap<FileImporter, File> map = new MultiMap<FileImporter, File>();
|
---|
[2980] | 206 | List<File> filesWithKnownImporter = new LinkedList<File>();
|
---|
| 207 | List<File> filesWithUnknownImporter = new LinkedList<File>();
|
---|
| 208 | FILES: for (File f : files) {
|
---|
| 209 | for (FileImporter importer : ExtensionFileFilter.importers) {
|
---|
| 210 | if (importer.acceptFile(f)) {
|
---|
| 211 | map.put(importer, f);
|
---|
| 212 | filesWithKnownImporter.add(f);
|
---|
| 213 | continue FILES;
|
---|
[2702] | 214 | }
|
---|
| 215 | }
|
---|
[2980] | 216 | filesWithUnknownImporter.add(f);
|
---|
| 217 | }
|
---|
| 218 | if (!filesWithUnknownImporter.isEmpty()) {
|
---|
| 219 | alertFilesWithUnknownImporter(filesWithUnknownImporter);
|
---|
| 220 | }
|
---|
[2702] | 221 | List<FileImporter> ims = new ArrayList<FileImporter>(map.keySet());
|
---|
| 222 | Collections.sort(ims);
|
---|
| 223 | Collections.reverse(ims);
|
---|
| 224 | for (FileImporter importer : ims) {
|
---|
[2946] | 225 | List<File> files = new ArrayList<File>(map.get(importer));
|
---|
[2702] | 226 | importData(importer, files);
|
---|
| 227 | }
|
---|
| 228 | }
|
---|
| 229 | }
|
---|
| 230 |
|
---|
| 231 | public void importData(FileImporter importer, List<File> files) {
|
---|
| 232 | if (importer.isBatchImporter()) {
|
---|
[2047] | 233 | if (cancelled) return;
|
---|
[2702] | 234 | String msg;
|
---|
| 235 | if (files.size() == 1) {
|
---|
| 236 | msg = tr("Opening 1 file...");
|
---|
| 237 | } else {
|
---|
[2842] | 238 | msg = trn("Opening {0} file...", "Opening {0} files...", files.size(), files.size());
|
---|
[2047] | 239 | }
|
---|
[2980] | 240 | getProgressMonitor().setCustomText(msg);
|
---|
[2702] | 241 | getProgressMonitor().indeterminateSubTask(msg);
|
---|
[2851] | 242 | importer.importDataHandleExceptions(files, getProgressMonitor().createSubTaskMonitor(files.size(), false));
|
---|
[2702] | 243 | } else {
|
---|
| 244 | for (File f : files) {
|
---|
| 245 | if (cancelled) return;
|
---|
| 246 | getProgressMonitor().indeterminateSubTask(tr("Opening file ''{0}'' ...", f.getAbsolutePath()));
|
---|
[2851] | 247 | importer.importDataHandleExceptions(f, getProgressMonitor().createSubTaskMonitor(1, false));
|
---|
[2702] | 248 | }
|
---|
[2047] | 249 | }
|
---|
| 250 | }
|
---|
| 251 | }
|
---|
[2512] | 252 | }
|
---|