Put all smart playlist classes in their own namespace
This commit is contained in:
parent
d9ed5c91ef
commit
1f267881fe
@ -129,14 +129,14 @@ set(SOURCES
|
||||
radio/savedradio.cpp
|
||||
radio/somafmservice.cpp
|
||||
|
||||
smartplaylists/playlistgenerator.cpp
|
||||
smartplaylists/playlistgeneratorinserter.cpp
|
||||
smartplaylists/smartplaylistsearch.cpp
|
||||
smartplaylists/smartplaylistsearchpreview.cpp
|
||||
smartplaylists/smartplaylistsearchterm.cpp
|
||||
smartplaylists/smartplaylistsearchtermwidget.cpp
|
||||
smartplaylists/smartplaylistwizard.cpp
|
||||
smartplaylists/queryplaylistgenerator.cpp
|
||||
smartplaylists/generator.cpp
|
||||
smartplaylists/generatorinserter.cpp
|
||||
smartplaylists/querygenerator.cpp
|
||||
smartplaylists/search.cpp
|
||||
smartplaylists/searchpreview.cpp
|
||||
smartplaylists/searchterm.cpp
|
||||
smartplaylists/searchtermwidget.cpp
|
||||
smartplaylists/wizard.cpp
|
||||
|
||||
songinfo/artistinfoview.cpp
|
||||
songinfo/collapsibleinfoheader.cpp
|
||||
@ -287,12 +287,12 @@ set(HEADERS
|
||||
radio/savedradio.h
|
||||
radio/somafmservice.h
|
||||
|
||||
smartplaylists/generator.h
|
||||
smartplaylists/generatorinserter.h
|
||||
smartplaylists/generatormimedata.h
|
||||
smartplaylists/playlistgenerator.h
|
||||
smartplaylists/playlistgeneratorinserter.h
|
||||
smartplaylists/smartplaylistsearchpreview.h
|
||||
smartplaylists/smartplaylistsearchtermwidget.h
|
||||
smartplaylists/smartplaylistwizard.h
|
||||
smartplaylists/searchpreview.h
|
||||
smartplaylists/searchtermwidget.h
|
||||
smartplaylists/wizard.h
|
||||
|
||||
songinfo/artistinfoview.h
|
||||
songinfo/collapsibleinfoheader.h
|
||||
@ -374,9 +374,9 @@ set(UI
|
||||
radio/magnatunedownloaddialog.ui
|
||||
radio/radioviewcontainer.ui
|
||||
|
||||
smartplaylists/smartplaylistsearchpreview.ui
|
||||
smartplaylists/smartplaylistsearchtermwidget.ui
|
||||
smartplaylists/smartplaylistwizard.ui
|
||||
smartplaylists/searchpreview.ui
|
||||
smartplaylists/searchtermwidget.ui
|
||||
smartplaylists/wizard.ui
|
||||
|
||||
songinfo/lyricsettings.ui
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include "sqlrow.h"
|
||||
#include "core/database.h"
|
||||
#include "core/scopedtransaction.h"
|
||||
#include "smartplaylists/smartplaylistsearch.h"
|
||||
#include "smartplaylists/search.h"
|
||||
|
||||
#include <QDir>
|
||||
#include <QVariant>
|
||||
@ -814,7 +814,7 @@ bool LibraryBackend::ExecQuery(LibraryQuery *q) {
|
||||
return !db_->CheckErrors(q->Exec(db_->Connect(), songs_table_, fts_table_));
|
||||
}
|
||||
|
||||
SongList LibraryBackend::FindSongs(const SmartPlaylistSearch& search) {
|
||||
SongList LibraryBackend::FindSongs(const smart_playlists::Search& search) {
|
||||
QMutexLocker l(db_->Mutex());
|
||||
QSqlDatabase db(db_->Connect());
|
||||
|
||||
|
@ -27,7 +27,8 @@
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class Database;
|
||||
class SmartPlaylistSearch;
|
||||
|
||||
namespace smart_playlists { class Search; }
|
||||
|
||||
class LibraryBackendInterface : public QObject {
|
||||
public:
|
||||
@ -132,7 +133,7 @@ class LibraryBackend : public LibraryBackendInterface {
|
||||
void RemoveDirectory(const Directory& dir);
|
||||
|
||||
bool ExecQuery(LibraryQuery* q);
|
||||
SongList FindSongs(const SmartPlaylistSearch& search);
|
||||
SongList FindSongs(const smart_playlists::Search& search);
|
||||
|
||||
void IncrementPlayCountAsync(int id);
|
||||
void IncrementSkipCountAsync(int id, float progress);
|
||||
|
@ -21,9 +21,9 @@
|
||||
#include "sqlrow.h"
|
||||
#include "core/database.h"
|
||||
#include "playlist/songmimedata.h"
|
||||
#include "smartplaylists/generator.h"
|
||||
#include "smartplaylists/generatormimedata.h"
|
||||
#include "smartplaylists/playlistgenerator.h"
|
||||
#include "smartplaylists/queryplaylistgenerator.h"
|
||||
#include "smartplaylists/querygenerator.h"
|
||||
#include "ui/iconloader.h"
|
||||
|
||||
#include <QSettings>
|
||||
@ -33,6 +33,11 @@
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
|
||||
using smart_playlists::Generator;
|
||||
using smart_playlists::GeneratorMimeData;
|
||||
using smart_playlists::GeneratorPtr;
|
||||
using smart_playlists::QueryGenerator;
|
||||
|
||||
const char* LibraryModel::kSmartPlaylistsMimeType = "application/x-clementine-smart-playlist-generator";
|
||||
const char* LibraryModel::kSmartPlaylistsSettingsGroup = "SerialisedSmartPlaylists";
|
||||
|
||||
@ -747,7 +752,7 @@ QMimeData* LibraryModel::mimeData(const QModelIndexList& indexes) const {
|
||||
|
||||
// Special case: a smart playlist was dragged
|
||||
if (IndexToItem(indexes.first())->type == LibraryItem::Type_SmartPlaylist) {
|
||||
PlaylistGeneratorPtr generator = CreateGenerator(indexes.first());
|
||||
GeneratorPtr generator = CreateGenerator(indexes.first());
|
||||
if (!generator)
|
||||
return NULL;
|
||||
|
||||
@ -882,30 +887,33 @@ void LibraryModel::CreateSmartPlaylists() {
|
||||
s.beginGroup(kSmartPlaylistsSettingsGroup);
|
||||
s.beginWriteArray("smart");
|
||||
|
||||
// These defines really make this section more concise
|
||||
#define S SmartPlaylistSearch
|
||||
#define T SmartPlaylistSearchTerm
|
||||
using smart_playlists::Search;
|
||||
using smart_playlists::SearchTerm;
|
||||
|
||||
int i = 0;
|
||||
SaveDefaultGenerator(&s, i++, tr("50 random tracks"), S(
|
||||
S::Type_All, S::TermList(), S::Sort_Random, T::Field_Title, 50));
|
||||
SaveDefaultGenerator(&s, i++, tr("Ever played"), S(
|
||||
S::Type_And, S::TermList() << T(T::Field_PlayCount, T::Op_GreaterThan, 0),
|
||||
S::Sort_Random, T::Field_Title));
|
||||
SaveDefaultGenerator(&s, i++, tr("Never played"), S(
|
||||
S::Type_And, S::TermList() << T(T::Field_PlayCount, T::Op_Equals, 0),
|
||||
S::Sort_Random, T::Field_Title));
|
||||
SaveDefaultGenerator(&s, i++, tr("Last played"), S(
|
||||
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_LastPlayed));
|
||||
SaveDefaultGenerator(&s, i++, tr("Most played"), S(
|
||||
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_PlayCount));
|
||||
SaveDefaultGenerator(&s, i++, tr("Favourite tracks"), S(
|
||||
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_Score));
|
||||
SaveDefaultGenerator(&s, i++, tr("Newest tracks"), S(
|
||||
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_DateCreated));
|
||||
|
||||
#undef S
|
||||
#undef T
|
||||
SaveDefaultGenerator(&s, i++, tr("50 random tracks"), Search(
|
||||
Search::Type_All, Search::TermList(),
|
||||
Search::Sort_Random, SearchTerm::Field_Title, 50));
|
||||
SaveDefaultGenerator(&s, i++, tr("Ever played"), Search(
|
||||
Search::Type_And, Search::TermList()
|
||||
<< SearchTerm(SearchTerm::Field_PlayCount, SearchTerm::Op_GreaterThan, 0),
|
||||
Search::Sort_Random, SearchTerm::Field_Title));
|
||||
SaveDefaultGenerator(&s, i++, tr("Never played"), Search(
|
||||
Search::Type_And, Search::TermList()
|
||||
<< SearchTerm(SearchTerm::Field_PlayCount, SearchTerm::Op_Equals, 0),
|
||||
Search::Sort_Random, SearchTerm::Field_Title));
|
||||
SaveDefaultGenerator(&s, i++, tr("Last played"), Search(
|
||||
Search::Type_All, Search::TermList(),
|
||||
Search::Sort_FieldDesc, SearchTerm::Field_LastPlayed));
|
||||
SaveDefaultGenerator(&s, i++, tr("Most played"), Search(
|
||||
Search::Type_All, Search::TermList(),
|
||||
Search::Sort_FieldDesc, SearchTerm::Field_PlayCount));
|
||||
SaveDefaultGenerator(&s, i++, tr("Favourite tracks"), Search(
|
||||
Search::Type_All, Search::TermList(),
|
||||
Search::Sort_FieldDesc, SearchTerm::Field_Score));
|
||||
SaveDefaultGenerator(&s, i++, tr("Newest tracks"), Search(
|
||||
Search::Type_All, Search::TermList(),
|
||||
Search::Sort_FieldDesc, SearchTerm::Field_DateCreated));
|
||||
|
||||
s.endArray();
|
||||
s.endGroup();
|
||||
@ -925,28 +933,28 @@ void LibraryModel::CreateSmartPlaylists() {
|
||||
}
|
||||
|
||||
void LibraryModel::SaveDefaultGenerator(QSettings* s, int i, const QString& name,
|
||||
const SmartPlaylistSearch& search) const {
|
||||
boost::shared_ptr<QueryPlaylistGenerator> gen(new QueryPlaylistGenerator);
|
||||
const smart_playlists::Search& search) const {
|
||||
boost::shared_ptr<QueryGenerator> gen(new QueryGenerator);
|
||||
gen->set_name(name);
|
||||
gen->Load(search);
|
||||
SaveGenerator(s, i, boost::static_pointer_cast<PlaylistGenerator>(gen));
|
||||
SaveGenerator(s, i, boost::static_pointer_cast<Generator>(gen));
|
||||
}
|
||||
|
||||
void LibraryModel::SaveGenerator(QSettings* s, int i, PlaylistGeneratorPtr generator) const {
|
||||
void LibraryModel::SaveGenerator(QSettings* s, int i, GeneratorPtr generator) const {
|
||||
s->setArrayIndex(i);
|
||||
s->setValue("name", generator->name());
|
||||
s->setValue("type", generator->type());
|
||||
s->setValue("data", generator->Save());
|
||||
}
|
||||
|
||||
PlaylistGeneratorPtr LibraryModel::CreateGenerator(const QModelIndex& index) const {
|
||||
PlaylistGeneratorPtr ret;
|
||||
GeneratorPtr LibraryModel::CreateGenerator(const QModelIndex& index) const {
|
||||
GeneratorPtr ret;
|
||||
|
||||
const LibraryItem* item = IndexToItem(index);
|
||||
if (!item || item->type != LibraryItem::Type_SmartPlaylist)
|
||||
return ret;
|
||||
|
||||
ret = PlaylistGenerator::Create(item->key);
|
||||
ret = Generator::Create(item->key);
|
||||
if (!ret)
|
||||
return ret;
|
||||
|
||||
|
@ -27,13 +27,13 @@
|
||||
#include "core/simpletreemodel.h"
|
||||
#include "core/song.h"
|
||||
#include "engines/engine_fwd.h"
|
||||
#include "smartplaylists/playlistgenerator_fwd.h"
|
||||
#include "smartplaylists/generator_fwd.h"
|
||||
|
||||
#include <boost/scoped_ptr.hpp>
|
||||
|
||||
class LibraryDirectoryModel;
|
||||
class LibraryBackend;
|
||||
class SmartPlaylistSearch;
|
||||
namespace smart_playlists { class Search; }
|
||||
|
||||
class QSettings;
|
||||
|
||||
@ -102,7 +102,7 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
|
||||
SongList GetChildSongs(const QModelIndex& index) const;
|
||||
SongList GetChildSongs(const QModelIndexList& indexes) const;
|
||||
|
||||
PlaylistGeneratorPtr CreateGenerator(const QModelIndex& index) const;
|
||||
smart_playlists::GeneratorPtr CreateGenerator(const QModelIndex& index) const;
|
||||
|
||||
// QAbstractItemModel
|
||||
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const;
|
||||
@ -158,8 +158,8 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
|
||||
// Smart playlists are shown in another top-level node
|
||||
void CreateSmartPlaylists();
|
||||
void SaveDefaultGenerator(QSettings* s, int i, const QString& name,
|
||||
const SmartPlaylistSearch& search) const;
|
||||
void SaveGenerator(QSettings* s, int i, PlaylistGeneratorPtr generator) const;
|
||||
const smart_playlists::Search& search) const;
|
||||
void SaveGenerator(QSettings* s, int i, smart_playlists::GeneratorPtr generator) const;
|
||||
|
||||
// Helpers for ItemFromQuery and ItemFromSong
|
||||
LibraryItem* InitItem(GroupBy type, bool signal, LibraryItem* parent,
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include "core/musicstorage.h"
|
||||
#include "devices/devicemanager.h"
|
||||
#include "devices/devicestatefiltermodel.h"
|
||||
#include "smartplaylists/smartplaylistwizard.h"
|
||||
#include "smartplaylists/wizard.h"
|
||||
#include "ui/iconloader.h"
|
||||
#include "ui/organisedialog.h"
|
||||
#include "ui/organiseerrordialog.h"
|
||||
@ -35,6 +35,8 @@
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QSettings>
|
||||
|
||||
using smart_playlists::Wizard;
|
||||
|
||||
const char* LibraryView::kSettingsGroup = "LibraryView";
|
||||
|
||||
LibraryItemDelegate::LibraryItemDelegate(QObject *parent)
|
||||
@ -391,7 +393,7 @@ void LibraryView::CreateSmartPlaylistWizard() {
|
||||
if (smart_playlist_wizard_)
|
||||
return;
|
||||
|
||||
smart_playlist_wizard_.reset(new SmartPlaylistWizard(library_->backend(), this));
|
||||
smart_playlist_wizard_.reset(new Wizard(library_->backend(), this));
|
||||
}
|
||||
|
||||
void LibraryView::NewSmartPlaylist() {
|
||||
|
@ -27,9 +27,10 @@
|
||||
class DeviceManager;
|
||||
class LibraryModel;
|
||||
class OrganiseDialog;
|
||||
class SmartPlaylistWizard;
|
||||
class TaskManager;
|
||||
|
||||
namespace smart_playlists { class Wizard; }
|
||||
|
||||
class LibraryItemDelegate : public QStyledItemDelegate {
|
||||
public:
|
||||
LibraryItemDelegate(QObject* parent);
|
||||
@ -118,7 +119,7 @@ class LibraryView : public AutoExpandingTreeView {
|
||||
QAction* delete_smart_playlist_;
|
||||
|
||||
boost::scoped_ptr<OrganiseDialog> organise_dialog_;
|
||||
boost::scoped_ptr<SmartPlaylistWizard> smart_playlist_wizard_;
|
||||
boost::scoped_ptr<smart_playlists::Wizard> smart_playlist_wizard_;
|
||||
|
||||
bool is_in_keyboard_search_;
|
||||
};
|
||||
|
@ -33,8 +33,8 @@
|
||||
#include "radio/radiomodel.h"
|
||||
#include "radio/radioplaylistitem.h"
|
||||
#include "radio/savedradio.h"
|
||||
#include "smartplaylists/generatorinserter.h"
|
||||
#include "smartplaylists/generatormimedata.h"
|
||||
#include "smartplaylists/playlistgeneratorinserter.h"
|
||||
|
||||
#include <QtDebug>
|
||||
#include <QMimeData>
|
||||
@ -49,6 +49,9 @@
|
||||
|
||||
#include <lastfm/ScrobblePoint>
|
||||
|
||||
using smart_playlists::GeneratorInserter;
|
||||
using smart_playlists::GeneratorPtr;
|
||||
|
||||
using boost::shared_ptr;
|
||||
|
||||
const char* Playlist::kRowsMimetype = "application/x-clementine-playlist-rows";
|
||||
@ -530,6 +533,8 @@ bool Playlist::dropMimeData(const QMimeData* data, Qt::DropAction action, int ro
|
||||
if (action == Qt::IgnoreAction)
|
||||
return false;
|
||||
|
||||
using smart_playlists::GeneratorMimeData;
|
||||
|
||||
if (const SongMimeData* song_data = qobject_cast<const SongMimeData*>(data)) {
|
||||
// Dragged from a library
|
||||
// We want to check if these songs are from the actual local file backend,
|
||||
@ -592,8 +597,8 @@ void Playlist::InsertUrls(const QList<QUrl> &urls, bool play_now, int pos) {
|
||||
inserter->Load(this, pos, play_now, urls);
|
||||
}
|
||||
|
||||
void Playlist::InsertSmartPlaylist(PlaylistGeneratorPtr generator, int pos, bool play_now) {
|
||||
PlaylistGeneratorInserter* inserter = new PlaylistGeneratorInserter(task_manager_, library_, this);
|
||||
void Playlist::InsertSmartPlaylist(GeneratorPtr generator, int pos, bool play_now) {
|
||||
GeneratorInserter* inserter = new GeneratorInserter(task_manager_, library_, this);
|
||||
connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString)));
|
||||
connect(inserter, SIGNAL(PlayRequested(QModelIndex)), SIGNAL(PlayRequested(QModelIndex)));
|
||||
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include "playlistsequence.h"
|
||||
#include "core/song.h"
|
||||
#include "radio/radioitem.h"
|
||||
#include "smartplaylists/playlistgenerator_fwd.h"
|
||||
#include "smartplaylists/generator_fwd.h"
|
||||
|
||||
class LibraryBackend;
|
||||
class PlaylistBackend;
|
||||
@ -151,7 +151,7 @@ class Playlist : public QAbstractListModel {
|
||||
QModelIndex InsertMagnatuneItems(const SongList& items, int pos = -1);
|
||||
QModelIndex InsertSongs(const SongList& items, int pos = -1);
|
||||
QModelIndex InsertRadioStations(const QList<RadioItem*>& items, int pos = -1, bool play_now = false);
|
||||
void InsertSmartPlaylist(PlaylistGeneratorPtr generator, int pos = -1, bool play_now = false);
|
||||
void InsertSmartPlaylist(smart_playlists::GeneratorPtr generator, int pos = -1, bool play_now = false);
|
||||
void InsertUrls(const QList<QUrl>& urls, bool play_now, int pos = -1);
|
||||
void StopAfter(int row);
|
||||
void ReloadItems(const QList<int>& rows);
|
||||
|
@ -22,11 +22,13 @@
|
||||
#include "library/librarybackend.h"
|
||||
#include "library/libraryplaylistitem.h"
|
||||
#include "playlistparsers/playlistparser.h"
|
||||
#include "smartplaylists/playlistgenerator.h"
|
||||
#include "smartplaylists/generator.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QtDebug>
|
||||
|
||||
using smart_playlists::GeneratorPtr;
|
||||
|
||||
PlaylistManager::PlaylistManager(TaskManager* task_manager, QObject *parent)
|
||||
: QObject(parent),
|
||||
task_manager_(task_manager),
|
||||
@ -275,7 +277,7 @@ void PlaylistManager::SongsDiscovered(const SongList& songs) {
|
||||
}
|
||||
}
|
||||
|
||||
void PlaylistManager::PlaySmartPlaylist(PlaylistGeneratorPtr generator, bool as_new, bool clear) {
|
||||
void PlaylistManager::PlaySmartPlaylist(GeneratorPtr generator, bool as_new, bool clear) {
|
||||
if (as_new) {
|
||||
New(generator->name());
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <QObject>
|
||||
|
||||
#include "core/song.h"
|
||||
#include "smartplaylists/playlistgenerator_fwd.h"
|
||||
#include "smartplaylists/generator_fwd.h"
|
||||
|
||||
class LibraryBackend;
|
||||
class Playlist;
|
||||
@ -85,7 +85,7 @@ public slots:
|
||||
void SetActiveStopped();
|
||||
void SetActiveStreamMetadata(const QUrl& url, const Song& song);
|
||||
|
||||
void PlaySmartPlaylist(PlaylistGeneratorPtr generator, bool as_new, bool clear);
|
||||
void PlaySmartPlaylist(smart_playlists::GeneratorPtr generator, bool as_new, bool clear);
|
||||
|
||||
signals:
|
||||
void PlaylistAdded(int id, const QString& name);
|
||||
|
@ -14,24 +14,28 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "queryplaylistgenerator.h"
|
||||
#include "playlistgenerator.h"
|
||||
#include "generator.h"
|
||||
#include "querygenerator.h"
|
||||
|
||||
#include <QSettings>
|
||||
|
||||
const int PlaylistGenerator::kDefaultLimit = 20;
|
||||
namespace smart_playlists {
|
||||
|
||||
PlaylistGenerator::PlaylistGenerator()
|
||||
const int Generator::kDefaultLimit = 20;
|
||||
|
||||
Generator::Generator()
|
||||
: QObject(NULL),
|
||||
backend_(NULL)
|
||||
{
|
||||
}
|
||||
|
||||
PlaylistGeneratorPtr PlaylistGenerator::Create(const QString& type) {
|
||||
GeneratorPtr Generator::Create(const QString& type) {
|
||||
if (type == "Query")
|
||||
return PlaylistGeneratorPtr(new QueryPlaylistGenerator);
|
||||
return GeneratorPtr(new QueryGenerator);
|
||||
|
||||
qWarning() << "Invalid playlist generator type:" << type;
|
||||
return PlaylistGeneratorPtr();
|
||||
return GeneratorPtr();
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -24,15 +24,17 @@
|
||||
|
||||
class LibraryBackend;
|
||||
|
||||
class PlaylistGenerator : public QObject, public boost::enable_shared_from_this<PlaylistGenerator> {
|
||||
namespace smart_playlists {
|
||||
|
||||
class Generator : public QObject, public boost::enable_shared_from_this<Generator> {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PlaylistGenerator();
|
||||
virtual ~PlaylistGenerator() {}
|
||||
Generator();
|
||||
virtual ~Generator() {}
|
||||
|
||||
static const int kDefaultLimit;
|
||||
static boost::shared_ptr<PlaylistGenerator> Create(const QString& type);
|
||||
static boost::shared_ptr<Generator> Create(const QString& type);
|
||||
|
||||
void set_library(LibraryBackend* backend) { backend_ = backend; }
|
||||
|
||||
@ -55,6 +57,8 @@ protected:
|
||||
QString name_;
|
||||
};
|
||||
|
||||
#include "playlistgenerator_fwd.h"
|
||||
} // namespace
|
||||
|
||||
#include "generator_fwd.h"
|
||||
|
||||
#endif // PLAYLISTGENERATOR_H
|
@ -19,8 +19,12 @@
|
||||
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
class PlaylistGenerator;
|
||||
namespace smart_playlists {
|
||||
|
||||
typedef boost::shared_ptr<PlaylistGenerator> PlaylistGeneratorPtr;
|
||||
class Generator;
|
||||
|
||||
typedef boost::shared_ptr<Generator> GeneratorPtr;
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // PLAYLISTGENERATOR_FWD_H
|
@ -14,18 +14,20 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "playlistgenerator.h"
|
||||
#include "playlistgeneratorinserter.h"
|
||||
#include "generator.h"
|
||||
#include "generatorinserter.h"
|
||||
#include "core/taskmanager.h"
|
||||
#include "playlist/playlist.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
namespace smart_playlists {
|
||||
|
||||
typedef QFuture<PlaylistItemList> Future;
|
||||
typedef QFutureWatcher<PlaylistItemList> FutureWatcher;
|
||||
|
||||
PlaylistGeneratorInserter::PlaylistGeneratorInserter(
|
||||
GeneratorInserter::GeneratorInserter(
|
||||
TaskManager* task_manager, LibraryBackend* library, QObject* parent)
|
||||
: QObject(parent),
|
||||
task_manager_(task_manager),
|
||||
@ -34,12 +36,12 @@ PlaylistGeneratorInserter::PlaylistGeneratorInserter(
|
||||
{
|
||||
}
|
||||
|
||||
static PlaylistItemList Generate(PlaylistGeneratorPtr generator) {
|
||||
static PlaylistItemList Generate(GeneratorPtr generator) {
|
||||
return generator->Generate();
|
||||
}
|
||||
|
||||
void PlaylistGeneratorInserter::Load(
|
||||
Playlist* destination, int row, bool play_now, PlaylistGeneratorPtr generator) {
|
||||
void GeneratorInserter::Load(
|
||||
Playlist* destination, int row, bool play_now, GeneratorPtr generator) {
|
||||
task_id_ = task_manager_->StartTask(tr("Loading smart playlist"));
|
||||
|
||||
destination_ = destination;
|
||||
@ -55,7 +57,7 @@ void PlaylistGeneratorInserter::Load(
|
||||
connect(watcher, SIGNAL(finished()), SLOT(Finished()));
|
||||
}
|
||||
|
||||
void PlaylistGeneratorInserter::Finished() {
|
||||
void GeneratorInserter::Finished() {
|
||||
FutureWatcher* watcher = static_cast<FutureWatcher*>(sender());
|
||||
watcher->deleteLater();
|
||||
|
||||
@ -69,3 +71,5 @@ void PlaylistGeneratorInserter::Finished() {
|
||||
|
||||
deleteLater();
|
||||
}
|
||||
|
||||
} // namespace
|
@ -17,7 +17,7 @@
|
||||
#ifndef PLAYLISTGENERATORINSERTER_H
|
||||
#define PLAYLISTGENERATORINSERTER_H
|
||||
|
||||
#include "playlistgenerator_fwd.h"
|
||||
#include "generator_fwd.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@ -27,15 +27,17 @@ class TaskManager;
|
||||
|
||||
class QModelIndex;
|
||||
|
||||
class PlaylistGeneratorInserter : public QObject {
|
||||
namespace smart_playlists {
|
||||
|
||||
class GeneratorInserter : public QObject {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PlaylistGeneratorInserter(TaskManager* task_manager,
|
||||
LibraryBackend* library, QObject* parent);
|
||||
GeneratorInserter(TaskManager* task_manager,
|
||||
LibraryBackend* library, QObject* parent);
|
||||
|
||||
void Load(Playlist* destination, int row, bool play_now,
|
||||
PlaylistGeneratorPtr generator);
|
||||
GeneratorPtr generator);
|
||||
|
||||
signals:
|
||||
void Error(const QString& message);
|
||||
@ -54,4 +56,6 @@ private:
|
||||
bool play_now_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // PLAYLISTGENERATORINSERTER_H
|
@ -19,15 +19,19 @@
|
||||
|
||||
#include <QMimeData>
|
||||
|
||||
#include "playlistgenerator_fwd.h"
|
||||
#include "generator_fwd.h"
|
||||
|
||||
namespace smart_playlists {
|
||||
|
||||
class GeneratorMimeData : public QMimeData {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
GeneratorMimeData(PlaylistGeneratorPtr generator) : generator_(generator) {}
|
||||
GeneratorMimeData(GeneratorPtr generator) : generator_(generator) {}
|
||||
|
||||
PlaylistGeneratorPtr generator_;
|
||||
GeneratorPtr generator_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // GENERATORMIMEDATA_H
|
||||
|
@ -14,26 +14,28 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "queryplaylistgenerator.h"
|
||||
#include "querygenerator.h"
|
||||
#include "library/librarybackend.h"
|
||||
#include "library/libraryplaylistitem.h"
|
||||
|
||||
#include <QtDebug>
|
||||
|
||||
QueryPlaylistGenerator::QueryPlaylistGenerator()
|
||||
namespace smart_playlists {
|
||||
|
||||
QueryGenerator::QueryGenerator()
|
||||
{
|
||||
}
|
||||
|
||||
void QueryPlaylistGenerator::Load(const SmartPlaylistSearch& search) {
|
||||
void QueryGenerator::Load(const Search& search) {
|
||||
search_ = search;
|
||||
}
|
||||
|
||||
void QueryPlaylistGenerator::Load(const QByteArray& data) {
|
||||
void QueryGenerator::Load(const QByteArray& data) {
|
||||
QDataStream s(data);
|
||||
s >> search_;
|
||||
}
|
||||
|
||||
QByteArray QueryPlaylistGenerator::Save() const {
|
||||
QByteArray QueryGenerator::Save() const {
|
||||
QByteArray ret;
|
||||
QDataStream s(&ret, QIODevice::WriteOnly);
|
||||
s << search_;
|
||||
@ -41,7 +43,7 @@ QByteArray QueryPlaylistGenerator::Save() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
PlaylistItemList QueryPlaylistGenerator::Generate() {
|
||||
PlaylistItemList QueryGenerator::Generate() {
|
||||
SongList songs = backend_->FindSongs(search_);
|
||||
|
||||
PlaylistItemList items;
|
||||
@ -50,3 +52,5 @@ PlaylistItemList QueryPlaylistGenerator::Generate() {
|
||||
}
|
||||
return items;
|
||||
}
|
||||
|
||||
} // namespace
|
@ -17,23 +17,27 @@
|
||||
#ifndef QUERYPLAYLISTGENERATOR_H
|
||||
#define QUERYPLAYLISTGENERATOR_H
|
||||
|
||||
#include "playlistgenerator.h"
|
||||
#include "smartplaylistsearch.h"
|
||||
#include "generator.h"
|
||||
#include "search.h"
|
||||
|
||||
class QueryPlaylistGenerator : public PlaylistGenerator {
|
||||
namespace smart_playlists {
|
||||
|
||||
class QueryGenerator : public Generator {
|
||||
public:
|
||||
QueryPlaylistGenerator();
|
||||
QueryGenerator();
|
||||
|
||||
QString type() const { return "Query"; }
|
||||
|
||||
void Load(const SmartPlaylistSearch& search);
|
||||
void Load(const Search& search);
|
||||
void Load(const QByteArray& data);
|
||||
QByteArray Save() const;
|
||||
|
||||
PlaylistItemList Generate();
|
||||
|
||||
private:
|
||||
SmartPlaylistSearch search_;
|
||||
Search search_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // QUERYPLAYLISTGENERATOR_H
|
@ -14,18 +14,20 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "smartplaylistsearch.h"
|
||||
#include "search.h"
|
||||
#include "core/song.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
SmartPlaylistSearch::SmartPlaylistSearch() {
|
||||
namespace smart_playlists {
|
||||
|
||||
Search::Search() {
|
||||
Reset();
|
||||
}
|
||||
|
||||
SmartPlaylistSearch::SmartPlaylistSearch(
|
||||
Search::Search(
|
||||
SearchType type, TermList terms, SortType sort_type,
|
||||
SmartPlaylistSearchTerm::Field sort_field, int limit)
|
||||
SearchTerm::Field sort_field, int limit)
|
||||
: search_type_(type),
|
||||
terms_(terms),
|
||||
sort_type_(sort_type),
|
||||
@ -34,20 +36,20 @@ SmartPlaylistSearch::SmartPlaylistSearch(
|
||||
{
|
||||
}
|
||||
|
||||
void SmartPlaylistSearch::Reset() {
|
||||
void Search::Reset() {
|
||||
search_type_ = Type_And;
|
||||
terms_.clear();
|
||||
sort_type_ = Sort_Random;
|
||||
sort_field_ = SmartPlaylistSearchTerm::Field_Title;
|
||||
sort_field_ = SearchTerm::Field_Title;
|
||||
limit_ = -1;
|
||||
}
|
||||
|
||||
QString SmartPlaylistSearch::ToSql(const QString& songs_table) const {
|
||||
QString Search::ToSql(const QString& songs_table) const {
|
||||
QString sql = "SELECT ROWID," + Song::kColumnSpec + " FROM " + songs_table;
|
||||
|
||||
// Add search terms
|
||||
QStringList term_sql;
|
||||
foreach (const SmartPlaylistSearchTerm& term, terms_) {
|
||||
foreach (const SearchTerm& term, terms_) {
|
||||
term_sql += term.ToSql();
|
||||
}
|
||||
if (!terms_.isEmpty() && search_type_ != Type_All) {
|
||||
@ -59,7 +61,7 @@ QString SmartPlaylistSearch::ToSql(const QString& songs_table) const {
|
||||
if (sort_type_ == Sort_Random) {
|
||||
sql += " ORDER BY random()";
|
||||
} else {
|
||||
sql += " ORDER BY " + SmartPlaylistSearchTerm::FieldColumnName(sort_field_)
|
||||
sql += " ORDER BY " + SearchTerm::FieldColumnName(sort_field_)
|
||||
+ (sort_type_ == Sort_FieldAsc ? " ASC" : " DESC");
|
||||
}
|
||||
|
||||
@ -71,13 +73,15 @@ QString SmartPlaylistSearch::ToSql(const QString& songs_table) const {
|
||||
return sql;
|
||||
}
|
||||
|
||||
bool SmartPlaylistSearch::is_valid() const {
|
||||
bool Search::is_valid() const {
|
||||
if (search_type_ == Type_All)
|
||||
return true;
|
||||
return !terms_.isEmpty();
|
||||
}
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearch& search) {
|
||||
} // namespace
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const smart_playlists::Search& search) {
|
||||
s << search.terms_;
|
||||
s << quint8(search.sort_type_);
|
||||
s << quint8(search.sort_field_);
|
||||
@ -85,13 +89,13 @@ QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearch& search) {
|
||||
return s;
|
||||
}
|
||||
|
||||
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearch& search) {
|
||||
QDataStream& operator >>(QDataStream& s, smart_playlists::Search& search) {
|
||||
quint8 sort_type, sort_field;
|
||||
qint32 limit;
|
||||
|
||||
s >> search.terms_ >> sort_type >> sort_field >> limit;
|
||||
search.sort_type_ = SmartPlaylistSearch::SortType(sort_type);
|
||||
search.sort_field_ = SmartPlaylistSearchTerm::Field(sort_field);
|
||||
search.sort_type_ = smart_playlists::Search::SortType(sort_type);
|
||||
search.sort_field_ = smart_playlists::SearchTerm::Field(sort_field);
|
||||
search.limit_ = limit;
|
||||
|
||||
return s;
|
@ -17,12 +17,14 @@
|
||||
#ifndef SMARTPLAYLISTSEARCH_H
|
||||
#define SMARTPLAYLISTSEARCH_H
|
||||
|
||||
#include "playlistgenerator.h"
|
||||
#include "smartplaylistsearchterm.h"
|
||||
#include "generator.h"
|
||||
#include "searchterm.h"
|
||||
|
||||
class SmartPlaylistSearch {
|
||||
namespace smart_playlists {
|
||||
|
||||
class Search {
|
||||
public:
|
||||
typedef QList<SmartPlaylistSearchTerm> TermList;
|
||||
typedef QList<SearchTerm> TermList;
|
||||
|
||||
// These values are persisted, so add to the end of the enum only
|
||||
enum SearchType {
|
||||
@ -38,24 +40,26 @@ public:
|
||||
Sort_FieldDesc,
|
||||
};
|
||||
|
||||
SmartPlaylistSearch();
|
||||
SmartPlaylistSearch(SearchType type, TermList terms, SortType sort_type,
|
||||
SmartPlaylistSearchTerm::Field sort_field,
|
||||
int limit = PlaylistGenerator::kDefaultLimit);
|
||||
Search();
|
||||
Search(SearchType type, TermList terms, SortType sort_type,
|
||||
SearchTerm::Field sort_field,
|
||||
int limit = Generator::kDefaultLimit);
|
||||
|
||||
bool is_valid() const;
|
||||
|
||||
SearchType search_type_;
|
||||
TermList terms_;
|
||||
SortType sort_type_;
|
||||
SmartPlaylistSearchTerm::Field sort_field_;
|
||||
SearchTerm::Field sort_field_;
|
||||
int limit_;
|
||||
|
||||
void Reset();
|
||||
QString ToSql(const QString& songs_table) const;
|
||||
};
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearch& search);
|
||||
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearch& search);
|
||||
} // namespace
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const smart_playlists::Search& search);
|
||||
QDataStream& operator >>(QDataStream& s, smart_playlists::Search& search);
|
||||
|
||||
#endif // SMARTPLAYLISTSEARCH_H
|
@ -14,18 +14,20 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "queryplaylistgenerator.h"
|
||||
#include "smartplaylistsearchpreview.h"
|
||||
#include "ui_smartplaylistsearchpreview.h"
|
||||
#include "querygenerator.h"
|
||||
#include "searchpreview.h"
|
||||
#include "ui_searchpreview.h"
|
||||
#include "playlist/playlist.h"
|
||||
|
||||
#include <QFutureWatcher>
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
namespace smart_playlists {
|
||||
|
||||
typedef QFuture<PlaylistItemList> Future;
|
||||
typedef QFutureWatcher<PlaylistItemList> FutureWatcher;
|
||||
|
||||
SmartPlaylistSearchPreview::SmartPlaylistSearchPreview(QWidget *parent)
|
||||
SearchPreview::SearchPreview(QWidget *parent)
|
||||
: QWidget(parent),
|
||||
ui_(new Ui_SmartPlaylistSearchPreview),
|
||||
model_(NULL)
|
||||
@ -42,11 +44,11 @@ SmartPlaylistSearchPreview::SmartPlaylistSearchPreview(QWidget *parent)
|
||||
ui_->busy_container->hide();
|
||||
}
|
||||
|
||||
SmartPlaylistSearchPreview::~SmartPlaylistSearchPreview() {
|
||||
SearchPreview::~SearchPreview() {
|
||||
delete ui_;
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchPreview::set_library(LibraryBackend* backend) {
|
||||
void SearchPreview::set_library(LibraryBackend* backend) {
|
||||
backend_ = backend;
|
||||
|
||||
model_ = new Playlist(NULL, NULL, backend_, -1, this);
|
||||
@ -55,7 +57,7 @@ void SmartPlaylistSearchPreview::set_library(LibraryBackend* backend) {
|
||||
ui_->tree->SetItemDelegates(backend_);
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchPreview::Update(const SmartPlaylistSearch& search) {
|
||||
void SearchPreview::Update(const Search& search) {
|
||||
if (generator_) {
|
||||
// It's busy generating something already
|
||||
pending_search_ = search;
|
||||
@ -65,21 +67,21 @@ void SmartPlaylistSearchPreview::Update(const SmartPlaylistSearch& search) {
|
||||
RunSearch(search);
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchPreview::RunSearch(const SmartPlaylistSearch& search) {
|
||||
generator_.reset(new QueryPlaylistGenerator);
|
||||
void SearchPreview::RunSearch(const Search& search) {
|
||||
generator_.reset(new QueryGenerator);
|
||||
generator_->set_library(backend_);
|
||||
generator_->Load(search);
|
||||
|
||||
ui_->busy_container->show();
|
||||
ui_->count_label->hide();
|
||||
Future future = QtConcurrent::run(generator_.get(), &QueryPlaylistGenerator::Generate);
|
||||
Future future = QtConcurrent::run(generator_.get(), &QueryGenerator::Generate);
|
||||
|
||||
FutureWatcher* watcher = new FutureWatcher(this);
|
||||
watcher->setFuture(future);
|
||||
connect(watcher, SIGNAL(finished()), SLOT(SearchFinished()));
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchPreview::SearchFinished() {
|
||||
void SearchPreview::SearchFinished() {
|
||||
FutureWatcher* watcher = static_cast<FutureWatcher*>(sender());
|
||||
watcher->deleteLater();
|
||||
generator_.reset();
|
||||
@ -88,12 +90,12 @@ void SmartPlaylistSearchPreview::SearchFinished() {
|
||||
// There was another search done while we were running - throw away these
|
||||
// results and do that one now instead
|
||||
RunSearch(pending_search_);
|
||||
pending_search_ = SmartPlaylistSearch();
|
||||
pending_search_ = Search();
|
||||
return;
|
||||
}
|
||||
|
||||
PlaylistItemList all_items = watcher->result();
|
||||
PlaylistItemList displayed_items = all_items.mid(0, PlaylistGenerator::kDefaultLimit);
|
||||
PlaylistItemList displayed_items = all_items.mid(0, Generator::kDefaultLimit);
|
||||
|
||||
model_->Clear();
|
||||
model_->InsertItems(displayed_items);
|
||||
@ -108,3 +110,5 @@ void SmartPlaylistSearchPreview::SearchFinished() {
|
||||
ui_->busy_container->hide();
|
||||
ui_->count_label->show();
|
||||
}
|
||||
|
||||
} // namespace
|
@ -17,7 +17,7 @@
|
||||
#ifndef SMARTPLAYLISTSEARCHPREVIEW_H
|
||||
#define SMARTPLAYLISTSEARCHPREVIEW_H
|
||||
|
||||
#include "smartplaylistsearch.h"
|
||||
#include "search.h"
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
@ -25,35 +25,40 @@
|
||||
|
||||
class LibraryBackend;
|
||||
class Playlist;
|
||||
class QueryPlaylistGenerator;
|
||||
class Ui_SmartPlaylistSearchPreview;
|
||||
|
||||
class SmartPlaylistSearchPreview : public QWidget {
|
||||
namespace smart_playlists {
|
||||
|
||||
class QueryGenerator;
|
||||
|
||||
class SearchPreview : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SmartPlaylistSearchPreview(QWidget *parent = 0);
|
||||
~SmartPlaylistSearchPreview();
|
||||
SearchPreview(QWidget *parent = 0);
|
||||
~SearchPreview();
|
||||
|
||||
void set_library(LibraryBackend* backend);
|
||||
|
||||
void Update(const SmartPlaylistSearch& search);
|
||||
void Update(const Search& search);
|
||||
|
||||
private:
|
||||
void RunSearch(const SmartPlaylistSearch& search);
|
||||
void RunSearch(const Search& search);
|
||||
|
||||
private slots:
|
||||
void SearchFinished();
|
||||
|
||||
private:
|
||||
Ui_SmartPlaylistSearchPreview* ui_;
|
||||
QList<SmartPlaylistSearchTerm::Field> fields_;
|
||||
QList<SearchTerm::Field> fields_;
|
||||
|
||||
LibraryBackend* backend_;
|
||||
Playlist* model_;
|
||||
|
||||
SmartPlaylistSearch pending_search_;
|
||||
boost::scoped_ptr<QueryPlaylistGenerator> generator_;
|
||||
Search pending_search_;
|
||||
boost::scoped_ptr<QueryGenerator> generator_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // SMARTPLAYLISTSEARCHPREVIEW_H
|
@ -14,16 +14,18 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "smartplaylistsearchterm.h"
|
||||
#include "searchterm.h"
|
||||
#include "playlist/playlist.h"
|
||||
|
||||
SmartPlaylistSearchTerm::SmartPlaylistSearchTerm()
|
||||
namespace smart_playlists {
|
||||
|
||||
SearchTerm::SearchTerm()
|
||||
: field_(Field_Title),
|
||||
operator_(Op_Equals)
|
||||
{
|
||||
}
|
||||
|
||||
SmartPlaylistSearchTerm::SmartPlaylistSearchTerm(
|
||||
SearchTerm::SearchTerm(
|
||||
Field field, Operator op, const QVariant& value)
|
||||
: field_(field),
|
||||
operator_(op),
|
||||
@ -31,7 +33,7 @@ SmartPlaylistSearchTerm::SmartPlaylistSearchTerm(
|
||||
{
|
||||
}
|
||||
|
||||
QString SmartPlaylistSearchTerm::ToSql() const {
|
||||
QString SearchTerm::ToSql() const {
|
||||
const QString col = FieldColumnName(field_);
|
||||
QString value = value_.toString();
|
||||
value.replace('\'', "''");
|
||||
@ -58,7 +60,7 @@ QString SmartPlaylistSearchTerm::ToSql() const {
|
||||
return QString();
|
||||
}
|
||||
|
||||
bool SmartPlaylistSearchTerm::is_valid() const {
|
||||
bool SearchTerm::is_valid() const {
|
||||
switch (TypeOf(field_)) {
|
||||
case Type_Text: return !value_.toString().isEmpty();
|
||||
case Type_Date: return value_.toInt() != 0;
|
||||
@ -69,7 +71,7 @@ bool SmartPlaylistSearchTerm::is_valid() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
SmartPlaylistSearchTerm::Type SmartPlaylistSearchTerm::TypeOf(Field field) {
|
||||
SearchTerm::Type SearchTerm::TypeOf(Field field) {
|
||||
switch (field) {
|
||||
case Field_Length:
|
||||
return Type_Time;
|
||||
@ -99,7 +101,7 @@ SmartPlaylistSearchTerm::Type SmartPlaylistSearchTerm::TypeOf(Field field) {
|
||||
}
|
||||
}
|
||||
|
||||
OperatorList SmartPlaylistSearchTerm::OperatorsForType(Type type) {
|
||||
OperatorList SearchTerm::OperatorsForType(Type type) {
|
||||
switch (type) {
|
||||
case Type_Text:
|
||||
return OperatorList() << Op_Contains << Op_NotContains << Op_Equals
|
||||
@ -109,7 +111,7 @@ OperatorList SmartPlaylistSearchTerm::OperatorsForType(Type type) {
|
||||
}
|
||||
}
|
||||
|
||||
QString SmartPlaylistSearchTerm::OperatorText(Type type, Operator op) {
|
||||
QString SearchTerm::OperatorText(Type type, Operator op) {
|
||||
if (type == Type_Date) {
|
||||
switch (op) {
|
||||
case Op_GreaterThan: return QObject::tr("after");
|
||||
@ -132,7 +134,7 @@ QString SmartPlaylistSearchTerm::OperatorText(Type type, Operator op) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString SmartPlaylistSearchTerm::FieldColumnName(Field field) {
|
||||
QString SearchTerm::FieldColumnName(Field field) {
|
||||
switch (field) {
|
||||
case Field_Length: return "length";
|
||||
case Field_Track: return "track";
|
||||
@ -161,7 +163,7 @@ QString SmartPlaylistSearchTerm::FieldColumnName(Field field) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString SmartPlaylistSearchTerm::FieldName(Field field) {
|
||||
QString SearchTerm::FieldName(Field field) {
|
||||
switch (field) {
|
||||
case Field_Length: return Playlist::column_name(Playlist::Column_Length);
|
||||
case Field_Track: return Playlist::column_name(Playlist::Column_Track);
|
||||
@ -190,7 +192,7 @@ QString SmartPlaylistSearchTerm::FieldName(Field field) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString SmartPlaylistSearchTerm::FieldSortOrderText(Type type, bool ascending) {
|
||||
QString SearchTerm::FieldSortOrderText(Type type, bool ascending) {
|
||||
switch (type) {
|
||||
case Type_Text: return ascending ? QObject::tr("A-Z") : QObject::tr("Z-A");
|
||||
case Type_Date: return ascending ? QObject::tr("oldest first") : QObject::tr("newest first");
|
||||
@ -201,17 +203,19 @@ QString SmartPlaylistSearchTerm::FieldSortOrderText(Type type, bool ascending) {
|
||||
return QString();
|
||||
}
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearchTerm& term) {
|
||||
} // namespace
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const smart_playlists::SearchTerm& term) {
|
||||
s << quint8(term.field_);
|
||||
s << quint8(term.operator_);
|
||||
s << term.value_;
|
||||
return s;
|
||||
}
|
||||
|
||||
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearchTerm& term) {
|
||||
QDataStream& operator >>(QDataStream& s, smart_playlists::SearchTerm& term) {
|
||||
quint8 field, op;
|
||||
s >> field >> op >> term.value_;
|
||||
term.field_ = SmartPlaylistSearchTerm::Field(field);
|
||||
term.operator_ = SmartPlaylistSearchTerm::Operator(op);
|
||||
term.field_ = smart_playlists::SearchTerm::Field(field);
|
||||
term.operator_ = smart_playlists::SearchTerm::Operator(op);
|
||||
return s;
|
||||
}
|
@ -20,7 +20,9 @@
|
||||
#include <QDataStream>
|
||||
#include <QVariant>
|
||||
|
||||
class SmartPlaylistSearchTerm {
|
||||
namespace smart_playlists {
|
||||
|
||||
class SearchTerm {
|
||||
public:
|
||||
// These values are persisted, so add to the end of the enum only
|
||||
enum Field {
|
||||
@ -74,8 +76,8 @@ public:
|
||||
Type_Rating,
|
||||
};
|
||||
|
||||
SmartPlaylistSearchTerm();
|
||||
SmartPlaylistSearchTerm(Field field, Operator op, const QVariant& value);
|
||||
SearchTerm();
|
||||
SearchTerm(Field field, Operator op, const QVariant& value);
|
||||
|
||||
Field field_;
|
||||
Operator operator_;
|
||||
@ -92,9 +94,11 @@ public:
|
||||
static QString FieldSortOrderText(Type type, bool ascending);
|
||||
};
|
||||
|
||||
typedef QList<SmartPlaylistSearchTerm::Operator> OperatorList;
|
||||
typedef QList<SearchTerm::Operator> OperatorList;
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearchTerm& term);
|
||||
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearchTerm& term);
|
||||
} // namespace
|
||||
|
||||
QDataStream& operator <<(QDataStream& s, const smart_playlists::SearchTerm& term);
|
||||
QDataStream& operator >>(QDataStream& s, smart_playlists::SearchTerm& term);
|
||||
|
||||
#endif // SMARTPLAYLISTSEARCHTERM_H
|
@ -14,9 +14,9 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "smartplaylistsearchterm.h"
|
||||
#include "smartplaylistsearchtermwidget.h"
|
||||
#include "ui_smartplaylistsearchtermwidget.h"
|
||||
#include "searchterm.h"
|
||||
#include "searchtermwidget.h"
|
||||
#include "ui_searchtermwidget.h"
|
||||
#include "core/utilities.h"
|
||||
#include "playlist/playlist.h"
|
||||
#include "playlist/playlistdelegates.h"
|
||||
@ -31,9 +31,11 @@
|
||||
// Exported by QtGui
|
||||
void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0);
|
||||
|
||||
class SmartPlaylistSearchTermWidget::Overlay : public QWidget {
|
||||
namespace smart_playlists {
|
||||
|
||||
class SearchTermWidget::Overlay : public QWidget {
|
||||
public:
|
||||
Overlay(SmartPlaylistSearchTermWidget* parent);
|
||||
Overlay(SearchTermWidget* parent);
|
||||
void Grab();
|
||||
void SetOpacity(float opacity);
|
||||
float opacity() const { return opacity_; }
|
||||
@ -46,7 +48,7 @@ protected:
|
||||
void mouseReleaseEvent(QMouseEvent*);
|
||||
|
||||
private:
|
||||
SmartPlaylistSearchTermWidget* parent_;
|
||||
SearchTermWidget* parent_;
|
||||
|
||||
float opacity_;
|
||||
QString text_;
|
||||
@ -54,11 +56,11 @@ private:
|
||||
QPixmap icon_;
|
||||
};
|
||||
|
||||
const int SmartPlaylistSearchTermWidget::Overlay::kSpacing = 6;
|
||||
const int SmartPlaylistSearchTermWidget::Overlay::kIconSize = 22;
|
||||
const int SearchTermWidget::Overlay::kSpacing = 6;
|
||||
const int SearchTermWidget::Overlay::kIconSize = 22;
|
||||
|
||||
|
||||
SmartPlaylistSearchTermWidget::SmartPlaylistSearchTermWidget(LibraryBackend* library, QWidget* parent)
|
||||
SearchTermWidget::SearchTermWidget(LibraryBackend* library, QWidget* parent)
|
||||
: QWidget(parent),
|
||||
ui_(new Ui_SmartPlaylistSearchTermWidget),
|
||||
library_(library),
|
||||
@ -80,8 +82,8 @@ SmartPlaylistSearchTermWidget::SmartPlaylistSearchTermWidget(LibraryBackend* lib
|
||||
ui_->value_date->setDate(QDate::currentDate());
|
||||
|
||||
// Populate the combo boxes
|
||||
for (int i=0 ; i<SmartPlaylistSearchTerm::FieldCount ; ++i) {
|
||||
ui_->field->addItem(SmartPlaylistSearchTerm::FieldName(SmartPlaylistSearchTerm::Field(i)));
|
||||
for (int i=0 ; i<SearchTerm::FieldCount ; ++i) {
|
||||
ui_->field->addItem(SearchTerm::FieldName(SearchTerm::Field(i)));
|
||||
ui_->field->setItemData(i, i);
|
||||
}
|
||||
ui_->field->model()->sort(0);
|
||||
@ -101,41 +103,41 @@ SmartPlaylistSearchTermWidget::SmartPlaylistSearchTermWidget(LibraryBackend* lib
|
||||
setStyleSheet(stylesheet);
|
||||
}
|
||||
|
||||
SmartPlaylistSearchTermWidget::~SmartPlaylistSearchTermWidget() {
|
||||
SearchTermWidget::~SearchTermWidget() {
|
||||
delete ui_;
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::FieldChanged(int index) {
|
||||
SmartPlaylistSearchTerm::Field field = SmartPlaylistSearchTerm::Field(
|
||||
void SearchTermWidget::FieldChanged(int index) {
|
||||
SearchTerm::Field field = SearchTerm::Field(
|
||||
ui_->field->itemData(index).toInt());
|
||||
SmartPlaylistSearchTerm::Type type = SmartPlaylistSearchTerm::TypeOf(field);
|
||||
SearchTerm::Type type = SearchTerm::TypeOf(field);
|
||||
|
||||
// Populate the operator combo box
|
||||
ui_->op->clear();
|
||||
foreach (SmartPlaylistSearchTerm::Operator op, SmartPlaylistSearchTerm::OperatorsForType(type)) {
|
||||
foreach (SearchTerm::Operator op, SearchTerm::OperatorsForType(type)) {
|
||||
const int i = ui_->op->count();
|
||||
ui_->op->addItem(SmartPlaylistSearchTerm::OperatorText(type, op));
|
||||
ui_->op->addItem(SearchTerm::OperatorText(type, op));
|
||||
ui_->op->setItemData(i, op);
|
||||
}
|
||||
|
||||
// Show the correct value editor
|
||||
QWidget* page = NULL;
|
||||
switch (type) {
|
||||
case SmartPlaylistSearchTerm::Type_Time: page = ui_->page_time; break;
|
||||
case SmartPlaylistSearchTerm::Type_Number: page = ui_->page_number; break;
|
||||
case SmartPlaylistSearchTerm::Type_Date: page = ui_->page_date; break;
|
||||
case SmartPlaylistSearchTerm::Type_Rating: page = ui_->page_rating; break;
|
||||
case SmartPlaylistSearchTerm::Type_Text: page = ui_->page_text; break;
|
||||
case SearchTerm::Type_Time: page = ui_->page_time; break;
|
||||
case SearchTerm::Type_Number: page = ui_->page_number; break;
|
||||
case SearchTerm::Type_Date: page = ui_->page_date; break;
|
||||
case SearchTerm::Type_Rating: page = ui_->page_rating; break;
|
||||
case SearchTerm::Type_Text: page = ui_->page_text; break;
|
||||
}
|
||||
ui_->value_stack->setCurrentWidget(page);
|
||||
|
||||
// Maybe set a tag completer
|
||||
switch (field) {
|
||||
case SmartPlaylistSearchTerm::Field_Artist:
|
||||
case SearchTerm::Field_Artist:
|
||||
new TagCompleter(library_, Playlist::Column_Artist, ui_->value_text);
|
||||
break;
|
||||
|
||||
case SmartPlaylistSearchTerm::Field_Album:
|
||||
case SearchTerm::Field_Album:
|
||||
new TagCompleter(library_, Playlist::Column_Album, ui_->value_text);
|
||||
break;
|
||||
|
||||
@ -146,7 +148,7 @@ void SmartPlaylistSearchTermWidget::FieldChanged(int index) {
|
||||
emit Changed();
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::SetActive(bool active) {
|
||||
void SearchTermWidget::SetActive(bool active) {
|
||||
active_ = active;
|
||||
delete overlay_;
|
||||
overlay_ = NULL;
|
||||
@ -156,7 +158,7 @@ void SmartPlaylistSearchTermWidget::SetActive(bool active) {
|
||||
}
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::enterEvent(QEvent*) {
|
||||
void SearchTermWidget::enterEvent(QEvent*) {
|
||||
if (!overlay_)
|
||||
return;
|
||||
|
||||
@ -166,7 +168,7 @@ void SmartPlaylistSearchTermWidget::enterEvent(QEvent*) {
|
||||
animation_->start();
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::leaveEvent(QEvent*) {
|
||||
void SearchTermWidget::leaveEvent(QEvent*) {
|
||||
if (!overlay_)
|
||||
return;
|
||||
|
||||
@ -176,40 +178,40 @@ void SmartPlaylistSearchTermWidget::leaveEvent(QEvent*) {
|
||||
animation_->start();
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::resizeEvent(QResizeEvent* e) {
|
||||
void SearchTermWidget::resizeEvent(QResizeEvent* e) {
|
||||
QWidget::resizeEvent(e);
|
||||
if (overlay_ && overlay_->isVisible()) {
|
||||
QTimer::singleShot(0, this, SLOT(Grab()));
|
||||
}
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::showEvent(QShowEvent* e) {
|
||||
void SearchTermWidget::showEvent(QShowEvent* e) {
|
||||
QWidget::showEvent(e);
|
||||
if (overlay_) {
|
||||
QTimer::singleShot(0, this, SLOT(Grab()));
|
||||
}
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::Grab() {
|
||||
void SearchTermWidget::Grab() {
|
||||
overlay_->Grab();
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::set_overlay_opacity(float opacity) {
|
||||
void SearchTermWidget::set_overlay_opacity(float opacity) {
|
||||
if (overlay_)
|
||||
overlay_->SetOpacity(opacity);
|
||||
}
|
||||
|
||||
float SmartPlaylistSearchTermWidget::overlay_opacity() const {
|
||||
float SearchTermWidget::overlay_opacity() const {
|
||||
return overlay_ ? overlay_->opacity() : 0.0;
|
||||
}
|
||||
|
||||
SmartPlaylistSearchTerm SmartPlaylistSearchTermWidget::Term() const {
|
||||
SearchTerm SearchTermWidget::Term() const {
|
||||
const int field = ui_->field->itemData(ui_->field->currentIndex()).toInt();
|
||||
const int op = ui_->op->itemData(ui_->op->currentIndex()).toInt();
|
||||
|
||||
SmartPlaylistSearchTerm ret;
|
||||
ret.field_ = SmartPlaylistSearchTerm::Field(field);
|
||||
ret.operator_ = SmartPlaylistSearchTerm::Operator(op);
|
||||
SearchTerm ret;
|
||||
ret.field_ = SearchTerm::Field(field);
|
||||
ret.operator_ = SearchTerm::Operator(op);
|
||||
|
||||
// The value depends on the data type
|
||||
const QWidget* value_page = ui_->value_stack->currentWidget();
|
||||
@ -230,7 +232,7 @@ SmartPlaylistSearchTerm SmartPlaylistSearchTermWidget::Term() const {
|
||||
|
||||
|
||||
|
||||
SmartPlaylistSearchTermWidget::Overlay::Overlay(SmartPlaylistSearchTermWidget* parent)
|
||||
SearchTermWidget::Overlay::Overlay(SearchTermWidget* parent)
|
||||
: QWidget(parent),
|
||||
parent_(parent),
|
||||
opacity_(0.0),
|
||||
@ -240,12 +242,12 @@ SmartPlaylistSearchTermWidget::Overlay::Overlay(SmartPlaylistSearchTermWidget* p
|
||||
raise();
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::Overlay::SetOpacity(float opacity) {
|
||||
void SearchTermWidget::Overlay::SetOpacity(float opacity) {
|
||||
opacity_ = opacity;
|
||||
update();
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::Overlay::Grab() {
|
||||
void SearchTermWidget::Overlay::Grab() {
|
||||
hide();
|
||||
|
||||
// Take a "screenshot" of the window
|
||||
@ -267,7 +269,7 @@ void SmartPlaylistSearchTermWidget::Overlay::Grab() {
|
||||
update();
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::Overlay::paintEvent(QPaintEvent*) {
|
||||
void SearchTermWidget::Overlay::paintEvent(QPaintEvent*) {
|
||||
QPainter p(this);
|
||||
|
||||
// Background
|
||||
@ -300,6 +302,8 @@ void SmartPlaylistSearchTermWidget::Overlay::paintEvent(QPaintEvent*) {
|
||||
p.drawText(text, Qt::TextDontClip | Qt::AlignVCenter, text_);
|
||||
}
|
||||
|
||||
void SmartPlaylistSearchTermWidget::Overlay::mouseReleaseEvent(QMouseEvent*) {
|
||||
void SearchTermWidget::Overlay::mouseReleaseEvent(QMouseEvent*) {
|
||||
emit parent_->Clicked();
|
||||
}
|
||||
|
||||
} // namespace
|
@ -17,7 +17,7 @@
|
||||
#ifndef SMARTPLAYLISTSEARCHTERMWIDGET_H
|
||||
#define SMARTPLAYLISTSEARCHTERMWIDGET_H
|
||||
|
||||
#include "smartplaylistsearchterm.h"
|
||||
#include "searchterm.h"
|
||||
|
||||
#include <QPushButton>
|
||||
#include <QWidget>
|
||||
@ -27,22 +27,24 @@ class Ui_SmartPlaylistSearchTermWidget;
|
||||
|
||||
class QPropertyAnimation;
|
||||
|
||||
class SmartPlaylistSearchTermWidget : public QWidget {
|
||||
namespace smart_playlists {
|
||||
|
||||
class SearchTermWidget : public QWidget {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(float overlay_opacity
|
||||
READ overlay_opacity
|
||||
WRITE set_overlay_opacity);
|
||||
|
||||
public:
|
||||
SmartPlaylistSearchTermWidget(LibraryBackend* library, QWidget* parent);
|
||||
~SmartPlaylistSearchTermWidget();
|
||||
SearchTermWidget(LibraryBackend* library, QWidget* parent);
|
||||
~SearchTermWidget();
|
||||
|
||||
void SetActive(bool active);
|
||||
|
||||
float overlay_opacity() const;
|
||||
void set_overlay_opacity(float opacity);
|
||||
|
||||
SmartPlaylistSearchTerm Term() const;
|
||||
SearchTerm Term() const;
|
||||
|
||||
signals:
|
||||
void Clicked();
|
||||
@ -72,4 +74,6 @@ private:
|
||||
bool active_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // SMARTPLAYLISTSEARCHTERMWIDGET_H
|
@ -14,35 +14,37 @@
|
||||
along with Clementine. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "smartplaylistsearchpreview.h"
|
||||
#include "smartplaylistsearchtermwidget.h"
|
||||
#include "smartplaylistwizard.h"
|
||||
#include "ui_smartplaylistwizard.h"
|
||||
#include "playlistgenerator.h"
|
||||
#include "generator.h"
|
||||
#include "searchpreview.h"
|
||||
#include "searchtermwidget.h"
|
||||
#include "wizard.h"
|
||||
#include "ui_wizard.h"
|
||||
|
||||
SmartPlaylistWizard::SearchPage::SearchPage(QWidget* parent)
|
||||
namespace smart_playlists {
|
||||
|
||||
Wizard::SearchPage::SearchPage(QWidget* parent)
|
||||
: QWizardPage(parent)
|
||||
{
|
||||
}
|
||||
|
||||
bool SmartPlaylistWizard::SearchPage::isComplete() const {
|
||||
bool Wizard::SearchPage::isComplete() const {
|
||||
if (type_->currentIndex() == 2) // All songs
|
||||
return true;
|
||||
|
||||
foreach (SmartPlaylistSearchTermWidget* widget, terms_) {
|
||||
foreach (SearchTermWidget* widget, terms_) {
|
||||
if (!widget->Term().is_valid())
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
SmartPlaylistWizard::SmartPlaylistWizard(LibraryBackend* library, QWidget* parent)
|
||||
Wizard::Wizard(LibraryBackend* library, QWidget* parent)
|
||||
: QWizard(parent),
|
||||
ui_(new Ui_SmartPlaylistWizard),
|
||||
library_(library)
|
||||
{
|
||||
ui_->setupUi(this);
|
||||
ui_->limit_value->setValue(PlaylistGenerator::kDefaultLimit);
|
||||
ui_->limit_value->setValue(Generator::kDefaultLimit);
|
||||
|
||||
connect(ui_->search_type, SIGNAL(currentIndexChanged(int)), SLOT(SearchTypeChanged()));
|
||||
|
||||
@ -50,7 +52,7 @@ SmartPlaylistWizard::SmartPlaylistWizard(LibraryBackend* library, QWidget* paren
|
||||
ui_->page_query_search->type_ = ui_->search_type;
|
||||
|
||||
// Create the new search term widget
|
||||
ui_->page_query_search->new_term_ = new SmartPlaylistSearchTermWidget(library_, this);
|
||||
ui_->page_query_search->new_term_ = new SearchTermWidget(library_, this);
|
||||
ui_->page_query_search->new_term_->SetActive(false);
|
||||
connect(ui_->page_query_search->new_term_, SIGNAL(Clicked()), SLOT(AddSearchTerm()));
|
||||
|
||||
@ -62,14 +64,14 @@ SmartPlaylistWizard::SmartPlaylistWizard(LibraryBackend* library, QWidget* paren
|
||||
// Add the preview widget at the bottom of the search terms page
|
||||
QVBoxLayout* terms_page_layout = static_cast<QVBoxLayout*>(ui_->page_query_search->layout());
|
||||
terms_page_layout->addStretch();
|
||||
ui_->page_query_search->preview_ = new SmartPlaylistSearchPreview(this);
|
||||
ui_->page_query_search->preview_ = new SearchPreview(this);
|
||||
ui_->page_query_search->preview_->set_library(library_);
|
||||
terms_page_layout->addWidget(ui_->page_query_search->preview_);
|
||||
|
||||
// Add sort field texts
|
||||
for (int i=0 ; i<SmartPlaylistSearchTerm::FieldCount ; ++i) {
|
||||
const SmartPlaylistSearchTerm::Field field = SmartPlaylistSearchTerm::Field(i);
|
||||
const QString field_name = SmartPlaylistSearchTerm::FieldName(field);
|
||||
for (int i=0 ; i<SearchTerm::FieldCount ; ++i) {
|
||||
const SearchTerm::Field field = SearchTerm::Field(i);
|
||||
const QString field_name = SearchTerm::FieldName(field);
|
||||
ui_->sort_field_value->addItem(field_name);
|
||||
}
|
||||
connect(ui_->sort_field_value, SIGNAL(currentIndexChanged(int)), SLOT(UpdateSortOrder()));
|
||||
@ -84,25 +86,25 @@ SmartPlaylistWizard::SmartPlaylistWizard(LibraryBackend* library, QWidget* paren
|
||||
ui_->sort_preview->set_library(library_);
|
||||
}
|
||||
|
||||
SmartPlaylistWizard::~SmartPlaylistWizard() {
|
||||
Wizard::~Wizard() {
|
||||
delete ui_;
|
||||
}
|
||||
|
||||
void SmartPlaylistWizard::UpdateSortOrder() {
|
||||
const SmartPlaylistSearchTerm::Field field =
|
||||
SmartPlaylistSearchTerm::Field(ui_->sort_field_value->currentIndex());
|
||||
const SmartPlaylistSearchTerm::Type type = SmartPlaylistSearchTerm::TypeOf(field);
|
||||
const QString asc = SmartPlaylistSearchTerm::FieldSortOrderText(type, true);
|
||||
const QString desc = SmartPlaylistSearchTerm::FieldSortOrderText(type, false);
|
||||
void Wizard::UpdateSortOrder() {
|
||||
const SearchTerm::Field field =
|
||||
SearchTerm::Field(ui_->sort_field_value->currentIndex());
|
||||
const SearchTerm::Type type = SearchTerm::TypeOf(field);
|
||||
const QString asc = SearchTerm::FieldSortOrderText(type, true);
|
||||
const QString desc = SearchTerm::FieldSortOrderText(type, false);
|
||||
|
||||
ui_->sort_order->clear();
|
||||
ui_->sort_order->addItem(asc);
|
||||
ui_->sort_order->addItem(desc);
|
||||
}
|
||||
|
||||
void SmartPlaylistWizard::AddSearchTerm() {
|
||||
SmartPlaylistSearchTermWidget* widget =
|
||||
new SmartPlaylistSearchTermWidget(library_, this);
|
||||
void Wizard::AddSearchTerm() {
|
||||
SearchTermWidget* widget =
|
||||
new SearchTermWidget(library_, this);
|
||||
connect(widget, SIGNAL(RemoveClicked()), SLOT(RemoveSearchTerm()));
|
||||
connect(widget, SIGNAL(Changed()), SLOT(UpdateTermPreview()));
|
||||
|
||||
@ -113,9 +115,9 @@ void SmartPlaylistWizard::AddSearchTerm() {
|
||||
UpdateTermPreview();
|
||||
}
|
||||
|
||||
void SmartPlaylistWizard::RemoveSearchTerm() {
|
||||
SmartPlaylistSearchTermWidget* widget =
|
||||
qobject_cast<SmartPlaylistSearchTermWidget*>(sender());
|
||||
void Wizard::RemoveSearchTerm() {
|
||||
SearchTermWidget* widget =
|
||||
qobject_cast<SearchTermWidget*>(sender());
|
||||
if (!widget)
|
||||
return;
|
||||
|
||||
@ -127,8 +129,8 @@ void SmartPlaylistWizard::RemoveSearchTerm() {
|
||||
UpdateTermPreview();
|
||||
}
|
||||
|
||||
void SmartPlaylistWizard::UpdateTermPreview() {
|
||||
SmartPlaylistSearch search = MakeSearch();
|
||||
void Wizard::UpdateTermPreview() {
|
||||
Search search = MakeSearch();
|
||||
emit ui_->page_query_search->completeChanged();
|
||||
if (!search.is_valid())
|
||||
return;
|
||||
@ -139,35 +141,35 @@ void SmartPlaylistWizard::UpdateTermPreview() {
|
||||
ui_->page_query_search->preview_->Update(search);
|
||||
}
|
||||
|
||||
void SmartPlaylistWizard::UpdateSortPreview() {
|
||||
SmartPlaylistSearch search = MakeSearch();
|
||||
void Wizard::UpdateSortPreview() {
|
||||
Search search = MakeSearch();
|
||||
if (!search.is_valid())
|
||||
return;
|
||||
|
||||
ui_->sort_preview->Update(search);
|
||||
}
|
||||
|
||||
SmartPlaylistSearch SmartPlaylistWizard::MakeSearch() const {
|
||||
SmartPlaylistSearch ret;
|
||||
Search Wizard::MakeSearch() const {
|
||||
Search ret;
|
||||
|
||||
// Search type
|
||||
ret.search_type_ = SmartPlaylistSearch::SearchType(ui_->search_type->currentIndex());
|
||||
ret.search_type_ = Search::SearchType(ui_->search_type->currentIndex());
|
||||
|
||||
// Search terms
|
||||
foreach (SmartPlaylistSearchTermWidget* widget, ui_->page_query_search->terms_) {
|
||||
SmartPlaylistSearchTerm term = widget->Term();
|
||||
foreach (SearchTermWidget* widget, ui_->page_query_search->terms_) {
|
||||
SearchTerm term = widget->Term();
|
||||
if (term.is_valid())
|
||||
ret.terms_ << term;
|
||||
}
|
||||
|
||||
// Sort order
|
||||
if (ui_->sort_random->isChecked()) {
|
||||
ret.sort_type_ = SmartPlaylistSearch::Sort_Random;
|
||||
ret.sort_type_ = Search::Sort_Random;
|
||||
} else {
|
||||
const bool ascending = ui_->sort_order->currentIndex() == 0;
|
||||
ret.sort_type_ = ascending ? SmartPlaylistSearch::Sort_FieldAsc :
|
||||
SmartPlaylistSearch::Sort_FieldDesc;
|
||||
ret.sort_field_ = SmartPlaylistSearchTerm::Field(
|
||||
ret.sort_type_ = ascending ? Search::Sort_FieldAsc :
|
||||
Search::Sort_FieldDesc;
|
||||
ret.sort_field_ = SearchTerm::Field(
|
||||
ui_->sort_field_value->currentIndex());
|
||||
}
|
||||
|
||||
@ -180,9 +182,11 @@ SmartPlaylistSearch SmartPlaylistWizard::MakeSearch() const {
|
||||
return ret;
|
||||
}
|
||||
|
||||
void SmartPlaylistWizard::SearchTypeChanged() {
|
||||
void Wizard::SearchTypeChanged() {
|
||||
const bool all = ui_->search_type->currentIndex() == 2;
|
||||
ui_->terms_group->setEnabled(!all);
|
||||
|
||||
UpdateTermPreview();
|
||||
}
|
||||
|
||||
} // namespace
|
@ -17,37 +17,40 @@
|
||||
#ifndef SMARTPLAYLISTWIZARD_H
|
||||
#define SMARTPLAYLISTWIZARD_H
|
||||
|
||||
#include "smartplaylistsearch.h"
|
||||
#include "search.h"
|
||||
|
||||
#include <QWizard>
|
||||
|
||||
class LibraryBackend;
|
||||
class SmartPlaylistSearchPreview;
|
||||
class SmartPlaylistSearchTermWidget;
|
||||
class Ui_SmartPlaylistWizard;
|
||||
|
||||
class QComboBox;
|
||||
class QVBoxLayout;
|
||||
|
||||
class SmartPlaylistWizard : public QWizard {
|
||||
namespace smart_playlists {
|
||||
|
||||
class SearchPreview;
|
||||
class SearchTermWidget;
|
||||
|
||||
class Wizard : public QWizard {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
SmartPlaylistWizard(LibraryBackend* library, QWidget* parent);
|
||||
~SmartPlaylistWizard();
|
||||
Wizard(LibraryBackend* library, QWidget* parent);
|
||||
~Wizard();
|
||||
|
||||
class SearchPage : public QWizardPage {
|
||||
friend class SmartPlaylistWizard;
|
||||
friend class Wizard;
|
||||
public:
|
||||
SearchPage(QWidget* parent = 0);
|
||||
bool isComplete() const;
|
||||
|
||||
QVBoxLayout* layout_;
|
||||
QComboBox* type_;
|
||||
QList<SmartPlaylistSearchTermWidget*> terms_;
|
||||
SmartPlaylistSearchTermWidget* new_term_;
|
||||
QList<SearchTermWidget*> terms_;
|
||||
SearchTermWidget* new_term_;
|
||||
|
||||
SmartPlaylistSearchPreview* preview_;
|
||||
SearchPreview* preview_;
|
||||
};
|
||||
|
||||
private slots:
|
||||
@ -61,11 +64,13 @@ private slots:
|
||||
void UpdateSortOrder();
|
||||
|
||||
private:
|
||||
SmartPlaylistSearch MakeSearch() const;
|
||||
Search MakeSearch() const;
|
||||
|
||||
private:
|
||||
Ui_SmartPlaylistWizard* ui_;
|
||||
LibraryBackend* library_;
|
||||
};
|
||||
|
||||
} // namespace
|
||||
|
||||
#endif // SMARTPLAYLISTWIZARD_H
|
@ -81,7 +81,7 @@ QLabel {
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<widget class="SmartPlaylistWizard::SearchPage" name="page_query_search">
|
||||
<widget class="smart_playlists::Wizard::SearchPage" name="page_query_search">
|
||||
<property name="styleSheet">
|
||||
<string notr="true">#termframe {
|
||||
border: 1px solid grey;
|
||||
@ -233,22 +233,22 @@ margin-left: 9px;
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="SmartPlaylistSearchPreview" name="sort_preview" native="true"/>
|
||||
<widget class="smart_playlists::SearchPreview" name="sort_preview" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>SmartPlaylistSearchPreview</class>
|
||||
<class>smart_playlists::SearchPreview</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>smartplaylists/smartplaylistsearchpreview.h</header>
|
||||
<header>smartplaylists/searchpreview.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>SmartPlaylistWizard::SearchPage</class>
|
||||
<class>smart_playlists::Wizard::SearchPage</class>
|
||||
<extends>QWizardPage</extends>
|
||||
<header>smartplaylists/smartplaylistwizard.h</header>
|
||||
<header>smartplaylists/wizard.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
@ -653,7 +653,7 @@ void MainWindow::LibrarySongsDoubleClicked(const SongList &songs) {
|
||||
AddLibrarySongsToPlaylist(autoclear_playlist_, songs);
|
||||
}
|
||||
|
||||
void MainWindow::AddSmartPlaylistToPlaylist(bool clear_first, PlaylistGeneratorPtr gen) {
|
||||
void MainWindow::AddSmartPlaylistToPlaylist(bool clear_first, smart_playlists::GeneratorPtr gen) {
|
||||
if (clear_first)
|
||||
playlists_->ClearCurrent();
|
||||
|
||||
|
@ -198,7 +198,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
||||
void AddFilesToPlaylist(bool clear_first, const QList<QUrl>& urls);
|
||||
void AddLibraryItemToPlaylist(bool clear_first, const QModelIndexList& indexes);
|
||||
void AddLibrarySongsToPlaylist(bool clear_first, const SongList& songs);
|
||||
void AddSmartPlaylistToPlaylist(bool clear_first, PlaylistGeneratorPtr gen);
|
||||
void AddSmartPlaylistToPlaylist(bool clear_first, smart_playlists::GeneratorPtr gen);
|
||||
void AddDeviceSongsToPlaylist(bool clear_first, const SongList& songs);
|
||||
void AddUrls(bool play_now, const QList<QUrl>& urls);
|
||||
void ConnectInfoView(SongInfoBase* view);
|
||||
|
Loading…
x
Reference in New Issue
Block a user