load same folder, add playlist listview for debug

This commit is contained in:
Gary Wang 2020-04-07 19:09:08 +08:00
parent 6435c4e79f
commit 86994811fe
7 changed files with 836 additions and 416 deletions

View File

@ -19,6 +19,8 @@ add_executable(pineapple-music
mainwindow.h mainwindow.h
seekableslider.cpp seekableslider.cpp
seekableslider.h seekableslider.h
playlistmodel.h
playlistmodel.cpp
mainwindow.ui mainwindow.ui
resources.qrc resources.qrc
) )

View File

@ -1,11 +1,35 @@
#include "mainwindow.h" #include "mainwindow.h"
#include <QApplication> #include <QApplication>
#include <QCommandLineParser>
#include <QUrl>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
QApplication a(argc, argv); QApplication a(argc, argv);
// parse commandline arguments
QCommandLineParser parser;
parser.addPositionalArgument("File list", QCoreApplication::translate("main", "File list."));
parser.addHelpOption();
parser.process(a);
QStringList urlStrList = parser.positionalArguments();
QList<QUrl> urlList;
for (const QString & str : urlStrList) {
QUrl url = QUrl::fromLocalFile(str);
if (url.isValid()) {
urlList.append(url);
}
}
MainWindow w; MainWindow w;
w.show(); w.show();
if (!urlList.isEmpty()) {
w.commandlinePlayAudioFiles(urlList);
}
return a.exec(); return a.exec();
} }

View File

