/* * Cantata * * Copyright (c) 2011-2013 Craig Drummond * * ---- * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; see the file COPYING. If not, write to * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, * Boston, MA 02110-1301, USA. */ #ifndef DYNAMIC_H #define DYNAMIC_H #include #include #include #include #include #include "actionmodel.h" class QTimer; class NetworkJob; class QUdpSocket; class MulticastReceiver : public QObject { Q_OBJECT public: MulticastReceiver(QObject *parent, const QString &i, const QString &group, quint16 port); Q_SIGNALS: void status(const QString &st); private Q_SLOTS: void processMessages(); private: QUdpSocket *socket; QString id; }; class Dynamic : public ActionModel { Q_OBJECT public: enum Command { Unknown, Id, List, Status, Save, Del, SetActive, Control }; static Command toCommand(const QString &cmd); static QString toString(Command cmd); static void enableDebug(); typedef QMap Rule; struct Entry { Entry(const QString &n=QString()) : name(n) { } bool operator==(const Entry &o) const { return name==o.name; } QString name; QList rules; }; static Dynamic * self(); static const QString constRuleKey; static const QString constArtistKey; static const QString constSimilarArtistsKey; static const QString constAlbumArtistKey; static const QString constComposerKey; static const QString constAlbumKey; static const QString constTitleKey; static const QString constGenreKey; static const QString constDateKey; static const QString constExactKey; static const QString constExcludeKey; Dynamic(); virtual ~Dynamic() { stopReceiver(); } bool isRemote() const { return !dynamicUrl.isEmpty(); } QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const; int rowCount(const QModelIndex &parent = QModelIndex()) const; int columnCount(const QModelIndex&) const { return 1; } bool hasChildren(const QModelIndex &parent) const; QModelIndex parent(const QModelIndex &index) const; QModelIndex index(int row, int column, const QModelIndex &parent) const; QVariant data(const QModelIndex &, int) const; Qt::ItemFlags flags(const QModelIndex &index) const; Entry entry(const QString &e); Entry entry(int row) const { return row>=0 && row & entries() const { return entryList; } void helperMessage(const QString &message) { Q_UNUSED(message) checkHelper(); } Action * startAct() const { return startAction; } Action * stopAct() const { return stopAction; } void enableRemotePolling(bool e); Q_SIGNALS: void running(bool status); void remoteRunning(bool status); void error(const QString &str); // These are for communicating with MPD object (which is in its own thread, so need to talk via signal/slots) void clear(); // These are as the result of asynchronous HTTP calls void saved(bool s); void loadingList(); void loadedList(); public Q_SLOTS: void refreshList(); private Q_SLOTS: void checkHelper(); void checkIfRemoteIsRunning(); void updateRemoteStatus(); void remoteJobFinished(); void dynamicUrlChanged(const QString &url); void parseStatus(const QString &response); private: void pollRemoteHelper(); int getPid() const; bool controlApp(bool isStart); QList::Iterator find(const QString &e); void sendCommand(Command cmd, const QStringList &args=QStringList()); void loadLocal(); void loadRemote(); void parseRemote(const QString &response); void parseId(const QString &response); void checkResponse(const QString &response); void updateEntry(const Entry &e); void stopReceiver(); void startReceiver(const QString &id, const QString &group, quint16 port); private: QTimer *localTimer; QList entryList; QString currentEntry; Action *startAction; Action *stopAction; // For remote dynamic servers... QTimer *remoteTimer; bool remotePollingEnabled; int statusTime; QString lastState; QString dynamicUrl; NetworkJob *currentJob; Command currentCommand; QStringList currentArgs; Entry currentSave; MulticastReceiver *receiver; }; #endif