diff options
8 files changed, 580 insertions, 46 deletions
diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp index 55c85a33..88abce82 100644 --- a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp +++ b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.cpp @@ -28,6 +28,10 @@ PianoBarProcess::~PianoBarProcess(){ } } +PianoBarProcess::State PianoBarProcess::currentState(){ + return cState; +} + // ===== PUBLIC ====== //Interaction functions bool PianoBarProcess::isSetup(){ //email/password already saved for use or not @@ -51,7 +55,7 @@ void PianoBarProcess::closePianoBar(){ //"q" sendToProcess("q"); } -QString PianoBarProcess::currentStation(){ return cstation; } +QString PianoBarProcess::currentStation(){ return cstation.simplified(); } QStringList PianoBarProcess::stations(){ return stationList; } void PianoBarProcess::setCurrentStation(QString station){ cstation = station; @@ -70,11 +74,13 @@ void PianoBarProcess::deleteCurrentStation(){ //"d" -> "y" void PianoBarProcess::createStationFromCurrentSong(){ //"v" -> "s" sendToProcess("v"); sendToProcess("s",true); + setCurrentStation("<NEW>"); //internal definition for auto-switching to a new station } void PianoBarProcess::createStationFromCurrentArtist(){ //"v" -> "a" sendToProcess("v"); sendToProcess("a",true); + setCurrentStation("<NEW>"); //internal definition for auto-switching to a new station } //Settings Manipulation @@ -116,9 +122,21 @@ void PianoBarProcess::play(){ PROC->start(); }else{ sendToProcess("P"); + cState = PianoBarProcess::Running; + emit currentStateChanged(cState); } } +void PianoBarProcess::pause(){ + sendToProcess("S"); + cState = PianoBarProcess::Paused; + emit currentStateChanged(cState); +} + +void PianoBarProcess::skipSong(){ + sendToProcess("n"); +} + // ====== PRIVATE ====== void PianoBarProcess::GenerateSettings(){ currentSettings << "audio_quality = medium"; @@ -187,6 +205,8 @@ void PianoBarProcess::setupProcess(){ LUtils::isValidBinary(bin); //will change "bin" to the full path PROC->setProgram(bin); connect(PROC, SIGNAL(readyRead()), this, SLOT(ProcUpdate()) ); + connect(PROC, SIGNAL(stateChanged(QProcess::ProcessState)), this, SLOT(ProcStateChanged(QProcess::ProcessState)) ); + cState = PianoBarProcess::Stopped; } void PianoBarProcess::sendToProcess(QString txt, bool withreturn){ @@ -218,7 +238,7 @@ void PianoBarProcess::ProcUpdate(){ //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 + cstation = data[0].simplified(); //save the name for later emit NowPlayingStation(data[0], data[1]); if(stationList.isEmpty()){ //Need to prompt to list all the available stations @@ -231,23 +251,40 @@ void PianoBarProcess::ProcUpdate(){ }else if(data.length()==6){ //song emit NowPlayingSong( data[0]=="<3", data[1], data[2], data[3], data[4], data[5] ); } + //If a new song/station is detected, ensure that the state is set to "Running" + if(cState!=PianoBarProcess::Running){ + cState = PianoBarProcess::Running; + emit currentStateChanged(cState); + } }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 - qDebug() << "Got Question:" << info[i] << infoList; + //qDebug() << "Got Question:" << info[i] << infoList; if(info[i].contains("Select station:")){ - qDebug() << "Change to Station:" << cstation; + //qDebug() << "Change to Station:" << cstation; + //Clean up the station list a bit first (remove the quickmix-status) + for(int j=0; j<infoList.length(); j++){ + infoList[j] = infoList[j].simplified(); + if(infoList[j].startsWith("q ")){ infoList[j] = infoList[j].section("q ",1,-1); } + if(infoList[j].startsWith("Q ")){ infoList[j] = infoList[j].section("Q ",1,-1); } + } + if(cstation=="<NEW>"){ + //Compare the new list to the previous list and switch to the new one automatically + for(int j=0; j<infoList.length(); j++){ + if(!stationList.contains(infoList[j])){ cstation = infoList[j]; break; } + } + } 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[i].endsWith(cstation) ){ - qDebug() << "Activate Station:" << stationList[i]; - sendToProcess(QString::number(i), true); + for(int j=0; j<stationList.length(); j++){ + if(stationList[j].endsWith(cstation) ){ + //qDebug() << "Activate Station:" << stationList[i]; + sendToProcess(QString::number(j), true); break; - }else if(i==stationList.length()-1){ - qDebug() << "Activate Last Station:" << stationList[i]; + }else if(j==stationList.length()-1){ + //qDebug() << "Activate Last Station:" << stationList[i]; sendToProcess(QString::number(stationList.length()-1), true); } } @@ -263,3 +300,9 @@ void PianoBarProcess::ProcUpdate(){ } } } + +void PianoBarProcess::ProcStateChanged(QProcess::ProcessState stat){ + if(stat == QProcess::NotRunning){ cState = PianoBarProcess::Stopped; } + else{ cState = PianoBarProcess::Paused; } + emit currentStateChanged(cState); +} diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h index a11da247..f250c964 100644 --- a/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h +++ b/src-qt5/desktop-utils/lumina-mediaplayer/PianoBarProcess.h @@ -39,11 +39,6 @@ public: QString currentStation(); //Re-direct for the "autostartStation()" function; QStringList stations(); void setCurrentStation(QString station); - - void deleteCurrentStation(); //"d" - //void createNewStation(); //"c" - void createStationFromCurrentSong(); //"v" -> "s" - void createStationFromCurrentArtist(); //"v" -> "a" //Settings Manipulation QString audioQuality(); // "audio_quality" = [low, medium, high] @@ -58,6 +53,7 @@ public: private: //Process QProcess *PROC; + PianoBarProcess::State cState; QStringList infoList; void setupProcess(); void sendToProcess(QString, bool withreturn = false); @@ -78,17 +74,22 @@ private: public slots: void play(); // "P" - void pause(){ sendToProcess("S"); } //"S" + void pause(); //"S" void volumeDown(){ sendToProcess("("); } //"(" void volumeUp(){ sendToProcess(")"); } //")" - void skipSong(){ sendToProcess("n"); } //"n" + void skipSong(); //"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 bookmarkSong(){ sendToProcess("b"); sendToProcess("s", true); } //"b"->"s" + void bookmarkArtist(){ sendToProcess("b"); sendToProcess("a",true); } //"b"->"a" + + void deleteCurrentStation(); //"d" + //void createNewStation(); //"c" + void createStationFromCurrentSong(); //"v" -> "s" + void createStationFromCurrentArtist(); //"v" -> "a" void explainSong(){ sendToProcess("e"); } //"e" @@ -98,6 +99,7 @@ public slots: private slots: void ProcUpdate(); + void ProcStateChanged(QProcess::ProcessState); void saveSettingsFile(); signals: diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/extra/Pandora.svg b/src-qt5/desktop-utils/lumina-mediaplayer/extra/Pandora.svg new file mode 100644 index 00000000..62f656c1 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-mediaplayer/extra/Pandora.svg @@ -0,0 +1,151 @@ +<?xml version="1.0" encoding="UTF-8" standalone="no"?> +<!-- Created with Inkscape (http://www.inkscape.org/) --> + +<svg + xmlns:dc="http://purl.org/dc/elements/1.1/" + xmlns:cc="http://creativecommons.org/ns#" + xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" + xmlns:svg="http://www.w3.org/2000/svg" + xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink" + xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" + xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" + width="256" + height="256" + id="svg2" + sodipodi:version="0.32" + inkscape:version="0.47 r22583" + sodipodi:docname="pandora.svg" + version="1.0" + inkscape:output_extension="org.inkscape.output.svg.inkscape"> + <defs + id="defs4"> + <inkscape:perspective + sodipodi:type="inkscape:persp3d" + inkscape:vp_x="0 : 128 : 1" + inkscape:vp_y="0 : 1000 : 0" + inkscape:vp_z="256 : 128 : 1" + inkscape:persp3d-origin="128 : 85.333333 : 1" + id="perspective2850" /> + <linearGradient + inkscape:collect="always" + id="linearGradient2555"> + <stop + style="stop-color: rgb(255, 255, 255); stop-opacity: 1;" + offset="0" + id="stop2557" /> + <stop + style="stop-color: rgb(255, 255, 255); stop-opacity: 0;" + offset="1" + id="stop2559" /> + </linearGradient> + <linearGradient + inkscape:collect="always" + xlink:href="#linearGradient2555" + id="linearGradient2449" + gradientUnits="userSpaceOnUse" + gradientTransform="matrix(-0.5914583,0,0,0.5914584,210.0216,142.2324)" + x1="-344.15295" + y1="274.711" + x2="-395.84943" + y2="425.39993" /> + </defs> + <sodipodi:namedview + id="base" + pagecolor="#ffffff" + bordercolor="#666666" + borderopacity="1.0" + inkscape:pageopacity="0.0" + inkscape:pageshadow="2" + inkscape:zoom="0.35" + inkscape:cx="-44.119664" + inkscape:cy="119.95386" + inkscape:document-units="px" + inkscape:current-layer="layer1" + inkscape:window-width="853" + inkscape:window-height="674" + inkscape:window-x="1" + inkscape:window-y="281" + showgrid="false" + inkscape:window-maximized="0" /> + <metadata + id="metadata7"> + <rdf:RDF> + <cc:Work + rdf:about=""> + <dc:format>image/svg+xml</dc:format> + <dc:type + rdf:resource="http://purl.org/dc/dcmitype/StillImage" /> + <dc:title /> + <dc:creator> + <cc:Agent> + <dc:title>User:ZyMOS</dc:title> + </cc:Agent> + </dc:creator> + <dc:subject> + <rdf:Bag /> + </dc:subject> + <cc:license + rdf:resource="http://creativecommons.org/licenses/publicdomain/" /> + <dc:description /> + <dc:contributor> + <cc:Agent> + <dc:title /> + </cc:Agent> + </dc:contributor> + <dc:publisher> + <cc:Agent> + <dc:title>Open Icon Library</dc:title> + </cc:Agent> + </dc:publisher> + </cc:Work> + <cc:License + rdf:about="http://creativecommons.org/licenses/publicdomain/"> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Reproduction" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#Distribution" /> + <cc:permits + rdf:resource="http://creativecommons.org/ns#DerivativeWorks" /> + </cc:License> + </rdf:RDF> + </metadata> + <g + inkscape:label="Layer 1" + inkscape:groupmode="layer" + id="layer1" + transform="translate(-373.642,-318.344)"> + <rect + inkscape:export-ydpi="7.7063322" + inkscape:export-xdpi="7.7063322" + inkscape:export-filename="C:\Documents and Settings\Molumen\Desktop\path3511111.png" + transform="scale(-1,1)" + ry="35.487503" + rx="35.487503" + y="328.84921" + x="-619.14587" + height="234.98955" + width="235.00784" + id="rect1942" + style="fill:#9dafdf;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.5;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.5,1;stroke-dashoffset:0;stroke-opacity:1" /> + <path + inkscape:export-ydpi="7.7063322" + inkscape:export-xdpi="7.7063322" + inkscape:export-filename="C:\Documents and Settings\Molumen\Desktop\path3511111.png" + sodipodi:nodetypes="ccccsssc" + id="path1950" + d="M 557.05665,338.89518 L 446.22721,338.89518 C 416.89033,338.89518 393.27256,362.70492 393.27256,392.28025 L 393.27256,500.40761 C 394.22216,523.49366 397.87485,508.89915 404.82758,483.3329 C 412.90814,453.61975 439.22406,427.65003 471.27219,408.1872 C 495.73352,393.33195 523.11328,383.84595 572.95174,382.94353 C 601.21656,382.43177 598.72124,346.26062 557.05665,338.89518 z" + style="opacity:1;fill:url(#linearGradient2449);fill-opacity:1;fill-rule:evenodd;stroke:none;stroke-width:0.87500000000000000;stroke-linecap:square;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:0.87500000000000000, 1.75000000000000000;stroke-dashoffset:0;stroke-opacity:1" /> + <text + xml:space="preserve" + style="font-size:119.42172241px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;fill:#000000;fill-opacity:1;stroke:none;font-family:Georgia;-inkscape-font-specification:Georgia" + x="432.28491" + y="531.48682" + id="text6520"><tspan + sodipodi:role="line" + id="tspan6522" + x="432.28491" + y="531.48682" + style="font-size:238.84344482px;fill:#ffffff;fill-opacity:1">P</tspan></text> + </g> +</svg> diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/extra/resources.qrc b/src-qt5/desktop-utils/lumina-mediaplayer/extra/resources.qrc new file mode 100644 index 00000000..3e09863d --- /dev/null +++ b/src-qt5/desktop-utils/lumina-mediaplayer/extra/resources.qrc @@ -0,0 +1,5 @@ +<RCC> + <qresource> + <file alias="pandora">Pandora.svg</file> + </qresource> +</RCC> diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro index dd8a14d6..46286e40 100644 --- a/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro +++ b/src-qt5/desktop-utils/lumina-mediaplayer/lumina-mediaplayer.pro @@ -23,6 +23,8 @@ HEADERS += mainUI.h \ FORMS += mainUI.ui +RESOURCES += extra/resources.qrc + TRANSLATIONS = i18n/l-mediap_af.ts \ i18n/l-mediap_ar.ts \ i18n/l-mediap_az.ts \ diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp index bf8a7558..967687be 100644 --- a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp +++ b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.cpp @@ -8,16 +8,29 @@ #include "ui_mainUI.h" #include <QDebug> +#include <LuminaXDG.h> +#include <QDesktopServices> +#include <QUrl> + MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI()){ ui->setupUi(this); + closing = false; //Any special UI changes QWidget *spacer = new QWidget(this); spacer->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred); ui->toolBar->insertWidget(ui->actionVolUp, spacer); - + //Setup an action group for the various modes/streams + QButtonGroup *grp = new QButtonGroup(this); + grp->addButton(ui->radio_local); + grp->addButton(ui->radio_pandora); + grp->setExclusive(true); setupPandora(); ui->radio_pandora->setChecked(true); + setupTrayIcon(); setupConnections(); + setupIcons(); + PlayerTypeChanged(); + SYSTRAY->show(); } MainUI::~MainUI(){ @@ -52,9 +65,23 @@ void MainUI::setupPandora(){ ui->line_pandora_pass->setText( PANDORA->password() ); ui->line_pandora_proxy->setText( PANDORA->proxy() ); ui->line_pandora_cproxy->setText( PANDORA->controlProxy() ); + //Make sure the interface is enabled/disabled as needed + PandoraStateChanged(PANDORA->currentState()); + ui->progress_pandora->setRange(0,1); + ui->progress_pandora->setValue(0); + + //Setup the menu for new stations + QMenu *tmp = new QMenu(this); + tmp->addAction(ui->action_pandora_newstation_song); + tmp->addAction(ui->action_pandora_newstation_artist); + ui->tool_pandora_stationadd->setMenu( tmp ); + } void MainUI::setupConnections(){ + connect(ui->radio_local, SIGNAL(toggled(bool)), this, SLOT(PlayerTypeChanged(bool)) ); + connect(ui->radio_pandora, SIGNAL(toggled(bool)), this, SLOT(PlayerTypeChanged(bool)) ); + connect(ui->actionPlay, SIGNAL(triggered()), this, SLOT(playToggled()) ); connect(ui->actionPause, SIGNAL(triggered()), this, SLOT(pauseToggled()) ); connect(ui->actionStop, SIGNAL(triggered()), this, SLOT(stopToggled()) ); @@ -62,16 +89,89 @@ void MainUI::setupConnections(){ 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->actionClose, SIGNAL(triggered()), this, SLOT(closeApplication()) ); + connect(ui->push_pandora_apply, SIGNAL(clicked()), this, SLOT(applyPandoraSettings()) ); connect(ui->combo_pandora_station, SIGNAL(activated(QString)), this, SLOT(changePandoraStation(QString)) ); + connect(ui->tool_pandora_ban, SIGNAL(clicked()), PANDORA, SLOT(banSong()) ); + connect(ui->tool_pandora_love, SIGNAL(clicked()), PANDORA, SLOT(loveSong()) ); + connect(ui->tool_pandora_tired, SIGNAL(clicked()), PANDORA, SLOT(tiredSong()) ); + connect(ui->tool_pandora_info, SIGNAL(clicked()), this, SLOT(showPandoraSongInfo()) ); + connect(ui->tool_pandora_stationrm, SIGNAL(clicked()), PANDORA, SLOT(deleteCurrentStation()) ); + connect(ui->action_pandora_newstation_artist, SIGNAL(triggered()), PANDORA, SLOT(createStationFromCurrentArtist()) ); + connect(ui->action_pandora_newstation_song, SIGNAL(triggered()), PANDORA, SLOT(createStationFromCurrentSong()) ); + + connect(SYSTRAY, SIGNAL(activated(QSystemTrayIcon::ActivationReason)), this, SLOT(trayClicked(QSystemTrayIcon::ActivationReason)) ); + connect(SYSTRAY, SIGNAL(messageClicked()), this, SLOT(showNormal()) ); } +void MainUI::setupIcons(){ + ui->actionClose->setIcon( LXDG::findIcon("application-close","dialog-close") ); + ui->actionPlay->setIcon( LXDG::findIcon("media-playback-start","") ); + ui->actionPause->setIcon( LXDG::findIcon("media-playback-pause","") ); + ui->actionStop->setIcon( LXDG::findIcon("media-playback-stop","") ); + ui->actionNext->setIcon( LXDG::findIcon("media-skip-forward","") ); + ui->actionBack->setIcon( LXDG::findIcon("media-skip-backward","") ); + + //Pandora Pages + ui->push_pandora_apply->setIcon( LXDG::findIcon("dialog-ok-apply","dialog-ok") ); + ui->tool_pandora_ban->setIcon( LXDG::findIcon("dialog-cancel","") ); + ui->tool_pandora_info->setIcon( LXDG::findIcon("help-about","") ); + ui->tool_pandora_love->setIcon( LXDG::findIcon("emblem-favorite","") ); + ui->tool_pandora_tired->setIcon( LXDG::findIcon("flag-yellow","flag") ); + ui->tool_pandora_stationrm->setIcon( LXDG::findIcon("list-remove","") ); + ui->tool_pandora_stationadd->setIcon( LXDG::findIcon("list-add","") ); + ui->action_pandora_newstation_artist->setIcon( LXDG::findIcon("list-add-user","") ); + ui->action_pandora_newstation_song->setIcon( LXDG::findIcon("audio-x-generic","") ); + +} + +void MainUI::setupTrayIcon(){ + SYSTRAY = new QSystemTrayIcon(this); + QMenu *tmp = new QMenu(this); + SYSTRAY->setContextMenu(tmp); + tmp->addAction(ui->actionPlay); + tmp->addAction(ui->actionPause); + tmp->addAction(ui->actionStop); + tmp->addAction(ui->actionBack); + tmp->addAction(ui->actionNext); + tmp->addSeparator(); + tmp->addAction(ui->actionClose); +} + +void MainUI::closeTrayIcon(){ + +} // ==== PRIVATE SLOTS ==== -void MainUI::PlayerTypeChanged(){ - if(ui->radio_pandora->isChecked()){ ui->stackedWidget->setCurrentWidget(ui->page_pandora); } - else{ ui->stackedWidget->setCurrentWidget(ui->page_local); } +void MainUI::closeApplication(){ + closing = true; + if(PANDORA->currentState()!= PianoBarProcess::Stopped){ + PANDORA->closePianoBar(); + this->hide(); + QTimer::singleShot(500, this, SLOT(close()) ); + }else{ + this->close(); + } +} + +void MainUI::PlayerTypeChanged(bool active){ + if(!active){ return; } //this gets rid of the "extra" signals from the radio button functionality (1 signal from each button on change) + if(ui->radio_pandora->isChecked()){ + ui->stackedWidget->setCurrentWidget(ui->page_pandora); + PandoraStateChanged(PANDORA->currentState()); + SYSTRAY->setIcon( QIcon(":pandora") ); + this->setWindowIcon( QIcon(":pandora") ); + this->setWindowTitle( tr("Pandora Radio") ); + }else{ + ui->stackedWidget->setCurrentWidget(ui->page_local); + SYSTRAY->setIcon( LXDG::findIcon("audio-x-generic","") ); + this->setWindowIcon( LXDG::findIcon("audio-x-generic","") ); + this->setWindowTitle( tr("Media Player") ); + } + //Now close down any currently running streams as needed + if(!ui->radio_pandora->isChecked() && PANDORA->currentState()!=PianoBarProcess::Stopped){ PANDORA->closePianoBar(); } + //Now hide/deactivate any toolbar buttons which are not used ui->actionBack->setVisible(!ui->radio_pandora->isChecked()); } @@ -117,10 +217,12 @@ void MainUI::voldownToggled(){ //Pandora Options void MainUI::showPandoraSongInfo(){ - + QDesktopServices::openUrl( QUrl(ui->tool_pandora_info->whatsThis()) ); } void MainUI::changePandoraStation(QString station){ + if(station == PANDORA->currentStation()){ return; } + qDebug() << "[CHANGE STATION]" << station << "from:" << PANDORA->currentStation(); PANDORA->setCurrentStation(station); } @@ -132,8 +234,19 @@ void MainUI::applyPandoraSettings(){ } //Pandora Process Feedback -void MainUI::PandoraStateChanged(PianoBarProcess::State){ - +void MainUI::PandoraStateChanged(PianoBarProcess::State state){ + //qDebug() << "[STATE CHANGE]" << state; + ui->actionPlay->setVisible(state != PianoBarProcess::Running); + ui->actionPause->setVisible(state == PianoBarProcess::Running); + ui->actionStop->setVisible(state != PianoBarProcess::Stopped); + ui->actionBack->setVisible(false); //never available for Pandora streams + ui->actionNext->setVisible(state!=PianoBarProcess::Stopped); + ui->tabWidget_pandora->setTabEnabled(0, state !=PianoBarProcess::Stopped); + if(!ui->tabWidget_pandora->isTabEnabled(0) && ui->tabWidget_pandora->currentIndex()==0){ + ui->tabWidget_pandora->setCurrentWidget(ui->tab_pandora_settings); + }else if(state == PianoBarProcess::Running){ + ui->tabWidget_pandora->setCurrentWidget(ui->tab_pandora_playing); + } } void MainUI::NewPandoraInfo(QString info){ @@ -142,9 +255,16 @@ void MainUI::NewPandoraInfo(QString info){ } void MainUI::PandoraStationChanged(QString station){ - //qDebug() << "[STATION CHANGE]" << station; - int index = ui->combo_pandora_station->findText( station ); - if(index>=0){ ui->combo_pandora_station->setCurrentIndex(index); } + qDebug() << "[STATION CHANGE]" << station; + int index = ui->combo_pandora_station->findText( station ); + if(index>=0){ + qDebug() <<" [FOUND]" << ui->combo_pandora_station->itemText(index); + ui->combo_pandora_station->setCurrentIndex(index); + }else{ + //Could not find the station in the current list - need to update that first + qDebug() <<" [NOT FOUND]"; + PandoraStationListChanged(PANDORA->stations()); + } } void MainUI::PandoraSongChanged(bool isLoved, QString title, QString artist, QString album, QString detailsURL, QString fromStation){ @@ -155,27 +275,67 @@ void MainUI::PandoraSongChanged(bool isLoved, QString title, QString artist, QSt ui->label_pandora_album->setText(album); ui->label_pandora_artist->setText(artist); ui->label_pandora_title->setText(title); + ui->progress_pandora->setRange(0,1); + ui->progress_pandora->setValue(0); + ui->progress_pandora->setFormat(""); + if(ui->action_showNotifications->isChecked()){ + QString msg = QString(tr("%1\nBy %2 on %3")).arg(title, artist, album); + SYSTRAY->showMessage(tr("Now Playing"), msg, QSystemTrayIcon::NoIcon, 1500); //1.5 seconds + } } void MainUI::PandoraTimeUpdate(int curS, int totS){ //qDebug() << "[TIME UPDATE]" << curS << "/" << totS; ui->progress_pandora->setRange(0, totS); ui->progress_pandora->setValue(curS); + QString time = QTime(0, curS/60, curS%60,0).toString("m:ss") + "/" + QTime(0, totS/60, totS%60,0).toString("m:ss"); + ui->progress_pandora->setFormat(time); } void MainUI::PandoraStationListChanged(QStringList list){ - //qDebug() << "[STATION LIST]" << list; + qDebug() << "[STATION LIST]" << list; ui->combo_pandora_station->clear(); - for(int i=0; i<list.length(); i++){ - list[i] =list[i].simplified(); - if(list[i].startsWith("q ")){ list[i] = list[i].section("q ",1,-1); } - if(list[i].startsWith("Q ")){ list[i] = list[i].section("Q ",1,-1); } - ui->combo_pandora_station->addItem(list[i]); - } + if(list.isEmpty()){ return; } + ui->combo_pandora_station->addItems(list); int index = ui->combo_pandora_station->findText( PANDORA->currentStation() ); + qDebug() << "[CURRENT STATION]" << PANDORA->currentStation() << index; if(index>=0){ ui->combo_pandora_station->setCurrentIndex(index); } } void MainUI::PandoraListInfo(QStringList list){ qDebug() << "[LIST INFO]" << list; } + +//System Tray interactions +void MainUI::toggleVisibility(){ + if(this->isVisible()){ this->hide(); } + else{ this->showNormal(); } +} + +void MainUI::trayClicked(QSystemTrayIcon::ActivationReason rsn){ + if(rsn == QSystemTrayIcon::Context){ + SYSTRAY->contextMenu()->popup(QCursor::pos()); + }else{ + toggleVisibility(); + } +} + +void MainUI::closeEvent(QCloseEvent *ev){ + if(!closing){ + //Check if we have audio playing to determine if we should just minimize instead + if(ui->action_closeToTray->isChecked()){ + closing = (PANDORA->currentState()!=PianoBarProcess::Running); + }else if(PANDORA->currentState()!=PianoBarProcess::Stopped){ + //Make sure we close the stream down first + PANDORA->closePianoBar(); + QTimer::singleShot(500, this, SLOT(close()) ); //try again in a moment + }else{ + closing = true; + } + } + if(closing){ QMainWindow::closeEvent(ev); } //normal close procedure + else{ + ev->ignore(); + this->hide(); + } +} diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h index f19e2e2b..a545eda3 100644 --- a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h +++ b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.h @@ -11,6 +11,8 @@ #include <QAction> #include <QString> #include <QStringList> +#include <QSystemTrayIcon> +#include <QCloseEvent> #include "PianoBarProcess.h" @@ -29,12 +31,18 @@ public: private: Ui::MainUI *ui; PianoBarProcess *PANDORA; + QSystemTrayIcon *SYSTRAY; + bool closing; void setupPandora(); void setupConnections(); + void setupIcons(); + void setupTrayIcon(); + void closeTrayIcon(); private slots: - void PlayerTypeChanged(); + void closeApplication(); + void PlayerTypeChanged(bool active = true); //Toolbar actions void playToggled(); @@ -57,6 +65,13 @@ private slots: void PandoraTimeUpdate(int,int); //current secs, total secs void PandoraStationListChanged(QStringList); void PandoraListInfo(QStringList); + + //System Tray interactions + void toggleVisibility(); + void trayClicked(QSystemTrayIcon::ActivationReason); + +protected: + void closeEvent(QCloseEvent *ev); }; #endif diff --git a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui index 6cd3ca14..e00d3c90 100644 --- a/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui +++ b/src-qt5/desktop-utils/lumina-mediaplayer/mainUI.ui @@ -11,7 +11,7 @@ </rect> </property> <property name="windowTitle"> - <string>MainWindow</string> + <string>Media Player</string> </property> <widget class="QWidget" name="centralwidget"> <layout class="QVBoxLayout" name="verticalLayout"> @@ -40,20 +40,39 @@ <number>1</number> </property> <item> - <widget class="QRadioButton" name="radio_local"> + <widget class="QToolButton" name="radio_local"> <property name="text"> <string>Local Files</string> </property> + <property name="checkable"> + <bool>true</bool> + </property> <property name="checked"> + <bool>false</bool> + </property> + <property name="autoRaise"> <bool>true</bool> </property> </widget> </item> <item> - <widget class="QRadioButton" name="radio_pandora"> + <widget class="QToolButton" name="radio_pandora"> <property name="text"> <string>Pandora Radio</string> </property> + <property name="icon"> + <iconset resource="extra/resources.qrc"> + <normaloff>:/pandora</normaloff>:/pandora</iconset> + </property> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="toolButtonStyle"> + <enum>Qt::ToolButtonTextBesideIcon</enum> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> </widget> </item> </layout> @@ -83,6 +102,21 @@ <string>Current Song</string> </property> <layout class="QHBoxLayout" name="horizontalLayout_3"> + <property name="spacing"> + <number>1</number> + </property> + <property name="leftMargin"> + <number>2</number> + </property> + <property name="topMargin"> + <number>2</number> + </property> + <property name="rightMargin"> + <number>2</number> + </property> + <property name="bottomMargin"> + <number>2</number> + </property> <item> <layout class="QVBoxLayout" name="verticalLayout_4"> <item> @@ -103,9 +137,15 @@ <property name="text"> <string>TITLE</string> </property> + <property name="scaledContents"> + <bool>false</bool> + </property> <property name="alignment"> <set>Qt::AlignCenter</set> </property> + <property name="wordWrap"> + <bool>true</bool> + </property> <property name="openExternalLinks"> <bool>false</bool> </property> @@ -113,9 +153,17 @@ </item> <item> <widget class="QLabel" name="label_pandora_artist"> + <property name="font"> + <font> + <italic>true</italic> + </font> + </property> <property name="text"> <string>ARTIST</string> </property> + <property name="wordWrap"> + <bool>true</bool> + </property> </widget> </item> <item> @@ -123,6 +171,9 @@ <property name="text"> <string>ALBUM</string> </property> + <property name="wordWrap"> + <bool>true</bool> + </property> </widget> </item> <item> @@ -138,9 +189,19 @@ </layout> </item> <item> + <widget class="Line" name="line_2"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + </widget> + </item> + <item> <layout class="QVBoxLayout" name="verticalLayout_3"> <item> <widget class="QToolButton" name="tool_pandora_love"> + <property name="statusTip"> + <string>Love this song</string> + </property> <property name="text"> <string notr="true">love</string> </property> @@ -154,6 +215,9 @@ </item> <item> <widget class="QToolButton" name="tool_pandora_tired"> + <property name="statusTip"> + <string>Tired of this song (will not play for a month)</string> + </property> <property name="text"> <string notr="true">tired</string> </property> @@ -164,6 +228,9 @@ </item> <item> <widget class="QToolButton" name="tool_pandora_ban"> + <property name="statusTip"> + <string>Ban this song (will never play again)</string> + </property> <property name="text"> <string notr="true">ban</string> </property> @@ -181,9 +248,15 @@ </item> <item> <widget class="QToolButton" name="tool_pandora_info"> + <property name="statusTip"> + <string>View details about song (launches web browser)</string> + </property> <property name="text"> <string notr="true">info</string> </property> + <property name="autoRaise"> + <bool>true</bool> + </property> </widget> </item> </layout> @@ -216,6 +289,35 @@ <item> <widget class="QComboBox" name="combo_pandora_station"/> </item> + <item> + <widget class="QToolButton" name="tool_pandora_stationrm"> + <property name="statusTip"> + <string>Delete current station</string> + </property> + <property name="text"> + <string>rm</string> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="tool_pandora_stationadd"> + <property name="statusTip"> + <string>Create new station</string> + </property> + <property name="text"> + <string>add</string> + </property> + <property name="popupMode"> + <enum>QToolButton::InstantPopup</enum> + </property> + <property name="autoRaise"> + <bool>true</bool> + </property> + </widget> + </item> </layout> </item> </layout> @@ -258,6 +360,25 @@ </property> </widget> </item> + <item row="2" column="1"> + <widget class="QLabel" name="label_7"> + <property name="font"> + <font> + <pointsize>8</pointsize> + <italic>true</italic> + </font> + </property> + <property name="text"> + <string><a href=https://www.pandora.com/account/register>Need an account?</a></string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <property name="openExternalLinks"> + <bool>true</bool> + </property> + </widget> + </item> </layout> </widget> </item> @@ -365,11 +486,17 @@ <string>File</string> </property> <addaction name="separator"/> - <addaction name="actionClose_to_tray_when_running"/> - <addaction name="separator"/> <addaction name="actionClose"/> </widget> + <widget class="QMenu" name="menuView"> + <property name="title"> + <string>View</string> + </property> + <addaction name="action_closeToTray"/> + <addaction name="action_showNotifications"/> + </widget> <addaction name="menuFile"/> + <addaction name="menuView"/> </widget> <widget class="QStatusBar" name="statusbar"/> <widget class="QToolBar" name="toolBar"> @@ -436,7 +563,7 @@ </action> <action name="actionClose"> <property name="text"> - <string>Close</string> + <string>Close Application</string> </property> <property name="shortcut"> <string>Ctrl+Q</string> @@ -445,7 +572,7 @@ <enum>Qt::ApplicationShortcut</enum> </property> </action> - <action name="actionClose_to_tray_when_running"> + <action name="action_closeToTray"> <property name="checkable"> <bool>true</bool> </property> @@ -456,7 +583,36 @@ <string>Close to tray when active</string> </property> </action> + <action name="action_pandora_newstation_artist"> + <property name="text"> + <string>From current artist</string> + </property> + <property name="statusTip"> + <string>Create station from current artist</string> + </property> + </action> + <action name="action_pandora_newstation_song"> + <property name="text"> + <string>From current song</string> + </property> + <property name="statusTip"> + <string>Create station from current song</string> + </property> + </action> + <action name="action_showNotifications"> + <property name="checkable"> + <bool>true</bool> + </property> + <property name="checked"> + <bool>true</bool> + </property> + <property name="text"> + <string>Show song notifications</string> + </property> + </action> </widget> - <resources/> + <resources> + <include location="extra/resources.qrc"/> + </resources> <connections/> </ui> |