@ -1,6 +1,8 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "./ui_mainwindow.h" #include "./ui_mainwindow.h"
#include "playlistmodel.h"
#include <QPainter> #include <QPainter>
#include <QMediaPlayer> #include <QMediaPlayer>
#include <QMediaPlaylist> #include <QMediaPlaylist>
@ -9,11 +11,14 @@
#include <QTime> #include <QTime>
#include <QStyle> #include <QStyle>
#include <QScreen> #include <QScreen>
#include <QListView>
#include <QCollator>
MainWindow::MainWindow(QWidget *parent) MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent) : QMainWindow(parent)
, ui(new Ui::MainWindow) , ui(new Ui::MainWindow)
, m_mediaPlayer(new QMediaPlayer(this)) , m_mediaPlayer(new QMediaPlayer(this))
, m_playlistModel(new PlaylistModel(this))
{ {
ui->setupUi(this); ui->setupUi(this);
@ -31,6 +36,45 @@ MainWindow::~MainWindow()
delete ui; delete ui;
} }
void MainWindow::commandlinePlayAudioFiles(QList<QUrl> audioFiles)
{
if (!audioFiles.isEmpty()) {
if (audioFiles.count() == 1) {
loadPlaylistBySingleLocalFile(audioFiles.first().toLocalFile());
} else {
createPlaylist(audioFiles);
}
m_mediaPlayer->play();
}
}
void MainWindow::loadPlaylistBySingleLocalFile(const QString &path)
{
QFileInfo info(path);
QDir dir(info.path());
QString currentFileName = info.fileName();
QStringList entryList = dir.entryList({"*.mp3", "*.wav", "*.aiff", "*.ape", "*.flac", "*.ogg", "*.oga"},
QDir::Files | QDir::NoSymLinks, QDir::NoSort);
QCollator collator;
collator.setNumericMode(true);
std::sort(entryList.begin(), entryList.end(), collator);
QList<QUrl> urlList;
int currentFileIndex = -1;
for (int i = 0; i < entryList.count(); i++) {
const QString & oneEntry = entryList.at(i);
urlList.append(QUrl::fromLocalFile(dir.absoluteFilePath(oneEntry)));
if (oneEntry == currentFileName) {
currentFileIndex = i;
}
}
QMediaPlaylist * playlist = createPlaylist(urlList);
playlist->setCurrentIndex(currentFileIndex);
}
void MainWindow::closeEvent(QCloseEvent *) void MainWindow::closeEvent(QCloseEvent *)
{ {
qApp->exit(); qApp->exit();
@ -86,16 +130,33 @@ void MainWindow::loadFile()
tr("Select songs to play"), tr("Select songs to play"),
QDir::homePath(), QDir::homePath(),
tr("Audio Files") + " (*.mp3 *.wav *.aiff *.ape *.flac *.ogg *.oga)"); tr("Audio Files") + " (*.mp3 *.wav *.aiff *.ape *.flac *.ogg *.oga)");
QList<QUrl> urlList;
for (const QString & fileName : files) {
urlList.append(QUrl::fromLocalFile(fileName));
}
createPlaylist(urlList);
}
/*
* The returned QMediaPlaylist* ownership belongs to the internal QMediaPlayer instance.
*/
QMediaPlaylist *MainWindow::createPlaylist(QList<QUrl> urlList)
{
QMediaPlaylist * playlist = new QMediaPlaylist(m_mediaPlayer); QMediaPlaylist * playlist = new QMediaPlaylist(m_mediaPlayer);
playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop); playlist->setPlaybackMode(QMediaPlaylist::CurrentItemInLoop);
for (const QString & fileName : files) {
bool succ = playlist->addMedia(QMediaContent(QUrl::fromLocalFile(fileName))); for (const QUrl & url : urlList) {
bool succ = playlist->addMedia(QMediaContent(url));
if (!succ) { if (!succ) {
qDebug("!!!!!!!!! break point time !!!!!!!!!"); qDebug("!!!!!!!!! break point time !!!!!!!!!");
} }
} }
m_mediaPlayer->setPlaylist(playlist); m_mediaPlayer->setPlaylist(playlist);
m_playlistModel->setPlaylist(playlist);
return playlist;
} }
void MainWindow::centerWindow() void MainWindow::centerWindow()
@ -208,12 +269,22 @@ void MainWindow::initUiAndAnimation()
m_fadeOutAnimation->setStartValue(1); m_fadeOutAnimation->setStartValue(1);
m_fadeOutAnimation->setEndValue(0); m_fadeOutAnimation->setEndValue(0);
connect(m_fadeOutAnimation, &QPropertyAnimation::finished, this, &QMainWindow::close); connect(m_fadeOutAnimation, &QPropertyAnimation::finished, this, &QMainWindow::close);
// temp: a playlist for debug...
QListView * tmp_listview = new QListView(ui->pluginWidget);
tmp_listview->setModel(m_playlistModel);
tmp_listview->setGeometry({0,0,490,250});
this->setGeometry({0,0,490,160}); // temp size, hide the playlist thing.
} }
void MainWindow::initConnections() void MainWindow::initConnections()
{ {
connect(m_mediaPlayer, &QMediaPlayer::currentMediaChanged, this, [=](const QMediaContent &media) { connect(m_mediaPlayer, &QMediaPlayer::currentMediaChanged, this, [=](const QMediaContent &media) {
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
ui->titleLabel->setText(media.canonicalUrl().fileName());
#else
ui->titleLabel->setText(media.request().url().fileName()); ui->titleLabel->setText(media.request().url().fileName());
#endif // QT_VERSION < QT_VERSION_CHECK(5, 0, 0)
}); });
connect(m_mediaPlayer, &QMediaPlayer::positionChanged, this, [=](qint64 pos) { connect(m_mediaPlayer, &QMediaPlayer::positionChanged, this, [=](qint64 pos) {

View File

@ -7,9 +7,11 @@ QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } namespace Ui { class MainWindow; }
class QMediaPlayer; class QMediaPlayer;
class QMediaPlaylist;
class QPropertyAnimation; class QPropertyAnimation;
QT_END_NAMESPACE QT_END_NAMESPACE
class PlaylistModel;
class MainWindow : public QMainWindow class MainWindow : public QMainWindow
{ {
Q_OBJECT Q_OBJECT
@ -18,6 +20,9 @@ public:
MainWindow(QWidget *parent = nullptr); MainWindow(QWidget *parent = nullptr);
~MainWindow() override; ~MainWindow() override;
void commandlinePlayAudioFiles(QList<QUrl> audioFiles);
void loadPlaylistBySingleLocalFile(const QString &path);
protected: protected:
void closeEvent(QCloseEvent *) override; void closeEvent(QCloseEvent *) override;
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
@ -27,21 +32,17 @@ protected:
void loadFile(); void loadFile();
void centerWindow(); void centerWindow();
QMediaPlaylist *createPlaylist(QList<QUrl> urlList);
private slots: private slots:
void on_closeWindowBtn_clicked(); void on_closeWindowBtn_clicked();
void on_playBtn_clicked(); void on_playBtn_clicked();
void on_volumeSlider_valueChanged(int value); void on_volumeSlider_valueChanged(int value);
void on_stopBtn_clicked(); void on_stopBtn_clicked();
void on_playbackSlider_valueChanged(int value); void on_playbackSlider_valueChanged(int value);
void on_prevBtn_clicked(); void on_prevBtn_clicked();
void on_nextBtn_clicked(); void on_nextBtn_clicked();
void on_volumeBtn_clicked(); void on_volumeBtn_clicked();
void on_minimumWindowBtn_clicked(); void on_minimumWindowBtn_clicked();
private: private:
@ -54,6 +55,7 @@ private:
QMediaPlayer *m_mediaPlayer; QMediaPlayer *m_mediaPlayer;
QPropertyAnimation *m_fadeOutAnimation; QPropertyAnimation *m_fadeOutAnimation;
PlaylistModel *m_playlistModel = nullptr; // TODO: move playback logic to player.cpp
void initUiAndAnimation(); void initUiAndAnimation();
void initConnections(); void initConnections();

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>485</width> <width>490</width>
<height>160</height> <height>420</height>
</rect> </rect>
</property> </property>
<property name="minimumSize"> <property name="minimumSize">
@ -106,12 +106,12 @@ QLabel#coverLabel {
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<layout class="QVBoxLayout" name="verticalLayout" stretch="0"> <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0">
<property name="spacing"> <property name="spacing">
<number>7</number> <number>7</number>
</property> </property>
<property name="leftMargin"> <property name="leftMargin">
<number>10</number> <number>0</number>
</property> </property>
<property name="topMargin"> <property name="topMargin">
<number>0</number> <number>0</number>
@ -123,412 +123,460 @@ QLabel#coverLabel {
<number>0</number> <number>0</number>
</property> </property>
<item> <item>
<layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0"> <widget class="QFrame" name="playerFrame">
<property name="spacing"> <property name="sizePolicy">
<number>10</number> <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property> </property>
<item> <property name="minimumSize">
<widget class="QLabel" name="coverLabel"> <size>
<property name="sizePolicy"> <width>0</width>
<sizepolicy hsizetype="Fixed" vsizetype="Fixed"> <height>160</height>
<horstretch>0</horstretch> </size>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="maximumSize">
</property> <size>
<property name="minimumSize"> <width>16777215</width>
<size> <height>160</height>
<width>128</width> </size>
<height>128</height> </property>
</size> <layout class="QHBoxLayout" name="horizontalLayout" stretch="0,0">
</property> <property name="spacing">
<property name="maximumSize"> <number>10</number>
<size> </property>
<width>128</width> <property name="leftMargin">
<height>128</height> <number>10</number>
</size> </property>
</property> <property name="topMargin">
<property name="text"> <number>0</number>
<string>AlbumCover</string> </property>
</property> <property name="rightMargin">
</widget> <number>0</number>
</item> </property>
<item> <property name="bottomMargin">
<layout class="QVBoxLayout" name="playerContainerLayout" stretch="0,1"> <number>0</number>
<property name="spacing"> </property>
<number>0</number> <item>
</property> <widget class="QLabel" name="coverLabel">
<item> <property name="sizePolicy">
<layout class="QHBoxLayout" name="titlebarLayout"> <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<property name="spacing"> <horstretch>0</horstretch>
<number>0</number> <verstretch>0</verstretch>
</property> </sizepolicy>
<item> </property>
<spacer name="horizontalSpacer"> <property name="minimumSize">
<property name="orientation"> <size>
<enum>Qt::Horizontal</enum> <width>128</width>
</property> <height>128</height>
<property name="sizeHint" stdset="0"> </size>
<size> </property>
<width>40</width> <property name="maximumSize">
<height>20</height> <size>
</size> <width>128</width>
</property> <height>128</height>
</spacer> </size>
</item> </property>
<item> <property name="text">
<widget class="QPushButton" name="miniModeBtn"> <string>AlbumCover</string>
<property name="maximumSize"> </property>
<size> </widget>
<width>25</width> </item>
<height>20</height> <item>
</size> <layout class="QVBoxLayout" name="playerContainerLayout" stretch="0,1">
</property> <property name="spacing">
<property name="text"> <number>0</number>
<string>^</string> </property>
</property> <item>
</widget> <layout class="QHBoxLayout" name="titlebarLayout">
</item> <property name="spacing">
<item> <number>0</number>
<widget class="QPushButton" name="minimumWindowBtn"> </property>
<property name="maximumSize"> <item>
<size> <spacer name="horizontalSpacer">
<width>25</width> <property name="orientation">
<height>20</height> <enum>Qt::Horizontal</enum>
</size> </property>
</property> <property name="sizeHint" stdset="0">
<property name="text"> <size>
<string/> <width>40</width>
</property> <height>20</height>
<property name="icon"> </size>
<iconset resource="resources.qrc"> </property>
<normaloff>:/icons/icons/window-minimize.png</normaloff>:/icons/icons/window-minimize.png</iconset> </spacer>
</property> </item>
</widget> <item>
</item> <widget class="QPushButton" name="miniModeBtn">
<item> <property name="maximumSize">
<widget class="QPushButton" name="closeWindowBtn"> <size>
<property name="minimumSize"> <width>25</width>
<size> <height>20</height>
<width>40</width> </size>
<height>20</height> </property>
</size> <property name="text">
</property> <string>^</string>
<property name="maximumSize"> </property>
<size> </widget>
<width>40</width> </item>
<height>20</height> <item>
</size> <widget class="QPushButton" name="minimumWindowBtn">
</property> <property name="maximumSize">
<property name="text"> <size>
<string/> <width>25</width>
</property> <height>20</height>
<property name="icon"> </size>
<iconset resource="resources.qrc"> </property>
<normaloff>:/icons/icons/window-close.png</normaloff>:/icons/icons/window-close.png</iconset> <property name="text">
</property> <string/>
</widget> </property>
</item> <property name="icon">
</layout> <iconset resource="resources.qrc">
</item> <normaloff>:/icons/icons/window-minimize.png</normaloff>:/icons/icons/window-minimize.png</iconset>
<item> </property>
<layout class="QVBoxLayout" name="playerPanelLayout"> </widget>
<property name="sizeConstraint"> </item>
<enum>QLayout::SetDefaultConstraint</enum> <item>
</property> <widget class="QPushButton" name="closeWindowBtn">
<property name="rightMargin"> <property name="minimumSize">
<number>10</number> <size>
</property> <width>40</width>
<property name="bottomMargin"> <height>20</height>
<number>10</number> </size>
</property> </property>
<item> <property name="maximumSize">
<widget class="QLabel" name="titleLabel"> <size>
<property name="sizePolicy"> <width>40</width>
<sizepolicy hsizetype="Preferred" vsizetype="Preferred"> <height>20</height>
<horstretch>0</horstretch> </size>
<verstretch>0</verstretch> </property>
</sizepolicy> <property name="text">
</property> <string/>
<property name="text"> </property>
<string>No song loaded...</string> <property name="icon">
</property> <iconset resource="resources.qrc">
</widget> <normaloff>:/icons/icons/window-close.png</normaloff>:/icons/icons/window-close.png</iconset>
</item> </property>
<item> </widget>
<widget class="QLabel" name="propLabel"> </item>
<property name="text"> </layout>
<string>44100 Hz | 233 Kbps | Stereo | MP3</string> </item>
</property> <item>
</widget> <layout class="QVBoxLayout" name="playerPanelLayout">
</item> <property name="sizeConstraint">
<item> <enum>QLayout::SetDefaultConstraint</enum>
<layout class="QHBoxLayout" name="playbackTimeLayout"> </property>
<item> <property name="rightMargin">
<widget class="QLabel" name="nowTimeLabel"> <number>10</number>
<property name="text"> </property>
<string>0:00</string> <property name="bottomMargin">
</property> <number>10</number>
</widget> </property>
</item> <item>
<item> <widget class="QLabel" name="titleLabel">
<widget class="QLabel" name="totalTimeLabel"> <property name="sizePolicy">
<property name="text"> <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<string>0:00</string> <horstretch>0</horstretch>
</property> <verstretch>0</verstretch>
<property name="alignment"> </sizepolicy>
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> </property>
</property> <property name="text">
</widget> <string>No song loaded...</string>
</item> </property>
</layout> </widget>
</item> </item>
<item> <item>
<widget class="SeekableSlider" name="playbackSlider"> <widget class="QLabel" name="propLabel">
<property name="maximum"> <property name="text">
<number>1000</number> <string>44100 Hz | 233 Kbps | Stereo | MP3</string>
</property> </property>
<property name="orientation"> </widget>
<enum>Qt::Horizontal</enum> </item>
</property> <item>
</widget> <layout class="QHBoxLayout" name="playbackTimeLayout">
</item> <item>
<item> <widget class="QLabel" name="nowTimeLabel">
<layout class="QHBoxLayout" name="playbackControlLayout"> <property name="text">
<property name="spacing"> <string>0:00</string>
<number>5</number> </property>
</property> </widget>
<item> </item>
<widget class="QPushButton" name="playBtn"> <item>
<property name="minimumSize"> <widget class="QLabel" name="totalTimeLabel">
<size> <property name="text">
<width>32</width> <string>0:00</string>
<height>32</height> </property>
</size> <property name="alignment">
</property> <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
<property name="maximumSize"> </property>
<size> </widget>
<width>32</width> </item>
<height>32</height> </layout>
</size> </item>
</property> <item>
<property name="locale"> <widget class="SeekableSlider" name="playbackSlider">
<locale language="English" country="UnitedStates"/> <property name="maximum">
</property> <number>1000</number>
<property name="text"> </property>
<string/> <property name="orientation">
</property> <enum>Qt::Horizontal</enum>
<property name="icon"> </property>
<iconset resource="resources.qrc"> </widget>
<normaloff>:/icons/icons/media-playback-start.png</normaloff>:/icons/icons/media-playback-start.png</iconset> </item>
</property> <item>
<property name="iconSize"> <layout class="QHBoxLayout" name="playbackControlLayout">
<size> <property name="spacing">
<width>32</width> <number>5</number>
<height>32</height> </property>
</size> <item>
</property> <widget class="QPushButton" name="playBtn">
</widget> <property name="minimumSize">
</item> <size>
<item> <width>32</width>
<widget class="QPushButton" name="stopBtn"> <height>32</height>
<property name="minimumSize"> </size>
<size> </property>
<width>32</width> <property name="maximumSize">
<height>32</height> <size>
</size> <width>32</width>
</property> <height>32</height>
<property name="maximumSize"> </size>
<size> </property>
<width>32</width> <property name="locale">
<height>32</height> <locale language="English" country="UnitedStates"/>
</size> </property>
</property> <property name="text">
<property name="text"> <string/>
<string/> </property>
</property> <property name="icon">
<property name="icon"> <iconset resource="resources.qrc">
<iconset resource="resources.qrc"> <normaloff>:/icons/icons/media-playback-start.png</normaloff>:/icons/icons/media-playback-start.png</iconset>
<normaloff>:/icons/icons/media-playback-stop.png</normaloff>:/icons/icons/media-playback-stop.png</iconset> </property>
</property> <property name="iconSize">
<property name="iconSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="stopBtn">
<widget class="QPushButton" name="prevBtn"> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string/>
<string/> </property>
</property> <property name="icon">
<property name="icon"> <iconset resource="resources.qrc">
<iconset resource="resources.qrc"> <normaloff>:/icons/icons/media-playback-stop.png</normaloff>:/icons/icons/media-playback-stop.png</iconset>
<normaloff>:/icons/icons/media-skip-backward.png</normaloff>:/icons/icons/media-skip-backward.png</iconset> </property>
</property> <property name="iconSize">
<property name="iconSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="prevBtn">
<widget class="QPushButton" name="nextBtn"> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string/>
<string/> </property>
</property> <property name="icon">
<property name="icon"> <iconset resource="resources.qrc">
<iconset resource="resources.qrc"> <normaloff>:/icons/icons/media-skip-backward.png</normaloff>:/icons/icons/media-skip-backward.png</iconset>
<normaloff>:/icons/icons/media-skip-forward.png</normaloff>:/icons/icons/media-skip-forward.png</iconset> </property>
</property> <property name="iconSize">
<property name="iconSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="nextBtn">
<widget class="QPushButton" name="playListBtn"> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string/>
<string/> </property>
</property> <property name="icon">
<property name="icon"> <iconset resource="resources.qrc">
<iconset resource="resources.qrc"> <normaloff>:/icons/icons/media-skip-forward.png</normaloff>:/icons/icons/media-skip-forward.png</iconset>
<normaloff>:/icons/icons/view-media-playlist.png</normaloff>:/icons/icons/view-media-playlist.png</iconset> </property>
</property> <property name="iconSize">
<property name="iconSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="playListBtn">
<widget class="QPushButton" name="playbackModeBtn"> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string/>
<string/> </property>
</property> <property name="icon">
<property name="icon"> <iconset resource="resources.qrc">
<iconset resource="resources.qrc"> <normaloff>:/icons/icons/view-media-playlist.png</normaloff>:/icons/icons/view-media-playlist.png</iconset>
<normaloff>:/icons/icons/media-playlist-repeat.png</normaloff>:/icons/icons/media-playlist-repeat.png</iconset> </property>
</property> <property name="iconSize">
<property name="iconSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="playbackModeBtn">
<widget class="QPushButton" name="volumeBtn"> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximumSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="text">
<property name="text"> <string/>
<string/> </property>
</property> <property name="icon">
<property name="icon"> <iconset resource="resources.qrc">
<iconset resource="resources.qrc"> <normaloff>:/icons/icons/media-playlist-repeat.png</normaloff>:/icons/icons/media-playlist-repeat.png</iconset>
<normaloff>:/icons/icons/audio-volume-high.png</normaloff>:/icons/icons/audio-volume-high.png</iconset> </property>
</property> <property name="iconSize">
<property name="iconSize"> <size>
<size> <width>32</width>
<width>32</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> </widget>
</widget> </item>
</item> <item>
<item> <widget class="QPushButton" name="volumeBtn">
<widget class="SeekableSlider" name="volumeSlider"> <property name="minimumSize">
<property name="minimumSize"> <size>
<size> <width>32</width>
<width>64</width> <height>32</height>
<height>32</height> </size>
</size> </property>
</property> <property name="maximumSize">
<property name="maximum"> <size>
<number>100</number> <width>32</width>
</property> <height>32</height>
<property name="value"> </size>
<number>100</number> </property>
</property> <property name="text">
<property name="orientation"> <string/>
<enum>Qt::Horizontal</enum> </property>
</property> <property name="icon">
</widget> <iconset resource="resources.qrc">
</item> <normaloff>:/icons/icons/audio-volume-high.png</normaloff>:/icons/icons/audio-volume-high.png</iconset>
</layout> </property>
</item> <property name="iconSize">
</layout> <size>
</item> <width>32</width>
</layout> <height>32</height>
</item> </size>
</layout> </property>
</widget>
</item>
<item>
<widget class="SeekableSlider" name="volumeSlider">
<property name="minimumSize">
<size>
<width>64</width>
<height>32</height>
</size>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="value">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QWidget" name="pluginWidget" native="true">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</widget>
</item> </item>
</layout> </layout>
</widget> </widget>

174
playlistmodel.cpp Normal file
View File

@ -0,0 +1,174 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include "playlistmodel.h"
#include <QFileInfo>
#include <QUrl>
#include <QMediaPlaylist>
PlaylistModel::PlaylistModel(QObject *parent)
: QAbstractItemModel(parent)
{
}
PlaylistModel::~PlaylistModel()
{
}
int PlaylistModel::rowCount(const QModelIndex &parent) const
{
return m_playlist && !parent.isValid() ? m_playlist->mediaCount() : 0;
}
int PlaylistModel::columnCount(const QModelIndex &parent) const
{
return !parent.isValid() ? ColumnCount : 0;
}
QModelIndex PlaylistModel::index(int row, int column, const QModelIndex &parent) const
{
return m_playlist && !parent.isValid()
&& row >= 0 && row < m_playlist->mediaCount()
&& column >= 0 && column < ColumnCount
? createIndex(row, column)
: QModelIndex();
}
QModelIndex PlaylistModel::parent(const QModelIndex &child) const
{
Q_UNUSED(child);
return QModelIndex();
}
QVariant PlaylistModel::data(const QModelIndex &index, int role) const
{
if (index.isValid() && role == Qt::DisplayRole) {
QVariant value = m_data[index];
if (!value.isValid() && index.column() == Title) {
#if QT_VERSION < QT_VERSION_CHECK(5, 14, 0)
QUrl location = m_playlist->media(index.row()).canonicalUrl();
#else
QUrl location = m_playlist->media(index.row()).request().url();
#endif
return QFileInfo(location.path()).fileName();
}
return value;
}
return QVariant();
}
QMediaPlaylist *PlaylistModel::playlist() const
{
return m_playlist.data();
}
void PlaylistModel::setPlaylist(QMediaPlaylist *playlist)
{
if (m_playlist) {
disconnect(m_playlist.data(), &QMediaPlaylist::mediaAboutToBeInserted, this, &PlaylistModel::beginInsertItems);
disconnect(m_playlist.data(), &QMediaPlaylist::mediaInserted, this, &PlaylistModel::endInsertItems);
disconnect(m_playlist.data(), &QMediaPlaylist::mediaAboutToBeRemoved, this, &PlaylistModel::beginRemoveItems);
disconnect(m_playlist.data(), &QMediaPlaylist::mediaRemoved, this, &PlaylistModel::endRemoveItems);
disconnect(m_playlist.data(), &QMediaPlaylist::mediaChanged, this, &PlaylistModel::changeItems);
}
beginResetModel();
m_playlist.reset(playlist);
if (m_playlist) {
connect(m_playlist.data(), &QMediaPlaylist::mediaAboutToBeInserted, this, &PlaylistModel::beginInsertItems);
connect(m_playlist.data(), &QMediaPlaylist::mediaInserted, this, &PlaylistModel::endInsertItems);
connect(m_playlist.data(), &QMediaPlaylist::mediaAboutToBeRemoved, this, &PlaylistModel::beginRemoveItems);
connect(m_playlist.data(), &QMediaPlaylist::mediaRemoved, this, &PlaylistModel::endRemoveItems);
connect(m_playlist.data(), &QMediaPlaylist::mediaChanged, this, &PlaylistModel::changeItems);
}
endResetModel();
}
bool PlaylistModel::setData(const QModelIndex &index, const QVariant &value, int role)
{
Q_UNUSED(role);
m_data[index] = value;
emit dataChanged(index, index);
return true;
}
void PlaylistModel::beginInsertItems(int start, int end)
{
m_data.clear();
beginInsertRows(QModelIndex(), start, end);
}
void PlaylistModel::endInsertItems()
{
endInsertRows();
}
void PlaylistModel::beginRemoveItems(int start, int end)
{
m_data.clear();
beginRemoveRows(QModelIndex(), start, end);
}
void PlaylistModel::endRemoveItems()
{
endInsertRows();
}
void PlaylistModel::changeItems(int start, int end)
{
m_data.clear();
emit dataChanged(index(start,0), index(end,ColumnCount));
}

99
playlistmodel.h Normal file
View File

@ -0,0 +1,99 @@
/****************************************************************************
**
** Copyright (C) 2017 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#ifndef PLAYLISTMODEL_H
#define PLAYLISTMODEL_H
#include <QAbstractItemModel>
#include <QScopedPointer>
class QMediaPlaylist;
class PlaylistModel : public QAbstractItemModel
{
Q_OBJECT
public:
enum Column
{
Title = 0,
ColumnCount
};
explicit PlaylistModel(QObject *parent = nullptr);
~PlaylistModel();
int rowCount(const QModelIndex &parent = QModelIndex()) const override;
int columnCount(const QModelIndex &parent = QModelIndex()) const override;
QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
QModelIndex parent(const QModelIndex &child) const override;
QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const override;
QMediaPlaylist *playlist() const;
void setPlaylist(QMediaPlaylist *playlist);
bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::DisplayRole) override;
private slots:
void beginInsertItems(int start, int end);
void endInsertItems();
void beginRemoveItems(int start, int end);
void endRemoveItems();
void changeItems(int start, int end);
private:
QScopedPointer<QMediaPlaylist> m_playlist;
QMap<QModelIndex, QVariant> m_data;
};
#endif // PLAYLISTMODEL_H