diff --git a/SoundBand/Header.qml b/SoundBand/Header.qml index 99e1ac9..1014a3e 100644 --- a/SoundBand/Header.qml +++ b/SoundBand/Header.qml @@ -10,7 +10,7 @@ Item { property int currentSongId: 0 property string currentSongName: qsTr("Song is not selected") - property bool playState: false + property bool playState: syncEngine.playState === 1; function changeSong(id, name){ @@ -84,7 +84,6 @@ Item { onClicked: { syncEngine.pause(playState); - playState = !playState; } } @@ -123,7 +122,7 @@ Item { anchors.right: parent.right; anchors.rightMargin: Utils.dp(Screen.pixelDensity, 5) onClicked: { - state = ++state % 4; + state = ++state % 5; syncEngine.setRepeat(state) } } diff --git a/SoundBand/syncengine.cpp b/SoundBand/syncengine.cpp index d381791..1eb35da 100644 --- a/SoundBand/syncengine.cpp +++ b/SoundBand/syncengine.cpp @@ -8,9 +8,11 @@ SyncEngine::SyncEngine() sqlApi = sync->getSqlApi(); connect(sync, SIGNAL(networkStateChange()), this, SIGNAL(serversCountChanged())); + connect(sync, SIGNAL(currentPlayListChanged()), this, SIGNAL(currentPlayListNameChanged())); connect(sync, SIGNAL(currentPlayListChanged()), this, SIGNAL(currentPlayListCountChanged())); connect(sync, SIGNAL(seekChanged(qint64)), this, SLOT(seekChanged(qint64))); connect(sync, SIGNAL(currentSongChanged()), this, SIGNAL(currentSongChanged())); + connect(sync, SIGNAL(playStateChanged()), this, SIGNAL(playStateChanged())); } @@ -251,6 +253,10 @@ bool SyncEngine::removeFromPlayList(int id, const QString &playList){ } +int SyncEngine::playState()const{ + return sync->playState(); +} + SyncEngine::~SyncEngine(){ disconnect(sync, SIGNAL(networkStateChange()), this, SIGNAL(serversCountChanged())); delete sync; diff --git a/SoundBand/syncengine.h b/SoundBand/syncengine.h index 35c53db..6be2ad1 100644 --- a/SoundBand/syncengine.h +++ b/SoundBand/syncengine.h @@ -16,6 +16,7 @@ class SyncEngine : public QObject Q_PROPERTY(double pos READ pos WRITE setPos NOTIFY posChanged) Q_PROPERTY(int repeat READ repeat WRITE setRepeat NOTIFY repeatChanged) Q_PROPERTY(QString currentPlayListName READ currentPlayListName NOTIFY currentPlayListNameChanged) + Q_PROPERTY(int playState READ playState NOTIFY playStateChanged) private: @@ -222,6 +223,17 @@ public slots: */ bool removeFromPlayList(int id, const QString& playList); + /** + * @brief playState + * @return playState current song ( ) + * @value 0 is no repeat + * @value 1 is single repeat + * @value 2 is single playlist + * @value 3 is repeat playlist + * @value 4 is random play + */ + int playState()const; + signals: /** @@ -278,6 +290,12 @@ signals: */ void currentPlayListNameChanged(); + /** + * @brief playStateChanged + * emited when state of playing song changed + */ + void playStateChanged(); + }; #endif // SYNCENGINE_H diff --git a/sync/playlist.cpp b/sync/playlist.cpp index 3a405dd..a44829d 100644 --- a/sync/playlist.cpp +++ b/sync/playlist.cpp @@ -47,14 +47,14 @@ bool PlayList::isEmpty()const{ } const SongHeader *PlayList::currentHeader()const{ - if(playList->isEmpty()) + if(playList->isEmpty() || playList->currentIndex() < 0) return nullptr; return static_cast(&playListInfo[playList->currentIndex()]); } const SongStorage *PlayList::currentSong()const{ - if(playList->isEmpty()) + if(playList->isEmpty() || playList->currentIndex() < 0) return nullptr; return &playListInfo[playList->currentIndex()]; @@ -64,6 +64,30 @@ int PlayList::size()const{ return playList->mediaCount(); } +int PlayList::find(const SongHeader &header)const{ + for(int i = 0; i < playList->mediaCount(); ++i) { + if(header == playList->media(i)) { + return i; + } + } + return -1; +} + +bool PlayList::selectSong(int index){ + if(playList->mediaCount() <= index || index < 0){ + return false; + } + + playList->setCurrentIndex(index); + return true; +} + +bool PlayList::selectSong(const SongHeader &header){ + return selectSong(find(header)); +} + + + PlayList::~PlayList(){ delete playList; } diff --git a/sync/playlist.h b/sync/playlist.h index c4e0fd7..256b40b 100644 --- a/sync/playlist.h +++ b/sync/playlist.h @@ -88,6 +88,25 @@ public: */ int size()const; + /** + * @brief find + * @return index of finded media + */ + int find(const SongHeader& header)const; + + /** + * @brief selectSong + * @return true if song selected + */ + bool selectSong(int index); + + /** + * @brief selectSong + * @param header of selecting song + * @return if song selected return true; + */ + bool selectSong(const SongHeader& header); + ~PlayList(); }; diff --git a/sync/song.cpp b/sync/song.cpp index c4cce2f..abfc11d 100644 --- a/sync/song.cpp +++ b/sync/song.cpp @@ -25,6 +25,20 @@ bool SongHeader::getName(QString & name, const QUrl &url) const { } +bool SongHeader::getSize(int & size, const QUrl &url) const { + if(url.isLocalFile() && url.isValid()){ + QFile f(url.toLocalFile()); + if(!f.exists()){ + return false; + } + size = f.size(); + return true; + } + + return false; + +} + SongHeader& SongHeader::operator =(const SongHeader& right){ this->id = right.id; this->name = right.name; @@ -37,20 +51,30 @@ SongHeader& SongHeader::operator =(const QMediaContent& right){ if(!getName(name, right.canonicalUrl())){ name.clear(); } - this->size = right.canonicalResource().dataSize(); + + if(!getSize(this->size, right.canonicalUrl())){ + this->size = 0; + } + return *this; } -bool SongHeader::operator ==(const SongHeader& right){ +bool SongHeader::operator ==(const SongHeader& right)const{ return this->name == right.name && this->size == right.size; } -bool SongHeader::operator ==(const QMediaContent& right){ +bool SongHeader::operator ==(const QMediaContent& right)const{ QString name; if(!getName(name, right.canonicalUrl())){ return false; } - return this->name == name && this->size == right.canonicalResource().dataSize(); + + int size;; + if(!getSize(size, right.canonicalUrl())){ + return false; + } + + return this->name == name && this->size == size; } bool SongHeader::isNameValid() const{ diff --git a/sync/song.h b/sync/song.h index 942fa7a..54aa297 100644 --- a/sync/song.h +++ b/sync/song.h @@ -27,6 +27,7 @@ struct Syncer class SongHeader{ protected: bool getName(QString &name, const QUrl& url)const; + bool getSize(int &size, const QUrl& url)const; public: bool isSelected; int id; @@ -36,8 +37,8 @@ public: SongHeader& operator = (const SongHeader& right); SongHeader& operator = (const QMediaContent& right); - bool operator == (const SongHeader& right); - bool operator == (const QMediaContent& right); + bool operator == (const SongHeader& right)const; + bool operator == (const QMediaContent& right)const; bool isNameValid() const; virtual bool isValid() const; virtual ~SongHeader(); diff --git a/sync/sync.cpp b/sync/sync.cpp index b629936..2744448 100644 --- a/sync/sync.cpp +++ b/sync/sync.cpp @@ -44,6 +44,14 @@ MySql* Sync::getSqlApi(){ return sql; } +bool Sync::setSingle(const QMediaContent& media){ + playList->clear(); + playList->addMedia(media); + + emit currentPlayListChanged(); + return true; +} + bool Sync::updateSongs(PlayList& list, const QString& playList){ if(!sql->updateAvailableSongs(list, playList)){ return false; @@ -82,6 +90,10 @@ bool Sync::play(const SongStorage &song, bool fbroadcast){ return false; } + if(playList->selectSong(song)){ + return play(fbroadcast); + } + playList->clear(); playList->addMedia(song); @@ -94,6 +106,10 @@ bool Sync::play(const SongHeader &header, bool fbroadcast){ return false; } + if(playList->selectSong(header)){ + return play(fbroadcast); + } + SongStorage song; SongHeader newheader = header; newheader.id = -1; @@ -126,8 +142,9 @@ bool Sync::play(const QMediaContent& media, bool fbroadcast){ return false; } - playList->clear(); - playList->addMedia(media); + if(!setSingle(media)){ + return false; + } return Sync::play(fbroadcast); } @@ -168,8 +185,7 @@ void Sync::setRepeat(QMediaPlaylist::PlaybackMode flag){ bool Sync::pause(bool state){ - if(!fbroadcaster){ - + if(player->state() == QMediaPlayer::StoppedState){ if(playList->isEmpty()) return false; @@ -222,7 +238,7 @@ void Sync::sync(){ package pac; if(!createPackage(t_sync, pac)){ - throw CreatePackageExaption(); + CreatePackageExaption(); return; } node->WriteAll(pac.parseTo()); @@ -468,10 +484,22 @@ void Sync::deepScaned(QList * list){ } void Sync::endPlay(QMediaPlayer::State state){ - if(state == QMediaPlayer::StoppedState && - playList->getList()->currentIndex() != -1){ - fbroadcaster = false; + + switch (state) { + case QMediaPlayer::StoppedState: + fbroadcaster = false; + break; + case QMediaPlayer::PlayingState: + sync(); + break; + + case QMediaPlayer::PausedState: + break; + default: + break; } + + emit playStateChanged(); } QString Sync::getVersion(){ @@ -539,6 +567,7 @@ bool Sync::next(){ return false; playList->next(); + emit currentSongChanged(); return true; } @@ -547,9 +576,14 @@ bool Sync::prev(){ return false; playList->prev(); + emit currentSongChanged(); return true; } +QMediaPlayer::State Sync::playState()const{ + return player->state(); +} + Sync::~Sync(){ delete node; delete player; diff --git a/sync/sync.h b/sync/sync.h index d14d130..9c65010 100644 --- a/sync/sync.h +++ b/sync/sync.h @@ -54,6 +54,12 @@ private: private slots: + /** + * @brief setSingle set singl or temp playlist + * @return true if all done + */ + bool setSingle(const QMediaContent& media); + /** * @brief updateSongs use method update avelable songs from sql database * @return true if all done @@ -290,6 +296,12 @@ public: */ bool prev(); + /** + * @brief playState + * @return state of media data + */ + QMediaPlayer::State playState()const; + Sync(const QString &address = DEFAULT_ADRESS, int port = DEFAULT_PORT, const QString& datadir = DATABASE_NAME); ~Sync(); @@ -326,6 +338,12 @@ signals: */ void currentSongChanged(); + /** + * @brief playStateChanged + * emited when state of playing song changed + */ + void playStateChanged(); + }; }