@@ -56,7 +56,6 @@
|
||||
#include "covermanager/discogscoverprovider.h"
|
||||
#include "covermanager/musicbrainzcoverprovider.h"
|
||||
#include "covermanager/deezercoverprovider.h"
|
||||
#include "covermanager/qobuzcoverprovider.h"
|
||||
#include "covermanager/musixmatchcoverprovider.h"
|
||||
#include "covermanager/spotifycoverprovider.h"
|
||||
|
||||
@@ -83,6 +82,11 @@
|
||||
# include "covermanager/tidalcoverprovider.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_QOBUZ
|
||||
# include "qobuz/qobuzservice.h"
|
||||
# include "covermanager/qobuzcoverprovider.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_MOODBAR
|
||||
# include "moodbar/moodbarcontroller.h"
|
||||
# include "moodbar/moodbarloader.h"
|
||||
@@ -124,11 +128,13 @@ class ApplicationImpl {
|
||||
cover_providers->AddProvider(new MusicbrainzCoverProvider(app, app));
|
||||
cover_providers->AddProvider(new DiscogsCoverProvider(app, app));
|
||||
cover_providers->AddProvider(new DeezerCoverProvider(app, app));
|
||||
cover_providers->AddProvider(new QobuzCoverProvider(app, app));
|
||||
cover_providers->AddProvider(new MusixmatchCoverProvider(app, app));
|
||||
cover_providers->AddProvider(new SpotifyCoverProvider(app, app));
|
||||
#ifdef HAVE_TIDAL
|
||||
cover_providers->AddProvider(new TidalCoverProvider(app, app));
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
cover_providers->AddProvider(new QobuzCoverProvider(app, app));
|
||||
#endif
|
||||
cover_providers->ReloadSettings();
|
||||
return cover_providers;
|
||||
@@ -159,6 +165,9 @@ class ApplicationImpl {
|
||||
#endif
|
||||
#ifdef HAVE_TIDAL
|
||||
internet_services->AddService(new TidalService(app, internet_services));
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
internet_services->AddService(new QobuzService(app, internet_services));
|
||||
#endif
|
||||
return internet_services;
|
||||
}),
|
||||
|
||||
@@ -54,7 +54,7 @@
|
||||
#include "scopedtransaction.h"
|
||||
|
||||
const char *Database::kDatabaseFilename = "strawberry.db";
|
||||
const int Database::kSchemaVersion = 12;
|
||||
const int Database::kSchemaVersion = 13;
|
||||
const char *Database::kMagicAllSongsTables = "%allsongstables";
|
||||
|
||||
int Database::sNextConnectionId = 1;
|
||||
|
||||
@@ -161,6 +161,9 @@
|
||||
# include "tidal/tidalservice.h"
|
||||
# include "settings/tidalsettingspage.h"
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
# include "settings/qobuzsettingspage.h"
|
||||
#endif
|
||||
|
||||
#include "internet/internetservices.h"
|
||||
#include "internet/internetservice.h"
|
||||
@@ -185,6 +188,9 @@
|
||||
# include "moodbar/moodbarproxystyle.h"
|
||||
#endif
|
||||
|
||||
#include "smartplaylists/smartplaylistsviewcontainer.h"
|
||||
#include "smartplaylists/smartplaylistsview.h"
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
# include "windows7thumbbar.h"
|
||||
#endif
|
||||
@@ -257,11 +263,15 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
||||
connect(add_stream_dialog, SIGNAL(accepted()), this, SLOT(AddStreamAccepted()));
|
||||
return add_stream_dialog;
|
||||
}),
|
||||
smartplaylists_view_(new SmartPlaylistsViewContainer(app, this)),
|
||||
#ifdef HAVE_SUBSONIC
|
||||
subsonic_view_(new InternetSongsView(app_, app->internet_services()->ServiceBySource(Song::Source_Subsonic), SubsonicSettingsPage::kSettingsGroup, SettingsDialog::Page_Subsonic, this)),
|
||||
#endif
|
||||
#ifdef HAVE_TIDAL
|
||||
tidal_view_(new InternetTabsView(app_, app->internet_services()->ServiceBySource(Song::Source_Tidal), TidalSettingsPage::kSettingsGroup, SettingsDialog::Page_Tidal, this)),
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
qobuz_view_(new InternetTabsView(app_, app->internet_services()->ServiceBySource(Song::Source_Qobuz), QobuzSettingsPage::kSettingsGroup, SettingsDialog::Page_Qobuz, this)),
|
||||
#endif
|
||||
lastfm_import_dialog_(new LastFMImportDialog(app_->lastfm_import(), this)),
|
||||
collection_show_all_(nullptr),
|
||||
@@ -296,6 +306,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
||||
playing_widget_(true),
|
||||
doubleclick_addmode_(BehaviourSettingsPage::AddBehaviour_Append),
|
||||
doubleclick_playmode_(BehaviourSettingsPage::PlayBehaviour_Never),
|
||||
doubleclick_playlist_addmode_(BehaviourSettingsPage::PlaylistAddBehaviour_Play),
|
||||
menu_playmode_(BehaviourSettingsPage::PlayBehaviour_Never),
|
||||
exit_count_(0),
|
||||
delete_files_(false)
|
||||
@@ -321,9 +332,10 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
||||
// Add tabs to the fancy tab widget
|
||||
ui_->tabs->AddTab(context_view_, "context", IconLoader::Load("strawberry"), tr("Context"));
|
||||
ui_->tabs->AddTab(collection_view_, "collection", IconLoader::Load("library-music"), tr("Collection"));
|
||||
ui_->tabs->AddTab(file_view_, "files", IconLoader::Load("document-open"), tr("Files"));
|
||||
ui_->tabs->AddTab(playlist_list_, "playlists", IconLoader::Load("view-media-playlist"), tr("Playlists"));
|
||||
ui_->tabs->AddTab(queue_view_, "queue", IconLoader::Load("footsteps"), tr("Queue"));
|
||||
ui_->tabs->AddTab(playlist_list_, "playlists", IconLoader::Load("view-media-playlist"), tr("Playlists"));
|
||||
ui_->tabs->AddTab(smartplaylists_view_, "smartplaylists", IconLoader::Load("view-media-playlist"), tr("Smart playlists"));
|
||||
ui_->tabs->AddTab(file_view_, "files", IconLoader::Load("document-open"), tr("Files"));
|
||||
#ifndef Q_OS_WIN
|
||||
ui_->tabs->AddTab(device_view_, "devices", IconLoader::Load("device"), tr("Devices"));
|
||||
#endif
|
||||
@@ -333,6 +345,9 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
||||
#ifdef HAVE_TIDAL
|
||||
ui_->tabs->AddTab(tidal_view_, "tidal", IconLoader::Load("tidal"), tr("Tidal"));
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
ui_->tabs->AddTab(qobuz_view_, "qobuz", IconLoader::Load("qobuz"), tr("Qobuz"));
|
||||
#endif
|
||||
|
||||
// Add the playing widget to the fancy tab widget
|
||||
ui_->tabs->addBottomWidget(ui_->widget_playing);
|
||||
@@ -644,6 +659,13 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
||||
connect(this, SIGNAL(AuthorizationUrlReceived(QUrl)), tidalservice, SLOT(AuthorizationUrlReceived(QUrl)));
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_QOBUZ
|
||||
connect(qobuz_view_->artists_collection_view(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
connect(qobuz_view_->albums_collection_view(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
connect(qobuz_view_->songs_collection_view(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
connect(qobuz_view_->search_view(), SIGNAL(AddToPlaylist(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
#endif
|
||||
|
||||
// Playlist menu
|
||||
connect(playlist_menu_, SIGNAL(aboutToHide()), SLOT(PlaylistMenuHidden()));
|
||||
playlist_play_pause_ = playlist_menu_->addAction(tr("Play"), this, SLOT(PlaylistPlay()));
|
||||
@@ -829,6 +851,9 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
||||
connect(app_->playlist_manager()->sequence(), SIGNAL(RepeatModeChanged(PlaylistSequence::RepeatMode)), osd_, SLOT(RepeatModeChanged(PlaylistSequence::RepeatMode)));
|
||||
connect(app_->playlist_manager()->sequence(), SIGNAL(ShuffleModeChanged(PlaylistSequence::ShuffleMode)), osd_, SLOT(ShuffleModeChanged(PlaylistSequence::ShuffleMode)));
|
||||
|
||||
// Smart playlists
|
||||
connect(smartplaylists_view_, SIGNAL(AddToPlaylist(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
|
||||
ScrobbleButtonVisibilityChanged(app_->scrobbler()->ScrobbleButton());
|
||||
LoveButtonVisibilityChanged(app_->scrobbler()->LoveButton());
|
||||
ScrobblingEnabledChanged(app_->scrobbler()->IsEnabled());
|
||||
@@ -849,8 +874,8 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSDBase *osd
|
||||
restoreGeometry(settings_.value("geometry").toByteArray());
|
||||
}
|
||||
|
||||
if (!ui_->splitter->restoreState(settings_.value("splitter_state").toByteArray())) {
|
||||
ui_->splitter->setSizes(QList<int>() << 250 << width() - 250);
|
||||
if (!settings_.contains("splitter_state") || !ui_->splitter->restoreState(settings_.value("splitter_state").toByteArray())) {
|
||||
ui_->splitter->setSizes(QList<int>() << 20 << (width() - 20));
|
||||
}
|
||||
|
||||
ui_->tabs->setCurrentIndex(settings_.value("current_tab", 1).toInt());
|
||||
@@ -981,9 +1006,9 @@ void MainWindow::ReloadSettings() {
|
||||
playing_widget_ = s.value("playing_widget", true).toBool();
|
||||
if (playing_widget_ != ui_->widget_playing->IsEnabled()) TabSwitched();
|
||||
doubleclick_addmode_ = BehaviourSettingsPage::AddBehaviour(s.value("doubleclick_addmode", BehaviourSettingsPage::AddBehaviour_Append).toInt());
|
||||
doubleclick_playmode_ = BehaviourSettingsPage::PlayBehaviour(s.value("doubleclick_playmode", BehaviourSettingsPage::PlayBehaviour_IfStopped).toInt());
|
||||
doubleclick_playlist_addmode_ = BehaviourSettingsPage::PlaylistAddBehaviour(s.value("doubleclick_playlist_addmode", BehaviourSettingsPage::PlaylistAddBehaviour_Play).toInt());
|
||||
menu_playmode_ = BehaviourSettingsPage::PlayBehaviour(s.value("menu_playmode", BehaviourSettingsPage::PlayBehaviour_IfStopped).toInt());
|
||||
doubleclick_playmode_ = BehaviourSettingsPage::PlayBehaviour(s.value("doubleclick_playmode", BehaviourSettingsPage::PlayBehaviour_Never).toInt());
|
||||
doubleclick_playlist_addmode_ = BehaviourSettingsPage::PlaylistAddBehaviour(s.value("doubleclick_playlist_addmode", BehaviourSettingsPage::PlayBehaviour_Never).toInt());
|
||||
menu_playmode_ = BehaviourSettingsPage::PlayBehaviour(s.value("menu_playmode", BehaviourSettingsPage::PlayBehaviour_Never).toInt());
|
||||
s.endGroup();
|
||||
|
||||
s.beginGroup(AppearanceSettingsPage::kSettingsGroup);
|
||||
@@ -1039,6 +1064,16 @@ void MainWindow::ReloadSettings() {
|
||||
ui_->tabs->DisableTab(tidal_view_);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_QOBUZ
|
||||
s.beginGroup(QobuzSettingsPage::kSettingsGroup);
|
||||
bool enable_qobuz = s.value("enabled", false).toBool();
|
||||
s.endGroup();
|
||||
if (enable_qobuz)
|
||||
ui_->tabs->EnableTab(qobuz_view_);
|
||||
else
|
||||
ui_->tabs->DisableTab(qobuz_view_);
|
||||
#endif
|
||||
|
||||
ui_->tabs->ReloadSettings();
|
||||
|
||||
}
|
||||
@@ -1061,6 +1096,7 @@ void MainWindow::ReloadAllSettings() {
|
||||
file_view_->ReloadSettings();
|
||||
queue_view_->ReloadSettings();
|
||||
playlist_list_->ReloadSettings();
|
||||
smartplaylists_view_->ReloadSettings();
|
||||
app_->cover_providers()->ReloadSettings();
|
||||
app_->lyrics_providers()->ReloadSettings();
|
||||
#ifdef HAVE_SUBSONIC
|
||||
@@ -1069,6 +1105,9 @@ void MainWindow::ReloadAllSettings() {
|
||||
#ifdef HAVE_TIDAL
|
||||
tidal_view_->ReloadSettings();
|
||||
#endif
|
||||
#ifdef HAVE_QOBUZ
|
||||
qobuz_view_->ReloadSettings();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -93,6 +93,7 @@ class TranscodeDialog;
|
||||
class Ui_MainWindow;
|
||||
class InternetSongsView;
|
||||
class InternetTabsView;
|
||||
class SmartPlaylistsViewContainer;
|
||||
#ifdef Q_OS_WIN
|
||||
class Windows7ThumbBar;
|
||||
#endif
|
||||
@@ -325,8 +326,11 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
||||
std::unique_ptr<TrackSelectionDialog> track_selection_dialog_;
|
||||
PlaylistItemList autocomplete_tag_items_;
|
||||
|
||||
SmartPlaylistsViewContainer *smartplaylists_view_;
|
||||
|
||||
InternetSongsView *subsonic_view_;
|
||||
InternetTabsView *tidal_view_;
|
||||
InternetTabsView *qobuz_view_;
|
||||
|
||||
LastFMImportDialog *lastfm_import_dialog_;
|
||||
|
||||
|
||||
@@ -69,6 +69,8 @@
|
||||
|
||||
#include "internet/internetsearchview.h"
|
||||
|
||||
#include "smartplaylists/playlistgenerator_fwd.h"
|
||||
|
||||
void RegisterMetaTypes() {
|
||||
|
||||
qRegisterMetaType<const char*>("const char*");
|
||||
@@ -136,4 +138,6 @@ void RegisterMetaTypes() {
|
||||
qRegisterMetaType<InternetSearchView::ResultList>("InternetSearchView::ResultList");
|
||||
qRegisterMetaType<InternetSearchView::Result>("InternetSearchView::Result");
|
||||
|
||||
qRegisterMetaType<PlaylistGeneratorPtr>("PlaylistGeneratorPtr");
|
||||
|
||||
}
|
||||
|
||||
@@ -125,6 +125,8 @@ const QStringList Song::kColumns = QStringList() << "title"
|
||||
|
||||
<< "cue_path"
|
||||
|
||||
<< "rating"
|
||||
|
||||
;
|
||||
|
||||
const QString Song::kColumnSpec = Song::kColumns.join(", ");
|
||||
@@ -217,6 +219,8 @@ struct Song::Private : public QSharedData {
|
||||
|
||||
QString cue_path_; // If the song has a CUE, this contains it's path.
|
||||
|
||||
float rating_; // Database rating, not read from tags.
|
||||
|
||||
QUrl stream_url_; // Temporary stream url set by url handler.
|
||||
QImage image_; // Album Cover image set by album cover loader.
|
||||
bool init_from_file_; // Whether this song was loaded from a file using taglib.
|
||||
@@ -259,6 +263,8 @@ Song::Private::Private(Song::Source source)
|
||||
compilation_on_(false),
|
||||
compilation_off_(false),
|
||||
|
||||
rating_(-1),
|
||||
|
||||
init_from_file_(false),
|
||||
suspicious_tags_(false)
|
||||
|
||||
@@ -347,6 +353,8 @@ const QImage &Song::image() const { return d->image_; }
|
||||
const QString &Song::cue_path() const { return d->cue_path_; }
|
||||
bool Song::has_cue() const { return !d->cue_path_.isEmpty(); }
|
||||
|
||||
float Song::rating() const { return d->rating_; }
|
||||
|
||||
bool Song::is_collection_song() const { return d->source_ == Source_Collection; }
|
||||
bool Song::is_metadata_good() const { return !d->url_.isEmpty() && !d->artist_.isEmpty() && !d->title_.isEmpty(); }
|
||||
bool Song::is_stream() const { return d->source_ == Source_Stream || d->source_ == Source_Tidal || d->source_ == Source_Subsonic || d->source_ == Source_Qobuz; }
|
||||
@@ -444,6 +452,8 @@ void Song::set_art_automatic(const QUrl &v) { d->art_automatic_ = v; }
|
||||
void Song::set_art_manual(const QUrl &v) { d->art_manual_ = v; }
|
||||
void Song::set_cue_path(const QString &v) { d->cue_path_ = v; }
|
||||
|
||||
void Song::set_rating(float v) { d->rating_ = v; }
|
||||
|
||||
void Song::set_stream_url(const QUrl &v) { d->stream_url_ = v; }
|
||||
void Song::set_image(const QImage &i) { d->image_ = i; }
|
||||
|
||||
@@ -1000,6 +1010,10 @@ void Song::InitFromQuery(const SqlRow &q, bool reliable_metadata, int col) {
|
||||
d->cue_path_ = tostr(x);
|
||||
}
|
||||
|
||||
else if (Song::kColumns.value(i) == "rating") {
|
||||
d->rating_ = tofloat(x);
|
||||
}
|
||||
|
||||
else {
|
||||
qLog(Error) << "Forgot to handle" << Song::kColumns.value(i);
|
||||
}
|
||||
@@ -1363,6 +1377,8 @@ void Song::BindToQuery(QSqlQuery *query) const {
|
||||
|
||||
query->bindValue(":cue_path", d->cue_path_);
|
||||
|
||||
query->bindValue(":rating", intval(d->rating_));
|
||||
|
||||
#undef intval
|
||||
#undef notnullintval
|
||||
#undef strval
|
||||
@@ -1441,6 +1457,16 @@ QString Song::SampleRateBitDepthToText() const {
|
||||
|
||||
}
|
||||
|
||||
QString Song::PrettyRating() const {
|
||||
|
||||
float rating = d->rating_;
|
||||
|
||||
if (rating == -1.0f) return "0";
|
||||
|
||||
return QString::number(static_cast<int>(rating * 100));
|
||||
|
||||
}
|
||||
|
||||
bool Song::IsMetadataEqual(const Song &other) const {
|
||||
|
||||
return d->title_ == other.d->title_ &&
|
||||
@@ -1547,5 +1573,6 @@ void Song::MergeUserSetData(const Song &other) {
|
||||
set_art_manual(other.art_manual());
|
||||
set_compilation_on(other.compilation_on());
|
||||
set_compilation_off(other.compilation_off());
|
||||
set_rating(other.rating());
|
||||
|
||||
}
|
||||
|
||||
@@ -245,6 +245,8 @@ class Song {
|
||||
const QString &cue_path() const;
|
||||
bool has_cue() const;
|
||||
|
||||
float rating() const;
|
||||
|
||||
const QString &effective_album() const;
|
||||
int effective_originalyear() const;
|
||||
const QString &effective_albumartist() const;
|
||||
@@ -288,6 +290,8 @@ class Song {
|
||||
|
||||
QString SampleRateBitDepthToText() const;
|
||||
|
||||
QString PrettyRating() const;
|
||||
|
||||
// Setters
|
||||
bool IsEditable() const;
|
||||
|
||||
@@ -346,6 +350,8 @@ class Song {
|
||||
|
||||
void set_cue_path(const QString &v);
|
||||
|
||||
void set_rating(const float v);
|
||||
|
||||
void set_stream_url(const QUrl &v);
|
||||
void set_image(const QImage &i);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user