aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp183
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h67
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro140
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/main.cpp30
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp160
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h62
-rw-r--r--src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui310
7 files changed, 800 insertions, 152 deletions
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp
index 667ebefb..19b6b99b 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp
@@ -10,64 +10,114 @@
#include <QDir>
#include <QFile>
#include <QTextStream>
-
+#include <QApplication>
#include <LUtils.h>
PianoBarProcess::PianoBarProcess(QWidget *parent) : QObject(parent){
setupProcess();
-
+ saveTimer = new QTimer(this);
+ saveTimer->setInterval(100); //1/10 second (just enough to change a few settings at once before dumping to disk)
+ saveTimer->setSingleShot(true);
+ connect(saveTimer, SIGNAL(timeout()), this, SLOT(saveSettingsFile()) );
+ if( !loadSettings() ){ GenerateSettings(); }
}
PianoBarProcess::~PianoBarProcess(){
-
+ if(PROC->state()!=QProcess::NotRunning){
+ PROC->kill();
+ }
}
// ===== PUBLIC ======
//Interaction functions
-bool PianoBarProcess::isSetup(); //email/password already saved for use or not
-void PianoBarProcess::setLogin(QString email, QString pass);
-void PianoBarProcess::closePianoBar(); //"q"
+bool PianoBarProcess::isSetup(){ //email/password already saved for use or not
+ return !(settingValue("user").isEmpty() || settingValue("password").isEmpty());
+}
-QString PianoBarProcess::currentStation(); //Re-direct for the "autostartStation()" function;
-QStringList PianoBarProcess::stations();
-void PianoBarProcess::setCurrentStation(QString station);
+void PianoBarProcess::setLogin(QString email, QString pass){
+ setSettingValue("user",email);
+ setSettingValue("password",pass);
+}
+
+QString PianoBarProcess::email(){
+ return settingValue("user");
+}
+
+QString PianoBarProcess::password(){
+ return settingValue("password");
+}
+
+void PianoBarProcess::closePianoBar(){ //"q"
+ sendToProcess("q");
+}
+
+QString PianoBarProcess::currentStation(){ return cstation; }
+QStringList PianoBarProcess::stations(){ return stationList; }
+void PianoBarProcess::setCurrentStation(QString station){
+ cstation = station;
+ sendToProcess("s");
+}
-void PianoBarProcess::deleteCurrentStation(); //"d"
-void PianoBarProcess::createNewStation(); //"c"
-void PianoBarProcess::createStationFromCurrentSong(); //"v"
-void PianoBarProcess::changeStation(); //"s"
+void PianoBarProcess::deleteCurrentStation(){ //"d" -> "y"
+ if(cstation == "QuickMix" || cstation=="Thumbprint Radio"){ return; } //cannot delete these stations - provided by Pandora itself
+ sendToProcess("d"); //delete current station
+ sendToProcess("y"); //yes, we want to delete it
+ //Now need to automatically change to another station
+ setCurrentStation("QuickMix"); //this is always a valid station
+}
+
+//void PianoBarProcess::createNewStation(); //"c"
+void PianoBarProcess::createStationFromCurrentSong(){ //"v" -> "s"
+ sendToProcess("v");
+ sendToProcess("s");
+}
+
+void PianoBarProcess::createStationFromCurrentArtist(){ //"v" -> "a"
+ sendToProcess("v");
+ sendToProcess("a");
+}
//Settings Manipulation
QString PianoBarProcess::audioQuality(){ // "audio_quality" = [low, medium, high]
-
+ return settingValue("audio_quality");
}
-void PianoBarProcess::setAudioQuality(QString); // [low, medium, high]
-QString PianoBarProcess::autostartStation(); //"autostart_station" = ID
-void PianoBarProcess::setAutostartStation(QString);
-QString PianoBarProcess::proxy(); //"proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
-void PianoBarProcess::setProxy(QString);
-QString PianoBarProcess::controlProxy(); //"control_proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
-void PianoBarProcess::setControlProxy(QString);
+void PianoBarProcess::setAudioQuality(QString val){ // [low, medium, high]
+ setSettingValue("audio_quality",val);
+}
-// ====== PUBLIC SLOTS ======
-void PianoBarProcess::play(); // "P"
-void PianoBarProcess::pause(); //"S"
+QString PianoBarProcess::autostartStation(){ //"autostart_station" = ID
+ return settingValue("autostart_station");
+}
+
+void PianoBarProcess::setAutostartStation(QString id){
+ setSettingValue("autostart_station", id);
+}
-void PianoBarProcess::volumeDown(); //"("
-void PianoBarProcess::volumeUp(); //")"
+QString PianoBarProcess::proxy(){ //"proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
+ return settingValue("proxy");
+}
-void PianoBarProcess::skipSong(); //"n"
-void PianoBarProcess::loveSong(); // "+"
-void PianoBarProcess::tiredSong(); // "t"
-void PianoBarProcess::banSong(); //"-"
-void PianoBarProcess::bookmarkSong(); //"b"
+void PianoBarProcess::setProxy(QString url){
+ setSettingValue("proxy",url);
+}
-void PianoBarProcess::explainSong(); //"e"
+QString PianoBarProcess::controlProxy(){ //"control_proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
+ return settingValue("control_proxy");
+}
-void PianoBarProcess::requestHistory(); // "h"
-void PianoBarProcess::requestSongInfo(); //"i"
-void PianoBarProcess::requestUpcoming(); //"u"
+void PianoBarProcess::setControlProxy(QString url){
+ setSettingValue("control_proxy", url);
+}
+
+// ====== PUBLIC SLOTS ======
+void PianoBarProcess::play(){
+ if(PROC->state() == QProcess::NotRunning){
+ PROC->start();
+ }else{
+ sendToProcess("P");
+ }
+}
// ====== PRIVATE ======
void PianoBarProcess::GenerateSettings(){
@@ -76,17 +126,20 @@ void PianoBarProcess::GenerateSettings(){
currentSettings << "format_list_song = %r::::%t::::%a"; //[rating, title, artist]
currentSettings << "format_nowplaying_song = %r::::%t::::%a::::%l::::%u::::%s"; // [rating, title, artist, album, details url, station (if not quickmix)]
currentSettings << "format_nowplaying_station = %n::::%i"; //[name, id]
+ saveSettingsFile(); //save this to disk *now* - needed before starting the pianobar process
}
-void PianoBarProcess::loadSettings(){
+bool PianoBarProcess::loadSettings(){
currentSettings.clear();
- QFile file(settingspath);
- if(!file.exists()){ return; }
+ QFile file(settingsPath);
+ if(!file.exists()){ return false; }
if(file.open(QIODevice::ReadOnly)){
QTextStream in(&file);
currentSettings = in.readAll().split("\n");
file.close();
+ return true;
}
+ return false;
}
QString PianoBarProcess::settingValue(QString var){
@@ -102,14 +155,15 @@ void PianoBarProcess::setSettingValue(QString var,QString val){
if(currentSettings[i].startsWith(var+" = ")){ currentSettings[i] = var+" = "+val; changed = true; }
}
if(!changed){ currentSettings << var+" = "+val; }
+ saveTimer->start(); //save this to disk in a moment
}
void PianoBarProcess::saveSettingsFile(){
//Ensure the parent directory exists first
- QDir dir(settingspath.section("/",0,-2));
+ QDir dir(settingsPath.section("/",0,-2));
if(!dir.exists()){ dir.mkpath(dir.absolutePath()); }
//Now save the settings
- QFile file(settingspath);
+ QFile file(settingsPath);
if(file.open(QIODevice::WriteOnly | QIODevice::Truncate)){
QTextStream out(&file);
out << currentSettings.join("\n");
@@ -125,7 +179,7 @@ void PianoBarProcess::setupProcess(){
else{ configdir.append("/lumina-desktop"); }
QProcessEnvironment penv;
penv.insert("XDG_CONFIG_HOME",configdir);
- settingspath = configdir+"/pianobar/config";
+ settingsPath = configdir+"/pianobar/config";
PROC->setProcessEnvironment(penv);
//Now setup the rest of the process
PROC->setProcessChannelMode(QProcess::MergedChannels);
@@ -135,18 +189,41 @@ void PianoBarProcess::setupProcess(){
connect(PROC, SIGNAL(readyRead()), this, SLOT(ProcUpdate()) );
}
+void PianoBarProcess::sendToProcess(QString txt){
+ if(PROC->state()==QProcess::Running){
+ PROC->write( QString(txt+"\r\n").toLocal8Bit() );
+ }
+}
+
// ====== PRIVATE SLOTS ======
void PianoBarProcess::ProcUpdate(){
- QStringList info = QString(PROC->readAllStandardOutput()).split("\n");
+ QString tmp = QString(PROC->readAllStandardOutput()).replace("\r","\n").remove("\u001B[2K");
+ QStringList info = tmp.split("\n",QString::SkipEmptyParts);
+
//NOTE: Need to have a cache of info lines which can carry over between updates as needed (for questions, etc)
- qDebug() << "Got Update:" << info;
+ //qDebug() << "Got Update:" << info;
for(int i=0; i<info.length(); i++){
+ //First handle any pending cache of listing lines
+ if((info[i].startsWith("\t")||info[i].startsWith(" ")) && info[i].contains(")")){
+ if(info[i].simplified().startsWith("0) ")){ infoList.clear(); }
+ infoList << info[i].section(") ",1,-1).simplified();
+ continue; //done handling this line
+ }else if(!info[i].startsWith("[?]") && !infoList.isEmpty()){
+ emit NewList(infoList);
+ infoList.clear();
+ }
+ //Now parse the lines for messages/etc
if(info[i].startsWith("|>")){
//Now playing line (station, or song)
QStringList data = info[i].section(">",1,-1).simplified().split("::::"); //Make sure to chop the line prefix off first
if(data.length()==2){ //station
cstation = data[0]; //save the name for later
emit NowPlayingStation(data[0], data[1]);
+ if(stationList.isEmpty()){
+ //Need to prompt to list all the available stations
+ sendToProcess("s");
+ sendToProcess(""); //empty line - canceles the prompt
+ }
//Automatically save this station for autostart next time (make toggle-able later)
if(data[1]!=autostartStation()){ setAutostartStation(data[1]); }
@@ -156,12 +233,18 @@ void PianoBarProcess::ProcUpdate(){
}else if(info[i].startsWith("(i) ")){ //informational line
emit NewInformation(info[i].section(" ",1,-1));
}else if(info[i].startsWith("[?] ")){ //waiting for reply to question
- if(info[i].contains("Select Station:"){
- //Find the number before this line which corresponds to the cstation variable/name
- for(j=i-1; j>=0; j--){
- if(info[j].contains(")" && info[j].contains(cstation) ){
- PROC->write(info[j].section(")",0,0).simplified() + "\r\n");
+ //qDebug() << "Got Question:" << info[i] << infoList;
+ if(info[i].contains("Select station:")){
+ stationList = infoList; //save this list for later
+ infoList.clear();
+ emit StationListChanged(stationList);
+ //Find the station number which corresponds to the cstation variable/name
+ for(int i=0; i<stationList.length(); i++){
+ if(stationList.endsWith(cstation) ){
+ sendToProcess(QString::number(i));
break;
+ }else if(i==stationList.length()-1){
+ sendToProcess(QString::number(stationList.length()-1));
}
}
}
@@ -169,9 +252,9 @@ void PianoBarProcess::ProcUpdate(){
}else if(info[i].startsWith("#")){
//Time Stamp
QTime stamp = QTime::fromString(info[i].section("/",0,0).section("-",1,-1), "mm:ss");
- int curS = 60*stamp.minutes() + stamp.seconds(); //time remaining
+ int curS = 60*stamp.minute() + stamp.second(); //time remaining
stamp = QTime::fromString(info[i].section("/",1,-1), "mm:ss");
- int totS = 60*stamp.minutes() + stamp.sections(); //time total
+ int totS = 60*stamp.minute() + stamp.second(); //time total
emit TimeUpdate(totS-curS, totS);
}
}
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h
index 83404e0c..77df3309 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h
@@ -13,7 +13,7 @@
#include <QObject>
#include <QWidget>
#include <QProcess>
-
+#include <QTimer>
// #define PIANOBAR_FIFO QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/pianobar/ctl"
// #define PIANOBAR_CONFIG QString(getenv("XDG_CONFIG_HOME"))+"/lumina-desktop/pianobar/config"
@@ -31,6 +31,9 @@ public:
//Interaction functions
bool isSetup(); //email/password already saved for use or not
void setLogin(QString email, QString pass);
+ QString email();
+ QString password();
+
void closePianoBar(); //"q"
QString currentStation(); //Re-direct for the "autostartStation()" function;
@@ -38,9 +41,9 @@ public:
void setCurrentStation(QString station);
void deleteCurrentStation(); //"d"
- void createNewStation(); //"c"
- void createStationFromCurrentSong(); //"v"
- void changeStation(); //"s"
+ //void createNewStation(); //"c"
+ void createStationFromCurrentSong(); //"v" -> "s"
+ void createStationFromCurrentArtist(); //"v" -> "a"
//Settings Manipulation
QString audioQuality(); // "audio_quality" = [low, medium, high]
@@ -52,52 +55,58 @@ public:
QString controlProxy(); //"control_proxy" = URL (example: "http://USER:PASSWORD@HOST:PORT/" )
void setControlProxy(QString);
-public slots:
- void play(); // "P"
- void pause(); //"S"
-
- void volumeDown(); //"("
- void volumeUp(); //")"
-
- void skipSong(); //"n"
- void loveSong(); // "+"
- void tiredSong(); // "t"
- void banSong(); //"-"
- void bookmarkSong(); //"b"
-
- void explainSong(); //"e"
-
- void requestHistory(); // "h"
- void requestSongInfo(); //"i"
- void requestUpcoming(); //"u"
-
-
private:
//Process
- QProcess PROC;
+ QProcess *PROC;
+ QStringList infoList;
void setupProcess();
+ void sendToProcess(QString);
//Settings file management
QStringList currentSettings; //cache of the settings file (file is really small);
QString settingsPath; //location of the settings file
+ QTimer *saveTimer;
void GenerateSettings();
- void loadSettings();
+ bool loadSettings();
QString settingValue(QString);
void setSettingValue(QString,QString);
- void saveSettingsFile();
+
//Cached Info
QString cstation; //current station
- QStringList stationNames;
+ QStringList stationList;
+
+public slots:
+ void play(); // "P"
+ void pause(){ sendToProcess("S"); } //"S"
+
+ void volumeDown(){ sendToProcess("("); } //"("
+ void volumeUp(){ sendToProcess(")"); } //")"
+
+ void skipSong(){ sendToProcess("n"); } //"n"
+ void loveSong(){ sendToProcess("+"); } // "+"
+ void tiredSong(){ sendToProcess("t"); } // "t"
+ void banSong(){ sendToProcess("-"); } //"-"
+ void bookmarkSong(){ sendToProcess("b"); sendToProcess("s"); } //"b"->"s"
+ void bookmarkArtist(){ sendToProcess("b"); sendToProcess("a"); } //"b"->"a"
+
+ void explainSong(){ sendToProcess("e"); } //"e"
+
+ void requestHistory(){ sendToProcess("h"); } // "h" NOTE: Long series of interactive prompts - better to avoid for now
+ void requestSongInfo(){ sendToProcess("i"); } //"i" NOTE: This will re-print the current station/song information
+ void requestUpcoming(){ sendToProcess("u"); } //"u" NOTE: This will often return "(i) No songs in queue" - best to run this after a "Receiving new playlist" info message
private slots:
void ProcUpdate();
-
+ void saveSettingsFile();
signals:
void NewInformation(QString); //random status updates/information
void NowPlayingStation(QString, QString); //[name, id]
void NowPlayingSong(bool, QString,QString,QString, QString, QString); //[isLoved, title, artist, album, detailsURL, fromStation]
void TimeUpdate(int, int); //[current secs, total secs];
+ void NewList(QStringList); //arranged in order: 0-end
+ void StationListChanged(QStringList);
+ void currentStateChanged(PianoBarProcess::State);
};
#endif
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
index 7d91b770..dd8a14d6 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro
@@ -1,88 +1,90 @@
include("$${PWD}/../../OS-detect.pri")
-QT += core gui
-greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent
+QT += core gui widgets multimedia multimediawidgets svg
TARGET = lumina-mediaplayer
-TEMPLATE = app
-
-
target.path = $${L_BINDIR}
+TEMPLATE = app
+
#include all the special classes from the Lumina tree
include(../../core/libLumina/LUtils.pri) #includes LUtils
include(../../core/libLumina/LuminaXDG.pri)
+include(../../core/libLumina/LuminaSingleApplication.pri)
+include(../../core/libLumina/LuminaThemes.pri)
SOURCES += main.cpp\
- mainUI.cpp
+ mainUI.cpp \
+ PianoBarProcess.cpp
-HEADERS += mainUI.h
+HEADERS += mainUI.h \
+ PianoBarProcess.h
FORMS += mainUI.ui
-TRANSLATIONS = i18nl-mediap_af.ts \
- i18nl-mediap_ar.ts \
- i18nl-mediap_az.ts \
- i18nl-mediap_bg.ts \
- i18nl-mediap_bn.ts \
- i18nl-mediap_bs.ts \
- i18nl-mediap_ca.ts \
- i18nl-mediap_cs.ts \
- i18nl-mediap_cy.ts \
- i18nl-mediap_da.ts \
- i18nl-mediap_de.ts \
- i18nl-mediap_el.ts \
- i18nl-mediap_en_GB.ts \
- i18nl-mediap_en_ZA.ts \
- i18nl-mediap_es.ts \
- i18nl-mediap_et.ts \
- i18nl-mediap_eu.ts \
- i18nl-mediap_fa.ts \
- i18nl-mediap_fi.ts \
- i18nl-mediap_fr.ts \
- i18nl-mediap_fr_CA.ts \
- i18nl-mediap_gl.ts \
- i18nl-mediap_he.ts \
- i18nl-mediap_hi.ts \
- i18nl-mediap_hr.ts \
- i18nl-mediap_hu.ts \
- i18nl-mediap_id.ts \
- i18nl-mediap_is.ts \
- i18nl-mediap_it.ts \
- i18nl-mediap_ja.ts \
- i18nl-mediap_ka.ts \
- i18nl-mediap_ko.ts \
- i18nl-mediap_lt.ts \
- i18nl-mediap_lv.ts \
- i18nl-mediap_mk.ts \
- i18nl-mediap_mn.ts \
- i18nl-mediap_ms.ts \
- i18nl-mediap_mt.ts \
- i18nl-mediap_nb.ts \
- i18nl-mediap_nl.ts \
- i18nl-mediap_pa.ts \
- i18nl-mediap_pl.ts \
- i18nl-mediap_pt.ts \
- i18nl-mediap_pt_BR.ts \
- i18nl-mediap_ro.ts \
- i18nl-mediap_ru.ts \
- i18nl-mediap_sk.ts \
- i18nl-mediap_sl.ts \
- i18nl-mediap_sr.ts \
- i18nl-mediap_sv.ts \
- i18nl-mediap_sw.ts \
- i18nl-mediap_ta.ts \
- i18nl-mediap_tg.ts \
- i18nl-mediap_th.ts \
- i18nl-mediap_tr.ts \
- i18nl-mediap_uk.ts \
- i18nl-mediap_uz.ts \
- i18nl-mediap_vi.ts \
- i18nl-mediap_zh_CN.ts \
- i18nl-mediap_zh_HK.ts \
- i18nl-mediap_zh_TW.ts \
- i18nl-mediap_zu.ts
+TRANSLATIONS = i18n/l-mediap_af.ts \
+ i18n/l-mediap_ar.ts \
+ i18n/l-mediap_az.ts \
+ i18n/l-mediap_bg.ts \
+ i18n/l-mediap_bn.ts \
+ i18n/l-mediap_bs.ts \
+ i18n/l-mediap_ca.ts \
+ i18n/l-mediap_cs.ts \
+ i18n/l-mediap_cy.ts \
+ i18n/l-mediap_da.ts \
+ i18n/l-mediap_de.ts \
+ i18n/l-mediap_el.ts \
+ i18n/l-mediap_en_GB.ts \
+ i18n/l-mediap_en_ZA.ts \
+ i18n/l-mediap_es.ts \
+ i18n/l-mediap_et.ts \
+ i18n/l-mediap_eu.ts \
+ i18n/l-mediap_fa.ts \
+ i18n/l-mediap_fi.ts \
+ i18n/l-mediap_fr.ts \
+ i18n/l-mediap_fr_CA.ts \
+ i18n/l-mediap_gl.ts \
+ i18n/l-mediap_he.ts \
+ i18n/l-mediap_hi.ts \
+ i18n/l-mediap_hr.ts \
+ i18n/l-mediap_hu.ts \
+ i18n/l-mediap_id.ts \
+ i18n/l-mediap_is.ts \
+ i18n/l-mediap_it.ts \
+ i18n/l-mediap_ja.ts \
+ i18n/l-mediap_ka.ts \
+ i18n/l-mediap_ko.ts \
+ i18n/l-mediap_lt.ts \
+ i18n/l-mediap_lv.ts \
+ i18n/l-mediap_mk.ts \
+ i18n/l-mediap_mn.ts \
+ i18n/l-mediap_ms.ts \
+ i18n/l-mediap_mt.ts \
+ i18n/l-mediap_nb.ts \
+ i18n/l-mediap_nl.ts \
+ i18n/l-mediap_pa.ts \
+ i18n/l-mediap_pl.ts \
+ i18n/l-mediap_pt.ts \
+ i18n/l-mediap_pt_BR.ts \
+ i18n/l-mediap_ro.ts \
+ i18n/l-mediap_ru.ts \
+ i18n/l-mediap_sk.ts \
+ i18n/l-mediap_sl.ts \
+ i18n/l-mediap_sr.ts \
+ i18n/l-mediap_sv.ts \
+ i18n/l-mediap_sw.ts \
+ i18n/l-mediap_ta.ts \
+ i18n/l-mediap_tg.ts \
+ i18n/l-mediap_th.ts \
+ i18n/l-mediap_tr.ts \
+ i18n/l-mediap_uk.ts \
+ i18n/l-mediap_uz.ts \
+ i18n/l-mediap_vi.ts \
+ i18n/l-mediap_zh_CN.ts \
+ i18n/l-mediap_zh_HK.ts \
+ i18n/l-mediap_zh_TW.ts \
+ i18n/l-mediap_zu.ts
dotrans.path=$${L_SHAREDIR}/lumina-desktop/i18n/
dotrans.extra=cd i18n && $${LRELEASE} -nounfinished *.ts && cp *.qm $(INSTALL_ROOT)$${L_SHAREDIR}/lumina-desktop/i18n/
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/main.cpp b/src-qt5/desktop-utils/lumina-mediaplayer/main.cpp
new file mode 100644
index 00000000..9eebff9f
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/main.cpp
@@ -0,0 +1,30 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include <QApplication>
+#include <QDebug>
+
+#include <LuminaThemes.h>
+#include <LUtils.h>
+#include <LuminaSingleApplication.h>
+
+#include "mainUI.h"
+
+int main(int argc, char *argv[]) {
+ LTHEME::LoadCustomEnvSettings();
+ LSingleApplication a(argc, argv, "l-mediap");
+ //Now go ahead and setup the app
+ QStringList args;
+ for(int i=1; i<argc; i++){
+ if( QString(argv[i]).startsWith("--") ){ args << QString(argv[i]); }
+ else{ args << LUtils::PathToAbsolute( QString(argv[i]) ); }
+ }
+ //Now start the window
+ MainUI W;
+ W.loadArguments(args);
+ W.show();
+ return a.exec();
+}
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp
new file mode 100644
index 00000000..128025ec
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp
@@ -0,0 +1,160 @@
+//===========================================
+// Lumina-Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "mainUI.h"
+#include "ui_mainUI.h"
+#include <QDebug>
+
+MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){
+ ui->setupUi(this);
+ //Any special UI changes
+ QWidget *spacer = new QWidget(this);
+ spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred);
+ ui->toolBar->insertWidget(ui->actionVolUp, spacer);
+
+ setupPandora();
+ ui->radio_pandora->setChecked(true);
+ setupConnections();
+}
+
+MainUI::~MainUI(){
+
+}
+
+void MainUI::loadArguments(QStringList){
+
+}
+
+
+// ==== PRIVATE ====
+void MainUI::setupPandora(){
+ PANDORA = new PianoBarProcess(this);
+ connect(PANDORA, SIGNAL(currentStateChanged(PianoBarProcess::State)), this, SLOT(PandoraStateChanged(PianoBarProcess::State)) );
+ connect(PANDORA, SIGNAL(NewInformation(QString)), this, SLOT(NewPandoraInfo(QString)) );
+ connect(PANDORA, SIGNAL(NowPlayingStation(QString, QString)), this, SLOT(PandoraStationChanged(QString)) );
+ connect(PANDORA, SIGNAL(NowPlayingSong(bool, QString,QString,QString, QString, QString)), this, SLOT(PandoraSongChanged(bool, QString, QString, QString, QString, QString)) );
+ connect(PANDORA, SIGNAL(TimeUpdate(int, int)), this, SLOT(PandoraTimeUpdate(int,int)) );
+ connect(PANDORA, SIGNAL(NewList(QStringList)), this, SLOT(PandoraListInfo(QStringList)) );
+ connect(PANDORA, SIGNAL(StationListChanged(QStringList)), this, SLOT(PandoraStationListChanged(QStringList)) );
+ //Setup a couple of the option lists
+ ui->combo_pandora_quality->clear();
+ ui->combo_pandora_quality->addItem(tr("Low"),"low");
+ ui->combo_pandora_quality->addItem(tr("Medium"), "medium");
+ ui->combo_pandora_quality->addItem(tr("High"),"high");
+ //Now load the current settings into the UI
+ int qual = ui->combo_pandora_quality->findData(PANDORA->audioQuality());
+ if(qual>=0){ ui->combo_pandora_quality->setCurrentIndex(qual); }
+ else{ ui->combo_pandora_quality->setCurrentIndex(1); } //medium quality by default
+ ui->line_pandora_email->setText( PANDORA->email() );
+ ui->line_pandora_pass->setText( PANDORA->password() );
+ ui->line_pandora_proxy->setText( PANDORA->proxy() );
+ ui->line_pandora_cproxy->setText( PANDORA->controlProxy() );
+}
+
+void MainUI::setupConnections(){
+ connect(ui->actionPlay, SIGNAL(triggered()), this, SLOT(playToggled()) );
+ connect(ui->actionPause, SIGNAL(triggered()), this, SLOT(pauseToggled()) );
+ connect(ui->actionStop, SIGNAL(triggered()), this, SLOT(stopToggled()) );
+ connect(ui->actionNext, SIGNAL(triggered()), this, SLOT(nextToggled()) );
+ connect(ui->actionBack, SIGNAL(triggered()), this, SLOT(backToggled()) );
+ connect(ui->actionVolUp, SIGNAL(triggered()), this, SLOT(volupToggled()) );
+ connect(ui->actionVolDown, SIGNAL(triggered()), this, SLOT(voldownToggled()) );
+ connect(ui->actionClose, SIGNAL(triggered()), this, SLOT(close()) );
+ connect(ui->push_pandora_apply, SIGNAL(clicked()), this, SLOT(applyPandoraSettings()) );
+}
+
+
+// ==== PRIVATE SLOTS ====
+void MainUI::PlayerTypeChanged(){
+ if(ui->radio_pandora->isChecked()){ ui->stackedWidget->setCurrentWidget(ui->page_pandora); }
+ else{ ui->stackedWidget->setCurrentWidget(ui->page_local); }
+ //Now hide/deactivate any toolbar buttons which are not used
+ ui->actionBack->setVisible(!ui->radio_pandora->isChecked());
+}
+
+
+//Toolbar actions
+void MainUI::playToggled(){
+ if(ui->radio_pandora->isChecked()){
+ PANDORA->play();
+ }
+}
+
+void MainUI::pauseToggled(){
+ if(ui->radio_pandora->isChecked()){
+ PANDORA->pause();
+ }
+}
+
+void MainUI::stopToggled(){
+ if(ui->radio_pandora->isChecked()){
+ PANDORA->closePianoBar();
+ }
+}
+
+void MainUI::nextToggled(){
+ if(ui->radio_pandora->isChecked()){
+ PANDORA->skipSong();
+ }
+}
+
+void MainUI::backToggled(){
+
+}
+
+void MainUI::volupToggled(){
+
+}
+
+void MainUI::voldownToggled(){
+
+}
+
+
+//Pandora Options
+void MainUI::showPandoraSongInfo(){
+
+}
+
+void MainUI::changePandoraStation(QString){
+
+}
+
+void MainUI::applyPandoraSettings(){
+ PANDORA->setLogin(ui->line_pandora_email->text(), ui->line_pandora_pass->text());
+ PANDORA->setAudioQuality(ui->combo_pandora_quality->currentData().toString());
+ PANDORA->setProxy(ui->line_pandora_proxy->text());
+ PANDORA->setControlProxy(ui->line_pandora_cproxy->text());
+}
+
+//Pandora Process Feedback
+void MainUI::PandoraStateChanged(PianoBarProcess::State){
+
+}
+
+void MainUI::NewPandoraInfo(QString info){
+ qDebug() << "[INFO]" << info;
+}
+
+void MainUI::PandoraStationChanged(QString station){
+ qDebug() << "[STATION CHANGE]" << station;
+}
+
+void MainUI::PandoraSongChanged(bool isLoved, QString title, QString artist, QString album, QString detailsURL, QString fromStation){
+ qDebug() << "[SONG CHANGE]" << isLoved << title << artist << album << detailsURL << fromStation;
+}
+
+void MainUI::PandoraTimeUpdate(int curS, int totS){
+ qDebug() << "[TIME UPDATE]" << curS << "/" << totS;
+}
+
+void MainUI::PandoraStationListChanged(QStringList list){
+ qDebug() << "[STATION LIST]" << list;
+}
+
+void MainUI::PandoraListInfo(QStringList list){
+ qDebug() << "[LIST INFO]" << list;
+}
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h
new file mode 100644
index 00000000..f19e2e2b
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h
@@ -0,0 +1,62 @@
+//===========================================
+// Lumina-Desktop source code
+// Copyright (c) 2017, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_MEDIA_PLAYER_MAIN_UI_H
+#define _LUMINA_MEDIA_PLAYER_MAIN_UI_H
+
+#include <QMainWindow>
+#include <QAction>
+#include <QString>
+#include <QStringList>
+
+#include "PianoBarProcess.h"
+
+namespace Ui{
+ class MainUI;
+};
+
+class MainUI : public QMainWindow{
+ Q_OBJECT
+public:
+ MainUI();
+ ~MainUI();
+
+ void loadArguments(QStringList);
+
+private:
+ Ui::MainUI *ui;
+ PianoBarProcess *PANDORA;
+
+ void setupPandora();
+ void setupConnections();
+
+private slots:
+ void PlayerTypeChanged();
+
+ //Toolbar actions
+ void playToggled();
+ void pauseToggled();
+ void stopToggled();
+ void nextToggled();
+ void backToggled();
+ void volupToggled();
+ void voldownToggled();
+
+ //Pandora Options
+ void showPandoraSongInfo();
+ void changePandoraStation(QString);
+ void applyPandoraSettings();
+ //Pandora Process Feedback
+ void PandoraStateChanged(PianoBarProcess::State);
+ void NewPandoraInfo(QString);
+ void PandoraStationChanged(QString);
+ void PandoraSongChanged(bool, QString, QString, QString, QString, QString); //[isLoved, title, artist, album, detailsURL, fromStation]
+ void PandoraTimeUpdate(int,int); //current secs, total secs
+ void PandoraStationListChanged(QStringList);
+ void PandoraListInfo(QStringList);
+
+};
+#endif
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui
index d662b20c..9c8dd46a 100644
--- a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui
+++ b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
- <class>MainWindow</class>
- <widget class="QMainWindow" name="MainWindow">
+ <class>MainUI</class>
+ <widget class="QMainWindow" name="MainUI">
<property name="geometry">
<rect>
<x>0</x>
@@ -33,11 +33,20 @@
<item>
<widget class="QFrame" name="frame_type">
<layout class="QHBoxLayout" name="horizontalLayout">
+ <property name="topMargin">
+ <number>1</number>
+ </property>
+ <property name="bottomMargin">
+ <number>1</number>
+ </property>
<item>
<widget class="QRadioButton" name="radio_local">
<property name="text">
<string>Local Files</string>
</property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
</widget>
</item>
<item>
@@ -52,11 +61,14 @@
</item>
<item>
<widget class="QStackedWidget" name="stackedWidget">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
<widget class="QWidget" name="page_local"/>
<widget class="QWidget" name="page_pandora">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
- <widget class="QTabWidget" name="tabWidget">
+ <widget class="QTabWidget" name="tabWidget_pandora">
<property name="currentIndex">
<number>0</number>
</property>
@@ -64,11 +76,269 @@
<attribute name="title">
<string>Now Playing</string>
</attribute>
+ <layout class="QVBoxLayout" name="verticalLayout_5">
+ <item>
+ <widget class="QGroupBox" name="groupBox_2">
+ <property name="title">
+ <string>Current Song</string>
+ </property>
+ <layout class="QHBoxLayout" name="horizontalLayout_3">
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_pandora_title">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="font">
+ <font>
+ <pointsize>10</pointsize>
+ <weight>75</weight>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="text">
+ <string>TITLE</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="openExternalLinks">
+ <bool>false</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_pandora_artist">
+ <property name="text">
+ <string>ARTIST</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_pandora_album">
+ <property name="text">
+ <string>ALBUM</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="progress_pandora">
+ <property name="value">
+ <number>24</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <layout class="QVBoxLayout" name="verticalLayout_3">
+ <item>
+ <widget class="QToolButton" name="tool_pandora_love">
+ <property name="text">
+ <string notr="true">love</string>
+ </property>
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_pandora_tired">
+ <property name="text">
+ <string notr="true">tired</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_pandora_ban">
+ <property name="text">
+ <string notr="true">ban</string>
+ </property>
+ <property name="autoRaise">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="Line" name="line">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="tool_pandora_info">
+ <property name="text">
+ <string notr="true">info</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item>
+ <spacer name="verticalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" name="horizontalLayout_4">
+ <item>
+ <widget class="QLabel" name="label_6">
+ <property name="text">
+ <string>Current Station</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="combo_pandora_station"/>
+ </item>
+ </layout>
+ </item>
+ </layout>
</widget>
<widget class="QWidget" name="tab_pandora_settings">
<attribute name="title">
<string>Settings</string>
</attribute>
+ <layout class="QFormLayout" name="formLayout_2">
+ <property name="labelAlignment">
+ <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
+ </property>
+ <item row="0" column="0" colspan="2">
+ <widget class="QGroupBox" name="groupBox">
+ <property name="title">
+ <string>Pandora Account Login</string>
+ </property>
+ <layout class="QFormLayout" name="formLayout">
+ <item row="0" column="0">
+ <widget class="QLabel" name="label">
+ <property name="text">
+ <string>Email</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
+ <widget class="QLineEdit" name="line_pandora_email"/>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_2">
+ <property name="text">
+ <string>Password</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QLineEdit" name="line_pandora_pass">
+ <property name="echoMode">
+ <enum>QLineEdit::Password</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0">
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Audio Quality</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QComboBox" name="combo_pandora_quality"/>
+ </item>
+ <item row="2" column="0">
+ <widget class="QLabel" name="label_4">
+ <property name="text">
+ <string>Proxy URL</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1">
+ <widget class="QLineEdit" name="line_pandora_proxy"/>
+ </item>
+ <item row="3" column="0">
+ <widget class="QLabel" name="label_5">
+ <property name="text">
+ <string>Control Proxy URL</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1">
+ <widget class="QLineEdit" name="line_pandora_cproxy"/>
+ </item>
+ <item row="5" column="0" colspan="2">
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <spacer name="horizontalSpacer">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="push_pandora_apply">
+ <property name="text">
+ <string>Apply Settings</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer name="horizontalSpacer_2">
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ <item row="4" column="0">
+ <spacer name="verticalSpacer">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
</widget>
</widget>
</item>
@@ -84,9 +354,19 @@
<x>0</x>
<y>0</y>
<width>385</width>
- <height>22</height>
+ <height>20</height>
</rect>
</property>
+ <widget class="QMenu" name="menuFile">
+ <property name="title">
+ <string>File</string>
+ </property>
+ <addaction name="separator"/>
+ <addaction name="actionClose_to_tray_when_running"/>
+ <addaction name="separator"/>
+ <addaction name="actionClose"/>
+ </widget>
+ <addaction name="menuFile"/>
</widget>
<widget class="QStatusBar" name="statusbar"/>
<widget class="QToolBar" name="toolBar">
@@ -151,6 +431,28 @@
<string>VolDown</string>
</property>
</action>
+ <action name="actionClose">
+ <property name="text">
+ <string>Close</string>
+ </property>
+ <property name="shortcut">
+ <string>Ctrl+Q</string>
+ </property>
+ <property name="shortcutContext">
+ <enum>Qt::ApplicationShortcut</enum>
+ </property>
+ </action>
+ <action name="actionClose_to_tray_when_running">
+ <property name="checkable">
+ <bool>true</bool>
+ </property>
+ <property name="checked">
+ <bool>true</bool>
+ </property>
+ <property name="text">
+ <string>Close to tray when active</string>
+ </property>
+ </action>
</widget>
<resources/>
<connections/>
bgstack15