diff options
author | Ken Moore <ken@ixsystems.com> | 2017-04-04 15:29:57 -0400 |
---|---|---|
committer | Ken Moore <ken@ixsystems.com> | 2017-04-04 15:29:57 -0400 |
commit | 6c4214252d6cd406ce36d79d468be1672f933cf8 (patch) | |
tree | 24970c3e98a382fc1f520d0ae3761cfbc2739196 /src-qt5/desktop-utils | |
parent | Update lumina-mediaplayer a bit more - get the UI starting to reflect the Pan... (diff) | |
download | lumina-6c4214252d6cd406ce36d79d468be1672f933cf8.tar.gz lumina-6c4214252d6cd406ce36d79d468be1672f933cf8.tar.bz2 lumina-6c4214252d6cd406ce36d79d468be1672f933cf8.zip |
Another large batch of work on lumina-mediaplayer. The Pandora streaming capabilities are almost completely done (just missing the interactive search for creating new stations) and very functional right now. Also get the system tray icon functional for the app too.
Diffstat (limited to 'src-qt5/desktop-utils')
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> |