diff --git a/src/audiomanager.cpp b/src/audiomanager.cpp
index 7bc68c95..8bff3c19 100644
--- a/src/audiomanager.cpp
+++ b/src/audiomanager.cpp
@@ -64,6 +64,7 @@ AudioManager::AudioManager(QObject *parent)
connect(&d->m_player, &QMediaPlayer::positionChanged, this, &AudioManager::positionChanged);
connect(this, &AudioManager::positionChanged, this, &AudioManager::savePlayPosition);
+ connect(this, &AudioManager::playbackRateChanged, &DataManager::instance(), &DataManager::playbackRateChanged);
connect(&DataManager::instance(), &DataManager::queueEntryMoved, this, &AudioManager::canGoNextChanged);
connect(&DataManager::instance(), &DataManager::queueEntryAdded, this, &AudioManager::canGoNextChanged);
connect(&DataManager::instance(), &DataManager::queueEntryRemoved, this, &AudioManager::canGoNextChanged);
@@ -586,7 +587,13 @@ QString AudioManager::formattedDuration() const
QString AudioManager::formattedLeftDuration() const
{
- return m_kformat.formatDuration(duration() - position());
+ qreal rate = 1.0;
+ if (SettingsManager::self()->adjustTimeLeft()) {
+ rate = playbackRate();
+ rate = (rate > 0.0) ? rate : 1.0;
+ }
+ qint64 diff = duration() - position();
+ return m_kformat.formatDuration(diff / rate);
}
QString AudioManager::formattedPosition() const
diff --git a/src/datamanager.h b/src/datamanager.h
index d2b71378..b37d41b3 100644
--- a/src/datamanager.h
+++ b/src/datamanager.h
@@ -91,6 +91,11 @@ Q_SIGNALS:
void bulkReadStatusActionFinished();
void bulkNewStatusActionFinished();
+ // this will relay the AudioManager::playbackRateChanged signal; this is
+ // required to avoid a dependency loop on startup
+ // TODO: find less hackish solution
+ void playbackRateChanged();
+
private:
DataManager();
void loadFeed(const QString &feedurl) const;
diff --git a/src/enclosure.cpp b/src/enclosure.cpp
index f00e7587..716c4826 100644
--- a/src/enclosure.cpp
+++ b/src/enclosure.cpp
@@ -39,6 +39,7 @@ Enclosure::Enclosure(Entry *entry)
: QObject(entry)
, m_entry(entry)
{
+ connect(this, &Enclosure::playPositionChanged, this, &Enclosure::leftDurationChanged);
connect(this, &Enclosure::statusChanged, &DownloadModel::instance(), &DownloadModel::monitorDownloadStatus);
connect(this, &Enclosure::downloadError, &ErrorLogModel::instance(), &ErrorLogModel::monitorErrorMessages);
connect(&Fetcher::instance(), &Fetcher::entryUpdated, this, [this](const QString &url, const QString &id) {
@@ -47,6 +48,10 @@ Enclosure::Enclosure(Entry *entry)
}
});
+ // we use the relayed signal from AudioManager::playbackRateChanged by
+ // DataManager; this is required to avoid a dependency loop on startup
+ connect(&DataManager::instance(), &DataManager::playbackRateChanged, this, &Enclosure::leftDurationChanged);
+
QSqlQuery query;
query.prepare(QStringLiteral("SELECT * FROM Enclosures WHERE id=:id"));
query.bindValue(QStringLiteral(":id"), entry->id());
@@ -489,7 +494,13 @@ QString Enclosure::formattedDuration() const
QString Enclosure::formattedLeftDuration() const
{
- return m_kformat.formatDuration(duration() * 1000 - playPosition());
+ qreal rate = 1.0;
+ if (SettingsManager::self()->adjustTimeLeft()) {
+ rate = AudioManager::instance().playbackRate();
+ rate = (rate > 0.0) ? rate : 1.0;
+ }
+ qint64 diff = duration() * 1000 - playPosition();
+ return m_kformat.formatDuration(diff / rate);
}
QString Enclosure::formattedPlayPosition() const
diff --git a/src/enclosure.h b/src/enclosure.h
index 515e4d70..95d88ff7 100644
--- a/src/enclosure.h
+++ b/src/enclosure.h
@@ -33,7 +33,7 @@ class Enclosure : public QObject
Q_PROPERTY(QString path READ path NOTIFY pathChanged)
Q_PROPERTY(QString cachedEmbeddedImage READ cachedEmbeddedImage CONSTANT)
Q_PROPERTY(qint64 playPosition READ playPosition WRITE setPlayPosition NOTIFY playPositionChanged)
- Q_PROPERTY(QString formattedLeftDuration READ formattedLeftDuration NOTIFY playPositionChanged)
+ Q_PROPERTY(QString formattedLeftDuration READ formattedLeftDuration NOTIFY leftDurationChanged)
Q_PROPERTY(QString formattedPlayPosition READ formattedPlayPosition NOTIFY playPositionChanged)
Q_PROPERTY(qint64 duration READ duration WRITE setDuration NOTIFY durationChanged)
Q_PROPERTY(QString formattedDuration READ formattedDuration NOTIFY durationChanged)
@@ -85,6 +85,7 @@ Q_SIGNALS:
void downloadProgressChanged();
void cancelDownload();
void playPositionChanged();
+ void leftDurationChanged();
void durationChanged();
void sizeChanged();
void sizeOnDiskChanged();
diff --git a/src/models/queuemodel.cpp b/src/models/queuemodel.cpp
index b2897fbe..71961f75 100644
--- a/src/models/queuemodel.cpp
+++ b/src/models/queuemodel.cpp
@@ -14,6 +14,7 @@
#include "datamanager.h"
#include "entry.h"
#include "models/episodemodel.h"
+#include "settingsmanager.h"
QueueModel::QueueModel(QObject *parent)
: QAbstractListModel(parent)
@@ -91,8 +92,13 @@ int QueueModel::timeLeft() const
QString QueueModel::formattedTimeLeft() const
{
+ qreal rate = 1.0;
+ if (SettingsManager::self()->adjustTimeLeft()) {
+ rate = AudioManager::instance().playbackRate();
+ rate = (rate > 0.0) ? rate : 1.0;
+ }
static KFormat format;
- return format.formatDuration(timeLeft());
+ return format.formatDuration(timeLeft() / rate);
}
// Hack to get a QItemSelection in QML
diff --git a/src/qml/Settings/GeneralSettingsPage.qml b/src/qml/Settings/GeneralSettingsPage.qml
index 60792682..4237496a 100644
--- a/src/qml/Settings/GeneralSettingsPage.qml
+++ b/src/qml/Settings/GeneralSettingsPage.qml
@@ -41,6 +41,12 @@ Kirigami.ScrollablePage {
text: i18n("Continue playing next episode after current one finishes")
onToggled: SettingsManager.continuePlayingNextEntry = checked
}
+ Controls.CheckBox {
+ id: adjustTimeLeft
+ checked: SettingsManager.adjustTimeLeft
+ text: i18n("Adjust time left based on current playback speed")
+ onToggled: SettingsManager.adjustTimeLeft = checked
+ }
Kirigami.Heading {
Kirigami.FormData.isSection: true
diff --git a/src/settingsmanager.kcfg b/src/settingsmanager.kcfg
index 7dfc47d4..52e3afc3 100644
--- a/src/settingsmanager.kcfg
+++ b/src/settingsmanager.kcfg
@@ -13,6 +13,10 @@
true
+
+
+ false
+
false