[2702] | 1 | // License: GPL. For details, see LICENSE file.
|
---|
| 2 | package org.openstreetmap.josm.io;
|
---|
| 3 |
|
---|
| 4 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 5 |
|
---|
| 6 | import java.io.File;
|
---|
| 7 | import java.io.IOException;
|
---|
[2851] | 8 | import java.util.ArrayList;
|
---|
[2702] | 9 | import java.util.Arrays;
|
---|
[2851] | 10 | import java.util.HashSet;
|
---|
[2702] | 11 | import java.util.List;
|
---|
[2851] | 12 | import java.util.Set;
|
---|
[2702] | 13 |
|
---|
| 14 | import org.openstreetmap.josm.actions.ExtensionFileFilter;
|
---|
| 15 | import org.openstreetmap.josm.gui.layer.GpxLayer;
|
---|
| 16 | import org.openstreetmap.josm.gui.layer.geoimage.GeoImageLayer;
|
---|
[2851] | 17 | import org.openstreetmap.josm.gui.progress.ProgressMonitor;
|
---|
[2702] | 18 |
|
---|
[5438] | 19 | /**
|
---|
| 20 | * File importer allowing to import geottaged images (*.jpg files).
|
---|
| 21 | *
|
---|
| 22 | */
|
---|
[2702] | 23 | public class JpgImporter extends FileImporter {
|
---|
| 24 | private GpxLayer gpx;
|
---|
[6070] | 25 |
|
---|
[5438] | 26 | /**
|
---|
| 27 | * The default file filter (only *.jpg files).
|
---|
| 28 | */
|
---|
[5361] | 29 | public static final ExtensionFileFilter FILE_FILTER = new ExtensionFileFilter(
|
---|
[7178] | 30 | "jpg,jpeg", "jpg", tr("Image Files") + " (*.jpg)");
|
---|
[6070] | 31 |
|
---|
[5438] | 32 | /**
|
---|
| 33 | * An alternate file filter that also includes folders.
|
---|
| 34 | * @since 5438
|
---|
| 35 | */
|
---|
| 36 | public static final ExtensionFileFilter FILE_FILTER_WITH_FOLDERS = new ExtensionFileFilter(
|
---|
[8846] | 37 | "jpg,jpeg", "jpg", tr("Image Files") + " (*.jpg, "+ tr("folder")+')');
|
---|
[2702] | 38 |
|
---|
[5438] | 39 | /**
|
---|
| 40 | * Constructs a new {@code JpgImporter}.
|
---|
| 41 | */
|
---|
[2702] | 42 | public JpgImporter() {
|
---|
[5438] | 43 | this(false);
|
---|
[2702] | 44 | }
|
---|
| 45 |
|
---|
[5438] | 46 | /**
|
---|
| 47 | * Constructs a new {@code JpgImporter} with folders selection, if wanted.
|
---|
| 48 | * @param includeFolders If true, includes folders in the file filter
|
---|
| 49 | * @since 5438
|
---|
| 50 | */
|
---|
| 51 | public JpgImporter(boolean includeFolders) {
|
---|
| 52 | super(includeFolders ? FILE_FILTER_WITH_FOLDERS : FILE_FILTER);
|
---|
| 53 | }
|
---|
| 54 |
|
---|
| 55 | /**
|
---|
| 56 | * Constructs a new {@code JpgImporter} for the given GPX layer. Folders selection is allowed.
|
---|
| 57 | * @param gpx The GPX layer
|
---|
| 58 | */
|
---|
[2702] | 59 | public JpgImporter(GpxLayer gpx) {
|
---|
[5438] | 60 | this(true);
|
---|
[2702] | 61 | this.gpx = gpx;
|
---|
| 62 | }
|
---|
| 63 |
|
---|
| 64 | @Override
|
---|
| 65 | public boolean acceptFile(File pathname) {
|
---|
| 66 | return super.acceptFile(pathname) || pathname.isDirectory();
|
---|
| 67 | }
|
---|
| 68 |
|
---|
| 69 | @Override
|
---|
[2851] | 70 | public void importData(List<File> sel, ProgressMonitor progressMonitor) throws IOException, IllegalDataException {
|
---|
| 71 | progressMonitor.beginTask(tr("Looking for image files"), 1);
|
---|
| 72 | try {
|
---|
[7005] | 73 | List<File> files = new ArrayList<>();
|
---|
| 74 | Set<String> visitedDirs = new HashSet<>();
|
---|
[2851] | 75 | addRecursiveFiles(files, visitedDirs, sel, progressMonitor.createSubTaskMonitor(1, true));
|
---|
| 76 |
|
---|
[4310] | 77 | if (progressMonitor.isCanceled())
|
---|
[2851] | 78 | return;
|
---|
| 79 |
|
---|
| 80 | if (files.isEmpty())
|
---|
| 81 | throw new IOException(tr("No image files found."));
|
---|
| 82 |
|
---|
| 83 | GeoImageLayer.create(files, gpx);
|
---|
| 84 | } finally {
|
---|
| 85 | progressMonitor.finishTask();
|
---|
| 86 | }
|
---|
[2702] | 87 | }
|
---|
| 88 |
|
---|
[12286] | 89 | static void addRecursiveFiles(List<File> files, Set<String> visitedDirs, List<File> sel, ProgressMonitor progressMonitor)
|
---|
[8540] | 90 | throws IOException {
|
---|
[2851] | 91 |
|
---|
[4310] | 92 | if (progressMonitor.isCanceled())
|
---|
[2851] | 93 | return;
|
---|
| 94 |
|
---|
| 95 | progressMonitor.beginTask(null, sel.size());
|
---|
| 96 | try {
|
---|
| 97 | for (File f : sel) {
|
---|
| 98 | if (f.isDirectory()) {
|
---|
| 99 | if (visitedDirs.add(f.getCanonicalPath())) { // Do not loop over symlinks
|
---|
| 100 | File[] dirFiles = f.listFiles(); // Can be null for some strange directories (like lost+found)
|
---|
| 101 | if (dirFiles != null) {
|
---|
| 102 | addRecursiveFiles(files, visitedDirs, Arrays.asList(dirFiles), progressMonitor.createSubTaskMonitor(1, true));
|
---|
| 103 | }
|
---|
| 104 | } else {
|
---|
| 105 | progressMonitor.worked(1);
|
---|
| 106 | }
|
---|
| 107 | } else {
|
---|
[12286] | 108 | if (FILE_FILTER.accept(f)) {
|
---|
[2851] | 109 | files.add(f);
|
---|
| 110 | }
|
---|
| 111 | progressMonitor.worked(1);
|
---|
| 112 | }
|
---|
[2702] | 113 | }
|
---|
[2851] | 114 | } finally {
|
---|
| 115 | progressMonitor.finishTask();
|
---|
[2702] | 116 | }
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | @Override
|
---|
| 120 | public boolean isBatchImporter() {
|
---|
| 121 | return true;
|
---|
| 122 | }
|
---|
| 123 |
|
---|
| 124 | /**
|
---|
| 125 | * Needs to be the last, to avoid problems.
|
---|
| 126 | */
|
---|
| 127 | @Override
|
---|
| 128 | public double getPriority() {
|
---|
| 129 | return -1000;
|
---|
| 130 | }
|
---|
| 131 | }
|
---|