diff --git a/src/audiowrapper.h b/src/audiowrapper.h --- a/src/audiowrapper.h +++ b/src/audiowrapper.h @@ -114,17 +114,17 @@ void sourceChanged(); - void statusChanged(); + void statusChanged(QMediaPlayer::MediaStatus status); - void playbackStateChanged(); + void playbackStateChanged(QMediaPlayer::State state); - void errorChanged(); + void errorChanged(QMediaPlayer::Error error); - void durationChanged(); + void durationChanged(qint64 duration); - void positionChanged(); + void positionChanged(qint64 position); - void seekableChanged(); + void seekableChanged(bool seekable); void playing(); diff --git a/src/audiowrapper.cpp b/src/audiowrapper.cpp --- a/src/audiowrapper.cpp +++ b/src/audiowrapper.cpp @@ -42,7 +42,7 @@ connect(&d->mPlayer, &QMediaPlayer::mediaStatusChanged, this, &AudioWrapper::statusChanged); connect(&d->mPlayer, &QMediaPlayer::stateChanged, this, &AudioWrapper::playbackStateChanged); connect(&d->mPlayer, &QMediaPlayer::stateChanged, this, &AudioWrapper::playerStateChanged); - connect(&d->mPlayer, SIGNAL(error(QMediaPlayer::Error)), this, SIGNAL(errorChanged())); + connect(&d->mPlayer, QOverload::of(&QMediaPlayer::error), this, &AudioWrapper::errorChanged); connect(&d->mPlayer, &QMediaPlayer::durationChanged, this, &AudioWrapper::durationChanged); connect(&d->mPlayer, &QMediaPlayer::positionChanged, this, &AudioWrapper::positionChanged); connect(&d->mPlayer, &QMediaPlayer::seekableChanged, this, &AudioWrapper::seekableChanged); diff --git a/src/elisaapplication.h b/src/elisaapplication.h --- a/src/elisaapplication.h +++ b/src/elisaapplication.h @@ -39,6 +39,7 @@ class SingleAlbumProxyModel; class MediaPlayList; class AudioWrapper; +class ManageAudioPlayer; class ElisaApplicationPrivate; class ELISALIB_EXPORT ElisaApplication : public QObject @@ -83,6 +84,10 @@ READ audioPlayer NOTIFY audioPlayerChanged) + Q_PROPERTY(ManageAudioPlayer *audioControl + READ audioControl + NOTIFY audioControlChanged) + public: explicit ElisaApplication(QObject *parent = nullptr); @@ -110,6 +115,8 @@ AudioWrapper *audioPlayer() const; + ManageAudioPlayer *audioControl() const; + Q_SIGNALS: void argumentsChanged(); @@ -130,6 +137,8 @@ void audioPlayerChanged(); + void audioControlChanged(); + void enqueue(const QStringList &files); public Q_SLOTS: diff --git a/src/elisaapplication.cpp b/src/elisaapplication.cpp --- a/src/elisaapplication.cpp +++ b/src/elisaapplication.cpp @@ -28,6 +28,7 @@ #include "models/singlealbumproxymodel.h" #include "mediaplaylist.h" #include "audiowrapper.h" +#include "manageaudioplayer.h" #include "elisa_settings.h" #include @@ -103,6 +104,8 @@ std::unique_ptr mAudioWrapper; + std::unique_ptr mAudioControl; + }; ElisaApplication::ElisaApplication(QObject *parent) : QObject(parent), d(std::make_unique(this)) @@ -284,6 +287,8 @@ Q_EMIT mediaPlayListChanged(); d->mAudioWrapper = std::make_unique(); Q_EMIT audioPlayerChanged(); + d->mAudioControl = std::make_unique(); + Q_EMIT audioControlChanged(); d->mMusicManager->setElisaApplication(this); @@ -319,6 +324,37 @@ ElisaUtils::PlayListEnqueueMode, ElisaUtils::PlayListEnqueueTriggerPlay)>(&MediaPlayList::enqueue)); + d->mAudioControl->setAlbumNameRole(MediaPlayList::AlbumRole); + d->mAudioControl->setArtistNameRole(MediaPlayList::ArtistRole); + d->mAudioControl->setTitleRole(MediaPlayList::TitleRole); + d->mAudioControl->setUrlRole(MediaPlayList::ResourceRole); + d->mAudioControl->setIsPlayingRole(MediaPlayList::IsPlayingRole); + d->mAudioControl->setPlayListModel(d->mMediaPlayList.get()); + d->mAudioControl->setCurrentTrack(d->mMediaPlayList->currentTrack()); + + + d->mAudioWrapper->setSource(d->mAudioControl->playerSource()); + + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerPlay, d->mAudioWrapper.get(), &AudioWrapper::play); + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerPause, d->mAudioWrapper.get(), &AudioWrapper::pause); + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerStop, d->mAudioWrapper.get(), &AudioWrapper::stop); + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::seek, d->mAudioWrapper.get(), &AudioWrapper::seek); + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::skipNextTrack, d->mMediaPlayList.get(), &MediaPlayList::skipNextTrack); + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::sourceInError, d->mMediaPlayList.get(), &MediaPlayList::trackInError); + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::sourceInError, d->mMusicManager.get(), &MusicListenersManager::playBackError); + QObject::connect(d->mAudioControl.get(), &ManageAudioPlayer::playerSourceChanged, d->mAudioWrapper.get(), &AudioWrapper::setSource); + + QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::ensurePlay, d->mAudioControl.get(), &ManageAudioPlayer::ensurePlay); + QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::playListFinished, d->mAudioControl.get(), &ManageAudioPlayer::playListFinished); + QObject::connect(d->mMediaPlayList.get(), &MediaPlayList::currentTrackChanged, d->mAudioControl.get(), &ManageAudioPlayer::setCurrentTrack); + + QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::playbackStateChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerPlaybackState); + QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::statusChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerStatus); + QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::errorChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerError); + QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::durationChanged, d->mAudioControl.get(), &ManageAudioPlayer::setAudioDuration); + QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::seekableChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerIsSeekable); + QObject::connect(d->mAudioWrapper.get(), &AudioWrapper::positionChanged, d->mAudioControl.get(), &ManageAudioPlayer::setPlayerPosition); + if (!d->mArguments.isEmpty()) { Q_EMIT enqueue(d->mArguments); } @@ -392,4 +428,9 @@ return d->mAudioWrapper.get(); } +ManageAudioPlayer *ElisaApplication::audioControl() const +{ + return d->mAudioControl.get(); +} + #include "moc_elisaapplication.cpp" diff --git a/src/manageaudioplayer.h b/src/manageaudioplayer.h --- a/src/manageaudioplayer.h +++ b/src/manageaudioplayer.h @@ -163,7 +163,7 @@ void playListModelChanged(); - void playerSourceChanged(); + void playerSourceChanged(QUrl url); void urlRoleChanged(); diff --git a/src/manageaudioplayer.cpp b/src/manageaudioplayer.cpp --- a/src/manageaudioplayer.cpp +++ b/src/manageaudioplayer.cpp @@ -504,7 +504,7 @@ { auto newUrlValue = mCurrentTrack.data(mUrlRole); if ((mCurrentTrack == mOldCurrentTrack && mOldPlayerSource == newUrlValue && mPlayingState) || mOldPlayerSource != newUrlValue) { - Q_EMIT playerSourceChanged(); + Q_EMIT playerSourceChanged(mCurrentTrack.data(mUrlRole).toUrl()); mOldPlayerSource = newUrlValue; } diff --git a/src/mediaplaylist.h b/src/mediaplaylist.h --- a/src/mediaplaylist.h +++ b/src/mediaplaylist.h @@ -171,7 +171,7 @@ void tracksCountChanged(); - void currentTrackChanged(); + void currentTrackChanged(QPersistentModelIndex currentTrack); void currentTrackRowChanged(); diff --git a/src/mediaplaylist.cpp b/src/mediaplaylist.cpp --- a/src/mediaplaylist.cpp +++ b/src/mediaplaylist.cpp @@ -1295,7 +1295,7 @@ void MediaPlayList::notifyCurrentTrackChanged() { - Q_EMIT currentTrackChanged(); + Q_EMIT currentTrackChanged(d->mCurrentTrack); Q_EMIT currentTrackRowChanged(); bool currentTrackIsValid = d->mCurrentTrack.isValid(); if (currentTrackIsValid) { diff --git a/src/mpris2/mediaplayer2player.cpp b/src/mpris2/mediaplayer2player.cpp --- a/src/mpris2/mediaplayer2player.cpp +++ b/src/mpris2/mediaplayer2player.cpp @@ -68,6 +68,7 @@ this, &MediaPlayer2Player::playerVolumeChanged); m_volume = m_audioPlayer->volume(); + m_canPlay = m_manageMediaPlayerControl->playControlEnabled(); signalPropertiesChange(QStringLiteral("Volume"), Volume()); m_mediaPlayerPresent = 1; diff --git a/src/qml/ContentView.qml b/src/qml/ContentView.qml --- a/src/qml/ContentView.qml +++ b/src/qml/ContentView.qml @@ -20,6 +20,7 @@ import QtQuick 2.7 import QtQuick.Controls 2.2 import QtQuick.Layouts 1.2 +import QtQuick.Window 2.2 import org.kde.elisa 1.0 RowLayout { @@ -314,9 +315,9 @@ Layout.maximumWidth: contentZone.width Layout.preferredWidth: contentZone.width - onStartPlayback: manageAudioPlayer.ensurePlay() + onStartPlayback: elisa.audioControl.ensurePlay() - onPausePlayback: manageAudioPlayer.playPause() + onPausePlayback: elisa.audioControl.playPause() onDisplayError: messageNotification.showNotification(errorText) } diff --git a/src/qml/ElisaMainWindow.qml b/src/qml/ElisaMainWindow.qml --- a/src/qml/ElisaMainWindow.qml +++ b/src/qml/ElisaMainWindow.qml @@ -114,28 +114,32 @@ persistentSettings.playListState = elisa.mediaPlayList.persistentState; persistentSettings.playListControlerState = elisa.mediaPlayList.persistentState; - persistentSettings.audioPlayerState = manageAudioPlayer.persistentState + persistentSettings.audioPlayerState = elisa.audioControl.persistentState persistentSettings.playControlItemVolume = headerBar.playerControl.volume persistentSettings.playControlItemMuted = headerBar.playerControl.muted } } - PlatformIntegration { - id: platformInterface + Loader { + id: mprisloader + active: false - playListModel: elisa.mediaPlayList - playListControler: elisa.mediaPlayList - audioPlayerManager: manageAudioPlayer - headerBarManager: myHeaderBarManager - manageMediaPlayerControl: myPlayControlManager - player: elisa.audioPlayer + sourceComponent: PlatformIntegration { + id: platformInterface - onRaisePlayer: - { - mainWindow.show() - mainWindow.raise() - mainWindow.requestActivate() + playListModel: elisa.mediaPlayList + playListControler: elisa.mediaPlayList + audioPlayerManager: elisa.audioControl + player: elisa.audioPlayer + headerBarManager: myHeaderBarManager + manageMediaPlayerControl: myPlayControlManager + onRaisePlayer: + { + mainWindow.show() + mainWindow.raise() + mainWindow.requestActivate() + } } } @@ -164,10 +168,6 @@ onPlayListLoadFailed: { messageNotification.showNotification(i18nc("message of passive notification when playlist load failed", "Load of playlist failed"), 3000) } - - onEnsurePlay: manageAudioPlayer.ensurePlay() - - onPlayListFinished: manageAudioPlayer.playListFinished() } ManageHeaderBar { @@ -183,40 +183,6 @@ isValidRole: MediaPlayList.IsValidRole } - ManageAudioPlayer { - id: manageAudioPlayer - - currentTrack: elisa.mediaPlayList.currentTrack - playListModel: elisa.mediaPlayList - urlRole: MediaPlayList.ResourceRole - isPlayingRole: MediaPlayList.IsPlayingRole - titleRole: MediaPlayList.TitleRole - artistNameRole: MediaPlayList.ArtistRole - albumNameRole: MediaPlayList.AlbumRole - - playerStatus: elisa.audioPlayer.status - playerPlaybackState: elisa.audioPlayer.playbackState - playerError: elisa.audioPlayer.error - audioDuration: elisa.audioPlayer.duration - playerIsSeekable: elisa.audioPlayer.seekable - playerPosition: elisa.audioPlayer.position - - persistentState: persistentSettings.audioPlayerState - - onPlayerPlay: elisa.audioPlayer.play() - onPlayerPause: elisa.audioPlayer.pause() - onPlayerStop: elisa.audioPlayer.stop() - onSkipNextTrack: elisa.mediaPlayList.skipNextTrack() - onSeek: elisa.audioPlayer.seek(position) - onSourceInError: - { - elisa.mediaPlayList.trackInError(source, playerError) - elisa.musicManager.playBackError(source, playerError) - } - - onDisplayTrackError: messageNotification.showNotification(i18n("Error when playing %1", "" + fileName), 3000) - } - ManageMediaPlayerControl { id: myPlayControlManager @@ -270,9 +236,8 @@ playerControl.onSeek: elisa.audioPlayer.seek(position) - playerControl.onPlay: manageAudioPlayer.playPause() - playerControl.onPause: manageAudioPlayer.playPause() - + playerControl.onPlay: elisa.audioControl.playPause() + playerControl.onPause: elisa.audioControl.playPause() playerControl.onPlayPrevious: elisa.mediaPlayList.skipPreviousTrack() playerControl.onPlayNext: elisa.mediaPlayList.skipNextTrack() @@ -291,6 +256,7 @@ topMargin: elisaTheme.layoutHorizontalMargin * 3 } } + Rectangle { anchors.fill: menuButton @@ -357,16 +323,21 @@ elisa.mediaPlayList.randomPlay = Qt.binding(function() { return contentView.playList.randomPlayChecked }) elisa.mediaPlayList.repeatPlay = Qt.binding(function() { return contentView.playList.repeatPlayChecked }) myPlayControlManager.randomOrContinuePlay = Qt.binding(function() { return contentView.playList.randomPlayChecked || contentView.playList.repeatPlayChecked }) + myPlayControlManager.playListModel = Qt.binding(function() { return elisa.mediaPlayList }) + myPlayControlManager.currentTrack = Qt.binding(function() { return elisa.mediaPlayList.currentTrack }) if (persistentSettings.playListState) { elisa.mediaPlayList.persistentState = persistentSettings.playListState } - + if (persistentSettings.audioPlayerState) { + elisa.audioControl.persistentState = persistentSettings.audioPlayerState + } elisa.audioPlayer.muted = Qt.binding(function() { return headerBar.playerControl.muted }) elisa.audioPlayer.volume = Qt.binding(function() { return headerBar.playerControl.volume }) - elisa.audioPlayer.source = Qt.binding(function() { return manageAudioPlayer.playerSource }) volume: headerBar.playerControl.volume + + mprisloader.active = true } }