Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package kf6-kfilemetadata for 
openSUSE:Factory checked in at 2025-09-15 19:49:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/kf6-kfilemetadata (Old)
 and      /work/SRC/openSUSE:Factory/.kf6-kfilemetadata.new.1977 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "kf6-kfilemetadata"

Mon Sep 15 19:49:32 2025 rev:19 rq:1304400 version:6.18.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/kf6-kfilemetadata/kf6-kfilemetadata.changes      
2025-08-09 20:03:00.294206522 +0200
+++ 
/work/SRC/openSUSE:Factory/.kf6-kfilemetadata.new.1977/kf6-kfilemetadata.changes
    2025-09-15 19:52:55.935166425 +0200
@@ -1,0 +2,19 @@
+Mon Sep  8 13:33:03 UTC 2025 - Christophe Marin <[email protected]>
+
+- Update to 6.18.0
+  * New feature release
+  * For more details please see:
+  * https://kde.org/announcements/frameworks/6/6.18.0
+- Changes since 6.17.0:
+  * Update dependency version to 6.18.0
+  * [PlaintextExtractor] Use explicitly sized type for 32bit compatibility
+  * Fix casing of ecm_generate_headers PREFIX arg value
+  * dump test: remove unused include directory
+  * [Exiv2Extractor] Fix compatibility with Exiv2 0.27.x
+  * [Exiv2Extractor] Add support for subsecond timestamps and timezones
+  * [Exiv2Extractor] Add dedicated parser for Exif compound dates
+  * Add tests for internal DateTime parser helper
+  * [Exiv2ExtractorTest] Fix incorrect QTime initialization
+  * Update version to 6.18.0
+
+-------------------------------------------------------------------

Old:
----
  kfilemetadata-6.17.0.tar.xz
  kfilemetadata-6.17.0.tar.xz.sig

New:
----
  kfilemetadata-6.18.0.tar.xz
  kfilemetadata-6.18.0.tar.xz.sig

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ kf6-kfilemetadata.spec ++++++
--- /var/tmp/diff_new_pack.H8vlfc/_old  2025-09-15 19:52:56.487189608 +0200
+++ /var/tmp/diff_new_pack.H8vlfc/_new  2025-09-15 19:52:56.487189608 +0200
@@ -19,12 +19,12 @@
 %define qt6_version 6.8.0
 
 %define rname kfilemetadata
-# Full KF6 version (e.g. 6.17.0)
+# Full KF6 version (e.g. 6.18.0)
 %{!?_kf6_version: %global _kf6_version %{version}}
 %bcond_without ffmpeg
 %bcond_without released
 Name:           kf6-kfilemetadata
-Version:        6.17.0
+Version:        6.18.0
 Release:        0
 Summary:        Library for extracting Metadata
 License:        GPL-2.0-or-later AND LGPL-2.1-or-later AND LGPL-3.0-only


++++++ kfilemetadata-6.17.0.tar.xz -> kfilemetadata-6.18.0.tar.xz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/CMakeLists.txt 
new/kfilemetadata-6.18.0/CMakeLists.txt
--- old/kfilemetadata-6.17.0/CMakeLists.txt     2025-08-01 12:34:24.000000000 
+0200
+++ new/kfilemetadata-6.18.0/CMakeLists.txt     2025-09-08 10:12:20.000000000 
+0200
@@ -1,11 +1,11 @@
 cmake_minimum_required(VERSION 3.16)
 
-set(KF_VERSION "6.17.0") # handled by release scripts
-set(KF_DEP_VERSION "6.17.0") # handled by release scripts
+set(KF_VERSION "6.18.0") # handled by release scripts
+set(KF_DEP_VERSION "6.18.0") # handled by release scripts
 project(KFileMetaData VERSION ${KF_VERSION})
 
 include(FeatureSummary)
-find_package(ECM 6.17.0  NO_MODULE)
+find_package(ECM 6.18.0  NO_MODULE)
 set_package_properties(ECM PROPERTIES TYPE REQUIRED DESCRIPTION "Extra CMake 
Modules." URL "https://commits.kde.org/extra-cmake-modules";)
 feature_summary(WHAT REQUIRED_PACKAGES_NOT_FOUND 
FATAL_ON_MISSING_REQUIRED_PACKAGES)
 
@@ -74,7 +74,7 @@
                        TYPE OPTIONAL
                        PURPOSE "Support for music metadata")
 
-find_package(LibExiv2 0.26)
+find_package(LibExiv2 0.27.4)
 set_package_properties(LibExiv2 PROPERTIES
                        TYPE OPTIONAL
                        PURPOSE "Support for image metadata")
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/autotests/CMakeLists.txt 
new/kfilemetadata-6.18.0/autotests/CMakeLists.txt
--- old/kfilemetadata-6.17.0/autotests/CMakeLists.txt   2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/autotests/CMakeLists.txt   2025-09-08 
10:12:20.000000000 +0200
@@ -26,6 +26,16 @@
 )
 
 #
