Put all smart playlist classes in their own namespace

This commit is contained in:
David Sansome 2010-11-18 20:19:33 +00:00
parent d9ed5c91ef
commit 1f267881fe
34 changed files with 380 additions and 287 deletions

View File

@ -129,14 +129,14 @@ set(SOURCES
radio/savedradio.cpp radio/savedradio.cpp
radio/somafmservice.cpp radio/somafmservice.cpp
smartplaylists/playlistgenerator.cpp smartplaylists/generator.cpp
smartplaylists/playlistgeneratorinserter.cpp smartplaylists/generatorinserter.cpp
smartplaylists/smartplaylistsearch.cpp smartplaylists/querygenerator.cpp
smartplaylists/smartplaylistsearchpreview.cpp smartplaylists/search.cpp
smartplaylists/smartplaylistsearchterm.cpp smartplaylists/searchpreview.cpp
smartplaylists/smartplaylistsearchtermwidget.cpp smartplaylists/searchterm.cpp
smartplaylists/smartplaylistwizard.cpp smartplaylists/searchtermwidget.cpp
smartplaylists/queryplaylistgenerator.cpp smartplaylists/wizard.cpp
songinfo/artistinfoview.cpp songinfo/artistinfoview.cpp
songinfo/collapsibleinfoheader.cpp songinfo/collapsibleinfoheader.cpp
@ -287,12 +287,12 @@ set(HEADERS
radio/savedradio.h radio/savedradio.h
radio/somafmservice.h radio/somafmservice.h
smartplaylists/generator.h
smartplaylists/generatorinserter.h
smartplaylists/generatormimedata.h smartplaylists/generatormimedata.h
smartplaylists/playlistgenerator.h smartplaylists/searchpreview.h
smartplaylists/playlistgeneratorinserter.h smartplaylists/searchtermwidget.h
smartplaylists/smartplaylistsearchpreview.h smartplaylists/wizard.h
smartplaylists/smartplaylistsearchtermwidget.h
smartplaylists/smartplaylistwizard.h
songinfo/artistinfoview.h songinfo/artistinfoview.h
songinfo/collapsibleinfoheader.h songinfo/collapsibleinfoheader.h
@ -374,9 +374,9 @@ set(UI
radio/magnatunedownloaddialog.ui radio/magnatunedownloaddialog.ui
radio/radioviewcontainer.ui radio/radioviewcontainer.ui
smartplaylists/smartplaylistsearchpreview.ui smartplaylists/searchpreview.ui
smartplaylists/smartplaylistsearchtermwidget.ui smartplaylists/searchtermwidget.ui
smartplaylists/smartplaylistwizard.ui smartplaylists/wizard.ui
songinfo/lyricsettings.ui songinfo/lyricsettings.ui

View File

@ -19,7 +19,7 @@
#include "sqlrow.h" #include "sqlrow.h"
#include "core/database.h" #include "core/database.h"
#include "core/scopedtransaction.h" #include "core/scopedtransaction.h"
#include "smartplaylists/smartplaylistsearch.h" #include "smartplaylists/search.h"
#include <QDir> #include <QDir>
#include <QVariant> #include <QVariant>
@ -814,7 +814,7 @@ bool LibraryBackend::ExecQuery(LibraryQuery *q) {
return !db_->CheckErrors(q->Exec(db_->Connect(), songs_table_, fts_table_)); 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()); QMutexLocker l(db_->Mutex());
QSqlDatabase db(db_->Connect()); QSqlDatabase db(db_->Connect());

View File

@ -27,7 +27,8 @@
#include <boost/shared_ptr.hpp> #include <boost/shared_ptr.hpp>
class Database; class Database;
class SmartPlaylistSearch;
namespace smart_playlists { class Search; }
class LibraryBackendInterface : public QObject { class LibraryBackendInterface : public QObject {
public: public:
@ -132,7 +133,7 @@ class LibraryBackend : public LibraryBackendInterface {
void RemoveDirectory(const Directory& dir); void RemoveDirectory(const Directory& dir);
bool ExecQuery(LibraryQuery* q); bool ExecQuery(LibraryQuery* q);
SongList FindSongs(const SmartPlaylistSearch& search); SongList FindSongs(const smart_playlists::Search& search);
void IncrementPlayCountAsync(int id); void IncrementPlayCountAsync(int id);
void IncrementSkipCountAsync(int id, float progress); void IncrementSkipCountAsync(int id, float progress);

View File

@ -21,9 +21,9 @@
#include "sqlrow.h" #include "sqlrow.h"
#include "core/database.h" #include "core/database.h"
#include "playlist/songmimedata.h" #include "playlist/songmimedata.h"
#include "smartplaylists/generator.h"
#include "smartplaylists/generatormimedata.h" #include "smartplaylists/generatormimedata.h"
#include "smartplaylists/playlistgenerator.h" #include "smartplaylists/querygenerator.h"
#include "smartplaylists/queryplaylistgenerator.h"
#include "ui/iconloader.h" #include "ui/iconloader.h"
#include <QSettings> #include <QSettings>
@ -33,6 +33,11 @@
#include <boost/bind.hpp> #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::kSmartPlaylistsMimeType = "application/x-clementine-smart-playlist-generator";
const char* LibraryModel::kSmartPlaylistsSettingsGroup = "SerialisedSmartPlaylists"; const char* LibraryModel::kSmartPlaylistsSettingsGroup = "SerialisedSmartPlaylists";
@ -747,7 +752,7 @@ QMimeData* LibraryModel::mimeData(const QModelIndexList& indexes) const {
// Special case: a smart playlist was dragged // Special case: a smart playlist was dragged
if (IndexToItem(indexes.first())->type == LibraryItem::Type_SmartPlaylist) { if (IndexToItem(indexes.first())->type == LibraryItem::Type_SmartPlaylist) {
PlaylistGeneratorPtr generator = CreateGenerator(indexes.first()); GeneratorPtr generator = CreateGenerator(indexes.first());
if (!generator) if (!generator)
return NULL; return NULL;
@ -882,30 +887,33 @@ void LibraryModel::CreateSmartPlaylists() {
s.beginGroup(kSmartPlaylistsSettingsGroup); s.beginGroup(kSmartPlaylistsSettingsGroup);
s.beginWriteArray("smart"); s.beginWriteArray("smart");
// These defines really make this section more concise using smart_playlists::Search;
#define S SmartPlaylistSearch using smart_playlists::SearchTerm;
#define T SmartPlaylistSearchTerm
int i = 0; int i = 0;
SaveDefaultGenerator(&s, i++, tr("50 random tracks"), S( SaveDefaultGenerator(&s, i++, tr("50 random tracks"), Search(
S::Type_All, S::TermList(), S::Sort_Random, T::Field_Title, 50)); Search::Type_All, Search::TermList(),
SaveDefaultGenerator(&s, i++, tr("Ever played"), S( Search::Sort_Random, SearchTerm::Field_Title, 50));
S::Type_And, S::TermList() << T(T::Field_PlayCount, T::Op_GreaterThan, 0), SaveDefaultGenerator(&s, i++, tr("Ever played"), Search(
S::Sort_Random, T::Field_Title)); Search::Type_And, Search::TermList()
SaveDefaultGenerator(&s, i++, tr("Never played"), S( << SearchTerm(SearchTerm::Field_PlayCount, SearchTerm::Op_GreaterThan, 0),
S::Type_And, S::TermList() << T(T::Field_PlayCount, T::Op_Equals, 0), Search::Sort_Random, SearchTerm::Field_Title));
S::Sort_Random, T::Field_Title)); SaveDefaultGenerator(&s, i++, tr("Never played"), Search(
SaveDefaultGenerator(&s, i++, tr("Last played"), S( Search::Type_And, Search::TermList()
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_LastPlayed)); << SearchTerm(SearchTerm::Field_PlayCount, SearchTerm::Op_Equals, 0),
SaveDefaultGenerator(&s, i++, tr("Most played"), S( Search::Sort_Random, SearchTerm::Field_Title));
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_PlayCount)); SaveDefaultGenerator(&s, i++, tr("Last played"), Search(
SaveDefaultGenerator(&s, i++, tr("Favourite tracks"), S( Search::Type_All, Search::TermList(),
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_Score)); Search::Sort_FieldDesc, SearchTerm::Field_LastPlayed));
SaveDefaultGenerator(&s, i++, tr("Newest tracks"), S( SaveDefaultGenerator(&s, i++, tr("Most played"), Search(
S::Type_All, S::TermList(), S::Sort_FieldDesc, T::Field_DateCreated)); Search::Type_All, Search::TermList(),
Search::Sort_FieldDesc, SearchTerm::Field_PlayCount));
#undef S SaveDefaultGenerator(&s, i++, tr("Favourite tracks"), Search(
#undef T 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.endArray();
s.endGroup(); s.endGroup();
@ -925,28 +933,28 @@ void LibraryModel::CreateSmartPlaylists() {
} }
void LibraryModel::SaveDefaultGenerator(QSettings* s, int i, const QString& name, void LibraryModel::SaveDefaultGenerator(QSettings* s, int i, const QString& name,
const SmartPlaylistSearch& search) const { const smart_playlists::Search& search) const {
boost::shared_ptr<QueryPlaylistGenerator> gen(new QueryPlaylistGenerator); boost::shared_ptr<QueryGenerator> gen(new QueryGenerator);
gen->set_name(name); gen->set_name(name);
gen->Load(search); 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->setArrayIndex(i);
s->setValue("name", generator->name()); s->setValue("name", generator->name());
s->setValue("type", generator->type()); s->setValue("type", generator->type());
s->setValue("data", generator->Save()); s->setValue("data", generator->Save());
} }
PlaylistGeneratorPtr LibraryModel::CreateGenerator(const QModelIndex& index) const { GeneratorPtr LibraryModel::CreateGenerator(const QModelIndex& index) const {
PlaylistGeneratorPtr ret; GeneratorPtr ret;
const LibraryItem* item = IndexToItem(index); const LibraryItem* item = IndexToItem(index);
if (!item || item->type != LibraryItem::Type_SmartPlaylist) if (!item || item->type != LibraryItem::Type_SmartPlaylist)
return ret; return ret;
ret = PlaylistGenerator::Create(item->key); ret = Generator::Create(item->key);
if (!ret) if (!ret)
return ret; return ret;

View File

@ -27,13 +27,13 @@
#include "core/simpletreemodel.h" #include "core/simpletreemodel.h"
#include "core/song.h" #include "core/song.h"
#include "engines/engine_fwd.h" #include "engines/engine_fwd.h"
#include "smartplaylists/playlistgenerator_fwd.h" #include "smartplaylists/generator_fwd.h"
#include <boost/scoped_ptr.hpp> #include <boost/scoped_ptr.hpp>
class LibraryDirectoryModel; class LibraryDirectoryModel;
class LibraryBackend; class LibraryBackend;
class SmartPlaylistSearch; namespace smart_playlists { class Search; }
class QSettings; class QSettings;
@ -102,7 +102,7 @@ class LibraryModel : public SimpleTreeModel<LibraryItem> {
SongList GetChildSongs(const QModelIndex& index) const; SongList GetChildSongs(const QModelIndex& index) const;
SongList GetChildSongs(const QModelIndexList& indexes) const; SongList GetChildSongs(const QModelIndexList& indexes) const;
PlaylistGeneratorPtr CreateGenerator(const QModelIndex& index) const; smart_playlists::GeneratorPtr CreateGenerator(const QModelIndex& index) const;
// QAbstractItemModel // QAbstractItemModel
QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 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 // Smart playlists are shown in another top-level node
void CreateSmartPlaylists(); void CreateSmartPlaylists();
void SaveDefaultGenerator(QSettings* s, int i, const QString& name, void SaveDefaultGenerator(QSettings* s, int i, const QString& name,
const SmartPlaylistSearch& search) const; const smart_playlists::Search& search) const;
void SaveGenerator(QSettings* s, int i, PlaylistGeneratorPtr generator) const; void SaveGenerator(QSettings* s, int i, smart_playlists::GeneratorPtr generator) const;
// Helpers for ItemFromQuery and ItemFromSong // Helpers for ItemFromQuery and ItemFromSong
LibraryItem* InitItem(GroupBy type, bool signal, LibraryItem* parent, LibraryItem* InitItem(GroupBy type, bool signal, LibraryItem* parent,

View File

@ -23,7 +23,7 @@
#include "core/musicstorage.h" #include "core/musicstorage.h"
#include "devices/devicemanager.h" #include "devices/devicemanager.h"
#include "devices/devicestatefiltermodel.h" #include "devices/devicestatefiltermodel.h"
#include "smartplaylists/smartplaylistwizard.h" #include "smartplaylists/wizard.h"
#include "ui/iconloader.h" #include "ui/iconloader.h"
#include "ui/organisedialog.h" #include "ui/organisedialog.h"
#include "ui/organiseerrordialog.h" #include "ui/organiseerrordialog.h"
@ -35,6 +35,8 @@
#include <QSortFilterProxyModel> #include <QSortFilterProxyModel>
#include <QSettings> #include <QSettings>
using smart_playlists::Wizard;
const char* LibraryView::kSettingsGroup = "LibraryView"; const char* LibraryView::kSettingsGroup = "LibraryView";
LibraryItemDelegate::LibraryItemDelegate(QObject *parent) LibraryItemDelegate::LibraryItemDelegate(QObject *parent)
@ -391,7 +393,7 @@ void LibraryView::CreateSmartPlaylistWizard() {
if (smart_playlist_wizard_) if (smart_playlist_wizard_)
return; return;
smart_playlist_wizard_.reset(new SmartPlaylistWizard(library_->backend(), this)); smart_playlist_wizard_.reset(new Wizard(library_->backend(), this));
} }
void LibraryView::NewSmartPlaylist() { void LibraryView::NewSmartPlaylist() {

View File

@ -27,9 +27,10 @@
class DeviceManager; class DeviceManager;
class LibraryModel; class LibraryModel;
class OrganiseDialog; class OrganiseDialog;
class SmartPlaylistWizard;
class TaskManager; class TaskManager;
namespace smart_playlists { class Wizard; }
class LibraryItemDelegate : public QStyledItemDelegate { class LibraryItemDelegate : public QStyledItemDelegate {
public: public:
LibraryItemDelegate(QObject* parent); LibraryItemDelegate(QObject* parent);
@ -118,7 +119,7 @@ class LibraryView : public AutoExpandingTreeView {
QAction* delete_smart_playlist_; QAction* delete_smart_playlist_;
boost::scoped_ptr<OrganiseDialog> organise_dialog_; 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_; bool is_in_keyboard_search_;
}; };

View File

@ -33,8 +33,8 @@
#include "radio/radiomodel.h" #include "radio/radiomodel.h"
#include "radio/radioplaylistitem.h" #include "radio/radioplaylistitem.h"
#include "radio/savedradio.h" #include "radio/savedradio.h"
#include "smartplaylists/generatorinserter.h"
#include "smartplaylists/generatormimedata.h" #include "smartplaylists/generatormimedata.h"
#include "smartplaylists/playlistgeneratorinserter.h"
#include <QtDebug> #include <QtDebug>
#include <QMimeData> #include <QMimeData>
@ -49,6 +49,9 @@
#include <lastfm/ScrobblePoint> #include <lastfm/ScrobblePoint>
using smart_playlists::GeneratorInserter;
using smart_playlists::GeneratorPtr;
using boost::shared_ptr; using boost::shared_ptr;
const char* Playlist::kRowsMimetype = "application/x-clementine-playlist-rows"; 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) if (action == Qt::IgnoreAction)
return false; return false;
using smart_playlists::GeneratorMimeData;
if (const SongMimeData* song_data = qobject_cast<const SongMimeData*>(data)) { if (const SongMimeData* song_data = qobject_cast<const SongMimeData*>(data)) {
// Dragged from a library // Dragged from a library
// We want to check if these songs are from the actual local file backend, // 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); inserter->Load(this, pos, play_now, urls);
} }
void Playlist::InsertSmartPlaylist(PlaylistGeneratorPtr generator, int pos, bool play_now) { void Playlist::InsertSmartPlaylist(GeneratorPtr generator, int pos, bool play_now) {
PlaylistGeneratorInserter* inserter = new PlaylistGeneratorInserter(task_manager_, library_, this); GeneratorInserter* inserter = new GeneratorInserter(task_manager_, library_, this);
connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString))); connect(inserter, SIGNAL(Error(QString)), SIGNAL(LoadTracksError(QString)));
connect(inserter, SIGNAL(PlayRequested(QModelIndex)), SIGNAL(PlayRequested(QModelIndex))); connect(inserter, SIGNAL(PlayRequested(QModelIndex)), SIGNAL(PlayRequested(QModelIndex)));

View File

@ -26,7 +26,7 @@
#include "playlistsequence.h" #include "playlistsequence.h"
#include "core/song.h" #include "core/song.h"
#include "radio/radioitem.h" #include "radio/radioitem.h"
#include "smartplaylists/playlistgenerator_fwd.h" #include "smartplaylists/generator_fwd.h"
class LibraryBackend; class LibraryBackend;
class PlaylistBackend; class PlaylistBackend;
@ -151,7 +151,7 @@ class Playlist : public QAbstractListModel {
QModelIndex InsertMagnatuneItems(const SongList& items, int pos = -1); QModelIndex InsertMagnatuneItems(const SongList& items, int pos = -1);
QModelIndex InsertSongs(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); 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 InsertUrls(const QList<QUrl>& urls, bool play_now, int pos = -1);
void StopAfter(int row); void StopAfter(int row);
void ReloadItems(const QList<int>& rows); void ReloadItems(const QList<int>& rows);

View File

@ -22,11 +22,13 @@
#include "library/librarybackend.h" #include "library/librarybackend.h"
#include "library/libraryplaylistitem.h" #include "library/libraryplaylistitem.h"
#include "playlistparsers/playlistparser.h" #include "playlistparsers/playlistparser.h"
#include "smartplaylists/playlistgenerator.h" #include "smartplaylists/generator.h"
#include <QFileInfo> #include <QFileInfo>
#include <QtDebug> #include <QtDebug>
using smart_playlists::GeneratorPtr;
PlaylistManager::PlaylistManager(TaskManager* task_manager, QObject *parent) PlaylistManager::PlaylistManager(TaskManager* task_manager, QObject *parent)
: QObject(parent), : QObject(parent),
task_manager_(task_manager), 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) { if (as_new) {
New(generator->name()); New(generator->name());
} }

View File

@ -22,7 +22,7 @@
#include <QObject> #include <QObject>
#include "core/song.h" #include "core/song.h"
#include "smartplaylists/playlistgenerator_fwd.h" #include "smartplaylists/generator_fwd.h"
class LibraryBackend; class LibraryBackend;
class Playlist; class Playlist;
@ -85,7 +85,7 @@ public slots:
void SetActiveStopped(); void SetActiveStopped();
void SetActiveStreamMetadata(const QUrl& url, const Song& song); 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: signals:
void PlaylistAdded(int id, const QString& name); void PlaylistAdded(int id, const QString& name);

View File

@ -14,24 +14,28 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "queryplaylistgenerator.h" #include "generator.h"
#include "playlistgenerator.h" #include "querygenerator.h"
#include <QSettings> #include <QSettings>
const int PlaylistGenerator::kDefaultLimit = 20; namespace smart_playlists {
PlaylistGenerator::PlaylistGenerator() const int Generator::kDefaultLimit = 20;
Generator::Generator()
: QObject(NULL), : QObject(NULL),
backend_(NULL) backend_(NULL)
{ {
} }
PlaylistGeneratorPtr PlaylistGenerator::Create(const QString& type) { GeneratorPtr Generator::Create(const QString& type) {
if (type == "Query") if (type == "Query")
return PlaylistGeneratorPtr(new QueryPlaylistGenerator); return GeneratorPtr(new QueryGenerator);
qWarning() << "Invalid playlist generator type:" << type; qWarning() << "Invalid playlist generator type:" << type;
return PlaylistGeneratorPtr(); return GeneratorPtr();
} }
} // namespace

View File

@ -24,15 +24,17 @@
class LibraryBackend; 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 Q_OBJECT
public: public:
PlaylistGenerator(); Generator();
virtual ~PlaylistGenerator() {} virtual ~Generator() {}
static const int kDefaultLimit; 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; } void set_library(LibraryBackend* backend) { backend_ = backend; }
@ -55,6 +57,8 @@ protected:
QString name_; QString name_;
}; };
#include "playlistgenerator_fwd.h" } // namespace
#include "generator_fwd.h"
#endif // PLAYLISTGENERATOR_H #endif // PLAYLISTGENERATOR_H

View File

@ -19,8 +19,12 @@
#include <boost/shared_ptr.hpp> #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 #endif // PLAYLISTGENERATOR_FWD_H

View File

@ -14,18 +14,20 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "playlistgenerator.h" #include "generator.h"
#include "playlistgeneratorinserter.h" #include "generatorinserter.h"
#include "core/taskmanager.h" #include "core/taskmanager.h"
#include "playlist/playlist.h" #include "playlist/playlist.h"
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QtConcurrentRun> #include <QtConcurrentRun>
namespace smart_playlists {
typedef QFuture<PlaylistItemList> Future; typedef QFuture<PlaylistItemList> Future;
typedef QFutureWatcher<PlaylistItemList> FutureWatcher; typedef QFutureWatcher<PlaylistItemList> FutureWatcher;
PlaylistGeneratorInserter::PlaylistGeneratorInserter( GeneratorInserter::GeneratorInserter(
TaskManager* task_manager, LibraryBackend* library, QObject* parent) TaskManager* task_manager, LibraryBackend* library, QObject* parent)
: QObject(parent), : QObject(parent),
task_manager_(task_manager), task_manager_(task_manager),
@ -34,12 +36,12 @@ PlaylistGeneratorInserter::PlaylistGeneratorInserter(
{ {
} }
static PlaylistItemList Generate(PlaylistGeneratorPtr generator) { static PlaylistItemList Generate(GeneratorPtr generator) {
return generator->Generate(); return generator->Generate();
} }
void PlaylistGeneratorInserter::Load( void GeneratorInserter::Load(
Playlist* destination, int row, bool play_now, PlaylistGeneratorPtr generator) { Playlist* destination, int row, bool play_now, GeneratorPtr generator) {
task_id_ = task_manager_->StartTask(tr("Loading smart playlist")); task_id_ = task_manager_->StartTask(tr("Loading smart playlist"));
destination_ = destination; destination_ = destination;
@ -55,7 +57,7 @@ void PlaylistGeneratorInserter::Load(
connect(watcher, SIGNAL(finished()), SLOT(Finished())); connect(watcher, SIGNAL(finished()), SLOT(Finished()));
} }
void PlaylistGeneratorInserter::Finished() { void GeneratorInserter::Finished() {
FutureWatcher* watcher = static_cast<FutureWatcher*>(sender()); FutureWatcher* watcher = static_cast<FutureWatcher*>(sender());
watcher->deleteLater(); watcher->deleteLater();
@ -69,3 +71,5 @@ void PlaylistGeneratorInserter::Finished() {
deleteLater(); deleteLater();
} }
} // namespace

View File

@ -17,7 +17,7 @@
#ifndef PLAYLISTGENERATORINSERTER_H #ifndef PLAYLISTGENERATORINSERTER_H
#define PLAYLISTGENERATORINSERTER_H #define PLAYLISTGENERATORINSERTER_H
#include "playlistgenerator_fwd.h" #include "generator_fwd.h"
#include <QObject> #include <QObject>
@ -27,15 +27,17 @@ class TaskManager;
class QModelIndex; class QModelIndex;
class PlaylistGeneratorInserter : public QObject { namespace smart_playlists {
class GeneratorInserter : public QObject {
Q_OBJECT Q_OBJECT
public: public:
PlaylistGeneratorInserter(TaskManager* task_manager, GeneratorInserter(TaskManager* task_manager,
LibraryBackend* library, QObject* parent); LibraryBackend* library, QObject* parent);
void Load(Playlist* destination, int row, bool play_now, void Load(Playlist* destination, int row, bool play_now,
PlaylistGeneratorPtr generator); GeneratorPtr generator);
signals: signals:
void Error(const QString& message); void Error(const QString& message);
@ -54,4 +56,6 @@ private:
bool play_now_; bool play_now_;
}; };
} // namespace
#endif // PLAYLISTGENERATORINSERTER_H #endif // PLAYLISTGENERATORINSERTER_H

View File

@ -19,15 +19,19 @@
#include <QMimeData> #include <QMimeData>
#include "playlistgenerator_fwd.h" #include "generator_fwd.h"
namespace smart_playlists {
class GeneratorMimeData : public QMimeData { class GeneratorMimeData : public QMimeData {
Q_OBJECT Q_OBJECT
public: public:
GeneratorMimeData(PlaylistGeneratorPtr generator) : generator_(generator) {} GeneratorMimeData(GeneratorPtr generator) : generator_(generator) {}
PlaylistGeneratorPtr generator_; GeneratorPtr generator_;
}; };
} // namespace
#endif // GENERATORMIMEDATA_H #endif // GENERATORMIMEDATA_H

View File

@ -14,26 +14,28 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "queryplaylistgenerator.h" #include "querygenerator.h"
#include "library/librarybackend.h" #include "library/librarybackend.h"
#include "library/libraryplaylistitem.h" #include "library/libraryplaylistitem.h"
#include <QtDebug> #include <QtDebug>
QueryPlaylistGenerator::QueryPlaylistGenerator() namespace smart_playlists {
QueryGenerator::QueryGenerator()
{ {
} }
void QueryPlaylistGenerator::Load(const SmartPlaylistSearch& search) { void QueryGenerator::Load(const Search& search) {
search_ = search; search_ = search;
} }
void QueryPlaylistGenerator::Load(const QByteArray& data) { void QueryGenerator::Load(const QByteArray& data) {
QDataStream s(data); QDataStream s(data);
s >> search_; s >> search_;
} }
QByteArray QueryPlaylistGenerator::Save() const { QByteArray QueryGenerator::Save() const {
QByteArray ret; QByteArray ret;
QDataStream s(&ret, QIODevice::WriteOnly); QDataStream s(&ret, QIODevice::WriteOnly);
s << search_; s << search_;
@ -41,7 +43,7 @@ QByteArray QueryPlaylistGenerator::Save() const {
return ret; return ret;
} }
PlaylistItemList QueryPlaylistGenerator::Generate() { PlaylistItemList QueryGenerator::Generate() {
SongList songs = backend_->FindSongs(search_); SongList songs = backend_->FindSongs(search_);
PlaylistItemList items; PlaylistItemList items;
@ -50,3 +52,5 @@ PlaylistItemList QueryPlaylistGenerator::Generate() {
} }
return items; return items;
} }
} // namespace

View File

@ -17,23 +17,27 @@
#ifndef QUERYPLAYLISTGENERATOR_H #ifndef QUERYPLAYLISTGENERATOR_H
#define QUERYPLAYLISTGENERATOR_H #define QUERYPLAYLISTGENERATOR_H
#include "playlistgenerator.h" #include "generator.h"
#include "smartplaylistsearch.h" #include "search.h"
class QueryPlaylistGenerator : public PlaylistGenerator { namespace smart_playlists {
class QueryGenerator : public Generator {
public: public:
QueryPlaylistGenerator(); QueryGenerator();
QString type() const { return "Query"; } QString type() const { return "Query"; }
void Load(const SmartPlaylistSearch& search); void Load(const Search& search);
void Load(const QByteArray& data); void Load(const QByteArray& data);
QByteArray Save() const; QByteArray Save() const;
PlaylistItemList Generate(); PlaylistItemList Generate();
private: private:
SmartPlaylistSearch search_; Search search_;
}; };
} // namespace
#endif // QUERYPLAYLISTGENERATOR_H #endif // QUERYPLAYLISTGENERATOR_H

View File

@ -14,18 +14,20 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "smartplaylistsearch.h" #include "search.h"
#include "core/song.h" #include "core/song.h"
#include <QStringList> #include <QStringList>
SmartPlaylistSearch::SmartPlaylistSearch() { namespace smart_playlists {
Search::Search() {
Reset(); Reset();
} }
SmartPlaylistSearch::SmartPlaylistSearch( Search::Search(
SearchType type, TermList terms, SortType sort_type, SearchType type, TermList terms, SortType sort_type,
SmartPlaylistSearchTerm::Field sort_field, int limit) SearchTerm::Field sort_field, int limit)
: search_type_(type), : search_type_(type),
terms_(terms), terms_(terms),
sort_type_(sort_type), sort_type_(sort_type),
@ -34,20 +36,20 @@ SmartPlaylistSearch::SmartPlaylistSearch(
{ {
} }
void SmartPlaylistSearch::Reset() { void Search::Reset() {
search_type_ = Type_And; search_type_ = Type_And;
terms_.clear(); terms_.clear();
sort_type_ = Sort_Random; sort_type_ = Sort_Random;
sort_field_ = SmartPlaylistSearchTerm::Field_Title; sort_field_ = SearchTerm::Field_Title;
limit_ = -1; 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; QString sql = "SELECT ROWID," + Song::kColumnSpec + " FROM " + songs_table;
// Add search terms // Add search terms
QStringList term_sql; QStringList term_sql;
foreach (const SmartPlaylistSearchTerm& term, terms_) { foreach (const SearchTerm& term, terms_) {
term_sql += term.ToSql(); term_sql += term.ToSql();
} }
if (!terms_.isEmpty() && search_type_ != Type_All) { if (!terms_.isEmpty() && search_type_ != Type_All) {
@ -59,7 +61,7 @@ QString SmartPlaylistSearch::ToSql(const QString& songs_table) const {
if (sort_type_ == Sort_Random) { if (sort_type_ == Sort_Random) {
sql += " ORDER BY random()"; sql += " ORDER BY random()";
} else { } else {
sql += " ORDER BY " + SmartPlaylistSearchTerm::FieldColumnName(sort_field_) sql += " ORDER BY " + SearchTerm::FieldColumnName(sort_field_)
+ (sort_type_ == Sort_FieldAsc ? " ASC" : " DESC"); + (sort_type_ == Sort_FieldAsc ? " ASC" : " DESC");
} }
@ -71,13 +73,15 @@ QString SmartPlaylistSearch::ToSql(const QString& songs_table) const {
return sql; return sql;
} }
bool SmartPlaylistSearch::is_valid() const { bool Search::is_valid() const {
if (search_type_ == Type_All) if (search_type_ == Type_All)
return true; return true;
return !terms_.isEmpty(); return !terms_.isEmpty();
} }
QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearch& search) { } // namespace
QDataStream& operator <<(QDataStream& s, const smart_playlists::Search& search) {
s << search.terms_; s << search.terms_;
s << quint8(search.sort_type_); s << quint8(search.sort_type_);
s << quint8(search.sort_field_); s << quint8(search.sort_field_);
@ -85,13 +89,13 @@ QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearch& search) {
return s; return s;
} }
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearch& search) { QDataStream& operator >>(QDataStream& s, smart_playlists::Search& search) {
quint8 sort_type, sort_field; quint8 sort_type, sort_field;
qint32 limit; qint32 limit;
s >> search.terms_ >> sort_type >> sort_field >> limit; s >> search.terms_ >> sort_type >> sort_field >> limit;
search.sort_type_ = SmartPlaylistSearch::SortType(sort_type); search.sort_type_ = smart_playlists::Search::SortType(sort_type);
search.sort_field_ = SmartPlaylistSearchTerm::Field(sort_field); search.sort_field_ = smart_playlists::SearchTerm::Field(sort_field);
search.limit_ = limit; search.limit_ = limit;
return s; return s;

View File

@ -17,12 +17,14 @@
#ifndef SMARTPLAYLISTSEARCH_H #ifndef SMARTPLAYLISTSEARCH_H
#define SMARTPLAYLISTSEARCH_H #define SMARTPLAYLISTSEARCH_H
#include "playlistgenerator.h" #include "generator.h"
#include "smartplaylistsearchterm.h" #include "searchterm.h"
class SmartPlaylistSearch { namespace smart_playlists {
class Search {
public: public:
typedef QList<SmartPlaylistSearchTerm> TermList; typedef QList<SearchTerm> TermList;
// These values are persisted, so add to the end of the enum only // These values are persisted, so add to the end of the enum only
enum SearchType { enum SearchType {
@ -38,24 +40,26 @@ public:
Sort_FieldDesc, Sort_FieldDesc,
}; };
SmartPlaylistSearch(); Search();
SmartPlaylistSearch(SearchType type, TermList terms, SortType sort_type, Search(SearchType type, TermList terms, SortType sort_type,
SmartPlaylistSearchTerm::Field sort_field, SearchTerm::Field sort_field,
int limit = PlaylistGenerator::kDefaultLimit); int limit = Generator::kDefaultLimit);
bool is_valid() const; bool is_valid() const;
SearchType search_type_; SearchType search_type_;
TermList terms_; TermList terms_;
SortType sort_type_; SortType sort_type_;
SmartPlaylistSearchTerm::Field sort_field_; SearchTerm::Field sort_field_;
int limit_; int limit_;
void Reset(); void Reset();
QString ToSql(const QString& songs_table) const; QString ToSql(const QString& songs_table) const;
}; };
QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearch& search); } // namespace
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearch& search);
QDataStream& operator <<(QDataStream& s, const smart_playlists::Search& search);
QDataStream& operator >>(QDataStream& s, smart_playlists::Search& search);
#endif // SMARTPLAYLISTSEARCH_H #endif // SMARTPLAYLISTSEARCH_H

View File

@ -14,18 +14,20 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "queryplaylistgenerator.h" #include "querygenerator.h"
#include "smartplaylistsearchpreview.h" #include "searchpreview.h"
#include "ui_smartplaylistsearchpreview.h" #include "ui_searchpreview.h"
#include "playlist/playlist.h" #include "playlist/playlist.h"
#include <QFutureWatcher> #include <QFutureWatcher>
#include <QtConcurrentRun> #include <QtConcurrentRun>
namespace smart_playlists {
typedef QFuture<PlaylistItemList> Future; typedef QFuture<PlaylistItemList> Future;
typedef QFutureWatcher<PlaylistItemList> FutureWatcher; typedef QFutureWatcher<PlaylistItemList> FutureWatcher;
SmartPlaylistSearchPreview::SmartPlaylistSearchPreview(QWidget *parent) SearchPreview::SearchPreview(QWidget *parent)
: QWidget(parent), : QWidget(parent),
ui_(new Ui_SmartPlaylistSearchPreview), ui_(new Ui_SmartPlaylistSearchPreview),
model_(NULL) model_(NULL)
@ -42,11 +44,11 @@ SmartPlaylistSearchPreview::SmartPlaylistSearchPreview(QWidget *parent)
ui_->busy_container->hide(); ui_->busy_container->hide();
} }
SmartPlaylistSearchPreview::~SmartPlaylistSearchPreview() { SearchPreview::~SearchPreview() {
delete ui_; delete ui_;
} }
void SmartPlaylistSearchPreview::set_library(LibraryBackend* backend) { void SearchPreview::set_library(LibraryBackend* backend) {
backend_ = backend; backend_ = backend;
model_ = new Playlist(NULL, NULL, backend_, -1, this); model_ = new Playlist(NULL, NULL, backend_, -1, this);
@ -55,7 +57,7 @@ void SmartPlaylistSearchPreview::set_library(LibraryBackend* backend) {
ui_->tree->SetItemDelegates(backend_); ui_->tree->SetItemDelegates(backend_);
} }
void SmartPlaylistSearchPreview::Update(const SmartPlaylistSearch& search) { void SearchPreview::Update(const Search& search) {
if (generator_) { if (generator_) {
// It's busy generating something already // It's busy generating something already
pending_search_ = search; pending_search_ = search;
@ -65,21 +67,21 @@ void SmartPlaylistSearchPreview::Update(const SmartPlaylistSearch& search) {
RunSearch(search); RunSearch(search);
} }
void SmartPlaylistSearchPreview::RunSearch(const SmartPlaylistSearch& search) { void SearchPreview::RunSearch(const Search& search) {
generator_.reset(new QueryPlaylistGenerator); generator_.reset(new QueryGenerator);
generator_->set_library(backend_); generator_->set_library(backend_);
generator_->Load(search); generator_->Load(search);
ui_->busy_container->show(); ui_->busy_container->show();
ui_->count_label->hide(); 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); FutureWatcher* watcher = new FutureWatcher(this);
watcher->setFuture(future); watcher->setFuture(future);
connect(watcher, SIGNAL(finished()), SLOT(SearchFinished())); connect(watcher, SIGNAL(finished()), SLOT(SearchFinished()));
} }
void SmartPlaylistSearchPreview::SearchFinished() { void SearchPreview::SearchFinished() {
FutureWatcher* watcher = static_cast<FutureWatcher*>(sender()); FutureWatcher* watcher = static_cast<FutureWatcher*>(sender());
watcher->deleteLater(); watcher->deleteLater();
generator_.reset(); generator_.reset();
@ -88,12 +90,12 @@ void SmartPlaylistSearchPreview::SearchFinished() {
// There was another search done while we were running - throw away these // There was another search done while we were running - throw away these
// results and do that one now instead // results and do that one now instead
RunSearch(pending_search_); RunSearch(pending_search_);
pending_search_ = SmartPlaylistSearch(); pending_search_ = Search();
return; return;
} }
PlaylistItemList all_items = watcher->result(); 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_->Clear();
model_->InsertItems(displayed_items); model_->InsertItems(displayed_items);
@ -108,3 +110,5 @@ void SmartPlaylistSearchPreview::SearchFinished() {
ui_->busy_container->hide(); ui_->busy_container->hide();
ui_->count_label->show(); ui_->count_label->show();
} }
} // namespace

View File

@ -17,7 +17,7 @@
#ifndef SMARTPLAYLISTSEARCHPREVIEW_H #ifndef SMARTPLAYLISTSEARCHPREVIEW_H
#define SMARTPLAYLISTSEARCHPREVIEW_H #define SMARTPLAYLISTSEARCHPREVIEW_H
#include "smartplaylistsearch.h" #include "search.h"
#include <QWidget> #include <QWidget>
@ -25,35 +25,40 @@
class LibraryBackend; class LibraryBackend;
class Playlist; class Playlist;
class QueryPlaylistGenerator;
class Ui_SmartPlaylistSearchPreview; class Ui_SmartPlaylistSearchPreview;
class SmartPlaylistSearchPreview : public QWidget { namespace smart_playlists {
class QueryGenerator;
class SearchPreview : public QWidget {
Q_OBJECT Q_OBJECT
public: public:
SmartPlaylistSearchPreview(QWidget *parent = 0); SearchPreview(QWidget *parent = 0);
~SmartPlaylistSearchPreview(); ~SearchPreview();
void set_library(LibraryBackend* backend); void set_library(LibraryBackend* backend);
void Update(const SmartPlaylistSearch& search); void Update(const Search& search);
private: private:
void RunSearch(const SmartPlaylistSearch& search); void RunSearch(const Search& search);
private slots: private slots:
void SearchFinished(); void SearchFinished();
private: private:
Ui_SmartPlaylistSearchPreview* ui_; Ui_SmartPlaylistSearchPreview* ui_;
QList<SmartPlaylistSearchTerm::Field> fields_; QList<SearchTerm::Field> fields_;
LibraryBackend* backend_; LibraryBackend* backend_;
Playlist* model_; Playlist* model_;
SmartPlaylistSearch pending_search_; Search pending_search_;
boost::scoped_ptr<QueryPlaylistGenerator> generator_; boost::scoped_ptr<QueryGenerator> generator_;
}; };
} // namespace
#endif // SMARTPLAYLISTSEARCHPREVIEW_H #endif // SMARTPLAYLISTSEARCHPREVIEW_H

View File

@ -14,16 +14,18 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "smartplaylistsearchterm.h" #include "searchterm.h"
#include "playlist/playlist.h" #include "playlist/playlist.h"
SmartPlaylistSearchTerm::SmartPlaylistSearchTerm() namespace smart_playlists {
SearchTerm::SearchTerm()
: field_(Field_Title), : field_(Field_Title),
operator_(Op_Equals) operator_(Op_Equals)
{ {
} }
SmartPlaylistSearchTerm::SmartPlaylistSearchTerm( SearchTerm::SearchTerm(
Field field, Operator op, const QVariant& value) Field field, Operator op, const QVariant& value)
: field_(field), : field_(field),
operator_(op), operator_(op),
@ -31,7 +33,7 @@ SmartPlaylistSearchTerm::SmartPlaylistSearchTerm(
{ {
} }
QString SmartPlaylistSearchTerm::ToSql() const { QString SearchTerm::ToSql() const {
const QString col = FieldColumnName(field_); const QString col = FieldColumnName(field_);
QString value = value_.toString(); QString value = value_.toString();
value.replace('\'', "''"); value.replace('\'', "''");
@ -58,7 +60,7 @@ QString SmartPlaylistSearchTerm::ToSql() const {
return QString(); return QString();
} }
bool SmartPlaylistSearchTerm::is_valid() const { bool SearchTerm::is_valid() const {
switch (TypeOf(field_)) { switch (TypeOf(field_)) {
case Type_Text: return !value_.toString().isEmpty(); case Type_Text: return !value_.toString().isEmpty();
case Type_Date: return value_.toInt() != 0; case Type_Date: return value_.toInt() != 0;
@ -69,7 +71,7 @@ bool SmartPlaylistSearchTerm::is_valid() const {
return false; return false;
} }
SmartPlaylistSearchTerm::Type SmartPlaylistSearchTerm::TypeOf(Field field) { SearchTerm::Type SearchTerm::TypeOf(Field field) {
switch (field) { switch (field) {
case Field_Length: case Field_Length:
return Type_Time; 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) { switch (type) {
case Type_Text: case Type_Text:
return OperatorList() << Op_Contains << Op_NotContains << Op_Equals 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) { if (type == Type_Date) {
switch (op) { switch (op) {
case Op_GreaterThan: return QObject::tr("after"); case Op_GreaterThan: return QObject::tr("after");
@ -132,7 +134,7 @@ QString SmartPlaylistSearchTerm::OperatorText(Type type, Operator op) {
return QString(); return QString();
} }
QString SmartPlaylistSearchTerm::FieldColumnName(Field field) { QString SearchTerm::FieldColumnName(Field field) {
switch (field) { switch (field) {
case Field_Length: return "length"; case Field_Length: return "length";
case Field_Track: return "track"; case Field_Track: return "track";
@ -161,7 +163,7 @@ QString SmartPlaylistSearchTerm::FieldColumnName(Field field) {
return QString(); return QString();
} }
QString SmartPlaylistSearchTerm::FieldName(Field field) { QString SearchTerm::FieldName(Field field) {
switch (field) { switch (field) {
case Field_Length: return Playlist::column_name(Playlist::Column_Length); case Field_Length: return Playlist::column_name(Playlist::Column_Length);
case Field_Track: return Playlist::column_name(Playlist::Column_Track); case Field_Track: return Playlist::column_name(Playlist::Column_Track);
@ -190,7 +192,7 @@ QString SmartPlaylistSearchTerm::FieldName(Field field) {
return QString(); return QString();
} }
QString SmartPlaylistSearchTerm::FieldSortOrderText(Type type, bool ascending) { QString SearchTerm::FieldSortOrderText(Type type, bool ascending) {
switch (type) { switch (type) {
case Type_Text: return ascending ? QObject::tr("A-Z") : QObject::tr("Z-A"); 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"); 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(); 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.field_);
s << quint8(term.operator_); s << quint8(term.operator_);
s << term.value_; s << term.value_;
return s; return s;
} }
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearchTerm& term) { QDataStream& operator >>(QDataStream& s, smart_playlists::SearchTerm& term) {
quint8 field, op; quint8 field, op;
s >> field >> op >> term.value_; s >> field >> op >> term.value_;
term.field_ = SmartPlaylistSearchTerm::Field(field); term.field_ = smart_playlists::SearchTerm::Field(field);
term.operator_ = SmartPlaylistSearchTerm::Operator(op); term.operator_ = smart_playlists::SearchTerm::Operator(op);
return s; return s;
} }

View File

@ -20,7 +20,9 @@
#include <QDataStream> #include <QDataStream>
#include <QVariant> #include <QVariant>
class SmartPlaylistSearchTerm { namespace smart_playlists {
class SearchTerm {
public: public:
// These values are persisted, so add to the end of the enum only // These values are persisted, so add to the end of the enum only
enum Field { enum Field {
@ -74,8 +76,8 @@ public:
Type_Rating, Type_Rating,
}; };
SmartPlaylistSearchTerm(); SearchTerm();
SmartPlaylistSearchTerm(Field field, Operator op, const QVariant& value); SearchTerm(Field field, Operator op, const QVariant& value);
Field field_; Field field_;
Operator operator_; Operator operator_;
@ -92,9 +94,11 @@ public:
static QString FieldSortOrderText(Type type, bool ascending); static QString FieldSortOrderText(Type type, bool ascending);
}; };
typedef QList<SmartPlaylistSearchTerm::Operator> OperatorList; typedef QList<SearchTerm::Operator> OperatorList;
QDataStream& operator <<(QDataStream& s, const SmartPlaylistSearchTerm& term); } // namespace
QDataStream& operator >>(QDataStream& s, SmartPlaylistSearchTerm& term);
QDataStream& operator <<(QDataStream& s, const smart_playlists::SearchTerm& term);
QDataStream& operator >>(QDataStream& s, smart_playlists::SearchTerm& term);
#endif // SMARTPLAYLISTSEARCHTERM_H #endif // SMARTPLAYLISTSEARCHTERM_H

View File

@ -14,9 +14,9 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "smartplaylistsearchterm.h" #include "searchterm.h"
#include "smartplaylistsearchtermwidget.h" #include "searchtermwidget.h"
#include "ui_smartplaylistsearchtermwidget.h" #include "ui_searchtermwidget.h"
#include "core/utilities.h" #include "core/utilities.h"
#include "playlist/playlist.h" #include "playlist/playlist.h"
#include "playlist/playlistdelegates.h" #include "playlist/playlistdelegates.h"
@ -31,9 +31,11 @@
// Exported by QtGui // Exported by QtGui
void qt_blurImage(QPainter *p, QImage &blurImage, qreal radius, bool quality, bool alphaOnly, int transposed = 0); 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: public:
Overlay(SmartPlaylistSearchTermWidget* parent); Overlay(SearchTermWidget* parent);
void Grab(); void Grab();
void SetOpacity(float opacity); void SetOpacity(float opacity);
float opacity() const { return opacity_; } float opacity() const { return opacity_; }
@ -46,7 +48,7 @@ protected:
void mouseReleaseEvent(QMouseEvent*); void mouseReleaseEvent(QMouseEvent*);
private: private:
SmartPlaylistSearchTermWidget* parent_; SearchTermWidget* parent_;
float opacity_; float opacity_;
QString text_; QString text_;
@ -54,11 +56,11 @@ private:
QPixmap icon_; QPixmap icon_;
}; };
const int SmartPlaylistSearchTermWidget::Overlay::kSpacing = 6; const int SearchTermWidget::Overlay::kSpacing = 6;
const int SmartPlaylistSearchTermWidget::Overlay::kIconSize = 22; const int SearchTermWidget::Overlay::kIconSize = 22;
SmartPlaylistSearchTermWidget::SmartPlaylistSearchTermWidget(LibraryBackend* library, QWidget* parent) SearchTermWidget::SearchTermWidget(LibraryBackend* library, QWidget* parent)
: QWidget(parent), : QWidget(parent),
ui_(new Ui_SmartPlaylistSearchTermWidget), ui_(new Ui_SmartPlaylistSearchTermWidget),
library_(library), library_(library),
@ -80,8 +82,8 @@ SmartPlaylistSearchTermWidget::SmartPlaylistSearchTermWidget(LibraryBackend* lib
ui_->value_date->setDate(QDate::currentDate()); ui_->value_date->setDate(QDate::currentDate());
// Populate the combo boxes // Populate the combo boxes
for (int i=0 ; i<SmartPlaylistSearchTerm::FieldCount ; ++i) { for (int i=0 ; i<SearchTerm::FieldCount ; ++i) {
ui_->field->addItem(SmartPlaylistSearchTerm::FieldName(SmartPlaylistSearchTerm::Field(i))); ui_->field->addItem(SearchTerm::FieldName(SearchTerm::Field(i)));
ui_->field->setItemData(i, i); ui_->field->setItemData(i, i);
} }
ui_->field->model()->sort(0); ui_->field->model()->sort(0);
@ -101,41 +103,41 @@ SmartPlaylistSearchTermWidget::SmartPlaylistSearchTermWidget(LibraryBackend* lib
setStyleSheet(stylesheet); setStyleSheet(stylesheet);
} }
SmartPlaylistSearchTermWidget::~SmartPlaylistSearchTermWidget() { SearchTermWidget::~SearchTermWidget() {
delete ui_; delete ui_;
} }
void SmartPlaylistSearchTermWidget::FieldChanged(int index) { void SearchTermWidget::FieldChanged(int index) {
SmartPlaylistSearchTerm::Field field = SmartPlaylistSearchTerm::Field( SearchTerm::Field field = SearchTerm::Field(
ui_->field->itemData(index).toInt()); ui_->field->itemData(index).toInt());
SmartPlaylistSearchTerm::Type type = SmartPlaylistSearchTerm::TypeOf(field); SearchTerm::Type type = SearchTerm::TypeOf(field);
// Populate the operator combo box // Populate the operator combo box
ui_->op->clear(); ui_->op->clear();
foreach (SmartPlaylistSearchTerm::Operator op, SmartPlaylistSearchTerm::OperatorsForType(type)) { foreach (SearchTerm::Operator op, SearchTerm::OperatorsForType(type)) {
const int i = ui_->op->count(); 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); ui_->op->setItemData(i, op);
} }
// Show the correct value editor // Show the correct value editor
QWidget* page = NULL; QWidget* page = NULL;
switch (type) { switch (type) {
case SmartPlaylistSearchTerm::Type_Time: page = ui_->page_time; break; case SearchTerm::Type_Time: page = ui_->page_time; break;
case SmartPlaylistSearchTerm::Type_Number: page = ui_->page_number; break; case SearchTerm::Type_Number: page = ui_->page_number; break;
case SmartPlaylistSearchTerm::Type_Date: page = ui_->page_date; break; case SearchTerm::Type_Date: page = ui_->page_date; break;
case SmartPlaylistSearchTerm::Type_Rating: page = ui_->page_rating; break; case SearchTerm::Type_Rating: page = ui_->page_rating; break;
case SmartPlaylistSearchTerm::Type_Text: page = ui_->page_text; break; case SearchTerm::Type_Text: page = ui_->page_text; break;
} }
ui_->value_stack->setCurrentWidget(page); ui_->value_stack->setCurrentWidget(page);
// Maybe set a tag completer // Maybe set a tag completer
switch (field) { switch (field) {
case SmartPlaylistSearchTerm::Field_Artist: case SearchTerm::Field_Artist:
new TagCompleter(library_, Playlist::Column_Artist, ui_->value_text); new TagCompleter(library_, Playlist::Column_Artist, ui_->value_text);
break; break;
case SmartPlaylistSearchTerm::Field_Album: case SearchTerm::Field_Album:
new TagCompleter(library_, Playlist::Column_Album, ui_->value_text); new TagCompleter(library_, Playlist::Column_Album, ui_->value_text);
break; break;
@ -146,7 +148,7 @@ void SmartPlaylistSearchTermWidget::FieldChanged(int index) {
emit Changed(); emit Changed();
} }
void SmartPlaylistSearchTermWidget::SetActive(bool active) { void SearchTermWidget::SetActive(bool active) {
active_ = active; active_ = active;
delete overlay_; delete overlay_;
overlay_ = NULL; overlay_ = NULL;
@ -156,7 +158,7 @@ void SmartPlaylistSearchTermWidget::SetActive(bool active) {
} }
} }
void SmartPlaylistSearchTermWidget::enterEvent(QEvent*) { void SearchTermWidget::enterEvent(QEvent*) {
if (!overlay_) if (!overlay_)
return; return;
@ -166,7 +168,7 @@ void SmartPlaylistSearchTermWidget::enterEvent(QEvent*) {
animation_->start(); animation_->start();
} }
void SmartPlaylistSearchTermWidget::leaveEvent(QEvent*) { void SearchTermWidget::leaveEvent(QEvent*) {
if (!overlay_) if (!overlay_)
return; return;
@ -176,40 +178,40 @@ void SmartPlaylistSearchTermWidget::leaveEvent(QEvent*) {
animation_->start(); animation_->start();
} }
void SmartPlaylistSearchTermWidget::resizeEvent(QResizeEvent* e) { void SearchTermWidget::resizeEvent(QResizeEvent* e) {
QWidget::resizeEvent(e); QWidget::resizeEvent(e);
if (overlay_ && overlay_->isVisible()) { if (overlay_ && overlay_->isVisible()) {
QTimer::singleShot(0, this, SLOT(Grab())); QTimer::singleShot(0, this, SLOT(Grab()));
} }
} }
void SmartPlaylistSearchTermWidget::showEvent(QShowEvent* e) { void SearchTermWidget::showEvent(QShowEvent* e) {
QWidget::showEvent(e); QWidget::showEvent(e);
if (overlay_) { if (overlay_) {
QTimer::singleShot(0, this, SLOT(Grab())); QTimer::singleShot(0, this, SLOT(Grab()));
} }
} }
void SmartPlaylistSearchTermWidget::Grab() { void SearchTermWidget::Grab() {
overlay_->Grab(); overlay_->Grab();
} }
void SmartPlaylistSearchTermWidget::set_overlay_opacity(float opacity) { void SearchTermWidget::set_overlay_opacity(float opacity) {
if (overlay_) if (overlay_)
overlay_->SetOpacity(opacity); overlay_->SetOpacity(opacity);
} }
float SmartPlaylistSearchTermWidget::overlay_opacity() const { float SearchTermWidget::overlay_opacity() const {
return overlay_ ? overlay_->opacity() : 0.0; 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 field = ui_->field->itemData(ui_->field->currentIndex()).toInt();
const int op = ui_->op->itemData(ui_->op->currentIndex()).toInt(); const int op = ui_->op->itemData(ui_->op->currentIndex()).toInt();
SmartPlaylistSearchTerm ret; SearchTerm ret;
ret.field_ = SmartPlaylistSearchTerm::Field(field); ret.field_ = SearchTerm::Field(field);
ret.operator_ = SmartPlaylistSearchTerm::Operator(op); ret.operator_ = SearchTerm::Operator(op);
// The value depends on the data type // The value depends on the data type
const QWidget* value_page = ui_->value_stack->currentWidget(); 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), : QWidget(parent),
parent_(parent), parent_(parent),
opacity_(0.0), opacity_(0.0),
@ -240,12 +242,12 @@ SmartPlaylistSearchTermWidget::Overlay::Overlay(SmartPlaylistSearchTermWidget* p
raise(); raise();
} }
void SmartPlaylistSearchTermWidget::Overlay::SetOpacity(float opacity) { void SearchTermWidget::Overlay::SetOpacity(float opacity) {
opacity_ = opacity; opacity_ = opacity;
update(); update();
} }
void SmartPlaylistSearchTermWidget::Overlay::Grab() { void SearchTermWidget::Overlay::Grab() {
hide(); hide();
// Take a "screenshot" of the window // Take a "screenshot" of the window
@ -267,7 +269,7 @@ void SmartPlaylistSearchTermWidget::Overlay::Grab() {
update(); update();
} }
void SmartPlaylistSearchTermWidget::Overlay::paintEvent(QPaintEvent*) { void SearchTermWidget::Overlay::paintEvent(QPaintEvent*) {
QPainter p(this); QPainter p(this);
// Background // Background
@ -300,6 +302,8 @@ void SmartPlaylistSearchTermWidget::Overlay::paintEvent(QPaintEvent*) {
p.drawText(text, Qt::TextDontClip | Qt::AlignVCenter, text_); p.drawText(text, Qt::TextDontClip | Qt::AlignVCenter, text_);
} }
void SmartPlaylistSearchTermWidget::Overlay::mouseReleaseEvent(QMouseEvent*) { void SearchTermWidget::Overlay::mouseReleaseEvent(QMouseEvent*) {
emit parent_->Clicked(); emit parent_->Clicked();
} }
} // namespace

View File

@ -17,7 +17,7 @@
#ifndef SMARTPLAYLISTSEARCHTERMWIDGET_H #ifndef SMARTPLAYLISTSEARCHTERMWIDGET_H
#define SMARTPLAYLISTSEARCHTERMWIDGET_H #define SMARTPLAYLISTSEARCHTERMWIDGET_H
#include "smartplaylistsearchterm.h" #include "searchterm.h"
#include <QPushButton> #include <QPushButton>
#include <QWidget> #include <QWidget>
@ -27,22 +27,24 @@ class Ui_SmartPlaylistSearchTermWidget;
class QPropertyAnimation; class QPropertyAnimation;
class SmartPlaylistSearchTermWidget : public QWidget { namespace smart_playlists {
class SearchTermWidget : public QWidget {
Q_OBJECT Q_OBJECT
Q_PROPERTY(float overlay_opacity Q_PROPERTY(float overlay_opacity
READ overlay_opacity READ overlay_opacity
WRITE set_overlay_opacity); WRITE set_overlay_opacity);
public: public:
SmartPlaylistSearchTermWidget(LibraryBackend* library, QWidget* parent); SearchTermWidget(LibraryBackend* library, QWidget* parent);
~SmartPlaylistSearchTermWidget(); ~SearchTermWidget();
void SetActive(bool active); void SetActive(bool active);
float overlay_opacity() const; float overlay_opacity() const;
void set_overlay_opacity(float opacity); void set_overlay_opacity(float opacity);
SmartPlaylistSearchTerm Term() const; SearchTerm Term() const;
signals: signals:
void Clicked(); void Clicked();
@ -72,4 +74,6 @@ private:
bool active_; bool active_;
}; };
} // namespace
#endif // SMARTPLAYLISTSEARCHTERMWIDGET_H #endif // SMARTPLAYLISTSEARCHTERMWIDGET_H

View File

@ -14,35 +14,37 @@
along with Clementine. If not, see <http://www.gnu.org/licenses/>. along with Clementine. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "smartplaylistsearchpreview.h" #include "generator.h"
#include "smartplaylistsearchtermwidget.h" #include "searchpreview.h"
#include "smartplaylistwizard.h" #include "searchtermwidget.h"
#include "ui_smartplaylistwizard.h" #include "wizard.h"
#include "playlistgenerator.h" #include "ui_wizard.h"
SmartPlaylistWizard::SearchPage::SearchPage(QWidget* parent) namespace smart_playlists {
Wizard::SearchPage::SearchPage(QWidget* parent)
: QWizardPage(parent) : QWizardPage(parent)
{ {
} }
bool SmartPlaylistWizard::SearchPage::isComplete() const { bool Wizard::SearchPage::isComplete() const {
if (type_->currentIndex() == 2) // All songs if (type_->currentIndex() == 2) // All songs
return true; return true;
foreach (SmartPlaylistSearchTermWidget* widget, terms_) { foreach (SearchTermWidget* widget, terms_) {
if (!widget->Term().is_valid()) if (!widget->Term().is_valid())
return false; return false;
} }
return true; return true;
} }
SmartPlaylistWizard::SmartPlaylistWizard(LibraryBackend* library, QWidget* parent) Wizard::Wizard(LibraryBackend* library, QWidget* parent)
: QWizard(parent), : QWizard(parent),
ui_(new Ui_SmartPlaylistWizard), ui_(new Ui_SmartPlaylistWizard),
library_(library) library_(library)
{ {
ui_->setupUi(this); ui_->setupUi(this);
ui_->limit_value->setValue(PlaylistGenerator::kDefaultLimit); ui_->limit_value->setValue(Generator::kDefaultLimit);
connect(ui_->search_type, SIGNAL(currentIndexChanged(int)), SLOT(SearchTypeChanged())); 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; ui_->page_query_search->type_ = ui_->search_type;
// Create the new search term widget // 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); ui_->page_query_search->new_term_->SetActive(false);
connect(ui_->page_query_search->new_term_, SIGNAL(Clicked()), SLOT(AddSearchTerm())); 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 // Add the preview widget at the bottom of the search terms page
QVBoxLayout* terms_page_layout = static_cast<QVBoxLayout*>(ui_->page_query_search->layout()); QVBoxLayout* terms_page_layout = static_cast<QVBoxLayout*>(ui_->page_query_search->layout());
terms_page_layout->addStretch(); 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_); ui_->page_query_search->preview_->set_library(library_);
terms_page_layout->addWidget(ui_->page_query_search->preview_); terms_page_layout->addWidget(ui_->page_query_search->preview_);
// Add sort field texts // Add sort field texts
for (int i=0 ; i<SmartPlaylistSearchTerm::FieldCount ; ++i) { for (int i=0 ; i<SearchTerm::FieldCount ; ++i) {
const SmartPlaylistSearchTerm::Field field = SmartPlaylistSearchTerm::Field(i); const SearchTerm::Field field = SearchTerm::Field(i);
const QString field_name = SmartPlaylistSearchTerm::FieldName(field); const QString field_name = SearchTerm::FieldName(field);
ui_->sort_field_value->addItem(field_name); ui_->sort_field_value->addItem(field_name);
} }
connect(ui_->sort_field_value, SIGNAL(currentIndexChanged(int)), SLOT(UpdateSortOrder())); 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_); ui_->sort_preview->set_library(library_);
} }
SmartPlaylistWizard::~SmartPlaylistWizard() { Wizard::~Wizard() {
delete ui_; delete ui_;
} }
void SmartPlaylistWizard::UpdateSortOrder() { void Wizard::UpdateSortOrder() {
const SmartPlaylistSearchTerm::Field field = const SearchTerm::Field field =
SmartPlaylistSearchTerm::Field(ui_->sort_field_value->currentIndex()); SearchTerm::Field(ui_->sort_field_value->currentIndex());
const SmartPlaylistSearchTerm::Type type = SmartPlaylistSearchTerm::TypeOf(field); const SearchTerm::Type type = SearchTerm::TypeOf(field);
const QString asc = SmartPlaylistSearchTerm::FieldSortOrderText(type, true); const QString asc = SearchTerm::FieldSortOrderText(type, true);
const QString desc = SmartPlaylistSearchTerm::FieldSortOrderText(type, false); const QString desc = SearchTerm::FieldSortOrderText(type, false);
ui_->sort_order->clear(); ui_->sort_order->clear();
ui_->sort_order->addItem(asc); ui_->sort_order->addItem(asc);
ui_->sort_order->addItem(desc); ui_->sort_order->addItem(desc);
} }
void SmartPlaylistWizard::AddSearchTerm() { void Wizard::AddSearchTerm() {
SmartPlaylistSearchTermWidget* widget = SearchTermWidget* widget =
new SmartPlaylistSearchTermWidget(library_, this); new SearchTermWidget(library_, this);
connect(widget, SIGNAL(RemoveClicked()), SLOT(RemoveSearchTerm())); connect(widget, SIGNAL(RemoveClicked()), SLOT(RemoveSearchTerm()));
connect(widget, SIGNAL(Changed()), SLOT(UpdateTermPreview())); connect(widget, SIGNAL(Changed()), SLOT(UpdateTermPreview()));
@ -113,9 +115,9 @@ void SmartPlaylistWizard::AddSearchTerm() {
UpdateTermPreview(); UpdateTermPreview();
} }
void SmartPlaylistWizard::RemoveSearchTerm() { void Wizard::RemoveSearchTerm() {
SmartPlaylistSearchTermWidget* widget = SearchTermWidget* widget =
qobject_cast<SmartPlaylistSearchTermWidget*>(sender()); qobject_cast<SearchTermWidget*>(sender());
if (!widget) if (!widget)
return; return;
@ -127,8 +129,8 @@ void SmartPlaylistWizard::RemoveSearchTerm() {
UpdateTermPreview(); UpdateTermPreview();
} }
void SmartPlaylistWizard::UpdateTermPreview() { void Wizard::UpdateTermPreview() {
SmartPlaylistSearch search = MakeSearch(); Search search = MakeSearch();
emit ui_->page_query_search->completeChanged(); emit ui_->page_query_search->completeChanged();
if (!search.is_valid()) if (!search.is_valid())
return; return;
@ -139,35 +141,35 @@ void SmartPlaylistWizard::UpdateTermPreview() {
ui_->page_query_search->preview_->Update(search); ui_->page_query_search->preview_->Update(search);
} }
void SmartPlaylistWizard::UpdateSortPreview() { void Wizard::UpdateSortPreview() {
SmartPlaylistSearch search = MakeSearch(); Search search = MakeSearch();
if (!search.is_valid()) if (!search.is_valid())
return; return;
ui_->sort_preview->Update(search); ui_->sort_preview->Update(search);
} }
SmartPlaylistSearch SmartPlaylistWizard::MakeSearch() const { Search Wizard::MakeSearch() const {
SmartPlaylistSearch ret; Search ret;
// Search type // Search type
ret.search_type_ = SmartPlaylistSearch::SearchType(ui_->search_type->currentIndex()); ret.search_type_ = Search::SearchType(ui_->search_type->currentIndex());
// Search terms // Search terms
foreach (SmartPlaylistSearchTermWidget* widget, ui_->page_query_search->terms_) { foreach (SearchTermWidget* widget, ui_->page_query_search->terms_) {
SmartPlaylistSearchTerm term = widget->Term(); SearchTerm term = widget->Term();
if (term.is_valid()) if (term.is_valid())
ret.terms_ << term; ret.terms_ << term;
} }
// Sort order // Sort order
if (ui_->sort_random->isChecked()) { if (ui_->sort_random->isChecked()) {
ret.sort_type_ = SmartPlaylistSearch::Sort_Random; ret.sort_type_ = Search::Sort_Random;
} else { } else {
const bool ascending = ui_->sort_order->currentIndex() == 0; const bool ascending = ui_->sort_order->currentIndex() == 0;
ret.sort_type_ = ascending ? SmartPlaylistSearch::Sort_FieldAsc : ret.sort_type_ = ascending ? Search::Sort_FieldAsc :
SmartPlaylistSearch::Sort_FieldDesc; Search::Sort_FieldDesc;
ret.sort_field_ = SmartPlaylistSearchTerm::Field( ret.sort_field_ = SearchTerm::Field(
ui_->sort_field_value->currentIndex()); ui_->sort_field_value->currentIndex());
} }
@ -180,9 +182,11 @@ SmartPlaylistSearch SmartPlaylistWizard::MakeSearch() const {
return ret; return ret;
} }
void SmartPlaylistWizard::SearchTypeChanged() { void Wizard::SearchTypeChanged() {
const bool all = ui_->search_type->currentIndex() == 2; const bool all = ui_->search_type->currentIndex() == 2;
ui_->terms_group->setEnabled(!all); ui_->terms_group->setEnabled(!all);
UpdateTermPreview(); UpdateTermPreview();
} }
} // namespace

View File

@ -17,37 +17,40 @@
#ifndef SMARTPLAYLISTWIZARD_H #ifndef SMARTPLAYLISTWIZARD_H
#define SMARTPLAYLISTWIZARD_H #define SMARTPLAYLISTWIZARD_H
#include "smartplaylistsearch.h" #include "search.h"
#include <QWizard> #include <QWizard>
class LibraryBackend; class LibraryBackend;
class SmartPlaylistSearchPreview;
class SmartPlaylistSearchTermWidget;
class Ui_SmartPlaylistWizard; class Ui_SmartPlaylistWizard;
class QComboBox; class QComboBox;
class QVBoxLayout; class QVBoxLayout;
class SmartPlaylistWizard : public QWizard { namespace smart_playlists {
class SearchPreview;
class SearchTermWidget;
class Wizard : public QWizard {
Q_OBJECT Q_OBJECT
public: public:
SmartPlaylistWizard(LibraryBackend* library, QWidget* parent); Wizard(LibraryBackend* library, QWidget* parent);
~SmartPlaylistWizard(); ~Wizard();
class SearchPage : public QWizardPage { class SearchPage : public QWizardPage {
friend class SmartPlaylistWizard; friend class Wizard;
public: public:
SearchPage(QWidget* parent = 0); SearchPage(QWidget* parent = 0);
bool isComplete() const; bool isComplete() const;
QVBoxLayout* layout_; QVBoxLayout* layout_;
QComboBox* type_; QComboBox* type_;
QList<SmartPlaylistSearchTermWidget*> terms_; QList<SearchTermWidget*> terms_;
SmartPlaylistSearchTermWidget* new_term_; SearchTermWidget* new_term_;
SmartPlaylistSearchPreview* preview_; SearchPreview* preview_;
}; };
private slots: private slots:
@ -61,11 +64,13 @@ private slots:
void UpdateSortOrder(); void UpdateSortOrder();
private: private:
SmartPlaylistSearch MakeSearch() const; Search MakeSearch() const;
private: private:
Ui_SmartPlaylistWizard* ui_; Ui_SmartPlaylistWizard* ui_;
LibraryBackend* library_; LibraryBackend* library_;
}; };
} // namespace
#endif // SMARTPLAYLISTWIZARD_H #endif // SMARTPLAYLISTWIZARD_H

View File

@ -81,7 +81,7 @@ QLabel {
</item> </item>
</layout> </layout>
</widget> </widget>
<widget class="SmartPlaylistWizard::SearchPage" name="page_query_search"> <widget class="smart_playlists::Wizard::SearchPage" name="page_query_search">
<property name="styleSheet"> <property name="styleSheet">
<string notr="true">#termframe { <string notr="true">#termframe {
border: 1px solid grey; border: 1px solid grey;
@ -233,22 +233,22 @@ margin-left: 9px;
</widget> </widget>
</item> </item>
<item> <item>
<widget class="SmartPlaylistSearchPreview" name="sort_preview" native="true"/> <widget class="smart_playlists::SearchPreview" name="sort_preview" native="true"/>
</item> </item>
</layout> </layout>
</widget> </widget>
</widget> </widget>
<customwidgets> <customwidgets>
<customwidget> <customwidget>
<class>SmartPlaylistSearchPreview</class> <class>smart_playlists::SearchPreview</class>
<extends>QWidget</extends> <extends>QWidget</extends>
<header>smartplaylists/smartplaylistsearchpreview.h</header> <header>smartplaylists/searchpreview.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
<customwidget> <customwidget>
<class>SmartPlaylistWizard::SearchPage</class> <class>smart_playlists::Wizard::SearchPage</class>
<extends>QWizardPage</extends> <extends>QWizardPage</extends>
<header>smartplaylists/smartplaylistwizard.h</header> <header>smartplaylists/wizard.h</header>
<container>1</container> <container>1</container>
</customwidget> </customwidget>
</customwidgets> </customwidgets>

View File

@ -653,7 +653,7 @@ void MainWindow::LibrarySongsDoubleClicked(const SongList &songs) {
AddLibrarySongsToPlaylist(autoclear_playlist_, 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) if (clear_first)
playlists_->ClearCurrent(); playlists_->ClearCurrent();

View File

@ -198,7 +198,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
void AddFilesToPlaylist(bool clear_first, const QList<QUrl>& urls); void AddFilesToPlaylist(bool clear_first, const QList<QUrl>& urls);
void AddLibraryItemToPlaylist(bool clear_first, const QModelIndexList& indexes); void AddLibraryItemToPlaylist(bool clear_first, const QModelIndexList& indexes);
void AddLibrarySongsToPlaylist(bool clear_first, const SongList& songs); 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 AddDeviceSongsToPlaylist(bool clear_first, const SongList& songs);
void AddUrls(bool play_now, const QList<QUrl>& urls); void AddUrls(bool play_now, const QList<QUrl>& urls);
void ConnectInfoView(SongInfoBase* view); void ConnectInfoView(SongInfoBase* view);