diff options
Diffstat (limited to 'src-qt5')
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/> |