+# Date/Time parser and timezone handling
+#
+ecm_add_test(
+    datetimetests.cpp
+    ${KfileMetaDataAutotest_SRCS}
+    TEST_NAME "datetimetest"
+    LINK_LIBRARIES Qt6::Test
+)
+
+#
 # Full text extraction test
 #
 ecm_add_test(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/autotests/datetimetests.cpp 
new/kfilemetadata-6.18.0/autotests/datetimetests.cpp
--- old/kfilemetadata-6.17.0/autotests/datetimetests.cpp        1970-01-01 
01:00:00.000000000 +0100
+++ new/kfilemetadata-6.18.0/autotests/datetimetests.cpp        2025-09-08 
10:12:20.000000000 +0200
@@ -0,0 +1,80 @@
+/*
+    SPDX-FileCopyrightText: 2025 Stefan Brüns <[email protected]>
+
+    SPDX-License-Identifier: LGPL-2.1-or-later
+*/
+
+#include "../src/datetimeparser_p.h"
+
+#include <QTest>
+#include <QTimeZone>
+
+using namespace KFileMetaData;
+using namespace Qt::Literals::StringLiterals;
+
+class DateTimeTest : public QObject
+{
+    Q_OBJECT
+
+private Q_SLOTS:
+    void testParser();
+    void testParser_data();
+    void testExifParser();
+    void testExifParser_data();
+};
+
+void DateTimeTest::testParser()
+{
+    QFETCH(QString, timeString);
+    QFETCH(QDateTime, expected);
+
+    auto dt = Parser::dateTimeFromString(timeString);
+
+    QCOMPARE(dt, expected);
+}
+
+void DateTimeTest::testParser_data()
+{
+    QTest::addColumn<QString>("timeString");
+    QTest::addColumn<QDateTime>("expected");
+
+    // clang-format off
+    QTest::addRow("ISO-8601-noTZ") << u"2025-07-27T14:35:56.448986511"_s       
<< QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56, 449), QTimeZone::LocalTime);
+    QTest::addRow("ISO-8601")      << u"2025-07-27T14:35:56.448986511+02:00"_s 
<< QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56, 449), QTimeZone(7200));
+    QTest::addRow("ISO-date-only") << u"2025-07-27"_s                          
<< QDateTime(QDate(2025, 07, 27), QTime(0, 0, 0), QTimeZone::LocalTime);
+    // clang-format on
+}
+
+void DateTimeTest::testExifParser()
+{
+    QFETCH(QString, timeString);
+    QFETCH(QString, offsetString);
+    QFETCH(QString, subSecString);
+    QFETCH(QDateTime, expected);
+
+    auto dt = Parser::dateTimeFromExifString(timeString, subSecString, 
offsetString, {});
+
+    QCOMPARE(dt, expected);
+}
+
+void DateTimeTest::testExifParser_data()
+{
+    QTest::addColumn<QString>("timeString");
+    QTest::addColumn<QString>("subSecString");
+    QTest::addColumn<QString>("offsetString");
+    QTest::addColumn<QDateTime>("expected");
+
+    // clang-format off
+    QTest::addRow("noTZ")             << u"2025:07:27 14:35:56"_s << u""_s     
  << u""_s       << QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56), 
QTimeZone::LocalTime);
+    QTest::addRow("ISO-TZ")           << u"2025:07:27 14:35:56"_s << u""_s     
  << u"+02:00"_s << QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56), 
QTimeZone(7200));
+    QTest::addRow("Subsec-1")         << u"2025:07:27 14:35:56"_s << u"1"_s    
  << u""_s       << QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56, 100), 
QTimeZone::LocalTime);
+    QTest::addRow("Subsec-200")       << u"2025:07:27 14:35:56"_s << u"200"_s  
  << u""_s       << QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56, 200), 
QTimeZone::LocalTime);
+    QTest::addRow("Subsec-trim")      << u"2025:07:27 14:35:56"_s << u"34 "_s  
  << u""_s       << QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56, 340), 
