Add sleep timer
FEATURE: 443400
This commit is contained in:
parent
ac58ad0a1a
commit
5f94b4a357
@ -222,6 +222,7 @@ if(ANDROID)
|
|||||||
emblem-music-symbolic
|
emblem-music-symbolic
|
||||||
gpodder
|
gpodder
|
||||||
kaccounts-nextcloud
|
kaccounts-nextcloud
|
||||||
|
clock
|
||||||
)
|
)
|
||||||
else()
|
else()
|
||||||
target_link_libraries(kasts PRIVATE Qt::Widgets Qt::DBus)
|
target_link_libraries(kasts PRIVATE Qt::Widgets Qt::DBus)
|
||||||
|
@ -44,6 +44,10 @@ private:
|
|||||||
// still pending
|
// still pending
|
||||||
qint64 m_pendingSeek = -1;
|
qint64 m_pendingSeek = -1;
|
||||||
|
|
||||||
|
QTimer *m_sleepTimer = nullptr;
|
||||||
|
qint64 m_sleepTime = -1;
|
||||||
|
qint64 m_remainingSleepTime = -1;
|
||||||
|
|
||||||
friend class AudioManager;
|
friend class AudioManager;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -600,3 +604,73 @@ QString AudioManager::formattedPosition() const
|
|||||||
{
|
{
|
||||||
return m_kformat.formatDuration(position());
|
return m_kformat.formatDuration(position());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint64 AudioManager::sleepTime() const
|
||||||
|
{
|
||||||
|
if (d->m_sleepTimer) {
|
||||||
|
return d->m_sleepTime;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qint64 AudioManager::remainingSleepTime() const
|
||||||
|
{
|
||||||
|
if (d->m_sleepTimer) {
|
||||||
|
return d->m_remainingSleepTime;
|
||||||
|
} else {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioManager::setSleepTimer(qint64 duration)
|
||||||
|
{
|
||||||
|
if (duration > 0) {
|
||||||
|
if (d->m_sleepTimer) {
|
||||||
|
stopSleepTimer();
|
||||||
|
}
|
||||||
|
|
||||||
|
d->m_sleepTime = duration;
|
||||||
|
d->m_remainingSleepTime = duration;
|
||||||
|
|
||||||
|
d->m_sleepTimer = new QTimer(this);
|
||||||
|
connect(d->m_sleepTimer, &QTimer::timeout, this, [this]() {
|
||||||
|
(d->m_remainingSleepTime)--;
|
||||||
|
if (d->m_remainingSleepTime > 0) {
|
||||||
|
Q_EMIT remainingSleepTimeChanged(remainingSleepTime());
|
||||||
|
} else {
|
||||||
|
pause();
|
||||||
|
stopSleepTimer();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
d->m_sleepTimer->start(1000);
|
||||||
|
|
||||||
|
Q_EMIT sleepTimerChanged(duration);
|
||||||
|
Q_EMIT remainingSleepTimeChanged(remainingSleepTime());
|
||||||
|
} else {
|
||||||
|
stopSleepTimer();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioManager::stopSleepTimer()
|
||||||
|
{
|
||||||
|
if (d->m_sleepTimer) {
|
||||||
|
d->m_sleepTime = -1;
|
||||||
|
d->m_remainingSleepTime = -1;
|
||||||
|
|
||||||
|
delete d->m_sleepTimer;
|
||||||
|
d->m_sleepTimer = nullptr;
|
||||||
|
|
||||||
|
Q_EMIT sleepTimerChanged(-1);
|
||||||
|
Q_EMIT remainingSleepTimeChanged(-1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString AudioManager::formattedRemainingSleepTime() const
|
||||||
|
{
|
||||||
|
qint64 timeLeft = remainingSleepTime() * 1000;
|
||||||
|
if (timeLeft < 0) {
|
||||||
|
timeLeft = 0;
|
||||||
|
}
|
||||||
|
return m_kformat.formatDuration(timeLeft);
|
||||||
|
}
|
||||||
|
@ -42,6 +42,9 @@ class AudioManager : public QObject
|
|||||||
Q_PROPERTY(QString formattedLeftDuration READ formattedLeftDuration NOTIFY positionChanged)
|
Q_PROPERTY(QString formattedLeftDuration READ formattedLeftDuration NOTIFY positionChanged)
|
||||||
Q_PROPERTY(QString formattedDuration READ formattedDuration NOTIFY durationChanged)
|
Q_PROPERTY(QString formattedDuration READ formattedDuration NOTIFY durationChanged)
|
||||||
Q_PROPERTY(QString formattedPosition READ formattedPosition NOTIFY positionChanged)
|
Q_PROPERTY(QString formattedPosition READ formattedPosition NOTIFY positionChanged)
|
||||||
|
Q_PROPERTY(qint64 sleepTime READ sleepTime WRITE setSleepTimer RESET stopSleepTimer NOTIFY sleepTimerChanged)
|
||||||
|
Q_PROPERTY(qint64 remainingSleepTime READ remainingSleepTime NOTIFY remainingSleepTimeChanged)
|
||||||
|
Q_PROPERTY(QString formattedRemainingSleepTime READ formattedRemainingSleepTime NOTIFY remainingSleepTimeChanged)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
const double MAX_RATE = 1.0;
|
const double MAX_RATE = 1.0;
|
||||||
@ -58,133 +61,88 @@ public:
|
|||||||
~AudioManager() override;
|
~AudioManager() override;
|
||||||
|
|
||||||
[[nodiscard]] Entry *entry() const;
|
[[nodiscard]] Entry *entry() const;
|
||||||
|
|
||||||
[[nodiscard]] bool muted() const;
|
[[nodiscard]] bool muted() const;
|
||||||
|
|
||||||
[[nodiscard]] qreal volume() const;
|
[[nodiscard]] qreal volume() const;
|
||||||
|
|
||||||
[[nodiscard]] QUrl source() const;
|
[[nodiscard]] QUrl source() const;
|
||||||
|
|
||||||
[[nodiscard]] QMediaPlayer::MediaStatus status() const;
|
[[nodiscard]] QMediaPlayer::MediaStatus status() const;
|
||||||
|
|
||||||
[[nodiscard]] QMediaPlayer::State playbackState() const;
|
[[nodiscard]] QMediaPlayer::State playbackState() const;
|
||||||
|
|
||||||
[[nodiscard]] qreal playbackRate() const;
|
[[nodiscard]] qreal playbackRate() const;
|
||||||
|
|
||||||
[[nodiscard]] qreal minimumPlaybackRate() const;
|
[[nodiscard]] qreal minimumPlaybackRate() const;
|
||||||
|
|
||||||
[[nodiscard]] qreal maximumPlaybackRate() const;
|
[[nodiscard]] qreal maximumPlaybackRate() const;
|
||||||
|
|
||||||
[[nodiscard]] QMediaPlayer::Error error() const;
|
[[nodiscard]] QMediaPlayer::Error error() const;
|
||||||
|
|
||||||
[[nodiscard]] qint64 duration() const;
|
[[nodiscard]] qint64 duration() const;
|
||||||
|
|
||||||
[[nodiscard]] qint64 position() const;
|
[[nodiscard]] qint64 position() const;
|
||||||
|
|
||||||
[[nodiscard]] bool seekable() const;
|
[[nodiscard]] bool seekable() const;
|
||||||
|
|
||||||
[[nodiscard]] bool canPlay() const;
|
[[nodiscard]] bool canPlay() const;
|
||||||
|
|
||||||
[[nodiscard]] bool canPause() const;
|
[[nodiscard]] bool canPause() const;
|
||||||
|
|
||||||
[[nodiscard]] bool canSkipForward() const;
|
[[nodiscard]] bool canSkipForward() const;
|
||||||
|
|
||||||
[[nodiscard]] bool canSkipBackward() const;
|
[[nodiscard]] bool canSkipBackward() const;
|
||||||
|
|
||||||
[[nodiscard]] bool canGoNext() const;
|
[[nodiscard]] bool canGoNext() const;
|
||||||
|
|
||||||
QString formattedDuration() const;
|
QString formattedDuration() const;
|
||||||
QString formattedLeftDuration() const;
|
QString formattedLeftDuration() const;
|
||||||
QString formattedPosition() const;
|
QString formattedPosition() const;
|
||||||
|
|
||||||
|
qint64 sleepTime() const; // returns originally set sleep time
|
||||||
|
qint64 remainingSleepTime() const; // returns remaining sleep time
|
||||||
|
QString formattedRemainingSleepTime() const;
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
|
|
||||||
void entryChanged(Entry *entry);
|
void entryChanged(Entry *entry);
|
||||||
|
|
||||||
void mutedChanged(bool muted);
|
void mutedChanged(bool muted);
|
||||||
|
|
||||||
void volumeChanged();
|
void volumeChanged();
|
||||||
|
|
||||||
void sourceChanged();
|
void sourceChanged();
|
||||||
|
|
||||||
void statusChanged(QMediaPlayer::MediaStatus status);
|
void statusChanged(QMediaPlayer::MediaStatus status);
|
||||||
|
|
||||||
void playbackStateChanged(QMediaPlayer::State state);
|
void playbackStateChanged(QMediaPlayer::State state);
|
||||||
|
|
||||||
void playbackRateChanged(qreal rate);
|
void playbackRateChanged(qreal rate);
|
||||||
|
|
||||||
void errorChanged(QMediaPlayer::Error error);
|
void errorChanged(QMediaPlayer::Error error);
|
||||||
|
|
||||||
void durationChanged(qint64 duration);
|
void durationChanged(qint64 duration);
|
||||||
|
|
||||||
void positionChanged(qint64 position);
|
void positionChanged(qint64 position);
|
||||||
|
|
||||||
void seekableChanged(bool seekable);
|
void seekableChanged(bool seekable);
|
||||||
|
|
||||||
void playing();
|
void playing();
|
||||||
|
|
||||||
void paused();
|
void paused();
|
||||||
|
|
||||||
void stopped();
|
void stopped();
|
||||||
|
|
||||||
void canPlayChanged();
|
void canPlayChanged();
|
||||||
|
|
||||||
void canPauseChanged();
|
void canPauseChanged();
|
||||||
|
|
||||||
void canSkipForwardChanged();
|
void canSkipForwardChanged();
|
||||||
|
|
||||||
void canSkipBackwardChanged();
|
void canSkipBackwardChanged();
|
||||||
|
|
||||||
void canGoNextChanged();
|
void canGoNextChanged();
|
||||||
|
|
||||||
|
void sleepTimerChanged(qint64 duration);
|
||||||
|
void remainingSleepTimeChanged(qint64 duration);
|
||||||
|
|
||||||
void logError(Error::Type type, const QString &url, const QString &id, const int errorId, const QString &errorString, const QString &title);
|
void logError(Error::Type type, const QString &url, const QString &id, const int errorId, const QString &errorString, const QString &title);
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
|
|
||||||
void setEntry(Entry *entry);
|
void setEntry(Entry *entry);
|
||||||
|
|
||||||
void setMuted(bool muted);
|
void setMuted(bool muted);
|
||||||
|
|
||||||
void setVolume(qreal volume);
|
void setVolume(qreal volume);
|
||||||
|
|
||||||
// void setSource(const QUrl &source); //source should only be set by audiomanager itself
|
// void setSource(const QUrl &source); //source should only be set by audiomanager itself
|
||||||
|
|
||||||
void setPosition(qint64 position);
|
void setPosition(qint64 position);
|
||||||
|
|
||||||
void setPlaybackRate(qreal rate);
|
void setPlaybackRate(qreal rate);
|
||||||
|
|
||||||
void play();
|
void play();
|
||||||
|
|
||||||
void pause();
|
void pause();
|
||||||
|
|
||||||
void playPause();
|
void playPause();
|
||||||
|
|
||||||
void stop();
|
void stop();
|
||||||
|
|
||||||
void seek(qint64 position);
|
void seek(qint64 position);
|
||||||
|
|
||||||
void skipBackward();
|
void skipBackward();
|
||||||
|
|
||||||
void skipForward();
|
void skipForward();
|
||||||
|
|
||||||
void next();
|
void next();
|
||||||
|
|
||||||
|
void setSleepTimer(qint64 duration);
|
||||||
|
void stopSleepTimer();
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
|
|
||||||
void mediaStatusChanged();
|
void mediaStatusChanged();
|
||||||
|
|
||||||
void playerStateChanged();
|
void playerStateChanged();
|
||||||
|
|
||||||
void playerDurationChanged(qint64 duration);
|
void playerDurationChanged(qint64 duration);
|
||||||
|
|
||||||
void playerMutedChanged();
|
void playerMutedChanged();
|
||||||
|
|
||||||
void playerVolumeChanged();
|
void playerVolumeChanged();
|
||||||
|
|
||||||
void savePlayPosition();
|
void savePlayPosition();
|
||||||
|
|
||||||
void prepareAudio();
|
void prepareAudio();
|
||||||
|
|
||||||
void checkForPendingSeek();
|
void checkForPendingSeek();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -110,7 +110,7 @@ Rectangle {
|
|||||||
|
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
id: chapterButton
|
id: chapterButton
|
||||||
visible: AudioManager.entry && chapterList.count !== 0 && (titlesAndButtons.width > essentialButtons.width + infoButton.implicitWidth + implicitWidth + parent.optionalButtonCollapseWidth)
|
visible: AudioManager.entry && chapterList.count !== 0 && (titlesAndButtons.width > essentialButtons.width + infoButton.implicitWidth + implicitWidth + 2 * infoButton.implicitWidth + parent.optionalButtonCollapseWidth)
|
||||||
text: i18n("Chapters")
|
text: i18n("Chapters")
|
||||||
icon.name: "view-media-playlist"
|
icon.name: "view-media-playlist"
|
||||||
icon.height: essentialButtons.iconSize
|
icon.height: essentialButtons.iconSize
|
||||||
@ -121,7 +121,7 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
Controls.ToolButton {
|
Controls.ToolButton {
|
||||||
id: infoButton
|
id: infoButton
|
||||||
visible: AudioManager.entry && (titlesAndButtons.width > essentialButtons.width + implicitWidth + parent.optionalButtonCollapseWidth)
|
visible: AudioManager.entry && (titlesAndButtons.width > essentialButtons.width + 2 * implicitWidth + parent.optionalButtonCollapseWidth)
|
||||||
icon.name: "help-about-symbolic"
|
icon.name: "help-about-symbolic"
|
||||||
icon.height: essentialButtons.iconSize
|
icon.height: essentialButtons.iconSize
|
||||||
icon.width: essentialButtons.iconSize
|
icon.width: essentialButtons.iconSize
|
||||||
@ -129,6 +129,21 @@ Rectangle {
|
|||||||
Layout.preferredWidth: essentialButtons.buttonSize
|
Layout.preferredWidth: essentialButtons.buttonSize
|
||||||
onClicked: entryDetailsOverlay.open();
|
onClicked: entryDetailsOverlay.open();
|
||||||
}
|
}
|
||||||
|
Controls.ToolButton {
|
||||||
|
id: sleepButton
|
||||||
|
checkable: true
|
||||||
|
checked: AudioManager.remainingSleepTime > 0
|
||||||
|
visible: titlesAndButtons.width > essentialButtons.width + implicitWidth + parent.optionalButtonCollapseWidth
|
||||||
|
icon.name: "clock"
|
||||||
|
icon.height: essentialButtons.iconSize
|
||||||
|
icon.width: essentialButtons.iconSize
|
||||||
|
Layout.alignment: Qt.AlignHCenter
|
||||||
|
Layout.preferredWidth: essentialButtons.buttonSize
|
||||||
|
onClicked: {
|
||||||
|
toggle(); // only set the on/off state based on sleep timer state
|
||||||
|
sleepTimerDialog.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: essentialButtons
|
id: essentialButtons
|
||||||
property int iconSize: Kirigami.Units.gridUnit
|
property int iconSize: Kirigami.Units.gridUnit
|
||||||
|
@ -294,6 +294,24 @@ Kirigami.Page {
|
|||||||
swipeView.currentIndex = 2;
|
swipeView.currentIndex = 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Item {
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
Controls.ToolButton {
|
||||||
|
checkable: true
|
||||||
|
checked: AudioManager.remainingSleepTime > 0
|
||||||
|
Layout.maximumHeight: parent.height
|
||||||
|
Layout.preferredHeight: contextButtons.buttonSize
|
||||||
|
Layout.maximumWidth: height
|
||||||
|
Layout.preferredWidth: height
|
||||||
|
icon.name: "clock"
|
||||||
|
icon.width: contextButtons.iconSize
|
||||||
|
icon.height: contextButtons.iconSize
|
||||||
|
onClicked: {
|
||||||
|
toggle(); // only set the on/off state based on sleep timer state
|
||||||
|
sleepTimerDialog.open()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Loader {
|
Loader {
|
||||||
|
96
src/qml/SleepTimerDialog.qml
Normal file
96
src/qml/SleepTimerDialog.qml
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
/**
|
||||||
|
* SPDX-FileCopyrightText: 2022 Bart De Vries <bart@mogwai.be>
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
|
||||||
|
*/
|
||||||
|
|
||||||
|
import QtQuick 2.14
|
||||||
|
import QtQuick.Controls 2.14 as Controls
|
||||||
|
import QtQuick.Layouts 1.14
|
||||||
|
|
||||||
|
import org.kde.kirigami 2.19 as Kirigami
|
||||||
|
import org.kde.kasts 1.0
|
||||||
|
|
||||||
|
Kirigami.Dialog {
|
||||||
|
id: sleepTimerDialog
|
||||||
|
title: i18n("Sleep Timer")
|
||||||
|
padding: Kirigami.Units.largeSpacing
|
||||||
|
closePolicy: Kirigami.Dialog.CloseOnEscape | Kirigami.Dialog.CloseOnPressOutside
|
||||||
|
standardButtons: Kirigami.Dialog.NoButton
|
||||||
|
|
||||||
|
property bool timerActive: AudioManager.remainingSleepTime > 0
|
||||||
|
|
||||||
|
customFooterActions: [
|
||||||
|
Kirigami.Action {
|
||||||
|
enabled: !timerActive
|
||||||
|
text: i18n("Start")
|
||||||
|
iconName: "dialog-ok"
|
||||||
|
onTriggered: {
|
||||||
|
sleepTimerDialog.close();
|
||||||
|
var sleepTimeSeconds = sleepTimerValueBox.value * sleepTimerUnitsBox.model[sleepTimerUnitsBox.currentIndex]["secs"];
|
||||||
|
if (sleepTimeSeconds > 0) {
|
||||||
|
SettingsManager.sleepTimerValue = sleepTimerValueBox.value;
|
||||||
|
SettingsManager.sleepTimerUnits = sleepTimerUnitsBox.currentValue;
|
||||||
|
SettingsManager.save();
|
||||||
|
AudioManager.sleepTime = sleepTimeSeconds;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Kirigami.Action {
|
||||||
|
enabled: timerActive
|
||||||
|
text: i18n("Stop")
|
||||||
|
iconName: "dialog-cancel"
|
||||||
|
onTriggered: {
|
||||||
|
sleepTimerDialog.close();
|
||||||
|
AudioManager.sleepTime = undefined; // make use of RESET
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: content
|
||||||
|
Text {
|
||||||
|
text: (timerActive) ? i18n("Status: Active") : i18n("Status: Inactive")
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
opacity: (timerActive) ? 1 : 0.5
|
||||||
|
Layout.bottomMargin: Kirigami.Units.largeSpacing
|
||||||
|
text: i18n("Remaining Time: %1", AudioManager.formattedRemainingSleepTime)
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
Controls.SpinBox {
|
||||||
|
id: sleepTimerValueBox
|
||||||
|
enabled: !timerActive
|
||||||
|
value: SettingsManager.sleepTimerValue
|
||||||
|
from: 1
|
||||||
|
to: 24 * 60 * 60
|
||||||
|
}
|
||||||
|
|
||||||
|
Controls.ComboBox {
|
||||||
|
id: sleepTimerUnitsBox
|
||||||
|
enabled: !timerActive
|
||||||
|
textRole: "text"
|
||||||
|
valueRole: "value"
|
||||||
|
model: [{"text": i18n("Seconds"), "value": 0, "secs": 1, "max": 24 * 60 * 60},
|
||||||
|
{"text": i18n("Minutes"), "value": 1, "secs": 60, "max": 24 * 60},
|
||||||
|
{"text": i18n("Hours"), "value": 2, "secs": 60 * 60, "max": 24}]
|
||||||
|
Component.onCompleted: {
|
||||||
|
currentIndex = indexOfValue(SettingsManager.sleepTimerUnits);
|
||||||
|
sleepTimerValueBox.to = sleepTimerUnitsBox.model[currentIndex]["max"];
|
||||||
|
if (sleepTimerValueBox.value > sleepTimerUnitsBox.model[currentIndex]["max"]) {
|
||||||
|
sleepTimerValueBox.value = sleepTimerUnitsBox.model[currentIndex]["max"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
onActivated: {
|
||||||
|
SettingsManager.sleepTimerUnits = currentValue;
|
||||||
|
if (sleepTimerValueBox.value > sleepTimerUnitsBox.model[currentIndex]["max"]) {
|
||||||
|
sleepTimerValueBox.value = sleepTimerUnitsBox.model[currentIndex]["max"];
|
||||||
|
}
|
||||||
|
sleepTimerValueBox.to = sleepTimerUnitsBox.model[currentIndex]["max"];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -355,6 +355,10 @@ Kirigami.ApplicationWindow {
|
|||||||
id: playbackRateDialog
|
id: playbackRateDialog
|
||||||
}
|
}
|
||||||
|
|
||||||
|
SleepTimerDialog {
|
||||||
|
id: sleepTimerDialog
|
||||||
|
}
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: Sync
|
target: Sync
|
||||||
function onPasswordInputRequired() {
|
function onPasswordInputRequired() {
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
<file alias="StorageSettingsPage.qml">qml/Settings/StorageSettingsPage.qml</file>
|
<file alias="StorageSettingsPage.qml">qml/Settings/StorageSettingsPage.qml</file>
|
||||||
<file alias="SynchronizationSettingsPage.qml">qml/Settings/SynchronizationSettingsPage.qml</file>
|
<file alias="SynchronizationSettingsPage.qml">qml/Settings/SynchronizationSettingsPage.qml</file>
|
||||||
<file alias="BottomToolbar.qml">qml/BottomToolbar.qml</file>
|
<file alias="BottomToolbar.qml">qml/BottomToolbar.qml</file>
|
||||||
|
<file alias="SleepTimerDialog.qml">qml/SleepTimerDialog.qml</file>
|
||||||
<file>qtquickcontrols2.conf</file>
|
<file>qtquickcontrols2.conf</file>
|
||||||
<file alias="logo.svg">../kasts.svg</file>
|
<file alias="logo.svg">../kasts.svg</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
|
@ -88,6 +88,28 @@
|
|||||||
<label>The top-level page that was open at shutdown</label>
|
<label>The top-level page that was open at shutdown</label>
|
||||||
<default>FeedListPage</default>
|
<default>FeedListPage</default>
|
||||||
</entry>
|
</entry>
|
||||||
|
<entry name="sleepTimerValue" type="Int">
|
||||||
|
<label>The number of seconds/minutes/hours to set the sleep timer to</label>
|
||||||
|
<default>30</default>
|
||||||
|
</entry>
|
||||||
|
<entry name="sleepTimerUnits" type="Enum">
|
||||||
|
<label>The units for the sleepTimerValue</label>
|
||||||
|
<choices>
|
||||||
|
<choice name="Seconds">
|
||||||
|
<label>Seconds</label>
|
||||||
|
<value>0</value>
|
||||||
|
</choice>
|
||||||
|
<choice name="Minutes">
|
||||||
|
<label>Minutes</label>
|
||||||
|
<value>1</value>
|
||||||
|
</choice>
|
||||||
|
<choice name="Hours">
|
||||||
|
<label>Hours</label>
|
||||||
|
<value>2</value>
|
||||||
|
</choice>
|
||||||
|
</choices>
|
||||||
|
<default>Minutes</default>
|
||||||
|
</entry>
|
||||||
</group>
|
</group>
|
||||||
<group name="Synchronization">
|
<group name="Synchronization">
|
||||||
<entry name="syncEnabled" type="Bool">
|
<entry name="syncEnabled" type="Bool">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user