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/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
|
||||||
|
|
||||||
|
@ -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());
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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() {
|
||||||
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
@ -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)));
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
@ -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
|
||||||
|
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
||||||
|
@ -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
|
@ -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
|
@ -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;
|
@ -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
|
@ -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
|
@ -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
|
@ -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;
|
||||||
}
|
}
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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
|
@ -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>
|
@ -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();
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user