QTimeZone::LocalTime);
+    QTest::addRow("Subsec-rounddown") << u"2025:07:27 14:35:56"_s << u"34544 
"_s << u""_s       << QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56, 345), 
QTimeZone::LocalTime);
+    QTest::addRow("Subsec-roundup")   << u"2025:07:27 14:35:56"_s << 
u"34567"_s  << u""_s       << QDateTime(QDate(2025, 07, 27), QTime(14, 35, 56, 
346), QTimeZone::LocalTime);
+    // clang-format on
+}
+
+QTEST_GUILESS_MAIN(DateTimeTest)
+
+#include "datetimetests.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kfilemetadata-6.17.0/autotests/exiv2extractortest.cpp 
new/kfilemetadata-6.18.0/autotests/exiv2extractortest.cpp
--- old/kfilemetadata-6.17.0/autotests/exiv2extractortest.cpp   2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/autotests/exiv2extractortest.cpp   2025-09-08 
10:12:20.000000000 +0200
@@ -14,6 +14,7 @@
 #include <QTimeZone>
 
 using namespace KFileMetaData;
+using namespace Qt::Literals::StringLiterals;
 
 class Exiv2ExtractorTest : public QObject
 {
@@ -26,6 +27,8 @@
     void testJpegJxlProperties();
     void testJpegJxlProperties_data();
     void testHeifProperties();
+    void testTimezone();
+    void testTimezone_data();
 };
 
 namespace {
@@ -148,11 +151,11 @@
     verifyProperty(Property::Height, 14);
     verifyProperty(Property::Manufacturer, QStringLiteral("LGE"));
     verifyProperty(Property::Model, QStringLiteral("Nexus 5"));
-    verifyProperty(Property::ImageDateTime, QDateTime(QDate(2014, 10, 04), 
QTime(13, 47, 43.000), QTimeZone::UTC));
+    verifyProperty(Property::ImageDateTime, QDateTime(QDate(2014, 10, 04), 
QTime(13, 47, 43, 0), QTimeZone::LocalTime));
     verifyProperty(Property::PhotoFlash, 0);
     verifyProperty(Property::PhotoPixelXDimension, 8);
     verifyProperty(Property::PhotoPixelYDimension, 14);
-    verifyProperty(Property::PhotoDateTimeOriginal, QDateTime(QDate(2014, 10, 
04), QTime(13, 47, 43.000), QTimeZone::UTC));
+    verifyProperty(Property::PhotoDateTimeOriginal, QDateTime(QDate(2014, 10, 
04), QTime(13, 47, 43, 0), QTimeZone::LocalTime));
     verifyProperty(Property::PhotoFocalLength, 4.f);
     verifyProperty(Property::PhotoFocalLengthIn35mmFilm, 10.f);
     verifyProperty(Property::PhotoExposureTime, 0.0027027f);
@@ -216,11 +219,11 @@
     verifyProperty(Property::Height, 1000);
     verifyProperty(Property::Manufacturer, QStringLiteral("samsung"));
     verifyProperty(Property::Model, QStringLiteral("SM-J610N"));
-    verifyProperty(Property::ImageDateTime, QDateTime(QDate(2022, 03, 24), 
QTime(18, 20, 07.000), QTimeZone::UTC));
+    verifyProperty(Property::ImageDateTime, QDateTime(QDate(2022, 03, 24), 
QTime(18, 20, 07, 0), QTimeZone::LocalTime));
     verifyProperty(Property::PhotoFlash, 0);
     verifyProperty(Property::PhotoPixelXDimension, 750);
     verifyProperty(Property::PhotoPixelYDimension, 1000);
-    verifyProperty(Property::PhotoDateTimeOriginal, QDateTime(QDate(2020, 03, 
31), QTime(11, 14, 30.000), QTimeZone::UTC));
+    verifyProperty(Property::PhotoDateTimeOriginal, QDateTime(QDate(2020, 03, 
31), QTime(11, 14, 30, 0), QTimeZone::LocalTime));
     verifyProperty(Property::PhotoFocalLength, 3.6f);
     verifyProperty(Property::PhotoFocalLengthIn35mmFilm, 26.f);
     verifyProperty(Property::PhotoExposureTime, 0.00429185f);
@@ -234,6 +237,33 @@
     verifyProperty(Property::PhotoSharpness, 0);
 }
 
+void Exiv2ExtractorTest::testTimezone()
+{
+    QFETCH(QString, fileName);
+    QFETCH(QString, mimeType);
+    QFETCH(QDateTime, dateTime);
+
+    Exiv2Extractor plugin{this};
+    QVERIFY(plugin.mimetypes().contains(mimeType));
+
+    SimpleExtractionResult result(testFilePath(fileName), mimeType);
+    plugin.extract(&result);
+
+    QCOMPARE(result.types().size(), 1);
+    QCOMPARE(result.types().constFirst(), Type::Image);
+
+    QCOMPARE(result.properties().value(Property::ImageDateTime), dateTime);
+}
+
+void Exiv2ExtractorTest::testTimezone_data()
+{
+    QTest::addColumn<QString>("fileName");
+    QTest::addColumn<QString>("mimeType");
+    QTest::addColumn<QDateTime>("dateTime");
+
+    QTest::addRow("CanonTi") << u"test_canonti.jpg"_s << u"image/jpeg"_s << 
QDateTime(QDate(2025, 8, 2), QTime(15, 28, 31, 290), QTimeZone(7200));
+}
+
 QTEST_GUILESS_MAIN(Exiv2ExtractorTest)
 
 #include "exiv2extractortest.moc"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kfilemetadata-6.17.0/autotests/extractorcoveragetest.cpp 
