[multimedia/subtitlecomposer] /: Support opening and saving files from KIO URLs
Mladen Milinkovic <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit dd5f95d5e976fff6803a974982cfeca1fa1dea5a by Mladen Milinkovic.
Committed on 29/07/2026 at 19:30.
Pushed by milinkovic into branch 'master'.
Support opening and saving files from KIO URLs
KIO support was removed in f8280dbcc0b23aed2e55d8db39c220ad900e7825 to
improve local file handling, remove build dependencies, address API
differences between KIO versions, and provide a better user experience
(e.g. by avoiding notifications during file operations).
This allows KIO-FUSE to provide access to network shares and virtual file
systems while continuing to use the local file APIs.
BUGREPORT 523629
M +1 -1 CMakeLists.txt
M +1 -1 src/application.h
M +3 -3 src/application_subtitle.cpp
M +10 -2 src/formats/formatmanager.cpp
M +2 -2 src/formats/formatmanager.h
M +35 -3 src/helpers/commondefs.cpp
M +8 -0 src/helpers/commondefs.h
https://invent.kde.org/multimedia/subtitlecomposer/-/commit/dd5f95d5e976fff6803a974982cfeca1fa1dea5a
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1a1eb652..0d67a487 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -32,7 +32,7 @@ include(ECMAddTests) # build tests
include(FeatureSummary)
find_package(Qt${QT_MAJOR_VERSION} ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
- Core Widgets Gui Test Qml ${QT_EXTRA_COMPONENTS})
+ Core Widgets Gui Test Qml DBus ${QT_EXTRA_COMPONENTS})
find_package(KF${KF_MAJOR_VERSION} ${KF_MIN_VERSION} REQUIRED COMPONENTS
Config ConfigWidgets CoreAddons I18n KIO XmlGui
diff --git a/src/application.h b/src/application.h
index 0473df24..d53a0771 100644
--- a/src/application.h
+++ b/src/application.h
@@ -92,7 +92,7 @@ public slots:
void openSubtitle();
void reopenSubtitleWithCodec(QTextCodec *codec = nullptr);
void demuxTextStream(int textStreamIndex);
- void openSubtitle(const QUrl &url, bool warnClashingUrls = true);
+ void openSubtitle(QUrl url, bool warnClashingUrls = true);
bool saveSubtitle(QTextCodec *codec = nullptr);
bool saveSubtitleAs(QTextCodec *codec = nullptr);
bool closeSubtitle();
diff --git a/src/application_subtitle.cpp b/src/application_subtitle.cpp
index 34d96895..031e15bb 100644
--- a/src/application_subtitle.cpp
+++ b/src/application_subtitle.cpp
@@ -155,7 +155,7 @@ Application::openSubtitle()
}
void
-Application::openSubtitle(const QUrl &url, bool warnClashingUrls)
+Application::openSubtitle(QUrl url, bool warnClashingUrls)
{
m_lastSubtitleUrl = url;
@@ -173,8 +173,8 @@ Application::openSubtitle(const QUrl &url, bool warnClashingUrls)
m_subtitleUrl = url;
processSubtitleOpened(codec, m_subtitleFormat);
- if(m_subtitleUrl.isLocalFile() && SCConfig::automaticVideoLoad()) {
- QFileInfo subtitleFileInfo(m_subtitleUrl.toLocalFile());
+ if(SCConfig::automaticVideoLoad() && System::makeUrlReachable(&url)) {
+ QFileInfo subtitleFileInfo(url.toLocalFile());
QString subtitleFileName = m_subtitleFileName.toLower();
QString videoFileName = QFileInfo(videoPlayer()->filePath()).completeBaseName().toLower();
diff --git a/src/formats/formatmanager.cpp b/src/formats/formatmanager.cpp
index 72579945..0197b7cb 100644
--- a/src/formats/formatmanager.cpp
+++ b/src/formats/formatmanager.cpp
@@ -14,6 +14,7 @@
#include "application.h"
#include "dialogs/encodingdetectdialog.h"
#include "scconfig.h"
+#include "helpers/commondefs.h"
#include "microdvd/microdvdinputformat.h"
#include "microdvd/microdvdoutputformat.h"
@@ -37,6 +38,7 @@
#include "youtubecaptions/youtubecaptionsinputformat.h"
#include "youtubecaptions/youtubecaptionsoutputformat.h"
+#include <QDir>
#include <QFile>
#include <QFileDevice>
#include <QFileInfo>
@@ -226,9 +228,12 @@ FormatManager::readText(Subtitle &subtitle, const QUrl &url, bool primary,
}
FormatManager::Status
-FormatManager::readSubtitle(Subtitle &subtitle, bool primary, const QUrl &url,
+FormatManager::readSubtitle(Subtitle &subtitle, bool primary, QUrl url,
QTextCodec **codec, QString *formatName) const
{
+ if(!url.isLocalFile() && !System::makeUrlReachable(&url))
+ return ERROR;
+
Status res = readBinary(subtitle, url, primary, codec, formatName);
if(res != ERROR) // when SUCCESS or CANCEL no need to try text formats
return res;
@@ -261,7 +266,7 @@ FormatManager::outputNames() const
}
bool
-FormatManager::writeSubtitle(const Subtitle &subtitle, bool primary, const QUrl &url,
+FormatManager::writeSubtitle(const Subtitle &subtitle, bool primary, QUrl url,
QTextCodec *codec, const QString &formatName, bool overwrite) const
{
const OutputFormat *format = output(formatName);
@@ -278,6 +283,9 @@ FormatManager::writeSubtitle(const Subtitle &subtitle, bool primary, const QUrl
if(format == nullptr)
return false;
+ if(!url.isLocalFile() && !System::makeUrlReachable(&url))
+ return false;
+
if(!overwrite && QFile::exists(url.toLocalFile()))
return false;
QSaveFile file(url.toLocalFile());
diff --git a/src/formats/formatmanager.h b/src/formats/formatmanager.h
index db965cc8..b3379043 100644
--- a/src/formats/formatmanager.h
+++ b/src/formats/formatmanager.h
@@ -37,7 +37,7 @@ public:
const InputFormat * input(const QString &name) const;
QStringList inputNames() const;
- Status readSubtitle(Subtitle &subtitle, bool primary, const QUrl &url,
+ Status readSubtitle(Subtitle &subtitle, bool primary, QUrl url,
QTextCodec **codec, QString *format = nullptr) const;
bool hasOutput(const QString &name) const;
@@ -45,7 +45,7 @@ public:
const OutputFormat * defaultOutput() const;
QStringList outputNames() const;
- bool writeSubtitle(const Subtitle &subtitle, bool primary, const QUrl &url,
+ bool writeSubtitle(const Subtitle &subtitle, bool primary, QUrl url,
QTextCodec *codec, const QString &format, bool overwrite) const;
protected:
diff --git a/src/helpers/commondefs.cpp b/src/helpers/commondefs.cpp
index 72eac8e9..b2d68e5a 100644
--- a/src/helpers/commondefs.cpp
+++ b/src/helpers/commondefs.cpp
@@ -10,12 +10,13 @@
#include <cstdlib>
#include <climits>
-#include <QStringBuilder>
+#include <QDBusInterface>
+#include <QDBusReply>
+#include <QDebug>
#include <QDir>
#include <QFileInfo>
-
-#include <QDebug>
#include <QStandardPaths>
+#include <QStringBuilder>
#ifndef Q_OS_WIN
#include <unistd.h>
@@ -243,3 +244,34 @@ System::urlIsInside(const QUrl &url, QStringList &path)
}
return false;
}
+
+bool
+System::makeUrlReachable(QUrl *url)
+{
+ if(url->isLocalFile())
+ return true;
+
+ QUrl parentUrl = url->adjusted(QUrl::RemoveFilename | QUrl::StripTrailingSlash);
+ QString filename = url->fileName();
+
+ if(filename.isEmpty()) {
+ qWarning() << "URL does not contain a valid file name:" << url;
+ return false;
+ }
+
+ QDBusInterface kioFuse(
+ QStringLiteral("org.kde.KIOFuse"),
+ QStringLiteral("/org/kde/KIOFuse"),
+ QStringLiteral("org.kde.KIOFuse.VFS"),
+ QDBusConnection::sessionBus()
+ );
+
+ QDBusReply<QString> reply = kioFuse.call(QStringLiteral("mountUrl"), parentUrl.toString());
+ if(!reply.isValid()) {
+ qWarning() << "KIOFuse mount failed:" << reply.error().message();
+ return false;
+ }
+
+ *url = QUrl::fromLocalFile(QDir(reply.value()).filePath(filename));
+ return true;
+}
diff --git a/src/helpers/commondefs.h b/src/helpers/commondefs.h
index 4abc6cb0..effc7a9f 100644
--- a/src/helpers/commondefs.h
+++ b/src/helpers/commondefs.h
@@ -37,6 +37,14 @@ public:
static bool isReadable(const QString &path);
static bool isWritable(const QString &path);
+ /**
+ * @brief Converts a KIO URL to a local file URL using the KIO-FUSE D-Bus mount.
+ * Local file URLs are left unchanged.
+ * @param url Pointer to the URL to mount. Updated with the local mounted path on success.
+ * @return true if the URL is already a local file or was successfully mounted; false otherwise.
+ */
+ static bool makeUrlReachable(QUrl *url);
+
static QString homeDir();
static QString tempDir();