summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/DirectoryMonitor.vala6
-rw-r--r--src/Photo.vala2
-rw-r--r--src/Resources.vala6
-rw-r--r--src/Tombstone.vala5
-rw-r--r--src/db/DatabaseTable.vala2
-rw-r--r--src/db/Db.vala8
-rw-r--r--src/db/VideoTable.vala2
-rw-r--r--src/dialogs/ExportDialog.vala12
-rw-r--r--src/main.vala19
-rw-r--r--src/meson.build2
-rw-r--r--src/photos/AvifSupport.vala25
-rw-r--r--src/photos/HeifSupport.vala2
-rw-r--r--src/photos/JfifSupport.vala6
-rw-r--r--src/photos/PhotoFileFormat.vala1
-rw-r--r--src/photos/PhotoMetadata.vala4
-rw-r--r--src/plugins/Plugins.vala10
-rw-r--r--src/plugins/SpitInterfaces.vala2
-rw-r--r--src/util/image.vala38
-rw-r--r--src/util/string.vala2
19 files changed, 111 insertions, 43 deletions
diff --git a/src/DirectoryMonitor.vala b/src/DirectoryMonitor.vala
index 19992dd..87d9a2e 100644
--- a/src/DirectoryMonitor.vala
+++ b/src/DirectoryMonitor.vala
@@ -871,7 +871,7 @@ public class DirectoryMonitor : Object {
}
}
- if (local_dir_info.get_is_hidden()) {
+ if (local_dir_info.has_attribute("standard::is-hidden") && local_dir_info.get_is_hidden()) {
warning("Ignoring hidden directory %s", dir.get_path());
explore_directory_completed(in_discovery);
@@ -918,7 +918,7 @@ public class DirectoryMonitor : Object {
dir.get_uri());
}
// we don't deal with hidden files or directories
- if (info.get_is_hidden()) {
+ if (info.has_attribute("standard::is-hidden") && info.get_is_hidden()) {
warning("Skipping hidden file/directory %s",
dir.get_child(info.get_name()).get_path());
@@ -1439,7 +1439,7 @@ public class DirectoryMonitor : Object {
// Returns true if the file is not a symlink or if symlinks are supported for the file type,
// false otherwise. If an unsupported file type, returns false.
public static bool is_file_symlink_supported(FileInfo info) {
- if (!info.get_is_symlink())
+ if (info.has_attribute("standard::is-symlink") && !info.get_is_symlink())
return true;
FType ftype = get_ftype(info);
diff --git a/src/Photo.vala b/src/Photo.vala
index 2b90361..1cab22f 100644
--- a/src/Photo.vala
+++ b/src/Photo.vala
@@ -3723,7 +3723,7 @@ public abstract class Photo : PhotoSource, Dateable, Positionable {
if (metadata == null)
metadata = export_format.create_metadata();
- if (!export_format.can_write())
+ if (!export_format.can_write_image())
export_format = PhotoFileFormat.get_system_default_format();
PhotoFileWriter writer = export_format.create_writer(dest_file.get_path());
diff --git a/src/Resources.vala b/src/Resources.vala
index 0bd8512..a99a210 100644
--- a/src/Resources.vala
+++ b/src/Resources.vala
@@ -15,9 +15,9 @@ namespace Resources {
public const string COPYRIGHT = _("Copyright 2016 Software Freedom Conservancy Inc.");
public const string APP_GETTEXT_PACKAGE = GETTEXT_PACKAGE;
- public const string HOME_URL = "https://wiki.gnome.org/Apps/Shotwell";
- public const string FAQ_URL = "https://wiki.gnome.org/Apps/Shotwell/FAQ";
- public const string BUG_DB_URL = "https://wiki.gnome.org/Apps/Shotwell/ReportingABug";
+ public const string HOME_URL = "https://shotwell-project.org";
+ public const string FAQ_URL = "https://gitlab.gnome.org/GNOME/shotwell/-/wikis/Frequently-Asked-Questions";
+ public const string BUG_DB_URL = "https://gitlab.gnome.org/GNOME/shotwell/issues";
public const string DIR_PATTERN_URI_SYSWIDE = "help:shotwell/other-files";
private const string LIB = _LIB;
diff --git a/src/Tombstone.vala b/src/Tombstone.vala
index 23cd984..2cae0c0 100644
--- a/src/Tombstone.vala
+++ b/src/Tombstone.vala
@@ -112,7 +112,10 @@ public class TombstoneSourceCollection : DatabaseSourceCollection {
private async void async_scan(DirectoryMonitor? monitor, Cancellable? cancellable) {
// search through all tombstones for missing files, which indicate the tombstone can go away
Marker marker = start_marking();
- foreach (DataObject object in get_all()) {
+
+ // There is an issue with modifying this list while this loop here is iterating it, source unknown
+ // Getting a copy of the list to work-around this (https://gitlab.gnome.org/GNOME/shotwell/-/issues/181)
+ foreach (DataObject object in get_dataset_copy().get_all()) {
Tombstone tombstone = (Tombstone) object;
File file = tombstone.get_file();
diff --git a/src/db/DatabaseTable.vala b/src/db/DatabaseTable.vala
index be45e5e..5d84df2 100644
--- a/src/db/DatabaseTable.vala
+++ b/src/db/DatabaseTable.vala
@@ -57,7 +57,7 @@ public abstract class DatabaseTable {
re = regex_map[pattern];
} else {
try {
- re = new Regex(pattern, RegexCompileFlags.DEFAULT, RegexMatchFlags.DEFAULT);
+ re = new Regex(pattern, 0, 0);
regex_map[pattern] = re;
} catch (Error err) {
context.result_error("Invalid pattern: %s".printf(err.message), Sqlite.ERROR);
diff --git a/src/db/Db.vala b/src/db/Db.vala
index 7f76f2d..e537ee0 100644
--- a/src/db/Db.vala
+++ b/src/db/Db.vala
@@ -56,8 +56,12 @@ public VerifyResult verify_database(out string app_version, out int schema_versi
return result;
}
- PhotoTable.clean_comments();
- VideoTable.clean_comments();
+ try {
+ PhotoTable.clean_comments();
+ VideoTable.clean_comments();
+ } catch (DatabaseError err) {
+ debug("Ignoring database error while clean ing comments: %s", err.message);
+ }
return VerifyResult.OK;
diff --git a/src/db/VideoTable.vala b/src/db/VideoTable.vala
index 67c50ba..753e02a 100644
--- a/src/db/VideoTable.vala
+++ b/src/db/VideoTable.vala
@@ -158,6 +158,8 @@ public class VideoTable : DatabaseTable {
if (res != Sqlite.DONE) {
if (res != Sqlite.CONSTRAINT)
throw_error("VideoTable.add", res);
+
+ return VideoID();
}
// fill in ignored fields with database values
diff --git a/src/dialogs/ExportDialog.vala b/src/dialogs/ExportDialog.vala
index 5a61dc4..1f0a581 100644
--- a/src/dialogs/ExportDialog.vala
+++ b/src/dialogs/ExportDialog.vala
@@ -71,7 +71,7 @@ public class ExportDialog : Gtk.Dialog {
format_combo = new Gtk.ComboBoxText();
format_add_option(UNMODIFIED_FORMAT_LABEL);
format_add_option(CURRENT_FORMAT_LABEL);
- foreach (PhotoFileFormat format in PhotoFileFormat.get_writeable()) {
+ foreach (PhotoFileFormat format in PhotoFileFormat.get_image_writeable()) {
format_add_option(format.get_properties().get_user_visible_name());
}
@@ -144,7 +144,7 @@ public class ExportDialog : Gtk.Dialog {
selection_ticker++;
}
- error("format_set_active_text: text '%s' isn't in combo box", text);
+ critical("format_set_active_text: text '%s' isn't in combo box", text);
}
private PhotoFileFormat get_specified_format() {
@@ -153,7 +153,7 @@ public class ExportDialog : Gtk.Dialog {
index = NUM_SPECIAL_FORMATS;
index -= NUM_SPECIAL_FORMATS;
- PhotoFileFormat[] writeable_formats = PhotoFileFormat.get_writeable();
+ PhotoFileFormat[] writeable_formats = PhotoFileFormat.get_image_writeable();
return writeable_formats[index];
}
@@ -276,7 +276,7 @@ public class ExportDialog : Gtk.Dialog {
if (format_combo.get_active_text() == UNMODIFIED_FORMAT_LABEL) {
// if the user wishes to export the media unmodified, then we just copy the original
- // files, so parameterizing size, quality, etc. is impossible -- these are all
+ // files, so parameterize size, quality, etc. is impossible -- these are all
// just as they are in the original file. In this case, we set the scale constraint to
// original and lock out all the controls
constraint_combo.set_active(0); /* 0 == original size */
@@ -303,7 +303,9 @@ public class ExportDialog : Gtk.Dialog {
constraint_combo.set_sensitive(true);
bool jpeg = get_specified_format() == PhotoFileFormat.JFIF;
quality_combo.sensitive = !original && jpeg;
- export_metadata.sensitive = true;
+
+ export_metadata.sensitive = get_specified_format().can_write_metadata();
+ export_metadata.active = get_specified_format().can_write_metadata();
}
}
diff --git a/src/main.vala b/src/main.vala
index e619178..1ea1900 100644
--- a/src/main.vala
+++ b/src/main.vala
@@ -262,9 +262,9 @@ void library_exec(string[] mounts) {
message(" PNG : %s, gdk-pixbuf", png ? "yes" : "no");
message(" GIF : %s, gdk-pixbuf", gif ? "yes" : "no");
message(" TIFF : %s, gdk-pixbuf", tiff ? "yes" : "no");
- message(" JPEG XL: %s, gdk-pixbuf, %s meta-data", jxl ? "yes" : "no", can_read_bmff ? "yes" : "no");
- message(" AVIF : %s, gdk-pixbuf, %s meta-data", avif ? "yes" : "no", can_read_bmff ? "yes" : "no");
- message(" HEIF : %s, gdk-pixbuf, %s meta-data", heif ? "yes" : "no", can_read_bmff ? "yes" : "no");
+ message(" JPEG XL: %s, gdk-pixbuf, %s meta-data", jxl ? "yes" : "no", can_read_bmff ? "read" : "no");
+ message(" AVIF : %s, gdk-pixbuf, %s meta-data", avif ? "yes" : "no", can_read_bmff ? "read" : "no");
+ message(" HEIF : %s, gdk-pixbuf, %s meta-data", heif ? "yes" : "no", can_read_bmff ? "read" : "no");
debug("%lf seconds to Gtk.main()", startup_timer.elapsed());
@@ -346,7 +346,16 @@ void dump_metadata (string filename) {
void editing_exec(string filename, bool fullscreen) {
File initial_file = File.new_for_commandline_arg(filename);
-
+
+ if (!initial_file.get_uri().has_prefix("file://")) {
+ if (!initial_file.get_uri().has_prefix("trash://")) {
+ initial_file = File.new_for_path(initial_file.get_path());
+ } else {
+ var info = initial_file.query_info("standard::target-uri", FileQueryInfoFlags.NONE);
+ initial_file = File.new_for_uri(info.get_attribute_as_string("standard::target-uri"));
+ }
+ }
+
// preconfigure units
Direct.preconfigure(initial_file);
Db.preconfigure(null);
@@ -542,7 +551,7 @@ void main(string[] args) {
foreach (var arg in args[1:args.length]) {
if (LibraryWindow.is_mount_uri_supported(arg)) {
mounts += arg;
- } else if (is_string_empty(filename) && !arg.contains("://")) {
+ } else if (is_string_empty(filename)) {
filename = arg;
}
}
diff --git a/src/meson.build b/src/meson.build
index 25f967a..e6339f0 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -41,7 +41,7 @@ face_sources = (['faces/FacesBranch.vala',
shotwell_deps = [gio, gee, sqlite, gtk, sqlite, posix, gphoto2,
gstreamer_pbu, gudev, gexiv2, gmodule, unity,
libraw, libexif, sw_plugin, webpdemux, webp, version,
- portal]
+ portal, math]
subdir('metadata')
subdir('publishing')
diff --git a/src/photos/AvifSupport.vala b/src/photos/AvifSupport.vala
index 842f0fc..0df57a6 100644
--- a/src/photos/AvifSupport.vala
+++ b/src/photos/AvifSupport.vala
@@ -79,7 +79,7 @@ public class AvifWriter : PhotoFileWriter {
}
public override void write(Gdk.Pixbuf pixbuf, Jpeg.Quality quality) throws Error {
- pixbuf.save(get_filepath(), "avif", "quality", "90", null);
+ pixbuf.save(get_filepath(), "avif", "quality", quality.get_pct_text(), null);
}
}
@@ -89,7 +89,8 @@ public class AvifMetadataWriter : PhotoFileMetadataWriter {
}
public override void write_metadata(PhotoMetadata metadata) throws Error {
- metadata.write_to_file(get_file());
+ // TODO: Not yet implemented in gexiv2
+ // metadata.write_to_file(get_file());
}
}
@@ -99,6 +100,19 @@ public class AvifFileFormatDriver : PhotoFileFormatDriver {
public static void init() {
instance = new AvifFileFormatDriver();
AvifFileFormatProperties.init();
+
+ var formats = Gdk.Pixbuf.get_formats();
+ var seen = false;
+ can_write = true;
+
+ foreach (var format in formats) {
+ if (format.get_name() == "avif") {
+ seen = true;
+ can_write = can_write && format.is_writable();
+ }
+ }
+
+ can_write = can_write && seen;
}
public static AvifFileFormatDriver get_instance() {
@@ -112,13 +126,14 @@ public class AvifFileFormatDriver : PhotoFileFormatDriver {
public override PhotoFileReader create_reader(string filepath) {
return new AvifReader(filepath);
}
-
+
+ static bool can_write;
public override bool can_write_image() {
- return true;
+ return AvifFileFormatDriver.can_write;
}
public override bool can_write_metadata() {
- return true;
+ return false;
}
public override PhotoFileWriter? create_writer(string filepath) {
diff --git a/src/photos/HeifSupport.vala b/src/photos/HeifSupport.vala
index 58b9d9d..873e5a1 100644
--- a/src/photos/HeifSupport.vala
+++ b/src/photos/HeifSupport.vala
@@ -128,7 +128,7 @@ public class HeifFileFormatDriver : PhotoFileFormatDriver {
}
public override bool can_write_metadata() {
- return true;
+ return false;
}
public override PhotoFileWriter? create_writer(string filepath) {
diff --git a/src/photos/JfifSupport.vala b/src/photos/JfifSupport.vala
index fc43663..ceca827 100644
--- a/src/photos/JfifSupport.vala
+++ b/src/photos/JfifSupport.vala
@@ -190,7 +190,11 @@ public class JfifWriter : PhotoFileWriter {
}
public override void write(Gdk.Pixbuf pixbuf, Jpeg.Quality quality) throws Error {
- pixbuf.save(get_filepath(), "jpeg", "quality", quality.get_pct_text());
+ if (pixbuf.has_alpha) {
+ apply_alpha_channel(pixbuf).save(get_filepath(), "jpeg", "quality", quality.get_pct_text());
+ } else {
+ pixbuf.save(get_filepath(), "jpeg", "quality", quality.get_pct_text());
+ }
}
}
diff --git a/src/photos/PhotoFileFormat.vala b/src/photos/PhotoFileFormat.vala
index 4c69de3..f7abc33 100644
--- a/src/photos/PhotoFileFormat.vala
+++ b/src/photos/PhotoFileFormat.vala
@@ -251,6 +251,7 @@ public enum PhotoFileFormat {
return PhotoFileFormat.AVIF;
case "heif":
+ case "heic":
return PhotoFileFormat.HEIF;
case "jxl":
diff --git a/src/photos/PhotoMetadata.vala b/src/photos/PhotoMetadata.vala
index 0624b41..3bf7b37 100644
--- a/src/photos/PhotoMetadata.vala
+++ b/src/photos/PhotoMetadata.vala
@@ -1044,6 +1044,10 @@ public class PhotoMetadata : MediaMetadata {
public override string? get_comment() {
var comment = get_first_string_interpreted (COMMENT_TAGS);
+ if (comment == null) {
+ return comment;
+ }
+
try {
var re = new Regex("^charset=\\w+\\s*");
return re.replace(comment, -1, 0, "", RegexMatchFlags.DEFAULT);
diff --git a/src/plugins/Plugins.vala b/src/plugins/Plugins.vala
index cfab7e8..7078680 100644
--- a/src/plugins/Plugins.vala
+++ b/src/plugins/Plugins.vala
@@ -300,13 +300,6 @@ public int compare_extension_point_names(ExtensionPoint a, ExtensionPoint b) {
return a.name.collate(b.name);
}
-private bool is_shared_library(File file) {
- string name, ext;
- disassemble_filename(file.get_basename(), out name, out ext);
-
- return ext == Module.SUFFIX;
-}
-
private void search_for_plugins(File dir) throws Error {
debug("Searching %s for plugins…", dir.get_path());
@@ -334,8 +327,9 @@ private void search_for_plugins(File dir) throws Error {
break;
case FileType.REGULAR:
- if (is_shared_library(file))
+ if (info.get_content_type() == "application/x-sharedlib") {
load_module(file);
+ }
break;
default:
diff --git a/src/plugins/SpitInterfaces.vala b/src/plugins/SpitInterfaces.vala
index 94e6f95..0eabdd1 100644
--- a/src/plugins/SpitInterfaces.vala
+++ b/src/plugins/SpitInterfaces.vala
@@ -172,7 +172,7 @@ public class PluggableInfo : Object {
public string? copyright {get; set; }
public string? license_blurp { get; set; default = _("LGPL v2.1 or later"); }
public string? license_url { get; set; default = "https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html"; }
- public string? website_url {get; set; default = "https://wiki.gnome.org/Apps/Shotwell";}
+ public string? website_url {get; set; default = "https://shotwell-project.org";}
public string? website_name { get; set; default = _("Visit the Shotwell home page");}
public string? translators {get; set; default = _("translator-credits"); }
diff --git a/src/util/image.vala b/src/util/image.vala
index 5b78a50..e46233d 100644
--- a/src/util/image.vala
+++ b/src/util/image.vala
@@ -185,8 +185,39 @@ public Gdk.Point subtract_points(Gdk.Point p1, Gdk.Point p2) {
return result;
}
+Gdk.Pixbuf apply_alpha_channel(Gdk.Pixbuf source, bool strip = false) {
+ var dest = new Gdk.Pixbuf (source.colorspace, false, source.bits_per_sample, source.width, source.height);
+ uchar *sp = source.pixels;
+ uchar *dp = dest.pixels;
+
+ for (int j = 0; j < source.height; j++) {
+ uchar *s = sp;
+ uchar *d = dp;
+ uchar *end = s + 4 * source.width;
+ while (s < end) {
+ if (strip) {
+ d[0] = s[0];
+ d[1] = s[1];
+ d[2] = s[2];
+ } else {
+ double alpha = s[3] / 255.0;
+ d[0] = (uchar)Math.round((255.0 * (1.0 - alpha)) + (s[0] * alpha));
+ d[1] = (uchar)Math.round((255.0 * (1.0 - alpha)) + (s[1] * alpha));
+ d[2] = (uchar)Math.round((255.0 * (1.0 - alpha)) + (s[2] * alpha));
+ }
+ s += 4;
+ d += 3;
+ }
+
+ sp += source.rowstride;
+ dp += dest.rowstride;
+ }
+
+ return dest;
+}
+
// Converts XRGB/ARGB (Cairo)-formatted pixels to RGBA (GDK).
-void fix_cairo_pixbuf(Gdk.Pixbuf pixbuf) {
+void argb2rgba(Gdk.Pixbuf pixbuf) {
uchar *gdk_pixels = pixbuf.pixels;
for (int j = 0 ; j < pixbuf.height; ++j) {
uchar *p = gdk_pixels;
@@ -274,9 +305,8 @@ Gdk.Pixbuf rotate_arb(Gdk.Pixbuf source_pixbuf, double angle) {
// prepare the newly-drawn image for use by
// the rest of the pipeline.
- fix_cairo_pixbuf(dest_pixbuf);
-
- return dest_pixbuf;
+ argb2rgba(dest_pixbuf);
+ return apply_alpha_channel(dest_pixbuf, true);
}
/**
diff --git a/src/util/string.vala b/src/util/string.vala
index 5ca4680..521e2ba 100644
--- a/src/util/string.vala
+++ b/src/util/string.vala
@@ -203,7 +203,7 @@ public string remove_diacritics(string istring) {
case UnicodeType.FORMAT:
case UnicodeType.UNASSIGNED:
case UnicodeType.NON_SPACING_MARK:
- case UnicodeType.COMBINING_MARK:
+ case UnicodeType.SPACING_MARK:
case UnicodeType.ENCLOSING_MARK:
// Ignore those
continue;