summaryrefslogtreecommitdiffstats
path: root/qtspotifymain.cpp
diff options
context:
space:
mode:
authorEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2009-10-23 21:06:09 +0200
committerEskil Abrahamsen Blomfeldt <eskil.abrahamsen-blomfeldt@nokia.com>2009-10-23 21:06:09 +0200
commit95fc9a918f123ec165f1048aa5ea8b522a4a806a (patch)
tree3a778fa417c954920fbf54071abde912236ace43 /qtspotifymain.cpp
First commit
Diffstat (limited to 'qtspotifymain.cpp')
-rw-r--r--qtspotifymain.cpp431
1 files changed, 431 insertions, 0 deletions
diff --git a/qtspotifymain.cpp b/qtspotifymain.cpp
new file mode 100644
index 0000000..af8e2a2
--- /dev/null
+++ b/qtspotifymain.cpp
@@ -0,0 +1,431 @@
+#include "qtspotifymain.h"
+#include "logindialog.h"
+
+#include <QtCore/QtConcurrentRun>
+#include <QtCore/QFuture>
+#include <QtCore/QFutureWatcher>
+#include <QtCore/QStateMachine>
+#include <QtCore/QState>
+#include <QtCore/QSettings>
+
+#include <QtGui/QMenuBar>
+#include <QtGui/QMenu>
+#include <QtGui/QMessageBox>
+#include <QtGui/QGridLayout>
+#include <QtGui/QInputDialog>
+
+#include "despotify_cpp.h"
+
+Q_DECLARE_METATYPE(playlist *)
+Q_DECLARE_METATYPE(track *)
+
+QtSpotifyMain::QtSpotifyMain(QWidget *parent)
+ : QMainWindow(parent), m_session(0), m_searchResult(0), m_storedPlaylist(0),
+ m_machine(new QStateMachine), m_debugging(false),
+ m_authenticationWatcher(0), m_retrievingPlayListWatcher(0)
+{
+ initUi();
+ initWatchers();
+ initMachine();
+}
+
+QtSpotifyMain::~QtSpotifyMain()
+{
+ QSettings settings("qtspotify", "qtspotify");
+ settings.setValue(QString::fromLatin1("debuggingOutput"),
+ m_ui.actionDebuggingOutput->isChecked());
+
+ if (m_session != 0) {
+ endSession();
+ }
+
+}
+
+void QtSpotifyMain::initUi()
+{
+ m_ui.setupUi(this);
+
+ m_logInDialog = new LogInDialog(this);
+
+ QSettings settings("qtspotify", "qtspotify");
+
+ bool debuggingOutput = settings.value(QString::fromLatin1("debuggingOutput")).toBool();
+ setDebugging(debuggingOutput);
+ m_ui.actionDebuggingOutput->setChecked(debuggingOutput);
+ connect(m_ui.actionDebuggingOutput, SIGNAL(toggled(bool)), this, SLOT(setDebugging(bool)));
+
+ QString userName = settings.value(QString::fromLatin1("userName")).toString();
+ QString password = settings.value(QString::fromLatin1("password")).toString();
+
+ if (userName.isEmpty() || password.isEmpty()) {
+ m_logInDialog->setRememberSettings(false);
+ } else {
+ m_logInDialog->setRememberSettings(true);
+ m_logInDialog->setUserName(userName);
+ m_logInDialog->setPassword(password);
+ }
+
+ setStatusBar(new MyStatusBar(this));
+}
+
+void QtSpotifyMain::initWatchers()
+{
+ m_authenticationWatcher = new QFutureWatcher<bool>(this);
+ connect(m_authenticationWatcher, SIGNAL(finished()), this, SLOT(decideLoginResult()));
+
+ m_retrievingPlayListWatcher = new QFutureWatcher<playlist *>(this);
+ connect(m_retrievingPlayListWatcher, SIGNAL(finished()), this, SLOT(populateSearchBox()));
+}
+
+void QtSpotifyMain::retrievePlayLists()
+{
+ debug(tr("Retrieving playlists"));
+ m_ui.searchComboBox->clear();
+ m_ui.searchComboBox->clearEditText();
+
+ if (m_storedPlaylist != 0)
+ despotify_free_playlist(m_storedPlaylist);
+
+ QFuture<playlist *> retrieving = QtConcurrent::run(despotify_get_stored_playlists, m_session);
+ m_retrievingPlayListWatcher->setFuture(retrieving);
+}
+
+void QtSpotifyMain::selectPlayList()
+{
+ QString searchTerm = m_ui.searchComboBox->currentText();
+ if (m_searchResult != 0) {
+ despotify_free_search(m_searchResult);
+ m_searchResult = 0;
+ }
+
+ m_ui.playList->clear();
+
+ int idx = m_ui.searchComboBox->currentIndex();
+ if (idx >= 0) {
+ QVariant data = m_ui.searchComboBox->itemData(idx);
+ playlist *pl = data.value<playlist *>();
+ if (pl != 0) {
+ debug(tr("Selecting playlist '%1'").arg(QString::fromUtf8(pl->name)));
+ setPlayList(pl->tracks);
+ return;
+ }
+ }
+
+ m_searchResult = despotify_search(m_session, searchTerm.toUtf8().data(), 50);
+ if (m_searchResult != 0) {
+ debug(tr("Searching for '%1'").arg(searchTerm));
+ setPlayList(m_searchResult->tracks);
+ } else {
+ debug(tr("No results when searching for '%1'").arg(searchTerm));
+ }
+}
+
+void QtSpotifyMain::populateSearchBox()
+{
+ debug(tr("Populating search box"));
+ m_storedPlaylist = m_retrievingPlayListWatcher->result();
+ if (m_storedPlaylist == 0)
+ debug(tr("Cannot get stored playlists, error==%1").arg(QString::fromUtf8(m_session->last_error)));
+
+ playlist *pl = m_storedPlaylist;
+ while (pl != 0) {
+ m_ui.searchComboBox->addItem(QString::fromUtf8(pl->name), QVariant::fromValue(pl));
+ debug(tr("Adding '%1'").arg(QString::fromUtf8(pl->name)));
+ pl = pl->next;
+ }
+
+ m_ui.searchComboBox->setEditText(QString());
+}
+
+void QtSpotifyMain::stop()
+{
+ debug(tr("Stopping"));
+ despotify_stop(m_session);
+}
+
+void QtSpotifyMain::pause()
+{
+ debug(tr("Pausing"));
+ despotify_pause(m_session);
+}
+
+void QtSpotifyMain::resume()
+{
+ debug(tr("Resuming"));
+ despotify_resume(m_session);
+}
+
+void QtSpotifyMain::play()
+{
+ if (m_ui.playList->currentItem() == 0) {
+ qWarning("Nothing to play");
+ return ;
+ }
+
+ QVariant data = m_ui.playList->currentItem()->data(0, Qt::UserRole);
+ track *t = data.value<track *>();
+ if (t != 0) {
+ debug(tr("Playing '%1'").arg(t->title));
+ if (!despotify_play(m_session, t, false)) {
+ QMessageBox::information(this, tr("Error when playing track"),
+ tr("Despotify error: %1").arg(QString::fromUtf8(m_session->last_error)));
+ } else {
+ setNewTrack(t);
+ }
+ } else {
+ qWarning("No track connected to current item");
+ }
+}
+
+void QtSpotifyMain::initPlayingState(QState *playingState)
+{
+ QState *notPaused = new QState(playingState);
+ notPaused->setObjectName("notPaused");
+ playingState->setInitialState(notPaused);
+
+ QState *paused = new QState(playingState);
+ paused->setObjectName("paused");
+ connect(paused, SIGNAL(entered()), this, SLOT(pause()));
+ connect(paused, SIGNAL(exited()), this, SLOT(resume()));
+
+ notPaused->addTransition(m_ui.actionPauseOrResume, SIGNAL(triggered()), paused);
+ paused->addTransition(m_ui.actionPauseOrResume, SIGNAL(triggered()), notPaused);
+}
+
+void QtSpotifyMain::decideLoginResult()
+{
+ if (m_authenticationWatcher->result()) {
+ debug(tr("Login succeeded"));
+ emit loggedIn();
+ } else {
+ debug(tr("Login failed, error==%1").arg(QString::fromUtf8(m_session->last_error)));
+ emit loginFailed();
+ }
+}
+
+void QtSpotifyMain::initPlayBackHandlingState(QState *playBackHandlingState)
+{
+ QState *stoppedState = new QState(playBackHandlingState);
+ stoppedState->assignProperty(m_ui.actionPauseOrResume, "enabled", false);
+ stoppedState->assignProperty(m_ui.actionPlayOrStop, "enabled", true);
+ stoppedState->assignProperty(m_ui.albumLabel, "text", QString());
+ stoppedState->assignProperty(m_ui.artistLabel, "text", QString());
+ stoppedState->assignProperty(m_ui.songLabel, "text", QString());
+ stoppedState->setObjectName("stoppedState");
+ connect(stoppedState, SIGNAL(entered()), this, SLOT(stop()));
+ playBackHandlingState->setInitialState(stoppedState);
+
+ QState *playingState = new QState(playBackHandlingState);
+ playingState->setObjectName("playingState");
+ playingState->assignProperty(m_ui.actionPlayOrStop, "enabled", true);
+ connect(playingState, SIGNAL(entered()), this, SLOT(play()));
+ stoppedState->assignProperty(m_ui.actionPauseOrResume, "enabled", true);
+ initPlayingState(playingState);
+
+ stoppedState->addTransition(m_ui.actionPlayOrStop, SIGNAL(triggered()), playingState);
+ playingState->addTransition(m_ui.actionPlayOrStop, SIGNAL(triggered()), stoppedState);
+
+
+ stoppedState->addTransition(m_ui.playList, SIGNAL(doubleClicked(QModelIndex)),
+ playingState);
+ playingState->addTransition(m_ui.playList, SIGNAL(doubleClicked(QModelIndex)),
+ playingState);
+
+}
+
+void QtSpotifyMain::initLoggedInState(QState *loggedIn)
+{
+ QState *playListHandlingState = new QState(loggedIn);
+ playListHandlingState->setObjectName("playListHandlingState");
+ initPlayListHandlingState(playListHandlingState);
+
+ QState *playBackHandlingState = new QState(loggedIn);
+ playBackHandlingState->setObjectName("playBackHandlingState");
+ initPlayBackHandlingState(playBackHandlingState);
+}
+
+void QtSpotifyMain::initPlayListHandlingState(QState *playListHandlingState)
+{
+ QState *idle = new QState(playListHandlingState);
+ idle->assignProperty(m_ui.actionSearch, "enabled", true);
+ idle->assignProperty(m_ui.searchComboBox, "enabled", true);
+ idle->assignProperty(m_ui.playList, "enabled", true);
+ idle->assignProperty(m_ui.actionRetrieveStoredPlaylists, "enabled", true);
+ idle->setObjectName("idle");
+ idle->assignProperty(statusBar(), "statusMessage", tr("Go ahead..."));
+ playListHandlingState->setInitialState(idle);
+
+ QState *requestedRetrieve = new QState(playListHandlingState);
+ requestedRetrieve->assignProperty(m_ui.actionSearch, "enabled", false);
+ requestedRetrieve->assignProperty(m_ui.searchComboBox, "enabled", false);
+ requestedRetrieve->assignProperty(m_ui.playList, "enabled", true);
+ requestedRetrieve->assignProperty(m_ui.actionRetrieveStoredPlaylists, "enabled", false);
+ connect(requestedRetrieve, SIGNAL(entered()), this, SLOT(retrievePlayLists()));
+ requestedRetrieve->setObjectName("requestedRetrieve");
+
+ QState *playListSelected = new QState(playListHandlingState);
+ playListSelected->setObjectName("playListSelected");
+ connect(playListSelected, SIGNAL(entered()), this, SLOT(selectPlayList()));
+
+ idle->addTransition(m_ui.searchComboBox, SIGNAL(activated(QString)),
+ playListSelected);
+ idle->addTransition(m_ui.actionRetrieveStoredPlaylists, SIGNAL(triggered()),
+ requestedRetrieve);
+
+ playListSelected->addTransition(idle);
+
+ requestedRetrieve->addTransition(m_retrievingPlayListWatcher, SIGNAL(finished()), idle);
+}
+
+void QtSpotifyMain::debug(const QString &text)
+{
+ if (m_debugging)
+ qDebug() << text;
+}
+
+void QtSpotifyMain::initLoggingInState(QState *loggingInState)
+{
+ QState *logInDialogShown = new QState(loggingInState);
+ connect(logInDialogShown, SIGNAL(entered()), m_logInDialog, SLOT(exec()));
+ logInDialogShown->assignProperty(statusBar(), "statusMessage", tr("Waiting for input"));
+ logInDialogShown->setObjectName("logInDialogShown");
+ loggingInState->setInitialState(logInDialogShown);
+
+ QState *logInDialogAccepted = new QState(loggingInState);
+ logInDialogAccepted->assignProperty(statusBar(), "statusMessage", tr("Trying to log in..."));
+ logInDialogAccepted->setObjectName("logInDialogAccepted");
+ connect(logInDialogAccepted, SIGNAL(entered()), this, SLOT(logIn()));
+
+ logInDialogShown->addTransition(m_logInDialog, SIGNAL(accepted()), logInDialogAccepted);
+}
+
+void QtSpotifyMain::initMachine()
+{
+ QState *notLoggedInState = new QState(m_machine);
+ notLoggedInState->assignProperty(m_ui.actionLogIn, "enabled", true);
+ notLoggedInState->assignProperty(m_ui.actionLogOut, "enabled", false);
+ notLoggedInState->assignProperty(m_ui.actionSearch, "enabled", false);
+ notLoggedInState->assignProperty(m_ui.centralwidget, "enabled", false);
+ notLoggedInState->assignProperty(m_ui.actionPauseOrResume, "enabled", false);
+ notLoggedInState->assignProperty(m_ui.actionPlayOrStop, "enabled", false);
+ notLoggedInState->assignProperty(m_ui.actionRetrieveStoredPlaylists, "enabled", false);
+ notLoggedInState->assignProperty(statusBar(), "statusMessage", tr("Not logged in"));
+ notLoggedInState->assignProperty(this, "debuggingMessage", tr("Entered 'notLoggedInState'"));
+ notLoggedInState->setObjectName("notLoggedInState");
+ m_machine->setInitialState(notLoggedInState);
+
+ QState *loggingInState = new QState(m_machine);
+ loggingInState->assignProperty(m_ui.actionLogIn, "enabled", false);
+ loggingInState->assignProperty(m_ui.actionLogOut, "enabled", false);
+ loggingInState->assignProperty(m_ui.actionSearch, "enabled", false);
+ loggingInState->assignProperty(m_ui.centralwidget, "enabled", false);
+ loggingInState->assignProperty(m_ui.actionPauseOrResume, "enabled", false);
+ loggingInState->assignProperty(m_ui.actionPlayOrStop, "enabled", false);
+ loggingInState->assignProperty(m_ui.actionRetrieveStoredPlaylists, "enabled", false);
+ loggingInState->setObjectName("loggingInState");
+ loggingInState->assignProperty(this, "debuggingMessage", tr("Entered 'loggingInState'"));
+ initLoggingInState(loggingInState);
+
+ QState *loggedInState = new QState(QState::ParallelStates, m_machine);
+ loggedInState->assignProperty(m_ui.actionLogIn, "enabled", false);
+ loggedInState->assignProperty(m_ui.actionLogOut, "enabled", true);
+ loggedInState->assignProperty(m_ui.centralwidget, "enabled", true);
+ loggedInState->setObjectName("loggedInState");
+ loggedInState->assignProperty(this, "debuggingMessage", tr("Entered 'loggedInState'"));
+ initLoggedInState(loggedInState);
+
+ notLoggedInState->addTransition(m_ui.actionLogIn, SIGNAL(triggered()), loggingInState);
+ loggingInState->addTransition(m_logInDialog, SIGNAL(rejected()), notLoggedInState);
+ loggingInState->addTransition(this, SIGNAL(loginFailed()), notLoggedInState);
+ loggingInState->addTransition(this, SIGNAL(loggedIn()), loggedInState);
+
+ m_machine->start();
+}
+
+void QtSpotifyMain::setPlayList(track *t)
+{
+ debug(tr("Setting new playlist"));
+ m_ui.playList->clear();
+ while (t != 0) {
+ QTreeWidgetItem *w = new QTreeWidgetItem();
+
+ w->setData(0, Qt::DisplayRole, QString::fromUtf8(t->artist->name));
+ w->setData(1, Qt::DisplayRole, QString::fromUtf8(t->title));
+ w->setData(2, Qt::DisplayRole, QString::fromUtf8(t->album));
+ w->setData(0, Qt::UserRole, QVariant::fromValue(t));
+
+ m_ui.playList->addTopLevelItem(w);
+
+ t = t->next;
+ }
+}
+
+static void callback(despotify_session *session, int signal, void *data, void *callbackData)
+{
+ if (callbackData == 0 || data == 0 || session == 0)
+ return;
+
+ switch (signal) {
+ case DESPOTIFY_TRACK_CHANGE:
+ {
+ track *t = reinterpret_cast<track *>(data);
+ QtSpotifyMain *qsm = reinterpret_cast<QtSpotifyMain*>(session->client_callback_data);
+ qsm->setNewTrack(t);
+ }
+ };
+}
+
+void QtSpotifyMain::endSession()
+{
+ debug("Ending session");
+ if (m_storedPlaylist != 0)
+ despotify_free_playlist(m_storedPlaylist);
+
+ if (m_searchResult != 0) {
+ despotify_free_search(m_searchResult);
+ m_searchResult = 0;
+ }
+
+ m_ui.searchComboBox->clear();
+ despotify_exit(m_session);
+}
+
+void QtSpotifyMain::logIn()
+{
+ if (m_session == 0) {
+ m_session = despotify_init_client(callback, this);
+ if (m_session == 0) {
+ emit loginFailed();
+ return;
+ }
+ }
+
+ QString userName = m_logInDialog->userName();
+ QString password = m_logInDialog->password();
+
+ QSettings settings("qtspotify", "qtspotify");
+ if (m_logInDialog->rememberSettings()) {
+ debug("Saving settings");
+ settings.setValue(QString::fromLatin1("userName"), userName);
+ settings.setValue(QString::fromLatin1("password"), password);
+ } else {
+ debug("Clearing settings");
+ settings.remove(QString::fromLatin1("userName"));
+ settings.remove(QString::fromLatin1("password"));
+ }
+
+ debug(tr("Logging in as user '%1'").arg(userName));
+ QFuture<bool> authentication = QtConcurrent::run(despotify_authenticate,
+ m_session,
+ userName.toLocal8Bit(),
+ password.toLocal8Bit());
+ m_authenticationWatcher->setFuture(authentication);
+}
+
+void QtSpotifyMain::setNewTrack(track *t)
+{
+ debug(tr("Setting new track '%1'").arg(QString::fromUtf8(t->title)));
+ m_ui.artistLabel->setText(QString::fromUtf8(t->artist->name));
+ m_ui.albumLabel->setText(QString::fromUtf8(t->album));
+ m_ui.songLabel->setText(QString::fromUtf8(t->title));
+}