summaryrefslogtreecommitdiff
path: root/src/camera
diff options
context:
space:
mode:
authorJörg Frings-Fürst <debian@jff.email>2023-06-14 20:36:37 +0200
committerJörg Frings-Fürst <debian@jff.email>2023-06-14 20:36:37 +0200
commitbb80d3feebdc9acc52e3f4ad24084d8425f043a2 (patch)
tree2084a84c39f159c6aea254775dc0880d52579d45 /src/camera
parentb26ff0798252a1a8072dd2c7a67f6205de9fde11 (diff)
parent31804433d72460cbe0a39f9f8ea5e76058d84cda (diff)
Merge branch 'feature/upstream' into develop
Diffstat (limited to 'src/camera')
-rw-r--r--src/camera/CameraBranch.vala2
-rw-r--r--src/camera/CameraTable.vala83
-rw-r--r--src/camera/DiscoveredCamera.vala119
-rw-r--r--src/camera/GPhoto.vala5
-rw-r--r--src/camera/ImportPage.vala162
5 files changed, 194 insertions, 177 deletions
diff --git a/src/camera/CameraBranch.vala b/src/camera/CameraBranch.vala
index 052f093..83e6a66 100644
--- a/src/camera/CameraBranch.vala
+++ b/src/camera/CameraBranch.vala
@@ -104,7 +104,7 @@ public class Camera.SidebarEntry : Sidebar.SimplePageEntry {
}
protected override Page create_page() {
- return new ImportPage(camera.gcamera, uri, get_sidebar_name(), get_sidebar_icon());
+ return new ImportPage(camera);
}
public string get_uri() {
diff --git a/src/camera/CameraTable.vala b/src/camera/CameraTable.vala
index 5f888ac..172c00a 100644
--- a/src/camera/CameraTable.vala
+++ b/src/camera/CameraTable.vala
@@ -4,20 +4,6 @@
* (version 2.1 or later). See the COPYING file in this distribution.
*/
-public class DiscoveredCamera {
- public GPhoto.Camera gcamera;
- public string uri;
- public string display_name;
- public string? icon;
-
- public DiscoveredCamera(GPhoto.Camera gcamera, string uri, string display_name, string? icon) {
- this.gcamera = gcamera;
- this.uri = uri;
- this.display_name = display_name;
- this.icon = icon;
- }
-}
-
public class CameraTable {
private const int UPDATE_DELAY_MSEC = 1000;
@@ -119,32 +105,6 @@ public class CameraTable {
return "gphoto2://[%s]/".printf(port);
}
- public static string? get_port_path(string port) {
- // Accepted format is usb:001,005
- return port.has_prefix("usb:") ?
- "/dev/bus/usb/%s".printf(port.substring(4).replace(",", "/")) : null;
- }
-
-#if HAVE_UDEV
- private string? get_name_for_uuid(string uuid) {
- foreach (Volume volume in volume_monitor.get_volumes()) {
- if (volume.get_identifier(VolumeIdentifier.UUID) == uuid) {
- return volume.get_name();
- }
- }
- return null;
- }
-
- private string? get_icon_for_uuid(string uuid) {
- foreach (Volume volume in volume_monitor.get_volumes()) {
- if (volume.get_identifier(VolumeIdentifier.UUID) == uuid) {
- return volume.get_symbolic_icon().to_string();
- }
- }
- return null;
- }
-#endif
-
private void update_camera_table() throws GPhotoError {
// need to do this because virtual ports come and go in the USB world (and probably others)
GPhoto.PortInfoList port_info_list;
@@ -217,8 +177,6 @@ public class CameraTable {
// add cameras which were not present before
foreach (string port in detected_map.keys) {
string name = detected_map.get(port);
- string display_name = null;
- string? icon = null;
string uri = get_port_uri(port);
if (camera_map.has_key(uri)) {
@@ -227,41 +185,7 @@ public class CameraTable {
continue;
}
-
-#if HAVE_UDEV
- // Get display name for camera.
- string path = get_port_path(port);
- if (null != path) {
- GUdev.Device device = client.query_by_device_file(path);
- string serial = device.get_property("ID_SERIAL_SHORT");
- if (null != serial) {
- // Try to get the name and icon.
- display_name = get_name_for_uuid(serial);
- icon = get_icon_for_uuid(serial);
- }
- if (null == display_name) {
- display_name = device.get_sysfs_attr("product");
- }
- if (null == display_name) {
- display_name = device.get_property("ID_MODEL");
- }
- }
-#endif
-
- if (port.has_prefix("disk:")) {
- try {
- var mount = File.new_for_path (port.substring(5)).find_enclosing_mount();
- var volume = mount.get_volume();
- // Translators: First %s is the name of camera as gotten from GPhoto, second is the GVolume name, e.g. Mass storage camera (510MB volume)
- display_name = _("%s (%s)").printf (name, volume.get_name ());
- icon = volume.get_symbolic_icon().to_string();
- } catch (Error e) { }
- }
- if (null == display_name) {
- // Default to GPhoto detected name.
- display_name = name;
- }
int index = port_info_list.lookup_path(port);
if (index < 0)
do_op((GPhoto.Result) index, "lookup port %s".printf(port));
@@ -283,14 +207,9 @@ public class CameraTable {
do_op(abilities_list.get_abilities(index, out camera_abilities),
"lookup camera abilities for %s".printf(name));
- GPhoto.Camera gcamera;
- do_op(GPhoto.Camera.create(out gcamera), "create camera object for %s".printf(name));
- do_op(gcamera.set_abilities(camera_abilities), "set camera abilities for %s".printf(name));
- do_op(gcamera.set_port_info(port_info), "set port info for %s on %s".printf(name, port));
-
debug("Adding to camera table: %s @ %s", name, port);
- DiscoveredCamera camera = new DiscoveredCamera(gcamera, uri, display_name, icon);
+ var camera = new DiscoveredCamera(name, port, port_info, camera_abilities);
camera_map.set(uri, camera);
camera_added(camera);
diff --git a/src/camera/DiscoveredCamera.vala b/src/camera/DiscoveredCamera.vala
new file mode 100644
index 0000000..700af8b
--- /dev/null
+++ b/src/camera/DiscoveredCamera.vala
@@ -0,0 +1,119 @@
+/* Copyright 2016 Software Freedom Conservancy Inc.
+ *
+ * This software is licensed under the GNU Lesser General Public License
+ * (version 2.1 or later). See the COPYING file in this distribution.
+ */
+
+public class DiscoveredCamera {
+ public GPhoto.Camera gcamera;
+ public string uri;
+ public string display_name;
+ public string? icon;
+
+ private string port;
+ private string camera_name;
+ private string[] mount_uris;
+
+ public DiscoveredCamera(string name, string port, GPhoto.PortInfo port_info, GPhoto.CameraAbilities camera_abilities) throws GPhotoError {
+ this.port = port;
+ this.camera_name = name;
+ this.uri = "gphoto2://[%s]".printf(port);
+
+ this.mount_uris = new string[0];
+ this.mount_uris += this.uri;
+ this.mount_uris += "mtp://[%s]".printf(port);
+
+ var res = GPhoto.Camera.create(out this.gcamera);
+
+ if (res != GPhoto.Result.OK) {
+ throw new GPhotoError.LIBRARY("[%d] Unable to create camera object for %s: %s",
+ (int) res, name, res.as_string());
+ }
+
+ res = gcamera.set_abilities(camera_abilities);
+ if (res != GPhoto.Result.OK) {
+ throw new GPhotoError.LIBRARY("[%d] Unable to set camera abilities for %s: %s",
+ (int) res, name, res.as_string());
+ }
+
+ res = gcamera.set_port_info(port_info);
+ if (res != GPhoto.Result.OK) {
+ throw new GPhotoError.LIBRARY("[%d] Unable to set port infor for %s: %s",
+ (int) res, name, res.as_string());
+ }
+
+ var path = get_port_path(port);
+ if (path != null) {
+ var monitor = VolumeMonitor.get();
+ foreach (var volume in monitor.get_volumes()) {
+ if (volume.get_identifier(VolumeIdentifier.UNIX_DEVICE) == path) {
+ this.display_name = volume.get_name();
+ this.icon = volume.get_symbolic_icon().to_string();
+ }
+ }
+
+#if HAVE_UDEV
+ var client = new GUdev.Client(null);
+ var device = client.query_by_device_file(path);
+
+
+ // Create alternative uris (used for unmount)
+ var serial = device.get_property("ID_SERIAL");
+ this.mount_uris += "gphoto2://%s".printf(serial);
+ this.mount_uris += "mtp://%s".printf(serial);
+
+ // Look-up alternative display names
+ if (display_name == null) {
+ display_name = device.get_sysfs_attr("product");
+ }
+
+ if (display_name == null) {
+ display_name = device.get_property("ID_MODEL");
+ }
+#endif
+ }
+
+ if (port.has_prefix("disk:")) {
+ try {
+ var mount = File.new_for_path (port.substring(5)).find_enclosing_mount();
+ var volume = mount.get_volume();
+ if (volume != null) {
+ // Translators: First %s is the name of camera as gotten from GPhoto, second is the GVolume name, e.g. Mass storage camera (510MB volume)
+ display_name = _("%s (%s)").printf (name, volume.get_name ());
+ icon = volume.get_symbolic_icon().to_string();
+ } else {
+ // Translators: First %s is the name of camera as gotten from GPhoto, second is the GMount name, e.g. Mass storage camera (510MB volume)
+ display_name = _("%s (%s)").printf (name, mount.get_name ());
+ icon = mount.get_symbolic_icon().to_string();
+ }
+
+ } catch (Error e) { }
+ }
+
+ if (display_name == null) {
+ this.display_name = camera_name;
+ }
+ }
+
+ public Mount? get_mount() {
+ foreach (var uri in this.mount_uris) {
+ var f = File.new_for_uri(uri);
+ try {
+ var mount = f.find_enclosing_mount(null);
+ if (mount != null)
+ return mount;
+ } catch (Error error) {}
+ }
+
+ return null;
+ }
+
+ private string? get_port_path(string port) {
+ // Accepted format is usb:001,005
+ return port.has_prefix("usb:") ?
+ "/dev/bus/usb/%s".printf(port.substring(4).replace(",", "/")) : null;
+ }
+
+}
+
+
diff --git a/src/camera/GPhoto.vala b/src/camera/GPhoto.vala
index 9bcb151..702f307 100644
--- a/src/camera/GPhoto.vala
+++ b/src/camera/GPhoto.vala
@@ -93,7 +93,7 @@ namespace GPhoto {
}
// For CameraFileInfoFile, CameraFileInfoPreview, and CameraStorageInformation. See:
- // http://redmine.yorba.org/issues/1851
+ // https://bugzilla.gnome.org/show_bug.cgi?id=716252
// https://bugzilla.redhat.com/show_bug.cgi?id=585676
// https://sourceforge.net/tracker/?func=detail&aid=3000198&group_id=8874&atid=108874
public const int MAX_FILENAME_LENGTH = 63;
@@ -129,11 +129,10 @@ namespace GPhoto {
// Libgphoto will in some instances refuse to get metadata from a camera, but the camera is accessible as a
// filesystem. In these cases shotwell can access the file directly. See:
- // http://redmine.yorba.org/issues/2959
+ // https://bugzilla.gnome.org/show_bug.cgi?id=716915
public PhotoMetadata? get_fallback_metadata(Camera camera, Context context, string folder, string filename) {
// Fixme: Why do we need to query get_storageinfo here first?
GPhoto.CameraStorageInformation[] sifs = null;
- int count = 0;
camera.get_storageinfo(out sifs, context);
GPhoto.PortInfo port_info;
diff --git a/src/camera/ImportPage.vala b/src/camera/ImportPage.vala
index 84d7cbe..a5d3b4e 100644
--- a/src/camera/ImportPage.vala
+++ b/src/camera/ImportPage.vala
@@ -21,13 +21,13 @@ abstract class ImportSource : ThumbnailSource, Indexable {
private string folder;
private string filename;
private ulong file_size;
- private time_t modification_time;
+ private DateTime modification_time;
private Gdk.Pixbuf? preview = null;
private string? indexable_keywords = null;
protected ImportSource(string camera_name, GPhoto.Camera camera, int fsid, string folder,
- string filename, ulong file_size, time_t modification_time) {
- this.camera_name = camera_name;
+ string filename, ulong file_size, DateTime modification_time) {
+ this.camera_name =camera_name;
this.camera = camera;
this.fsid = fsid;
this.folder = folder;
@@ -65,7 +65,7 @@ abstract class ImportSource : ThumbnailSource, Indexable {
return file_size;
}
- public time_t get_modification_time() {
+ public DateTime get_modification_time() {
return modification_time;
}
@@ -73,7 +73,7 @@ abstract class ImportSource : ThumbnailSource, Indexable {
return preview;
}
- public virtual time_t get_exposure_time() {
+ public virtual DateTime get_exposure_time() {
return get_modification_time();
}
@@ -110,7 +110,7 @@ abstract class ImportSource : ThumbnailSource, Indexable {
class VideoImportSource : ImportSource {
public VideoImportSource(string camera_name, GPhoto.Camera camera, int fsid, string folder,
- string filename, ulong file_size, time_t modification_time) {
+ string filename, ulong file_size, DateTime modification_time) {
base(camera_name, camera, fsid, folder, filename, file_size, modification_time);
}
@@ -159,7 +159,7 @@ class PhotoImportSource : ImportSource {
private PhotoImportSource? associated = null; // JPEG source for RAW+JPEG
public PhotoImportSource(string camera_name, GPhoto.Camera camera, int fsid, string folder,
- string filename, ulong file_size, time_t modification_time, PhotoFileFormat file_format) {
+ string filename, ulong file_size, DateTime modification_time, PhotoFileFormat file_format) {
base(camera_name, camera, fsid, folder, filename, file_size, modification_time);
this.file_format = file_format;
}
@@ -200,7 +200,7 @@ class PhotoImportSource : ImportSource {
this.exif_md5 = exif_md5;
}
- public override time_t get_exposure_time() {
+ public override DateTime get_exposure_time() {
if (metadata == null)
return get_modification_time();
@@ -340,10 +340,10 @@ class ImportPreview : MediaSourceItem {
if (duplicated_photo_id.is_valid()) {
// Check exposure timestamp
LibraryPhoto duplicated_photo = LibraryPhoto.global.fetch(duplicated_photo_id);
- time_t photo_exposure_time = photo_import_source.get_exposure_time();
- time_t duplicated_photo_exposure_time = duplicated_photo.get_exposure_time();
+ DateTime photo_exposure_time = photo_import_source.get_exposure_time();
+ DateTime duplicated_photo_exposure_time = duplicated_photo.get_exposure_time();
- if (photo_exposure_time == duplicated_photo_exposure_time) {
+ if (photo_exposure_time.equal(duplicated_photo_exposure_time)) {
duplicated_file = DuplicatedFile.create_from_photo_id(
LibraryPhoto.global.get_basename_filesize_duplicate(
get_import_source().get_filename(), (int64) filesize));
@@ -485,7 +485,7 @@ public class ImportPage : CheckerboardPage {
private string filename;
private uint64 filesize;
private PhotoMetadata metadata;
- private time_t exposure_time;
+ private DateTime exposure_time;
private CameraImportJob? associated = null;
private BackingPhotoRow? associated_file = null;
private DuplicatedFile? duplicated_file;
@@ -503,12 +503,13 @@ public class ImportPage : CheckerboardPage {
assert(fulldir != null);
filename = import_file.get_filename();
filesize = import_file.get_filesize();
- metadata = (import_file is PhotoImportSource) ?
- (import_file as PhotoImportSource).get_metadata() : null;
+ var photo_import_source = import_file as PhotoImportSource;
+ metadata = (photo_import_source != null) ?
+ photo_import_source.get_metadata() : null;
exposure_time = import_file.get_exposure_time();
}
- public time_t get_exposure_time() {
+ public DateTime get_exposure_time() {
return exposure_time;
}
@@ -516,8 +517,8 @@ public class ImportPage : CheckerboardPage {
return duplicated_file;
}
- public override time_t get_exposure_time_override() {
- return (import_file is VideoImportSource) ? get_exposure_time() : 0;
+ public override DateTime? get_exposure_time_override() {
+ return (import_file is VideoImportSource) ? get_exposure_time() : null;
}
public override string get_dest_identifier() {
@@ -682,16 +683,13 @@ public class ImportPage : CheckerboardPage {
private Gtk.Label camera_label = new Gtk.Label(null);
private Gtk.CheckButton hide_imported;
private Gtk.ProgressBar progress_bar = new Gtk.ProgressBar();
- private GPhoto.Camera camera;
- private string uri;
+ private DiscoveredCamera dcamera;
private bool busy = false;
private bool refreshed = false;
private GPhoto.Result refresh_result = GPhoto.Result.OK;
private string refresh_error = null;
- private string camera_name;
private VolumeMonitor volume_monitor = null;
private ImportPage? local_ref = null;
- private string? icon;
private ImportPageSearchViewFilter search_filter = new ImportPageSearchViewFilter();
private HideImportedViewFilter hide_imported_filter = new HideImportedViewFilter();
private CameraViewTracker tracker;
@@ -707,28 +705,15 @@ public class ImportPage : CheckerboardPage {
LIBRARY_ERROR
}
- public ImportPage(GPhoto.Camera camera, string uri, string? display_name = null, string? icon = null) {
+ public ImportPage(DiscoveredCamera dcamera) {
base(_("Camera"));
- this.camera = camera;
- this.uri = uri;
- this.import_sources = new ImportSourceCollection("ImportSources for %s".printf(uri));
- this.icon = icon;
+ this.dcamera = dcamera;
+ this.import_sources = new ImportSourceCollection("ImportSources for %s".printf(dcamera.uri));
tracker = new CameraViewTracker(get_view());
- // Get camera name.
- if (null != display_name) {
- camera_name = display_name;
- } else {
- GPhoto.CameraAbilities abilities;
- GPhoto.Result res = camera.get_abilities(out abilities);
- if (res != GPhoto.Result.OK) {
- debug("Unable to get camera abilities: %s", res.to_full_string());
- camera_name = _("Camera");
- }
- }
- camera_label.set_text(camera_name);
- set_page_name(camera_name);
+ camera_label.set_text(dcamera.display_name);
+ set_page_name(dcamera.display_name);
// Mount.unmounted signal is *only* fired when a VolumeMonitor has been instantiated.
this.volume_monitor = VolumeMonitor.get();
@@ -846,6 +831,14 @@ public class ImportPage : CheckerboardPage {
return tracker;
}
+ protected override string get_view_empty_icon() {
+ if (this.dcamera.icon != null) {
+ return this.dcamera.icon;
+ }
+
+ return "camera-photo-symbolic";
+ }
+
protected override string get_view_empty_message() {
return _("The camera seems to be empty. No photos/videos found to import");
}
@@ -855,8 +848,8 @@ public class ImportPage : CheckerboardPage {
}
private static int64 preview_comparator(void *a, void *b) {
- return ((ImportPreview *) a)->get_import_source().get_exposure_time()
- - ((ImportPreview *) b)->get_import_source().get_exposure_time();
+ return nullsafe_date_time_comperator(((ImportPreview *) a)->get_import_source().get_exposure_time(),
+ ((ImportPreview *) b)->get_import_source().get_exposure_time());
}
private static bool preview_comparator_predicate(DataObject object, Alteration alteration) {
@@ -864,7 +857,7 @@ public class ImportPage : CheckerboardPage {
}
private int64 import_job_comparator(void *a, void *b) {
- return ((CameraImportJob *) a)->get_exposure_time() - ((CameraImportJob *) b)->get_exposure_time();
+ return nullsafe_date_time_comperator(((CameraImportJob *) a)->get_exposure_time(), ((CameraImportJob *) b)->get_exposure_time());
}
protected override void init_collect_ui_filenames(Gee.List<string> ui_filenames) {
@@ -896,11 +889,11 @@ public class ImportPage : CheckerboardPage {
}
public GPhoto.Camera get_camera() {
- return camera;
+ return dcamera.gcamera;
}
public string get_uri() {
- return uri;
+ return dcamera.uri;
}
public bool is_busy() {
@@ -998,27 +991,9 @@ public class ImportPage : CheckerboardPage {
}
// if locked because it's mounted, offer to unmount
- debug("Checking if %s is mounted…", uri);
+ debug("Checking if %s is mounted…", dcamera.uri);
- File uri = File.new_for_uri(uri);
-
- Mount mount = null;
- try {
- mount = uri.find_enclosing_mount(null);
- } catch (Error err) {
- // error means not mounted
- }
-
- // Could not find mount for gphoto2://, re-try with mtp://
- // It seems some devices are mounted using MTP and not gphoto2 daemon
- if (mount == null && this.uri.has_prefix("gphoto2")) {
- uri = File.new_for_uri("mtp" + this.uri.substring(7));
- try {
- mount = uri.find_enclosing_mount(null);
- } catch (Error err) {
- // error means not mounted
- }
- }
+ var mount = dcamera.get_mount();
if (mount != null) {
// it's mounted, offer to unmount for the user
@@ -1128,7 +1103,7 @@ public class ImportPage : CheckerboardPage {
* @param search_target The name of the directory to look for.
*/
private bool check_directory_exists(int fsid, string dir, string search_target) {
- string? fulldir = get_fulldir(camera, camera_name, fsid, dir);
+ string? fulldir = get_fulldir(dcamera.gcamera, dcamera.display_name, fsid, dir);
GPhoto.Result result;
GPhoto.CameraList folders;
@@ -1138,7 +1113,7 @@ public class ImportPage : CheckerboardPage {
return false;
}
- result = camera.list_folders(fulldir, folders, spin_idle_context.context);
+ result = dcamera.gcamera.list_folders(fulldir, folders, spin_idle_context.context);
if (result != GPhoto.Result.OK) {
// fetching the list failed - can't determine whether specified dir is present
return false;
@@ -1167,7 +1142,7 @@ public class ImportPage : CheckerboardPage {
update_status(busy, false);
refresh_error = null;
- refresh_result = camera.init(spin_idle_context.context);
+ refresh_result = dcamera.gcamera.init(spin_idle_context.context);
// If we fail to claim the device, we might have run into a conflict
// with gvfs-gphoto2-volume-monitor. Back off, try again after
@@ -1209,7 +1184,7 @@ public class ImportPage : CheckerboardPage {
Gee.ArrayList<ImportSource> import_list = new Gee.ArrayList<ImportSource>();
GPhoto.CameraStorageInformation[] sifs = null;
- refresh_result = camera.get_storageinfo(out sifs, spin_idle_context.context);
+ refresh_result = dcamera.gcamera.get_storageinfo(out sifs, spin_idle_context.context);
if (refresh_result == GPhoto.Result.OK) {
for (int fsid = 0; fsid < sifs.length; fsid++) {
// Check well-known video and image paths first to prevent accidental
@@ -1302,7 +1277,7 @@ public class ImportPage : CheckerboardPage {
progress_bar.set_text("");
progress_bar.set_fraction(0.0);
- GPhoto.Result res = camera.exit(spin_idle_context.context);
+ GPhoto.Result res = dcamera.gcamera.exit(spin_idle_context.context);
if (res != GPhoto.Result.OK) {
// log but don't fail
warning("Unable to unlock camera: %s", res.to_full_string());
@@ -1386,7 +1361,7 @@ public class ImportPage : CheckerboardPage {
}
private bool enumerate_files(int fsid, string dir, Gee.ArrayList<ImportSource> import_list) {
- string? fulldir = get_fulldir(camera, camera_name, fsid, dir);
+ string? fulldir = get_fulldir(dcamera.gcamera, dcamera.display_name, fsid, dir);
if (fulldir == null) {
warning("Skipping enumerating %s: invalid folder name", dir);
@@ -1401,7 +1376,7 @@ public class ImportPage : CheckerboardPage {
return false;
}
- refresh_result = camera.list_files(fulldir, files, spin_idle_context.context);
+ refresh_result = dcamera.gcamera.list_files(fulldir, files, spin_idle_context.context);
if (refresh_result != GPhoto.Result.OK) {
warning("Unable to list files in %s: %s", fulldir, refresh_result.to_full_string());
@@ -1424,7 +1399,7 @@ public class ImportPage : CheckerboardPage {
try {
GPhoto.CameraFileInfo info;
- if (!GPhoto.get_info(spin_idle_context.context, camera, fulldir, filename, out info)) {
+ if (!GPhoto.get_info(spin_idle_context.context, dcamera.gcamera, fulldir, filename, out info)) {
warning("Skipping import of %s/%s: name too long", fulldir, filename);
continue;
@@ -1438,8 +1413,8 @@ public class ImportPage : CheckerboardPage {
}
if (VideoReader.is_supported_video_filename(filename)) {
- VideoImportSource video_source = new VideoImportSource(camera_name, camera,
- fsid, dir, filename, info.file.size, info.file.mtime);
+ VideoImportSource video_source = new VideoImportSource(dcamera.display_name, dcamera.gcamera,
+ fsid, dir, filename, info.file.size, new DateTime.from_unix_utc(info.file.mtime));
import_list.add(video_source);
} else {
// determine file format from type, and then from file extension
@@ -1454,8 +1429,8 @@ public class ImportPage : CheckerboardPage {
continue;
}
}
- import_list.add(new PhotoImportSource(camera_name, camera, fsid, dir, filename,
- info.file.size, info.file.mtime, file_format));
+ import_list.add(new PhotoImportSource(dcamera.display_name, dcamera.gcamera, fsid, dir, filename,
+ info.file.size, new DateTime.from_unix_utc(info.file.mtime), file_format));
}
progress_bar.pulse();
@@ -1479,7 +1454,7 @@ public class ImportPage : CheckerboardPage {
return false;
}
- refresh_result = camera.list_folders(fulldir, folders, spin_idle_context.context);
+ refresh_result = dcamera.gcamera.list_folders(fulldir, folders, spin_idle_context.context);
if (refresh_result != GPhoto.Result.OK) {
warning("Unable to list folders in %s: %s", fulldir, refresh_result.to_full_string());
@@ -1498,8 +1473,12 @@ public class ImportPage : CheckerboardPage {
return false;
}
- if (!enumerate_files(fsid, append_path(dir, subdir), import_list))
- return false;
+ if (subdir.has_prefix(".")) {
+ debug("Skipping hidden sub-folder %s in %s", subdir, dir);
+ } else {
+ if (!enumerate_files(fsid, append_path(dir, subdir), import_list))
+ return false;
+ }
}
return true;
@@ -1575,7 +1554,7 @@ public class ImportPage : CheckerboardPage {
PhotoMetadata? metadata = null;
if (!VideoReader.is_supported_video_filename(filename)) {
try {
- metadata = GPhoto.load_metadata(spin_idle_context.context, camera, fulldir,
+ metadata = GPhoto.load_metadata(spin_idle_context.context, dcamera.gcamera, fulldir,
filename);
} catch (Error err) {
warning("Unable to fetch metadata for %s/%s: %s", fulldir, filename,
@@ -1604,7 +1583,7 @@ public class ImportPage : CheckerboardPage {
preview_fulldir = associated.get_fulldir();
preview_filename = associated.get_filename();
}
- preview = GPhoto.load_preview(spin_idle_context.context, camera, preview_fulldir,
+ preview = GPhoto.load_preview(spin_idle_context.context, dcamera.gcamera, preview_fulldir,
preview_filename, out preview_md5);
} catch (Error err) {
// only issue the warning message if we're not reading a video. GPhoto is capable
@@ -1621,17 +1600,18 @@ public class ImportPage : CheckerboardPage {
debug("camera MD5 %s: exif=%s preview=%s", filename, exif_only_md5, preview_md5);
#endif
- if (import_source is VideoImportSource)
- (import_source as VideoImportSource).update(preview);
+ var video_import_source = import_source as VideoImportSource;
+ if (video_import_source != null)
+ video_import_source.update(preview);
- if (import_source is PhotoImportSource)
- (import_source as PhotoImportSource).update(preview, preview_md5, metadata,
- exif_only_md5);
+ var photo_import_source = import_source as PhotoImportSource;
+ if (photo_import_source != null)
+ photo_import_source.update(preview, preview_md5, metadata, exif_only_md5);
if (associated != null) {
try {
PhotoMetadata? associated_metadata = GPhoto.load_metadata(spin_idle_context.context,
- camera, associated.get_fulldir(), associated.get_filename());
+ dcamera.gcamera, associated.get_fulldir(), associated.get_filename());
associated.update(preview, preview_md5, associated_metadata, null);
} catch (Error err) {
warning("Unable to fetch metadata for %s/%s: %s", associated.get_fulldir(),
@@ -1671,7 +1651,7 @@ public class ImportPage : CheckerboardPage {
}
private void import(Gee.Iterable<DataObject> items) {
- GPhoto.Result res = camera.init(spin_idle_context.context);
+ GPhoto.Result res = dcamera.gcamera.init(spin_idle_context.context);
if (res != GPhoto.Result.OK) {
AppWindow.error_message(_("Unable to lock camera: %s").printf(res.to_full_string()));
@@ -1712,14 +1692,14 @@ public class ImportPage : CheckerboardPage {
jobs.add(import_job);
}
- debug("Importing %d files from %s", jobs.size, camera_name);
+ debug("Importing %d files from %s", jobs.size, dcamera.display_name);
if (jobs.size > 0) {
// see import_reporter() to see why this is held during the duration of the import
assert(local_ref == null);
local_ref = this;
- BatchImport batch_import = new BatchImport(jobs, camera_name, import_reporter,
+ BatchImport batch_import = new BatchImport(jobs, dcamera.display_name, import_reporter,
null, already_imported);
batch_import.import_job_failed.connect(on_import_job_failed);
batch_import.import_complete.connect(close_import);
@@ -1811,7 +1791,7 @@ public class ImportPage : CheckerboardPage {
}
private void close_import() {
- GPhoto.Result res = camera.exit(spin_idle_context.context);
+ GPhoto.Result res = dcamera.gcamera.exit(spin_idle_context.context);
if (res != GPhoto.Result.OK) {
// log but don't fail
message("Unable to unlock camera: %s", res.to_full_string());