Commit 9034ae25 authored by pontaoski's avatar pontaoski 🌈
Browse files

Add repeat one track option

parent 666d3fa1
Pipeline #43536 canceled with stage
This diff is collapsed.
/*
SPDX-FileCopyrightText: 2015 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-FileCopyrightText: 2019 (c) Alexander Stippich <a.stippich@gmx.net>
SPDX-FileCopyrightText: 2020 (c) Carson Black <uhhadd@gmail.com>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
......@@ -47,7 +48,7 @@ public:
int mCurrentPlayListPosition = -1;
bool mRepeatPlay = false;
MediaPlayListProxyModel::Repeat mRepeatMode = MediaPlayListProxyModel::Repeat::None;
bool mShufflePlayList = false;
......@@ -215,20 +216,20 @@ QPersistentModelIndex MediaPlayListProxyModel::nextTrack() const
return d->mNextTrack;
}
void MediaPlayListProxyModel::setRepeatPlay(const bool value)
void MediaPlayListProxyModel::setRepeatMode(Repeat value)
{
if (d->mRepeatPlay != value) {
d->mRepeatPlay = value;
Q_EMIT repeatPlayChanged();
if (d->mRepeatMode != value) {
d->mRepeatMode = value;
Q_EMIT repeatModeChanged();
Q_EMIT remainingTracksChanged();
Q_EMIT persistentStateChanged();
determineAndNotifyPreviousAndNextTracks();
}
}
bool MediaPlayListProxyModel::repeatPlay() const
MediaPlayListProxyModel::Repeat MediaPlayListProxyModel::repeatMode() const
{
return d->mRepeatPlay;
return d->mRepeatMode;
}
void MediaPlayListProxyModel::setShufflePlayList(const bool value)
......@@ -455,7 +456,7 @@ void MediaPlayListProxyModel::sourceHeaderDataChanged(Qt::Orientation orientatio
int MediaPlayListProxyModel::remainingTracks() const
{
if (!d->mCurrentTrack.isValid() || d->mRepeatPlay) {
if (!d->mCurrentTrack.isValid() || (d->mRepeatMode == Repeat::One) || (d->mRepeatMode == Repeat::Playlist)) {
return -1;
} else {
return rowCount() - d->mCurrentTrack.row() - 1;
......@@ -518,12 +519,24 @@ void MediaPlayListProxyModel::skipNextTrack()
}
if (d->mCurrentTrack.row() >= rowCount() - 1) {
d->mCurrentTrack = index(0, 0);
if (!d->mRepeatPlay) {
switch (d->mRepeatMode) {
case Repeat::One:
d->mCurrentTrack = index(d->mCurrentTrack.row(), 0);
break;
case Repeat::Playlist:
d->mCurrentTrack = index(0, 0);
break;
case Repeat::None:
d->mCurrentTrack = index(0, 0);
Q_EMIT playListFinished();
break;
}
} else {
d->mCurrentTrack = index(d->mCurrentTrack.row() + 1, 0);
if (d->mRepeatMode == Repeat::One) {
d->mCurrentTrack = index(d->mCurrentTrack.row(), 0);
} else {
d->mCurrentTrack = index(d->mCurrentTrack.row() + 1, 0);
}
}
notifyCurrentTrackChanged();
......@@ -541,13 +554,17 @@ void MediaPlayListProxyModel::skipPreviousTrack(qint64 position)
}
if (d->mCurrentTrack.row() == 0) {
if (d->mRepeatPlay) {
if (d->mRepeatMode == Repeat::One || d->mRepeatMode == Repeat::Playlist) {
d->mCurrentTrack = index(rowCount() - 1, 0);
} else {
return;
}
} else {
d->mCurrentTrack = index(d->mCurrentTrack.row() - 1, 0);
if (d->mRepeatMode == Repeat::One) {
d->mCurrentTrack = index(d->mCurrentTrack.row(), 0);
} else {
d->mCurrentTrack = index(d->mCurrentTrack.row() - 1, 0);
}
}
notifyCurrentTrackChanged();
......@@ -609,30 +626,37 @@ void MediaPlayListProxyModel::determineAndNotifyPreviousAndNextTracks()
}
auto mOldPreviousTrack = d->mPreviousTrack;
auto mOldNextTrack = d->mNextTrack;
if (d->mRepeatPlay) {
// forward to end or begin when repeating
switch (d->mRepeatMode) {
case Repeat::None:
// return nothing if no tracks available
if (d->mCurrentTrack.row() == 0) {
d->mPreviousTrack = index(rowCount() - 1, 0);
d->mPreviousTrack = QPersistentModelIndex();
} else {
d->mPreviousTrack = index(d->mCurrentTrack.row() - 1, 0);
}
if (d->mCurrentTrack.row() == rowCount() - 1) {
d->mNextTrack = index(0, 0);
d->mNextTrack = QPersistentModelIndex();
} else {
d->mNextTrack = index(d->mCurrentTrack.row() + 1, 0);
}
} else {
// return nothing if no tracks available
break;
case Repeat::Playlist:
// forward to end or begin when repeating
if (d->mCurrentTrack.row() == 0) {
d->mPreviousTrack = QPersistentModelIndex();
d->mPreviousTrack = index(rowCount() - 1, 0);
} else {
d->mPreviousTrack = index(d->mCurrentTrack.row() - 1, 0);
}
if (d->mCurrentTrack.row() == rowCount() - 1) {
d->mNextTrack = QPersistentModelIndex();
d->mNextTrack = index(0, 0);
} else {
d->mNextTrack = index(d->mCurrentTrack.row() + 1, 0);
}
break;
case Repeat::One:
d->mPreviousTrack = index(d->mCurrentTrack.row(), 0);
d->mNextTrack = index(d->mCurrentTrack.row(), 0);
break;
}
if (d->mPreviousTrack != mOldPreviousTrack) {
Q_EMIT previousTrackChanged(d->mPreviousTrack);
......@@ -744,7 +768,7 @@ QVariantMap MediaPlayListProxyModel::persistentState() const
currentState[QStringLiteral("playList")] = d->mPlayListModel->getEntriesForRestore();
currentState[QStringLiteral("currentTrack")] = d->mCurrentPlayListPosition;
currentState[QStringLiteral("shufflePlayList")] = d->mShufflePlayList;
currentState[QStringLiteral("repeatPlay")] = d->mRepeatPlay;
currentState[QStringLiteral("repeatMode")] = QVariant::fromValue(d->mRepeatMode);
return currentState;
}
......@@ -771,9 +795,15 @@ void MediaPlayListProxyModel::setPersistentState(const QVariantMap &persistentSt
if (shufflePlayListStoredValue != persistentStateValue.end()) {
setShufflePlayList(shufflePlayListStoredValue->toBool());
}
auto repeatPlayStoredValue = persistentStateValue.find(QStringLiteral("repeatPlay"));
if (repeatPlayStoredValue != persistentStateValue.end()) {
setRepeatPlay(repeatPlayStoredValue->toBool());
if (repeatPlayStoredValue != persistentStateValue.end() && repeatPlayStoredValue->value<bool>()) {
setRepeatMode(Repeat::Playlist);
}
auto repeatModeStoredValue = persistentStateValue.find(QStringLiteral("repeatMode"));
if (repeatModeStoredValue != persistentStateValue.end()) {
setRepeatMode(repeatModeStoredValue->value<Repeat>());
}
Q_EMIT persistentStateChanged();
......
/*
SPDX-FileCopyrightText: 2015 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-FileCopyrightText: 2019 (c) Alexander Stippich <a.stippich@gmx.net>
SPDX-FileCopyrightText: 2020 (c) Carson Black <uhhadd@gmail.com>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
......@@ -25,6 +26,16 @@ class ELISALIB_EXPORT MediaPlayListProxyModel : public QAbstractProxyModel
Q_OBJECT
public:
enum Repeat {
None,
One,
Playlist
};
Q_ENUM(Repeat)
private:
Q_PROPERTY(QVariantMap persistentState
READ persistentState
WRITE setPersistentState
......@@ -42,10 +53,10 @@ class ELISALIB_EXPORT MediaPlayListProxyModel : public QAbstractProxyModel
READ nextTrack
NOTIFY nextTrackChanged)
Q_PROPERTY(bool repeatPlay
READ repeatPlay
WRITE setRepeatPlay
NOTIFY repeatPlayChanged)
Q_PROPERTY(Repeat repeatMode
READ repeatMode
WRITE setRepeatMode
NOTIFY repeatModeChanged)
Q_PROPERTY(bool shufflePlayList
READ shufflePlayList
......@@ -100,7 +111,7 @@ public:
[[nodiscard]] QPersistentModelIndex nextTrack() const;
[[nodiscard]] bool repeatPlay() const;
[[nodiacard]] Repeat repeatMode() const;
[[nodiscard]] bool shufflePlayList() const;
......@@ -130,7 +141,7 @@ public Q_SLOTS:
ElisaUtils::PlayListEnqueueMode enqueueMode,
ElisaUtils::PlayListEnqueueTriggerPlay triggerPlay);
void setRepeatPlay(bool value);
void setRepeatMode(Repeat value);
void setShufflePlayList(bool value);
......@@ -177,7 +188,7 @@ Q_SIGNALS:
void nextTrackDataChanged();
void repeatPlayChanged();
void repeatModeChanged();
void shufflePlayListChanged();
......
......@@ -1004,11 +1004,19 @@ Module {
prototype: "QAbstractProxyModel"
exports: ["org.kde.elisa/MediaPlayListProxyModel 1.0"]
exportMetaObjectRevisions: [0]
Enum {
name: "Repeat"
values: {
"None": 0,
"One": 1,
"Playlist": 2
}
}
Property { name: "persistentState"; type: "QVariantMap" }
Property { name: "previousTrack"; type: "QPersistentModelIndex"; isReadonly: true }
Property { name: "currentTrack"; type: "QPersistentModelIndex"; isReadonly: true }
Property { name: "nextTrack"; type: "QPersistentModelIndex"; isReadonly: true }
Property { name: "repeatPlay"; type: "bool" }
Property { name: "repeatMode"; type: "Repeat" }
Property { name: "shufflePlayList"; type: "bool" }
Property { name: "remainingTracks"; type: "int"; isReadonly: true }
Property { name: "currentTrackRow"; type: "int"; isReadonly: true }
......@@ -1060,8 +1068,8 @@ Module {
Parameter { name: "triggerPlay"; type: "ElisaUtils::PlayListEnqueueTriggerPlay" }
}
Method {
name: "setRepeatPlay"
Parameter { name: "value"; type: "bool" }
name: "setRepeatMode"
Parameter { name: "value"; type: "Repeat" }
}
Method {
name: "setShufflePlayList"
......
......@@ -233,7 +233,7 @@ Kirigami.ApplicationWindow {
playerControl.playEnabled: ElisaApplication.playerControl.playControlEnabled
playerControl.isPlaying: ElisaApplication.playerControl.musicPlaying
playerControl.repeat: ElisaApplication.mediaPlayListProxyModel.repeatPlay
playerControl.repeat: ElisaApplication.mediaPlayListProxyModel.repeatMode
playerControl.shuffle: ElisaApplication.mediaPlayListProxyModel.shufflePlayList
playerControl.onSeek: ElisaApplication.audioControl.playerSeek(position)
......@@ -359,7 +359,7 @@ Kirigami.ApplicationWindow {
}
ElisaApplication.mediaPlayListProxyModel.shufflePlayList = Qt.binding(function() { return headerBar.playerControl.shuffle })
ElisaApplication.mediaPlayListProxyModel.repeatPlay = Qt.binding(function() { return headerBar.playerControl.repeat })
ElisaApplication.mediaPlayListProxyModel.repeatMode = Qt.binding(function() { return headerBar.playerControl.repeat })
ElisaApplication.audioPlayer.muted = Qt.binding(function() { return headerBar.playerControl.muted })
ElisaApplication.audioPlayer.volume = Qt.binding(function() { return headerBar.playerControl.volume })
......
/*
SPDX-FileCopyrightText: 2016 (c) Matthieu Gallien <matthieu_gallien@yahoo.fr>
SPDX-FileCopyrightText: 2020 (c) Carson Black <uhhadd@gmail.com>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
......@@ -7,7 +8,7 @@
import QtQuick 2.7
import QtQuick.Layouts 1.2
import QtGraphicalEffects 1.0
import QtQuick.Controls 2.3
import QtQuick.Controls 2.7
import org.kde.kirigami 2.5 as Kirigami
import org.kde.elisa 1.0
......@@ -24,7 +25,7 @@ FocusScope {
property bool isMaximized
property bool shuffle
property bool repeat
property int repeat: MediaPlayListProxyModel.None
signal play()
signal pause()
......@@ -325,9 +326,49 @@ FocusScope {
FlatButtonWithToolTip {
id: repeatButton
text: i18nc("toggle repeat mode for playlist", "Toggle Repeat")
icon.name: musicWidget.repeat ? "media-repeat-all" : "media-repeat-none"
onClicked: musicWidget.repeat = !musicWidget.repeat
text: {
const map = {
0: i18n("Don't repeat tracks"),
1: i18n("Repeat current track"),
2: i18n("Repeat all tracks in playlist")
}
return map[musicWidget.repeat]
}
icon.name: {
const map = {
0: "media-repeat-none",
1: "media-repeat-single",
2: "media-repeat-all"
}
return map[musicWidget.repeat]
}
onClicked: {
let nextRepeat = musicWidget.repeat + 1
if (nextRepeat >= 3) {
nextRepeat = 0
}
musicWidget.repeat = nextRepeat
}
onPressAndHold: {
playlistModeMenu.popup()
}
Menu {
id: playlistModeMenu
PlaylistModeItem {
text: i18n("Playlist")
mode: MediaPlayListProxyModel.Playlist
}
PlaylistModeItem {
text: i18n("One")
mode: MediaPlayListProxyModel.One
}
PlaylistModeItem {
text: i18n("None")
mode: MediaPlayListProxyModel.None
}
}
}
// Not a FlatButtonWithToolTip because we want text
......
......@@ -129,17 +129,17 @@ MenuBar {
items: repeatMenu.items
}
MenuItem {
text: i18n("On")
checkable: true
checked: ElisaApplication.mediaPlayListProxyModel.repeatPlay
onTriggered: ElisaApplication.mediaPlayListProxyModel.repeatPlay = true
NativeGlobalMenuPlaylistModeItem {
text: i18n("Playlist")
mode: MediaPlayListProxyModel.Playlist
}
MenuItem {
text: i18n("Off")
checkable: true
checked: !ElisaApplication.mediaPlayListProxyModel.repeatPlay
onTriggered: ElisaApplication.mediaPlayListProxyModel.repeatPlay = false
NativeGlobalMenuPlaylistModeItem {
text: i18n("One")
mode: MediaPlayListProxyModel.One
}
NativeGlobalMenuPlaylistModeItem {
text: i18n("None")
mode: MediaPlayListProxyModel.None
}
}
}
......
/*
SPDX-FileCopyrightText: 2020 Carson Black <uhhadd@gmail.com>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
import Qt.labs.platform 1.1
import org.kde.elisa 1.0
MenuItem {
property int mode: -1
checkable: true
checked: ElisaApplication.mediaPlayListProxyModel.repeatMode == mode
onTriggered: ElisaApplication.mediaPlayListProxyModel.repeatMode = mode
}
/*
SPDX-FileCopyrightText: 2020 Carson Black <uhhadd@gmail.com>
SPDX-License-Identifier: LGPL-3.0-or-later
*/
import org.kde.elisa 1.0
import QtQuick.Controls 2.3
MenuItem {
property int mode: -1
checkable: true
checked: ElisaApplication.mediaPlayListProxyModel.repeatMode == mode
onTriggered: ElisaApplication.mediaPlayListProxyModel.repeatMode = mode
}
......@@ -39,6 +39,8 @@
<file>qml/NativeMenuItemFromAction.qml</file>
<file>qml/NativeTrayMenu.qml</file>
<file>qml/NativeGlobalMenu.qml</file>
<file>qml/NativeGlobalMenuPlaylistModeItem.qml</file>
<file>qml/PlaylistModeItem.qml</file>
<file>qml/ElisaConfigurationDialog.qml</file>
<file>qml/FileScanningConfiguration.qml</file>
<file>qml/GeneralConfiguration.qml</file>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment