diff --git a/src/MediaServer.qml b/src/MediaServer.qml --- a/src/MediaServer.qml +++ b/src/MediaServer.qml @@ -141,7 +141,7 @@ id: allListeners elisaApplication: elisa - } + } AudioWrapper { id: audioPlayer @@ -222,7 +222,13 @@ onPlayerStop: audioPlayer.stop() onSkipNextTrack: playListModelItem.skipNextTrack() onSeek: audioPlayer.seek(position) - onSourceInError: allListeners.playBackError(source, playerError) + onSourceInError: + { + playListModelItem.trackInError(source, playerError) + allListeners.playBackError(source, playerError) + } + + onDisplayTrackError: messageNotification.showNotification(i18n("Error when playing %1", "" + fileName), 3000) } ManageMediaPlayerControl { @@ -376,6 +382,10 @@ onTriggered: applicationMenu.popup() } + PassiveNotification { + id: messageNotification + } + Rectangle { color: myPalette.base anchors.fill: parent diff --git a/src/PassiveNotification.qml b/src/PassiveNotification.qml --- a/src/PassiveNotification.qml +++ b/src/PassiveNotification.qml @@ -18,33 +18,33 @@ */ import QtQuick 2.5 -import QtQuick.Controls 1.3 +import QtQuick.Controls 2.0 as QQC2 import QtQuick.Layouts 1.2 import QtGraphicalEffects 1.0 -import QtQuick.Window 2.2 MouseArea { id: root + z: 9999999 width: background.width height: background.height opacity: 0 enabled: appearAnimation.appear anchors { horizontalCenter: parent.horizontalCenter bottom: parent.bottom - bottomMargin: Screen.pixelDensity * 2 + bottomMargin: 3 * 4 } function showNotification(message, timeout, actionText, callBack) { if (!message) { return; } appearAnimation.running = false; appearAnimation.appear = true; appearAnimation.running = true; - if (timeout === "short") { + if (timeout == "short") { timer.interval = 1000; - } else if (timeout === "long") { + } else if (timeout == "long") { timer.interval = 4500; } else if (timeout > 0) { timer.interval = timeout; @@ -90,39 +90,43 @@ target: root properties: "opacity" to: appearAnimation.appear ? 1 : 0 - duration: 250 + duration: 1000 easing.type: Easing.InOutQuad } NumberAnimation { target: transform properties: "y" to: appearAnimation.appear ? 0 : background.height - duration: 250 + duration: 1000 easing.type: appearAnimation.appear ? Easing.OutQuad : Easing.InQuad } } Item { id: background - width: backgroundRect.width + Screen.pixelDensity - height: backgroundRect.height + Screen.pixelDensity + width: backgroundRect.width + 3 + height: backgroundRect.height + 3 Rectangle { id: backgroundRect anchors.centerIn: parent - radius: Screen.pixelDensity * 2 + radius: 5 + color: myPalette.button opacity: 0.6 - width: mainLayout.width + Screen.pixelDensity * 4 - height: mainLayout.height + Screen.pixelDensity * 4 + width: mainLayout.width + Math.round((height - mainLayout.height)) + height: Math.max(mainLayout.height + 5*2, 3*2) } RowLayout { id: mainLayout anchors.centerIn: parent - LabelWithToolTip { + QQC2.Label { id: messageLabel - width: Math.min(root.parent.width - Screen.pixelDensity * 6, implicitWidth) + Layout.maximumWidth: Math.min(root.parent.width - 20*2, implicitWidth) elide: Text.ElideRight + wrapMode: Text.WordWrap + maximumLineCount: 4 + color: myPalette.buttonText } - Button { + QQC2.Button { id: actionButton property var callBack visible: text != "" @@ -135,16 +139,14 @@ } } } - } - - DropShadow { - anchors.fill: background - horizontalOffset: 0 - verticalOffset: Screen.pixelDensity / 3 - radius: Screen.pixelDensity / 3.5 - samples: 16 - color: Qt.rgba(0, 0, 0, 0.5) - source: background + layer.enabled: true + layer.effect: DropShadow { + horizontalOffset: 0 + verticalOffset: 0 + radius: 3 + samples: 32 + color: Qt.rgba(0, 0, 0, 0.5) + } } } diff --git a/src/manageaudioplayer.h b/src/manageaudioplayer.h --- a/src/manageaudioplayer.h +++ b/src/manageaudioplayer.h @@ -201,6 +201,8 @@ void sourceInError(QUrl source, QMediaPlayer::Error playerError); + void displayTrackError(const QString &fileName); + public Q_SLOTS: void setCurrentTrack(const QPersistentModelIndex ¤tTrack); diff --git a/src/manageaudioplayer.cpp b/src/manageaudioplayer.cpp --- a/src/manageaudioplayer.cpp +++ b/src/manageaudioplayer.cpp @@ -309,7 +309,15 @@ Q_EMIT playerErrorChanged(); if (mPlayerError != QMediaPlayer::NoError) { - Q_EMIT sourceInError(playerSource(), mPlayerError); + auto currentSource = playerSource(); + + Q_EMIT sourceInError(currentSource, mPlayerError); + + if (currentSource.isLocalFile()) { + Q_EMIT displayTrackError(currentSource.toLocalFile()); + } else { + Q_EMIT displayTrackError(currentSource.toString()); + } } } diff --git a/src/mediaplaylist.h b/src/mediaplaylist.h --- a/src/mediaplaylist.h +++ b/src/mediaplaylist.h @@ -26,6 +26,7 @@ #include #include #include +#include class MediaPlayListPrivate; class DatabaseInterface; @@ -204,6 +205,8 @@ void clearAndEnqueue(const QString &artistName); + void trackInError(QUrl sourceInError, QMediaPlayer::Error playerError); + private Q_SLOTS: bool rowHasHeader(int row) const; diff --git a/src/mediaplaylist.cpp b/src/mediaplaylist.cpp --- a/src/mediaplaylist.cpp +++ b/src/mediaplaylist.cpp @@ -846,6 +846,23 @@ notifyCurrentTrackChanged(); } +void MediaPlayList::trackInError(QUrl sourceInError, QMediaPlayer::Error playerError) +{ + Q_UNUSED(playerError) + + for (int i = 0; i < d->mData.size(); ++i) { + auto &oneTrack = d->mData[i]; + if (oneTrack.mIsValid) { + const auto &oneTrackData = d->mTrackData.at(i); + + if (oneTrackData.resourceURI() == sourceInError) { + oneTrack.mIsValid = false; + Q_EMIT dataChanged(index(i, 0), index(i, 0), {ColumnsRoles::IsValidRole}); + } + } + } +} + bool MediaPlayList::rowHasHeader(int row) const { if (row >= rowCount()) { diff --git a/src/musiclistenersmanager.h b/src/musiclistenersmanager.h --- a/src/musiclistenersmanager.h +++ b/src/musiclistenersmanager.h @@ -115,6 +115,8 @@ void removeTracksInError(QList tracks); + void displayTrackError(const QString &fileName); + public Q_SLOTS: void databaseReady(); diff --git a/src/musiclistenersmanager.cpp b/src/musiclistenersmanager.cpp --- a/src/musiclistenersmanager.cpp +++ b/src/musiclistenersmanager.cpp @@ -255,6 +255,12 @@ if (playerError == QMediaPlayer::ResourceError) { Q_EMIT removeTracksInError({sourceInError}); + + if (sourceInError.isLocalFile()) { + Q_EMIT displayTrackError(sourceInError.toLocalFile()); + } else { + Q_EMIT displayTrackError(sourceInError.toString()); + } } }