new/kfilemetadata-6.18.0/autotests/extractorcoveragetest.cpp
--- old/kfilemetadata-6.17.0/autotests/extractorcoveragetest.cpp        
2025-08-01 12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/autotests/extractorcoveragetest.cpp        
2025-09-08 10:12:20.000000000 +0200
@@ -34,6 +34,7 @@
 
     void initTestCase() {
         // Expected mimetypes
+        // clang-format off
         m_knownFiles = {
             { "test_plain_text_newlines.txt",  "text/plain"},
             { "test_plain_text_file.txt",      "text/plain"},
@@ -61,6 +62,7 @@
             { "test.flac",                     "audio/flac"},
             { "test.heif",                     "image/heif"}, // alias for 
image/heic
             { "test.jpg",                      "image/jpeg"},
+            { "test_canonti.jpg",              "image/jpeg"},
             { "test.jxl",                      "image/jxl"},
             { "test_libreoffice.docx",         
"application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
             { "test_libreoffice.pptx",         
"application/vnd.openxmlformats-officedocument.presentationml.presentation"},
@@ -122,6 +124,7 @@
             { "test.it",                       "audio/x-it"},
             { "test.xm",                       "audio/x-xm"},
         };
+        // clang-format off
 
         // Collect all test files from the samplefiles directory
         QDirIterator it(filePath(), {QStringLiteral("test*")}, QDir::Files);
Binary files old/kfilemetadata-6.17.0/autotests/samplefiles/test_canonti.jpg 
and new/kfilemetadata-6.18.0/autotests/samplefiles/test_canonti.jpg differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/autotests/taglibwritertest.cpp 
new/kfilemetadata-6.18.0/autotests/taglibwritertest.cpp
--- old/kfilemetadata-6.17.0/autotests/taglibwritertest.cpp     2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/autotests/taglibwritertest.cpp     2025-09-08 
10:12:20.000000000 +0200
@@ -8,10 +8,11 @@
 #include "indexerextractortestsconfig.h"
 #include "writers/taglibwriter.h"
 #include "writedata.h"
-#include <kfilemetadata/ExtractorCollection>
-#include <kfilemetadata/Extractor>
-#include <kfilemetadata/ExtractionResult>
-#include <kfilemetadata/SimpleExtractionResult>
+
+#include <KFileMetaData/ExtractorCollection>
+#include <KFileMetaData/Extractor>
+#include <KFileMetaData/ExtractionResult>
+#include <KFileMetaData/SimpleExtractionResult>
 
 #include <QTest>
 #include <QFile>
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/po/ar/kfilemetadata6.po 
new/kfilemetadata-6.18.0/po/ar/kfilemetadata6.po
--- old/kfilemetadata-6.17.0/po/ar/kfilemetadata6.po    2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/po/ar/kfilemetadata6.po    2025-09-08 
10:12:20.000000000 +0200
@@ -8,7 +8,7 @@
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: https://bugs.kde.org\n";
 "POT-Creation-Date: 2025-06-27 00:39+0000\n"
-"PO-Revision-Date: 2025-06-28 17:02+0400\n"
+"PO-Revision-Date: 2025-08-03 12:20+0400\n"
 "Last-Translator: Zayed Al-Saidi <[email protected]>\n"
 "Language-Team: ar\n"
 "Language: ar\n"
@@ -77,7 +77,7 @@
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "No flash"
-msgstr "بدون وميض"
+msgstr "بلا وميض"
 
 #: src/formatstrings.cpp:97
 #, kde-format
@@ -137,25 +137,25 @@
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "No, auto"
-msgstr "لا، آلي"
+msgstr "لا، آليّ"
 
 #: src/formatstrings.cpp:107
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "Yes, auto"
-msgstr "نعم، آلي"
+msgstr "نعم، آليّ"
 
 #: src/formatstrings.cpp:108
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "Yes, auto, return light not detected"
-msgstr "نعم، آلي، لم يرجع الضوء"
+msgstr "نعم، آليّ، لم يرجع الضوء"
 
 #: src/formatstrings.cpp:109
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "Yes, auto, return light detected"
-msgstr "نعم، آلي، رجع الضوء"
+msgstr "نعم، آليّ، رجع الضوء"
 
 #: src/formatstrings.cpp:110
 #, kde-format
@@ -215,25 +215,25 @@
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "No, auto, red-eye reduction"
-msgstr "لا، آلي، إنقاص العين الحمراء"
+msgstr "لا، آليّ، إنقاص العين الحمراء"
 
 #: src/formatstrings.cpp:120
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "Yes, auto, red-eye reduction"
-msgstr "نعم، آلي، إنقاص العين الحمراء"
+msgstr "نعم، آليّ، إنقاص العين الحمراء"
 
 #: src/formatstrings.cpp:121
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "Yes, auto, red-eye reduction, return light not detected"
-msgstr "نعم، آلي، إنقاص العين الحمراء، لم يرجع الضوء"
+msgstr "نعم، آليّ، إنقاص العين الحمراء، لم يرجع الضوء"
 
 #: src/formatstrings.cpp:122
 #, kde-format
 msgctxt "Description of photo flash"
 msgid "Yes, auto, red-eye reduction, return light detected"
-msgstr "نعم، آلي، إنقاص العين الحمراء، رجع الضوء"
+msgstr "نعم، آليّ، إنقاص العين الحمراء، رجع الضوء"
 
 #: src/formatstrings.cpp:127
 #, kde-format
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/po/cs/kfilemetadata6.po 
new/kfilemetadata-6.18.0/po/cs/kfilemetadata6.po
--- old/kfilemetadata-6.17.0/po/cs/kfilemetadata6.po    2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/po/cs/kfilemetadata6.po    2025-09-08 
10:12:20.000000000 +0200
@@ -308,12 +308,9 @@
 msgstr "Prázdné"
 
 #: src/propertyinfo.cpp:46
-#, fuzzy
-#| msgctxt "@label"
-#| msgid "Description"
 msgctxt "@label accessible alt text"
 msgid "Assistive Description"
-msgstr "Popis"
+msgstr ""
 
 #: src/propertyinfo.cpp:47
 msgctxt "@label music album"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/po/eu/kfilemetadata6.po 
new/kfilemetadata-6.18.0/po/eu/kfilemetadata6.po
--- old/kfilemetadata-6.17.0/po/eu/kfilemetadata6.po    2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/po/eu/kfilemetadata6.po    2025-09-08 
10:12:20.000000000 +0200
@@ -11,7 +11,7 @@
 "Project-Id-Version: kfilemetadata\n"
 "Report-Msgid-Bugs-To: https://bugs.kde.org\n";
 "POT-Creation-Date: 2025-06-27 00:39+0000\n"
-"PO-Revision-Date: 2025-06-28 14:23+0200\n"
+"PO-Revision-Date: 2025-08-13 23:48+0200\n"
 "Last-Translator: Iñigo Salvador Azurmendi <[email protected]>\n"
 "Language-Team: Basque <[email protected]>\n"
 "Language: eu\n"
@@ -19,7 +19,7 @@
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n != 1);\n"
-"X-Generator: Lokalize 25.04.2\n"
+"X-Generator: Lokalize 25.04.3\n"
 
 #: src/formatstrings.cpp:64
 #, kde-format
@@ -530,7 +530,7 @@
 #: src/propertyinfo.cpp:89
 msgctxt "@label EXIF"
 msgid "Sharpness"
-msgstr "Garbitasuna"
+msgstr "Araztasuna"
 
 #: src/propertyinfo.cpp:90
 msgctxt "@label EXIF"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/po/pt_BR/kfilemetadata6.po 
new/kfilemetadata-6.18.0/po/pt_BR/kfilemetadata6.po
--- old/kfilemetadata-6.17.0/po/pt_BR/kfilemetadata6.po 2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/po/pt_BR/kfilemetadata6.po 2025-09-08 
10:12:20.000000000 +0200
@@ -5,20 +5,21 @@
 # André Marcelo Alvarenga <[email protected]>, 2014, 2015, 2016, 2018, 2019.
 # Luiz Fernando Ranghetti <[email protected]>, 2017, 2018, 2019, 2023.
 # SPDX-FileCopyrightText: 2025 Guilherme Marçal Silva 
<[email protected]>
+# SPDX-FileCopyrightText: 2025 Marcus Gama <[email protected]>
 msgid ""
 msgstr ""
 "Project-Id-Version: kfilemetadata5\n"
 "Report-Msgid-Bugs-To: https://bugs.kde.org\n";
 "POT-Creation-Date: 2025-06-27 00:39+0000\n"
-"PO-Revision-Date: 2025-02-05 23:47-0300\n"
-"Last-Translator: Guilherme Marçal Silva <[email protected]>\n"
+"PO-Revision-Date: 2025-08-29 09:23-0300\n"
+"Last-Translator: Marcus Gama <[email protected]>\n"
 "Language-Team: Brazilian Portuguese <[email protected]>\n"
 "Language: pt_BR\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
 "Content-Transfer-Encoding: 8bit\n"
 "Plural-Forms: nplurals=2; plural=(n > 1);\n"
-"X-Generator: Lokalize 24.12.1\n"
+"X-Generator: Lokalize 25.08.0\n"
 
 #: src/formatstrings.cpp:64
 #, kde-format
@@ -316,12 +317,9 @@
 msgstr "Vazio"
 
 #: src/propertyinfo.cpp:46
-#, fuzzy
-#| msgctxt "@label"
-#| msgid "Description"
 msgctxt "@label accessible alt text"
 msgid "Assistive Description"
-msgstr "Descrição"
+msgstr "Descrição assistencial"
 
 #: src/propertyinfo.cpp:47
 msgctxt "@label music album"
@@ -546,28 +544,22 @@
 #: src/propertyinfo.cpp:91
 msgctxt "@label"
 msgid "Color Space"
-msgstr ""
+msgstr "Espaço de cor"
 
 #: src/propertyinfo.cpp:92
-#, fuzzy
-#| msgctxt "@label"
-#| msgid "Video"
 msgctxt "@label"
 msgid "Video Codec"
-msgstr "Vídeo"
+msgstr "Codec de vídeo"
 
 #: src/propertyinfo.cpp:93
-#, fuzzy
-#| msgctxt "@label"
-#| msgid "Audio"
 msgctxt "@label"
 msgid "Audio Codec"
-msgstr "Áudio"
+msgstr "Codec de áudio"
 
 #: src/propertyinfo.cpp:94
 msgctxt "@label"
 msgid "Pixel Format"
-msgstr ""
+msgstr "Formato de pixel"
 
 #: src/propertyinfo.cpp:95
 msgctxt "@label"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/src/CMakeLists.txt 
new/kfilemetadata-6.18.0/src/CMakeLists.txt
--- old/kfilemetadata-6.17.0/src/CMakeLists.txt 2025-08-01 12:34:24.000000000 
+0200
+++ new/kfilemetadata-6.18.0/src/CMakeLists.txt 2025-09-08 10:12:20.000000000 
+0200
@@ -77,7 +77,7 @@
     EmbeddedImageData
     MimeUtils
 
-    PREFIX kfilemetadata
+    PREFIX KFileMetaData
     REQUIRED_HEADERS KF6FileMetaData_HEADERS
 )
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/src/datetimeparser_p.h 
new/kfilemetadata-6.18.0/src/datetimeparser_p.h
--- old/kfilemetadata-6.17.0/src/datetimeparser_p.h     2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/src/datetimeparser_p.h     2025-09-08 
10:12:20.000000000 +0200
@@ -18,6 +18,42 @@
 namespace Parser
 {
 
+inline QDateTime dateTimeFromExifString(QStringView dateString, QStringView 
subSecsString, QStringView offsetString, std::optional<int> offsetSecs)
+{
+    using namespace Qt::Literals::StringLiterals;
+
+    if (auto dateTime = QDateTime::fromString(dateString, u"yyyy:MM:dd 
hh:mm:ss"_s); dateTime.isValid()) {
+        subSecsString = subSecsString.trimmed();
+        if (!subSecsString.isEmpty()) {
+            long subSecs = 0;
+            if (subSecsString.size() >= 4) {
+                subSecsString = subSecsString.first(4);
+                subSecs = (subSecsString.toLong() + 5) / 10;
+            } else if (subSecsString.size() == 3) {
+                subSecs = subSecsString.toLong();
+            } else if (subSecsString.size() == 2) {
+                subSecs = subSecsString.toLong() * 10;
+            } else if (subSecsString.size() == 1) {
+                subSecs = subSecsString.toLong() * 100;
+            }
+            dateTime = dateTime.addMSecs(subSecs);
+        }
+        if (!offsetString.isEmpty()) {
+            if (auto offset = QDateTime::fromString(offsetString, u"ttt"_s); 
offset.isValid()) {
+                dateTime.setTimeZone(offset.timeZone());
+            } else {
+                qCWarning(KFILEMETADATA_LOG) << "Could not parse timezone 
from:" << offsetString;
+            }
+        } else if (offsetSecs) {
+            dateTime.setTimeZone(QTimeZone(*offsetSecs));
+        }
+        return dateTime;
+    }
+
+    qCWarning(KFILEMETADATA_LOG) << "Could not parse datetime from:" << 
dateString << subSecsString << offsetString;
+    return {};
+}
+
 inline QDateTime dateTimeFromString(const QString &dateString)
 {
     if (auto dateTime = QDateTime::fromString(dateString, Qt::ISODate); 
dateTime.isValid()) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kfilemetadata-6.17.0/src/extractors/exiv2extractor.cpp 
new/kfilemetadata-6.18.0/src/extractors/exiv2extractor.cpp
--- old/kfilemetadata-6.17.0/src/extractors/exiv2extractor.cpp  2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/src/extractors/exiv2extractor.cpp  2025-09-08 
10:12:20.000000000 +0200
@@ -4,12 +4,12 @@
     SPDX-License-Identifier: LGPL-2.1-or-later
 */
 
-
-#include "datetimeparser_p.h"
 #include "exiv2extractor.h"
+#include "datetimeparser_p.h"
 #include <QTimeZone>
 #include <cmath>
 #include <exiv2/exiv2.hpp>
+#include <optional>
 
 using namespace KFileMetaData;
 
@@ -71,18 +71,73 @@
     return QString::fromUtf8(str.c_str(), str.length());
 }
 
-QVariant toVariantDateTime(const Exiv2::Value& value)
+enum DateTimeType {
+    DateTime,
+    DateTimeOrig,
+};
+template<DateTimeType dtType>
+QDateTime getDateTime(const Exiv2::ExifData data)
 {
-    if (value.typeId() == Exiv2::asciiString) {
-        QDateTime val = 
Parser::dateTimeFromString(QString::fromStdString(value.toString()));
-        if (val.isValid()) {
-            // Datetime is stored in exif as local time.
-            val.setTimeZone(QTimeZone::fromSecondsAheadOfUtc(0));
-            return QVariant(val);
+    using namespace std::string_literals;
+    using EK = Exiv2::ExifKey;
+
+    auto getStringValue = [&data](const Exiv2::ExifKey &key) -> 
std::optional<const std::string> {
+        const auto it = data.findKey(key);
+        if ((it != data.end()) && (it->typeId() == Exiv2::asciiString)) {
+            return it->toString();
+        }
+        return {};
+    };
+    auto getIntegerValue = [&data](const Exiv2::ExifKey &key) -> 
std::optional<int64_t> {
+        if (const auto it = data.findKey(key); it == data.end()) {
+            return {};
+        } else if ((it->typeId() == Exiv2::signedLong) || (it->typeId() == 
Exiv2::signedShort)) {
+#if EXIV2_TEST_VERSION(0,28,0)
+            return it->toInt64();
+#else
+            return it->toLong();
+#endif
+        }
+        return {};
+    };
+
+    const auto [dateTime, offsetTime, subSecTime] = [&data, getStringValue]() {
+        if (dtType == DateTime) {
+            return std::make_tuple(getStringValue(EK{"Exif.Image.DateTime"s}),
+                                   
getStringValue(EK{"Exif.Photo.OffsetTime"s}),
+                                   
getStringValue(EK{"Exif.Photo.SubSecTime"s}));
+        } else {
+            return 
std::make_tuple(getStringValue(EK{"Exif.Photo.DateTimeOriginal"s}),
+                                   
getStringValue(EK{"Exif.Photo.OffsetTimeOriginal"s}),
+                                   
getStringValue(EK{"Exif.Photo.SubSecTimeOriginal"s}));
         }
+    }();
+
+    if (!dateTime) {
+        return {};
     }
 
-    return QVariant();
+    const auto offsetFallback = [&]() -> std::optional<int64_t> {
+        if (offsetTime) {
+            return {};
+        }
+        // Offset in minutes, signed integer
+        if (const auto canonTiOffset = 
getIntegerValue(EK{"Exif.CanonTi.TimeZone"s})) {
+            return (*canonTiOffset * 60);
+        }
+        if (const auto nikonWtOffset = 
getIntegerValue(EK{"Exif.NikonWt.Timezone"s})) {
+            return (*nikonWtOffset * 60);
+        }
+        return {};
+    }();
+
+    auto dateTimeParsed = Parser::dateTimeFromExifString( //
+        QString::fromStdString(*dateTime),
+        subSecTime ? QString::fromStdString(*subSecTime) : QStringView{},
+        offsetTime ? QString::fromStdString(*offsetTime) : QStringView{},
+        offsetFallback);
+
+    return dateTimeParsed;
 }
 
 QVariant toVariantLong(const Exiv2::Value& value)
@@ -141,9 +196,6 @@
     case QMetaType::Int:
         return toVariantLong(value);
 
-    case QMetaType::QDateTime:
-        return toVariantDateTime(value);
-
     case QMetaType::Double:
         return toVariantDouble(value);
 
@@ -213,12 +265,10 @@
     add(result, data, Property::Artist, EK{"Exif.Image.Artist"s}, 
QMetaType::QString);
     add(result, data, Property::Copyright, EK{"Exif.Image.Copyright"s}, 
QMetaType::QString);
     add(result, data, Property::Generator, EK{"Exif.Image.Software"s}, 
QMetaType::QString);
-    add(result, data, Property::ImageDateTime, EK{"Exif.Image.DateTime"s}, 
QMetaType::QDateTime);
     add(result, data, Property::ImageOrientation, 
EK{"Exif.Image.Orientation"s}, QMetaType::Int);
     add(result, data, Property::PhotoFlash, EK{"Exif.Photo.Flash"s}, 
QMetaType::Int);
     add(result, data, Property::PhotoPixelXDimension, 
EK{"Exif.Photo.PixelXDimension"s}, QMetaType::Int);
     add(result, data, Property::PhotoPixelYDimension, 
EK{"Exif.Photo.PixelYDimension"s}, QMetaType::Int);
-    add(result, data, Property::PhotoDateTimeOriginal, 
EK{"Exif.Photo.DateTimeOriginal"s}, QMetaType::QDateTime);
     add(result, data, Property::PhotoFocalLength, 
EK{"Exif.Photo.FocalLength"s}, QMetaType::Double);
     add(result, data, Property::PhotoFocalLengthIn35mmFilm, 
EK{"Exif.Photo.FocalLengthIn35mmFilm"s}, QMetaType::Double);
     add(result, data, Property::PhotoExposureTime, 
EK{"Exif.Photo.ExposureTime"s}, QMetaType::Double);
@@ -233,6 +283,13 @@
     // https://exiv2.org/tags.html "Exif.Photo.ImageTitle" not natively 
supported, use tag value
     add(result, data, Property::Title, EK{0xa436, "Photo"s}, 
QMetaType::QString);
 
+    if (const auto dateTime = getDateTime<DateTime>(data); dateTime.isValid()) 
{
+        result->add(Property::ImageDateTime, dateTime);
+    }
+    if (const auto dateTimeOrig = getDateTime<DateTimeOrig>(data); 
dateTimeOrig.isValid()) {
+        result->add(Property::PhotoDateTimeOriginal, dateTimeOrig);
+    }
+
     double latitude = fetchGpsDouble(data, EK{"Exif.GPSInfo.GPSLatitude"s});
     double longitude = fetchGpsDouble(data, EK{"Exif.GPSInfo.GPSLongitude"s});
     double altitude = fetchGpsAltitude(data);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/kfilemetadata-6.17.0/src/extractors/plaintextextractor.cpp 
new/kfilemetadata-6.18.0/src/extractors/plaintextextractor.cpp
--- old/kfilemetadata-6.17.0/src/extractors/plaintextextractor.cpp      
2025-08-01 12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/src/extractors/plaintextextractor.cpp      
2025-09-08 10:12:20.000000000 +0200
@@ -118,12 +118,18 @@
     };
 
     // Read the first chunk, detect the encoding and decode it
-    QByteArray chunk(256 * 1024, Qt::Uninitialized);
-    auto size = file.read(chunk.data(), chunk.size());
+    constexpr int32_t chunkSize{256 * 1024};
+    QByteArray chunk(chunkSize, Qt::Uninitialized);
 
-    QStringDecoder codec{autodetectCodec({chunk.data(), size})};
+    QByteArrayView chunkData = [&file, &chunk]() {
+        // read() returns [0...chunkSize] or -1 (error), so no narrowing when 
casting from qint64
+        const auto size = static_cast<int32_t>(file.read(chunk.data(), 
chunkSize));
+        return QByteArrayView{chunk.data(), size};
+    }();
 
-    QString text = codec.decode({chunk.data(), size});
+    QStringDecoder codec{autodetectCodec(chunkData)};
+
+    QString text = codec.decode(chunkData);
     if (codec.hasError()) {
         qCDebug(KFILEMETADATA_LOG) << "Invalid" << codec.name() << "encoding. 
Ignoring" << result->inputUrl();
         return;
@@ -151,7 +157,7 @@
 
     // Read and decode the remainder
     while (!file.atEnd()) {
-        auto size = file.read(chunk.data(), chunk.size());
+        const auto size = static_cast<int32_t>(file.read(chunk.data(), 
chunkSize));
         if (size < 0) {
             // may happen when the file is truncated during read
             qCWarning(KFILEMETADATA_LOG) << "Error reading" << 
result->inputUrl();
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/kfilemetadata-6.17.0/tests/CMakeLists.txt 
new/kfilemetadata-6.18.0/tests/CMakeLists.txt
--- old/kfilemetadata-6.17.0/tests/CMakeLists.txt       2025-08-01 
12:34:24.000000000 +0200
+++ new/kfilemetadata-6.18.0/tests/CMakeLists.txt       2025-09-08 
10:12:20.000000000 +0200
@@ -8,8 +8,6 @@
         DESTINATION ${KDE_INSTALL_BINDIR}
 )
 
-target_include_directories(dump  PUBLIC 
"$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}>")
-
 target_link_libraries(dump
     Qt6::Gui
     KF6FileMetaData

Reply via email to