source: josm/trunk/src/org/openstreetmap/josm/actions/OpenFileAction.java@ 3872

Last change on this file since 3872 was 3758, checked in by stoecker, 13 years ago

fix help topics

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