feat: single app with local socket

This commit is contained in:
Gary Wang 2020-04-11 19:54:51 +08:00
parent 099284d5d4
commit 14d20fd925
6 changed files with 147 additions and 20 deletions

View File

@ -25,6 +25,8 @@ add_executable(${EXE_NAME}
seekableslider.h seekableslider.h
playlistmodel.h playlistmodel.h
playlistmodel.cpp playlistmodel.cpp
singleapplicationmanager.h
singleapplicationmanager.cpp
mainwindow.ui mainwindow.ui
resources.qrc resources.qrc

View File

@ -1,8 +1,11 @@
#include "mainwindow.h" #include "mainwindow.h"
#include "singleapplicationmanager.h"
#include <QApplication> #include <QApplication>
#include <QCommandLineParser> #include <QCommandLineParser>
#include <QUrl> #include <QUrl>
#include <QDebug>
int main(int argc, char *argv[]) int main(int argc, char *argv[])
{ {
@ -16,20 +19,22 @@ int main(int argc, char *argv[])
parser.process(a); parser.process(a);
QStringList urlStrList = parser.positionalArguments(); QStringList urlStrList = parser.positionalArguments();
QList<QUrl> urlList;
for (const QString & str : urlStrList) { SingleApplicationManager sam("_pineapple_music_owo_");
QUrl url = QUrl::fromLocalFile(str); if (sam.checkSingleInstance(QVariant::fromValue(urlStrList))) {
if (url.isValid()) { return 0;
urlList.append(url); } else {
} sam.createSingleInstance();
} }
MainWindow w; MainWindow w;
w.show(); w.show();
if (!urlList.isEmpty()) { if (!urlStrList.isEmpty()) {
w.commandlinePlayAudioFiles(urlList); w.commandlinePlayAudioFiles(urlStrList);
} }
QObject::connect(&sam, &SingleApplicationManager::dataReached, &w, &MainWindow::localSocketPlayAudioFiles);
return a.exec(); return a.exec();
} }

View File

@ -40,13 +40,15 @@ MainWindow::~MainWindow()
delete ui; delete ui;
} }
void MainWindow::commandlinePlayAudioFiles(QList<QUrl> audioFiles) void MainWindow::commandlinePlayAudioFiles(QStringList audioFiles)
{ {
if (!audioFiles.isEmpty()) { QList<QUrl> audioFileUrls = strlst2urllst(audioFiles);
if (audioFiles.count() == 1) {
loadPlaylistBySingleLocalFile(audioFiles.first().toLocalFile()); if (!audioFileUrls.isEmpty()) {
if (audioFileUrls.count() == 1) {
loadPlaylistBySingleLocalFile(audioFileUrls.first().toLocalFile());
} else { } else {
createPlaylist(audioFiles); createPlaylist(audioFileUrls);
} }
m_mediaPlayer->play(); m_mediaPlayer->play();
} }
@ -79,6 +81,17 @@ void MainWindow::loadPlaylistBySingleLocalFile(const QString &path)
playlist->setCurrentIndex(currentFileIndex); playlist->setCurrentIndex(currentFileIndex);
} }
void MainWindow::localSocketPlayAudioFiles(QVariant audioFilesVariant)
{
QStringList urlStrList = audioFilesVariant.toStringList();
qDebug() << urlStrList << "MainWindow::localSocketPlayAudioFiles";
commandlinePlayAudioFiles(urlStrList);
showNormal();
activateWindow();
raise();
}
void MainWindow::closeEvent(QCloseEvent *) void MainWindow::closeEvent(QCloseEvent *)
{ {
qApp->exit(); qApp->exit();
@ -172,12 +185,14 @@ void MainWindow::loadFile()
*/ */
QMediaPlaylist *MainWindow::createPlaylist(QList<QUrl> urlList) QMediaPlaylist *MainWindow::createPlaylist(QList<QUrl> urlList)
{ {
if (m_mediaPlayer->playlist()) { QMediaPlaylist * oldPlaylist = m_mediaPlayer->playlist();
m_mediaPlayer->playlist()->disconnect();
}
QMediaPlaylist * playlist = new QMediaPlaylist(m_mediaPlayer); QMediaPlaylist * playlist = new QMediaPlaylist(m_mediaPlayer);
if (oldPlaylist) {
oldPlaylist->disconnect();
oldPlaylist->deleteLater();
}
for (const QUrl & url : urlList) { for (const QUrl & url : urlList) {
bool succ = playlist->addMedia(QMediaContent(url)); bool succ = playlist->addMedia(QMediaContent(url));
if (!succ) { if (!succ) {
@ -253,6 +268,19 @@ QString MainWindow::ms2str(qint64 ms)
} }
} }
QList<QUrl> MainWindow::strlst2urllst(QStringList strlst)
{
QList<QUrl> urlList;
for (const QString & str : strlst) {
QUrl url = QUrl::fromLocalFile(str);
if (url.isValid()) {
urlList.append(url);
}
}
return urlList;
}
void MainWindow::on_volumeSlider_valueChanged(int value) void MainWindow::on_volumeSlider_valueChanged(int value)
{ {
if (m_mediaPlayer->isMuted()) { if (m_mediaPlayer->isMuted()) {

View File

@ -2,6 +2,7 @@
#define MAINWINDOW_H #define MAINWINDOW_H
#include <QMainWindow> #include <QMainWindow>
#include <QVariant>
QT_BEGIN_NAMESPACE QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; } namespace Ui { class MainWindow; }
@ -20,9 +21,12 @@ public:
MainWindow(QWidget *parent = nullptr); MainWindow(QWidget *parent = nullptr);
~MainWindow() override; ~MainWindow() override;
void commandlinePlayAudioFiles(QList<QUrl> audioFiles); void commandlinePlayAudioFiles(QStringList audioFiles);
void loadPlaylistBySingleLocalFile(const QString &path); void loadPlaylistBySingleLocalFile(const QString &path);
public slots:
void localSocketPlayAudioFiles(QVariant audioFilesVariant);
protected: protected:
void closeEvent(QCloseEvent *) override; void closeEvent(QCloseEvent *) override;
void paintEvent(QPaintEvent *e) override; void paintEvent(QPaintEvent *e) override;
@ -38,8 +42,6 @@ protected:
private slots: private slots:
void on_playbackModeBtn_clicked(); void on_playbackModeBtn_clicked();
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);
@ -66,5 +68,6 @@ private:
void initConnections(); void initConnections();
static QString ms2str(qint64 ms); static QString ms2str(qint64 ms);
static QList<QUrl> strlst2urllst(QStringList strlst);
}; };
#endif // MAINWINDOW_H #endif // MAINWINDOW_H

View File

@ -0,0 +1,57 @@
#include "singleapplicationmanager.h"
#include <QDataStream>
#include <QLocalServer>
#include <QLocalSocket>
SingleApplicationManager::SingleApplicationManager(QString applicationKey, QObject *parent)
: QObject(parent)
, m_applicationKey(applicationKey)
{
}
void SingleApplicationManager::on_localSocket_newConnection()
{
QScopedPointer<QLocalSocket> socket(m_localServer->nextPendingConnection());
if (socket) {
socket->waitForReadyRead(500);
QDataStream dataStream(socket.data());
QVariant data;
dataStream.startTransaction();
dataStream >> data;
dataStream.commitTransaction();
emit dataReached(data);
}
}
void SingleApplicationManager::createSingleInstance()
{
m_localServer = new QLocalServer(this);
connect(m_localServer, &QLocalServer::newConnection, this, &SingleApplicationManager::on_localSocket_newConnection);
if (!m_localServer->listen(m_applicationKey)) {
if (m_localServer->serverError() == QAbstractSocket::AddressInUseError) {
QLocalServer::removeServer(m_applicationKey);
m_localServer->listen(m_applicationKey);
}
}
}
bool SingleApplicationManager::checkSingleInstance(QVariant data)
{
QLocalSocket socket;
socket.connectToServer(m_applicationKey);
if (socket.waitForConnected(500)) {
QDataStream dataStream(&socket);
dataStream << data;
socket.waitForBytesWritten();
socket.close();
return true;
}
return false;
}

View File

@ -0,0 +1,32 @@
#ifndef SINGLEAPPLICATIONMANAGER_H
#define SINGLEAPPLICATIONMANAGER_H
#include <QObject>
QT_BEGIN_NAMESPACE
class QLocalServer;
QT_END_NAMESPACE
class SingleApplicationManager : public QObject
{
Q_OBJECT
public:
explicit SingleApplicationManager(QString applicationKey, QObject *parent = nullptr);
void createSingleInstance();
bool checkSingleInstance(QVariant data);
signals:
void dataReached(QVariant data);
private slots:
void on_localSocket_newConnection();
private:
QString m_applicationKey;
QLocalServer * m_localServer;
};
#endif // SINGLEAPPLICATIONMANAGER_H