Fix for Bug [#6295] Application polls vlc server even when the UI is not visible...
[vlc-remote] / src / playermainwindow.cpp
1   /*   VLC-REMOTE for MAEMO 5
2   *   Copyright (C) 2010 Schutz Sacha <istdasklar@gmail.com>, Dru Moore <usr@dru-id.co.uk>, Yann Nave <yannux@onbebop.net>
3   *   This program is free software; you can redistribute it and/or modify
4   *   it under the terms of the GNU General Public License version 2,
5   *   or (at your option) any later version, as published by the Free
6   *   Software Foundation
7   *
8   *   This program is distributed in the hope that it will be useful,
9   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11   *   GNU General Public License for more details
12   *
13   *   You should have received a copy of the GNU General Public
14   *   License along with this program; if not, write to the
15   *   Free Software Foundation, Inc.,
16   *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
17   */
18   //#include <QDebug>
19   #include <QTime>
20   #include <QtGui>
21   #include "playermainwindow.h"
22   #include "ui_playermainwindow.h"
23   #include "configdialog.h"
24   #include "aboutdialog.h"
25   #include "accountdialog.h"
26   #include "settingsdialog.h"
27   #include "appsettings.h"
28 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
29   #include <QMaemo5InformationBox>
30   #include <mce/dbus-names.h>
31   #include <mce/mode-names.h>
32   #include <QDBusConnection>
33   #include <QDBusMessage>
34   #include <QDBusInterface>
35 #endif
36 #include <QMessageBox>
37
38 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
39 QDBusConnection PlayerMainWindow::dBusConnection = QDBusConnection::systemBus();
40 QDBusInterface* PlayerMainWindow::dBusInterface = new QDBusInterface(MCE_SERVICE, MCE_REQUEST_PATH,
41                                    MCE_REQUEST_IF, dBusConnection);
42 #endif
43
44   PlayerMainWindow::PlayerMainWindow(QWidget *parent) :
45           QMainWindow(parent),
46           ui(new Ui::PlayerMainWindow)
47   {
48       ui->setupUi(this);
49       setWindowTitle("Vlc remote");
50
51       mIsFirstStatusCall = true;
52
53       mTimer = new QTimer(this);
54       mNetManager = new QNetworkAccessManager(this);
55       mPlayListMainWindow = new PlayListMainWindow;
56       mBrowserMainWindow = new BrowseMainWindow;
57       mFavouritesMainWindow = new FavouritesMainWindow;
58
59       mVolume = 100;
60       mMuted = false;
61
62       mIsLandscape = true;
63
64       ui->playlistButton->setIcon(QIcon::fromTheme("notes_bullets"));
65       ui->browseButton->setIcon(QIcon::fromTheme("filemanager_media_folder"));
66
67       ui->previousButton->setIcon(QIcon::fromTheme("pdf_viewer_first_page"));
68       ui->nextButton->setIcon(QIcon::fromTheme("pdf_viewer_last_page"));
69       ui->playpauseButton->setIcon(QIcon::fromTheme("camera_playback"));
70       ui->stopButton->setIcon(QIcon::fromTheme("camera_video_stop"));
71       ui->fullscreenButton->setIcon(QIcon::fromTheme("general_fullsize"));
72       ui->volDown->setIcon(QIcon::fromTheme("statusarea_volumelevel1"));
73       ui->volUp->setIcon(QIcon::fromTheme("statusarea_volumelevel4"));
74       ui->volMute->setIcon(QIcon::fromTheme("statusarea_volume_mute"));
75
76       ui->labelArtPortrait->setVisible(false);
77       ui->labelArtLandscape->setVisible(false);
78
79       ui->labelTitle->setTextFormat(Qt::RichText);
80       ui->labelArtist->setTextFormat(Qt::RichText);
81       ui->labelAlbum->setTextFormat(Qt::RichText);
82
83
84   #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
85       // Handle screen state on / off
86       dBusConnection.connect(MCE_SERVICE, MCE_SIGNAL_PATH, MCE_SIGNAL_IF,
87                                  MCE_DISPLAY_SIG, this, SLOT(displayStateChanged(const QDBusMessage &)));
88
89       mPlayListMainWindow->setParent(this);
90       mPlayListMainWindow->setAttribute(Qt::WA_Maemo5StackedWindow, true);
91       setAttribute(Qt::WA_Maemo5StackedWindow, true);
92       mPlayListMainWindow->setWindowFlags(mPlayListMainWindow->windowFlags() | Qt::Window);
93
94       mBrowserMainWindow->setParent(this);
95       mBrowserMainWindow->setAttribute(Qt::WA_Maemo5StackedWindow, true);
96       setAttribute(Qt::WA_Maemo5StackedWindow, true);
97       mBrowserMainWindow->setWindowFlags(mBrowserMainWindow->windowFlags() | Qt::Window);
98
99       mFavouritesMainWindow->setParent(this);
100       mFavouritesMainWindow->setAttribute(Qt::WA_Maemo5StackedWindow, true);
101       setAttribute(Qt::WA_Maemo5StackedWindow, true);
102       mFavouritesMainWindow->setWindowFlags(mFavouritesMainWindow->windowFlags() | Qt::Window);
103
104       connect(QApplication::desktop(), SIGNAL(resized(int)), this, SLOT(orientationChanged()));
105
106   #endif
107
108       connect(mTimer,SIGNAL(timeout()),this,SLOT(askStatus()));
109       connect(ui->actionSettings,SIGNAL(triggered()),this,SLOT(showSettings()));
110       connect(ui->actionConfiguration,SIGNAL(triggered()),this,SLOT(showConfig()));
111       connect(ui->actionAbout,SIGNAL(triggered()),this,SLOT(showAbout()));
112       connect(ui->actionFavourites,SIGNAL(triggered()),this,SLOT(showFavourites()));
113       //connect(ui->actionPortrait,SIGNAL(triggered()),this,SLOT(setPortrait()));
114       //connect(ui->actionLandscape,SIGNAL(triggered()),this,SLOT(setLandscape()));
115       //connect(ui->actionAutoRotate,SIGNAL(triggered()),this,SLOT(setAutoRotate()));
116       connect(ui->playlistButton,SIGNAL(clicked()),mPlayListMainWindow,SLOT(show()));
117       connect(ui->playlistButton,SIGNAL(clicked()),mPlayListMainWindow,SLOT(showPlayList()));
118       connect(ui->browseButton,SIGNAL(clicked()),mBrowserMainWindow,SLOT(show()));
119       connect(ui->browseButton,SIGNAL(clicked()),mBrowserMainWindow,SLOT(showCurrentDirectory()));
120
121       connect(ui->playpauseButton,SIGNAL(clicked()),this,SLOT(playpause()));
122       connect(ui->stopButton,SIGNAL(clicked()),this,SLOT(stop()));
123       connect(ui->previousButton,SIGNAL(clicked()),this,SLOT(previous()));
124       connect(ui->nextButton,SIGNAL(clicked()),this,SLOT(next()));
125       connect(ui->fullscreenButton,SIGNAL(clicked()),this,SLOT(fullscreen()));
126       connect(ui->volUp,SIGNAL(clicked()),this,SLOT(volUp()));
127       connect(ui->volDown,SIGNAL(clicked()),this,SLOT(volDown()));
128       connect(ui->volMute,SIGNAL(clicked()),this,SLOT(volMute()));
129       connect(ui->slider,SIGNAL(sliderMoved(int)),this,SLOT(slide(int)));
130
131       connect(mPlayListMainWindow, SIGNAL(idUpdated(int,bool,QString)), this, SLOT(playlistIdUpdated(int, bool, QString)));
132       connect(mBrowserMainWindow, SIGNAL(showFavouritesWindow()), this, SLOT(showFavourites()));
133
134       connect(mFavouritesMainWindow, SIGNAL(browseDirectory(QString)), mFavouritesMainWindow, SLOT(close()));
135       connect(mFavouritesMainWindow, SIGNAL(browseDirectory(QString)), mBrowserMainWindow, SLOT(browseDirectory(QString)));
136       connect(mFavouritesMainWindow, SIGNAL(closeSignal()), mBrowserMainWindow, SLOT(show()));
137
138
139       // check if last used connection is still valid or showConfig
140
141       // check for network
142       if (AppSettings::isConnected()) {
143           QSettings settings;
144           QString last_ip = AppSettings::getCurrentIp(); // AccountDialog::currentIp();
145           if (!last_ip.isNull() && !last_ip.isEmpty()) {
146               QTcpSocket * socket = new QTcpSocket;
147               if(last_ip.contains(":"))
148               {
149                   QStringList hostSplit = last_ip.split(":");
150                   QString ip   = hostSplit.at(0);
151                   QString port = hostSplit.at(1);
152                   socket->connectToHost(ip,port.toInt());
153               }
154               else {
155                   socket->connectToHost(last_ip,8080);
156               }
157               if (!socket->waitForConnected(AppSettings::getConnectionTimeout())) {
158                      showConfig();
159                  }
160               else {
161                   mIp= last_ip;
162
163                  mPlayListMainWindow->init();
164                  mBrowserMainWindow->init();
165                  mTimer->start(AppSettings::getStatusPollTimeout());
166                  askStatus();
167               }
168               delete socket;
169           }
170           else {
171             showConfig();
172           }
173       }
174       else {
175 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
176         QMaemo5InformationBox::information(this, tr("Network unavailable!"), QMaemo5InformationBox::DefaultTimeout);
177 #endif
178           showConfig();
179       }
180   }
181   
182
183   PlayerMainWindow::~PlayerMainWindow()
184   {
185       delete ui;
186   }
187
188   void PlayerMainWindow::changeEvent(QEvent *e)
189   {
190       QMainWindow::changeEvent(e);
191       switch (e->type()) {
192       case QEvent::LanguageChange:
193           ui->retranslateUi(this);
194           break;
195       default:
196           break;
197       }
198   }
199
200 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
201   void PlayerMainWindow::displayStateChanged(const QDBusMessage &message)
202   {
203       QString state = message.arguments().at(0).toString();
204       if (!state.isEmpty()) {
205           if (state == MCE_DISPLAY_ON_STRING) {
206               mTimer->start(AppSettings::getStatusPollTimeout());
207           }
208           else if (state == MCE_DISPLAY_OFF_STRING) {
209               mTimer->stop();
210           }
211       }
212   }
213 #endif
214
215   void PlayerMainWindow::showFavourites() {
216       mFavouritesMainWindow->show();
217       mFavouritesMainWindow->init();
218   }
219
220   void PlayerMainWindow::updateFromSettings()
221   {
222     #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
223     switch (AppSettings::getOrientation()) {
224       case LANDSCAPE:
225           this->setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
226           break;
227       case PORTRAIT:
228           this->setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
229           break;
230       case AUTO_ROTATE:
231           this->setAttribute(Qt::WA_Maemo5AutoOrientation, true);
232           break;
233     }
234     #endif
235     if (AppSettings::getShowAlbumArt()) {
236         this->mIsFirstStatusCall = true;
237     }
238     mTimer->start(AppSettings::getStatusPollTimeout());
239   }
240
241   void PlayerMainWindow::setPortrait()
242   {
243     #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
244       AppSettings::setOrientation(PORTRAIT);
245     this->setAttribute(Qt::WA_Maemo5PortraitOrientation, true);
246     #endif
247   }
248
249   void PlayerMainWindow::setLandscape()
250   {
251     #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
252       AppSettings::setOrientation(LANDSCAPE);
253     this->setAttribute(Qt::WA_Maemo5LandscapeOrientation, true);
254     #endif
255   }
256
257   void PlayerMainWindow::setAutoRotate()
258   {
259     #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
260       AppSettings::setOrientation(AUTO_ROTATE);
261     this->setAttribute(Qt::WA_Maemo5AutoOrientation, true);
262     #endif
263   }
264
265   void PlayerMainWindow::orientationChanged() {
266       QRect screenGeometry = QApplication::desktop()->screenGeometry();
267       mIsLandscape = (screenGeometry.width() > screenGeometry.height());
268       if (mHasImage) {
269           if (mIsLandscape) {
270               ui->labelArtPortrait->setVisible(false);
271               ui->labelArtLandscape->setVisible(true);
272           }
273           else {
274               ui->labelArtLandscape->setVisible(false);
275               ui->labelArtPortrait->setVisible(true);
276           }
277       }
278       else {
279           ui->labelArtLandscape->setVisible(false);
280           ui->labelArtPortrait->setVisible(false);
281       }
282   }
283
284   void PlayerMainWindow::playpause()
285   {
286       // NB. There is no guarentee that our current state is the real current state.
287       // This is due to the polling frequency and possibility of user interaction directly on the server.
288       // Still this is probably better than nothing and our next real poll will set us straight again.
289       if (PAUSED == mCurrentStatus.state) {
290         mCurrentStatus.state = PLAYING;
291         pause();
292         updateUiWithCurrentStatus();
293       }
294       else if (PLAYING == mCurrentStatus.state) {
295         mCurrentStatus.state = PAUSED;
296         pause();
297         updateUiWithCurrentStatus();
298       }
299       else {
300         // could be STOP or UNKNOWN, either way there is no guarentee we will enter a playing state next.
301         // So don't update the current state or UI
302         // Ideally we would try to find a way to check the current state again but this could lead to an infinite loop!
303         play();
304       }
305   }
306   void PlayerMainWindow::play()
307   {
308       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=pl_play")));
309   }
310   void PlayerMainWindow::stop()
311   {
312       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=pl_stop")));
313   }
314   void PlayerMainWindow::pause()
315   {
316       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=pl_pause")));
317   }
318   void PlayerMainWindow::previous()
319   {
320       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=pl_previous")));
321   }
322   void PlayerMainWindow::next()
323   {
324       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=pl_next")));
325   }
326   void PlayerMainWindow::fullscreen()
327   {
328       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=fullscreen")));
329   }
330   void PlayerMainWindow::volUp()
331   {
332       QUrl url = QUrl("http://"+mIp+"/requests/status.xml?command=volume");
333       url.addEncodedQueryItem(QByteArray("val"), QByteArray("%2B10"));
334       mNetManager->get(QNetworkRequest(url));
335   }
336   void PlayerMainWindow::volDown()
337   {
338       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=volume&val=-10")));
339   }
340   void PlayerMainWindow::volMute()
341   {
342       this->mMuted = !this->mMuted;
343       if (this->mMuted) {
344           mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=volume&val=0")));
345       }
346       else {
347           mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=volume&val="+QString::number(this->mVolume))));
348       }
349   }
350   void PlayerMainWindow::slide(int value)
351   {
352       mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml?command=seek&val="+QString::number(value)+"%25")));
353   }
354
355   void PlayerMainWindow::showSettings()
356   {
357     SettingsDialog * dialog = new SettingsDialog(this);
358     connect(dialog, SIGNAL(closeSignal()), this, SLOT(updateFromSettings()));
359     dialog->exec();
360   }
361   void PlayerMainWindow::showConfig()
362   {
363       mTimer->stop();
364       // check for network
365       if (AppSettings::isConnected()) {
366           AccountDialog * dialog = new AccountDialog(this);
367           dialog->exec();
368
369           mIp= AppSettings::getCurrentIp(); //AccountDialog::currentIp();
370
371           mPlayListMainWindow->init();
372           mBrowserMainWindow->init();
373           mTimer->start(AppSettings::getStatusPollTimeout());
374           askStatus();
375       }
376       else {
377 #if defined(Q_WS_S60) || defined(Q_WS_MAEMO_5)
378         QMaemo5InformationBox::information(this, tr("Network unavailable!"), QMaemo5InformationBox::DefaultTimeout);
379 #endif
380         QTimer::singleShot(AppSettings::getRetryNetworkTimeout(), this, SLOT(showConfig()));
381       }
382   }
383   void PlayerMainWindow::showAbout()
384   {
385
386       AboutDialog * dialog = new AboutDialog;
387       dialog->exec();
388
389   }
390
391   void PlayerMainWindow::askStatus()
392   {
393       if (AppSettings::isConnected()) {
394           QNetworkReply * reply =  mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/requests/status.xml")));
395           connect(reply,SIGNAL(readyRead()),this,SLOT(parseXmlStatus()));
396           connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(error(QNetworkReply::NetworkError)));
397       }
398       else {
399         showConfig(); // this will handle stopping and restarting the timer.
400       }
401   }
402
403   void PlayerMainWindow::parseXmlStatus()
404   {
405       QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());
406       QDomDocument doc;
407       doc.setContent(reply->readAll());
408       delete reply;
409       QDomElement docElem = doc.documentElement();
410       VlcStatusState oldState = mCurrentStatus.state;
411       // Get the raw values
412       int volume = docElem.namedItem("volume").toElement().text().toInt();
413       int length = docElem.namedItem("length").toElement().text().toInt();
414       int time = docElem.namedItem("time").toElement().text().toInt();
415       int position = docElem.namedItem("position").toElement().text().toInt();
416       int random = docElem.namedItem("random").toElement().text().toInt();
417       int loop = docElem.namedItem("loop").toElement().text().toInt();
418       int repeat = docElem.namedItem("repeat").toElement().text().toInt();
419       QString state = docElem.namedItem("state").toElement().text();
420       QDomNode infoNode =  docElem.namedItem("information");
421       QDomNode metaInfoNode =  infoNode.namedItem("meta-information");
422       QString title = metaInfoNode.namedItem("title").toElement().text().replace("\\\\", "\\");
423       // if it's a file style title fix it up
424       if (40 < title.length()) {
425           if (0 < title.lastIndexOf("\\")) {
426               title = title.right(title.length() - (title.lastIndexOf("\\") + 1));
427           }
428           else if (0 < title.lastIndexOf("/")) {
429               title = title.right(title.length() - (title.lastIndexOf("/") + 1));
430           }
431       }
432       QString artist = metaInfoNode.namedItem("artist").toElement().text();
433       QString album = metaInfoNode.namedItem("album").toElement().text();
434       QString now_playing = metaInfoNode.namedItem("now_playing").toElement().text();
435       QString art_url = metaInfoNode.namedItem("art_url").toElement().text();
436       // Populate the current status structure
437       // now would be a good time to work out if we are a new track / file or not.
438       // key if we are going to look for album art later
439       // for now we check length and title this will require further examination later
440       if (!state.isNull() && !state.isEmpty()) {
441           if (0 == QString::compare("playing", state, Qt::CaseInsensitive)) {
442             mCurrentStatus.state = PLAYING;
443           }
444           else if (0 == QString::compare("paused", state, Qt::CaseInsensitive)) {
445             mCurrentStatus.state = PAUSED;
446           }
447           else if (0 == QString::compare("stop", state, Qt::CaseInsensitive)) {
448             mCurrentStatus.state = STOP;
449           }
450           else {
451             mCurrentStatus.state = UNKNOWN;
452             mIsFirstStatusCall = true;
453           }
454       }
455       else {
456           mCurrentStatus.state = UNKNOWN;
457           mIsFirstStatusCall = true;
458       }
459       mCurrentStatus.newtrack = true;
460       if (mIsFirstStatusCall) {
461           mIsFirstStatusCall = false;
462           mCurrentStatus.newtrack = true; // unneeded but self-documenting
463       }
464       else if (STOP == oldState && STOP != mCurrentStatus.state) {
465           mCurrentStatus.newtrack = true; // unneeded but self-documenting
466       }
467       else {
468           if ( (0 == mCurrentStatus.length || STOP == mCurrentStatus.state) // stopped or null
469                   || // same track as current playing
470                (mCurrentStatus.length == length && !mCurrentStatus.title.isNull() && !title.isNull() && 0 == QString::compare(mCurrentStatus.title, title)) ){
471             mCurrentStatus.newtrack = false;
472           }
473       }
474       mCurrentStatus.volume = volume;
475       mCurrentStatus.length = length;
476       mCurrentStatus.time = time;
477       mCurrentStatus.position = position;
478       mCurrentStatus.random = (1 == random);
479       mCurrentStatus.loop = (1 == loop);
480       mCurrentStatus.repeat = (1 == repeat);
481       mCurrentStatus.title = title;
482       mCurrentStatus.artist = artist;
483       mCurrentStatus.album = album;
484       mCurrentStatus.nowplaying = now_playing;
485       mCurrentStatus.hasart = (!art_url.isNull() && !art_url.isEmpty());
486       // What's our mute status?
487       if (0 < mCurrentStatus.volume) {
488           this->mVolume = mCurrentStatus.volume;
489           this->mMuted = false;
490       }
491       else {
492           this->mMuted = true;
493       }
494       // Update the UI
495       updateUiWithCurrentStatus();
496
497   }
498
499   void PlayerMainWindow::updateUiWithCurrentStatus() {
500       // position
501       QTime timePosition(0,0,0) ;
502       timePosition =  timePosition.addSecs(mCurrentStatus.time);
503
504       ui->timeLabel->setText(timePosition.toString("h:mm:ss"));
505
506       // duration
507       if (0 < mCurrentStatus.length) {
508           QTime timeDuration(0,0,0) ;
509           timeDuration =  timeDuration.addSecs(mCurrentStatus.length);
510
511           ui->durationLabel->setText(timeDuration.toString("h:mm:ss"));
512       }
513       else {
514           ui->durationLabel->setText("0:00:00");
515       }
516
517
518       if (mCurrentStatus.position >= 0 && mCurrentStatus.position <= 100) {
519           ui->slider->blockSignals(true);
520           ui->slider->setValue(mCurrentStatus.position);
521           ui->slider->blockSignals(false);
522       }
523
524       ui->labelTitle->setText(mCurrentStatus.title);
525       ui->labelArtist->setText(mCurrentStatus.artist);
526       ui->labelAlbum->setText(mCurrentStatus.album);
527
528       if (PLAYING == mCurrentStatus.state) {
529           ui->playpauseButton->setIcon(QIcon::fromTheme("camera_video_pause"));
530       }
531       else {
532           ui->playpauseButton->setIcon(QIcon::fromTheme("camera_playback"));
533       }
534
535       if (STOP == mCurrentStatus.state || !AppSettings::getShowAlbumArt()) {
536           ui->labelArtPortrait->setVisible(false);
537           ui->labelArtLandscape->setVisible(false);
538       }
539
540       if (mCurrentStatus.newtrack && STOP != mCurrentStatus.state) {
541           // potential actions:
542           //   rebuild display layout
543           //   retrieve album art
544           if (AppSettings::getShowAlbumArt()) {
545               mHasImage = false;
546               QTimer::singleShot(AppSettings::getRetrieveArtTimeout(), mPlayListMainWindow, SLOT(requestPlayList()));
547           }
548       }
549       // Update the buttons on the playlist window
550       if (NULL != this->mPlayListMainWindow) {
551         this->mPlayListMainWindow->updateUiWithCurrentStatus(& mCurrentStatus);
552       }
553
554   }
555   void PlayerMainWindow::playlistIdUpdated(int id, bool hasart, QString extension) {
556       Q_UNUSED(extension);
557       if (hasart) {
558           getCoverArt(id);
559       }
560       else {
561           ui->labelArtLandscape->setVisible(false);
562           ui->labelArtPortrait->setVisible(false);
563           // could use a default graphic from extension here!
564           // setCoverArtFromPixmap();
565       }
566   }
567   void PlayerMainWindow::error(QNetworkReply::NetworkError code) {
568       Q_UNUSED(code);
569       //qDebug() << "Error Code: " << code;
570   }
571   void PlayerMainWindow::readReady() {
572     QNetworkReply * reply = qobject_cast<QNetworkReply*>(sender());
573     // append to buffer
574     mResponse += reply->readAll();
575   }
576   void PlayerMainWindow::finished(QNetworkReply * reply) {
577     // now we can call setCoverArt to process the full buffers
578     this->setCoverArt(mResponse);
579     // only interested in finished signals
580     disconnect(mNetManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finished(QNetworkReply *)));
581     delete reply;
582   }
583   void PlayerMainWindow::getCoverArt(int id) {
584     mResponse.clear();
585     QNetworkReply * reply =  mNetManager->get(QNetworkRequest(QUrl("http://"+mIp+"/art?id=" + QString::number(id))));
586     connect(reply,SIGNAL(readyRead()),this,SLOT(readReady()));
587     connect(reply,SIGNAL(error(QNetworkReply::NetworkError)),this,SLOT(error(QNetworkReply::NetworkError)));
588     connect(mNetManager,SIGNAL(finished(QNetworkReply *)),this,SLOT(finished(QNetworkReply *)));
589
590   }
591   void PlayerMainWindow::setCoverArt(const QByteArray data) {
592     QPixmap* image = new QPixmap();
593     if (image->loadFromData(data)) {
594         mHasImage = true;
595         ui->labelArtLandscape->setPixmap(image->scaledToHeight(160, Qt::SmoothTransformation));
596         ui->labelArtPortrait->setPixmap(image->scaledToHeight(310, Qt::SmoothTransformation));
597         if (mIsLandscape) {
598             ui->labelArtPortrait->setVisible(false);
599             ui->labelArtLandscape->setVisible(true);
600         }
601         else {
602             ui->labelArtLandscape->setVisible(false);
603             ui->labelArtPortrait->setVisible(true);
604         }
605     }
606     else {
607         ui->labelArtPortrait->setVisible(false);
608         ui->labelArtLandscape->setVisible(false);
609     }
610     delete image;
611   }
612   void PlayerMainWindow::setCoverArtFromPixmap(QPixmap image) {
613     mHasImage = true;
614     ui->labelArtLandscape->setPixmap(image.scaledToHeight(160, Qt::SmoothTransformation));
615     ui->labelArtPortrait->setPixmap(image.scaledToHeight(310, Qt::SmoothTransformation));
616     if (mIsLandscape) {
617         ui->labelArtPortrait->setVisible(false);
618         ui->labelArtLandscape->setVisible(true);
619     }
620     else {
621         ui->labelArtLandscape->setVisible(false);
622         ui->labelArtPortrait->setVisible(true);
623     }
624   }
625   void PlayerMainWindow::closeEvent(QCloseEvent * event) {
626       if (!AppSettings::getAlertOnClose() || PLAYING != mCurrentStatus.state) {
627           event->accept();
628       }
629       else { // handle alert
630           if (QMessageBox::Yes == QMessageBox::question(this
631                                                        , tr("Really quit?")
632                                                        , tr("You currently have media playing on your remote machine. Are you sure you wish to quit vlc-remote?")
633                                                        , QMessageBox::Yes | QMessageBox::No
634                                                        , QMessageBox::No)) {
635             event->accept();
636           }
637           else {
638             event->ignore();
639           }
640       }
641   }
642