New context with albums and lyrics +++ much more
* Added new lyrics provider with lyrics from AudD and API Seeds * New improved context widget with albums and lyrics * Fixed playing and context widget getting stuck in play mode when there was an error * Changed icons for artists in collection, tidal and cover manager * Removed "search" icon from "Search automatically" checkbox (right click) that looked ugly * Removed some unused widgets from the src/widgets directory * Fixed initial size of window and side panel * Fixed saving window size correctly
This commit is contained in:
@@ -52,6 +52,11 @@
|
||||
#include "covermanager/discogscoverprovider.h"
|
||||
#include "covermanager/musicbrainzcoverprovider.h"
|
||||
|
||||
#include "lyrics/lyricsproviders.h"
|
||||
#include "lyrics/lyricsprovider.h"
|
||||
#include "lyrics/auddlyricsprovider.h"
|
||||
#include "lyrics/apiseedslyricsprovider.h"
|
||||
|
||||
#include "internet/internetmodel.h"
|
||||
#include "tidal/tidalsearch.h"
|
||||
|
||||
@@ -60,18 +65,18 @@ bool Application::kIsPortable = false;
|
||||
class ApplicationImpl {
|
||||
public:
|
||||
ApplicationImpl(Application *app) :
|
||||
tag_reader_client_([=]() {
|
||||
tag_reader_client_([=]() {
|
||||
TagReaderClient *client = new TagReaderClient(app);
|
||||
app->MoveToNewThread(client);
|
||||
client->Start();
|
||||
return client;
|
||||
}),
|
||||
database_([=]() {
|
||||
database_([=]() {
|
||||
Database *db = new Database(app, app);
|
||||
app->MoveToNewThread(db);
|
||||
DoInAMinuteOrSo(db, SLOT(DoBackup()));
|
||||
return db;
|
||||
}),
|
||||
}),
|
||||
appearance_([=]() { return new Appearance(app); }),
|
||||
task_manager_([=]() { return new TaskManager(app); }),
|
||||
player_([=]() { return new Player(app, app); }),
|
||||
@@ -88,10 +93,10 @@ class ApplicationImpl {
|
||||
CoverProviders *cover_providers = new CoverProviders(app);
|
||||
// Initialize the repository of cover providers.
|
||||
#ifdef HAVE_LIBLASTFM
|
||||
cover_providers->AddProvider(new LastFmCoverProvider(app));
|
||||
cover_providers->AddProvider(new LastFmCoverProvider(app));
|
||||
#endif
|
||||
cover_providers->AddProvider(new AmazonCoverProvider(app));
|
||||
cover_providers->AddProvider(new DiscogsCoverProvider(app));
|
||||
cover_providers->AddProvider(new DiscogsCoverProvider(app));
|
||||
cover_providers->AddProvider(new MusicbrainzCoverProvider(app));
|
||||
return cover_providers;
|
||||
}),
|
||||
@@ -102,7 +107,13 @@ class ApplicationImpl {
|
||||
}),
|
||||
current_art_loader_([=]() { return new CurrentArtLoader(app, app); }),
|
||||
internet_model_([=]() { return new InternetModel(app, app); }),
|
||||
tidal_search_([=]() { return new TidalSearch(app, app); })
|
||||
tidal_search_([=]() { return new TidalSearch(app, app); }),
|
||||
lyrics_providers_([=]() {
|
||||
LyricsProviders *lyrics_providers = new LyricsProviders(app);
|
||||
lyrics_providers->AddProvider(new AuddLyricsProvider(app));
|
||||
lyrics_providers->AddProvider(new APISeedsLyricsProvider(app));
|
||||
return lyrics_providers;
|
||||
})
|
||||
{ }
|
||||
|
||||
Lazy<TagReaderClient> tag_reader_client_;
|
||||
@@ -120,6 +131,7 @@ class ApplicationImpl {
|
||||
Lazy<CurrentArtLoader> current_art_loader_;
|
||||
Lazy<InternetModel> internet_model_;
|
||||
Lazy<TidalSearch> tidal_search_;
|
||||
Lazy<LyricsProviders> lyrics_providers_;
|
||||
|
||||
};
|
||||
|
||||
@@ -227,3 +239,7 @@ InternetModel* Application::internet_model() const {
|
||||
TidalSearch* Application::tidal_search() const {
|
||||
return p_->tidal_search_.get();
|
||||
}
|
||||
|
||||
LyricsProviders *Application::lyrics_providers() const {
|
||||
return p_->lyrics_providers_.get();
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ class AlbumCoverLoader;
|
||||
class CurrentArtLoader;
|
||||
class InternetModel;
|
||||
class TidalSearch;
|
||||
class LyricsProviders;
|
||||
|
||||
class Application : public QObject {
|
||||
Q_OBJECT
|
||||
@@ -84,6 +85,8 @@ class Application : public QObject {
|
||||
InternetModel *internet_model() const;
|
||||
TidalSearch *tidal_search() const;
|
||||
|
||||
LyricsProviders *lyrics_providers() const;
|
||||
|
||||
void MoveToNewThread(QObject *object);
|
||||
void MoveToThread(QObject *object, QThread *thread);
|
||||
|
||||
|
||||
@@ -507,15 +507,14 @@ void Database::ExecSchemaCommands(QSqlDatabase &db, const QString &schema, int s
|
||||
}
|
||||
|
||||
void Database::ExecSongTablesCommands(QSqlDatabase &db, const QStringList &song_tables, const QStringList &commands) {
|
||||
|
||||
|
||||
for (const QString &command : commands) {
|
||||
// There are now lots of "songs" tables that need to have the same schema: songs and device_*_songs.
|
||||
// We allow a magic value in the schema files to update all songs tables at once.
|
||||
if (command.contains(kMagicAllSongsTables)) {
|
||||
for (const QString &table : song_tables) {
|
||||
// Another horrible hack: device songs tables don't have matching _fts tables, so if this command tries to touch one, ignore it.
|
||||
if (table.startsWith("device_") &&
|
||||
command.contains(QString(kMagicAllSongsTables) + "_fts")) {
|
||||
if (table.startsWith("device_") && command.contains(QString(kMagicAllSongsTables) + "_fts")) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -526,7 +525,8 @@ void Database::ExecSongTablesCommands(QSqlDatabase &db, const QStringList &song_
|
||||
if (CheckErrors(query))
|
||||
qFatal("Unable to update music collection database");
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
QSqlQuery query(db.exec(command));
|
||||
if (CheckErrors(query)) qFatal("Unable to update music collection database");
|
||||
}
|
||||
|
||||
@@ -1,193 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <QtGlobal>
|
||||
#include <QWidget>
|
||||
#include <QObject>
|
||||
#include <QLayout>
|
||||
#include <QLayoutItem>
|
||||
#include <QStyle>
|
||||
#include <QSize>
|
||||
#include <QPoint>
|
||||
#include <QRect>
|
||||
#include <QSizePolicy>
|
||||
|
||||
#include "flowlayout.h"
|
||||
|
||||
//! [1]
|
||||
FlowLayout::FlowLayout(QWidget *parent, int margin, int hSpacing, int vSpacing)
|
||||
: QLayout(parent), m_hSpace(hSpacing), m_vSpace(vSpacing)
|
||||
{
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
|
||||
FlowLayout::FlowLayout(int margin, int hSpacing, int vSpacing)
|
||||
: m_hSpace(hSpacing), m_vSpace(vSpacing) {
|
||||
setContentsMargins(margin, margin, margin, margin);
|
||||
}
|
||||
//! [1]
|
||||
|
||||
//! [2]
|
||||
FlowLayout::~FlowLayout() {
|
||||
QLayoutItem* item;
|
||||
while ((item = takeAt(0))) delete item;
|
||||
}
|
||||
//! [2]
|
||||
|
||||
//! [3]
|
||||
void FlowLayout::addItem(QLayoutItem* item) { itemList.append(item); }
|
||||
//! [3]
|
||||
|
||||
//! [4]
|
||||
int FlowLayout::horizontalSpacing() const {
|
||||
if (m_hSpace >= 0) {
|
||||
return m_hSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutHorizontalSpacing);
|
||||
}
|
||||
}
|
||||
|
||||
int FlowLayout::verticalSpacing() const {
|
||||
if (m_vSpace >= 0) {
|
||||
return m_vSpace;
|
||||
} else {
|
||||
return smartSpacing(QStyle::PM_LayoutVerticalSpacing);
|
||||
}
|
||||
}
|
||||
//! [4]
|
||||
|
||||
//! [5]
|
||||
int FlowLayout::count() const { return itemList.size(); }
|
||||
|
||||
QLayoutItem* FlowLayout::itemAt(int index) const {
|
||||
return itemList.value(index);
|
||||
}
|
||||
|
||||
QLayoutItem* FlowLayout::takeAt(int index) {
|
||||
if (index >= 0 && index < itemList.size())
|
||||
return itemList.takeAt(index);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
//! [5]
|
||||
|
||||
//! [6]
|
||||
Qt::Orientations FlowLayout::expandingDirections() const { return 0; }
|
||||
//! [6]
|
||||
|
||||
//! [7]
|
||||
bool FlowLayout::hasHeightForWidth() const { return true; }
|
||||
|
||||
int FlowLayout::heightForWidth(int width) const {
|
||||
int height = doLayout(QRect(0, 0, width, 0), true);
|
||||
return height;
|
||||
}
|
||||
//! [7]
|
||||
|
||||
//! [8]
|
||||
void FlowLayout::setGeometry(const QRect& rect) {
|
||||
QLayout::setGeometry(rect);
|
||||
doLayout(rect, false);
|
||||
}
|
||||
|
||||
QSize FlowLayout::sizeHint() const { return minimumSize(); }
|
||||
|
||||
QSize FlowLayout::minimumSize() const {
|
||||
QSize size;
|
||||
for (QLayoutItem* item : itemList)
|
||||
size = size.expandedTo(item->minimumSize());
|
||||
|
||||
size += QSize(2 * margin(), 2 * margin());
|
||||
return size;
|
||||
}
|
||||
//! [8]
|
||||
|
||||
//! [9]
|
||||
int FlowLayout::doLayout(const QRect& rect, bool testOnly) const {
|
||||
int left, top, right, bottom;
|
||||
getContentsMargins(&left, &top, &right, &bottom);
|
||||
QRect effectiveRect = rect.adjusted(+left, +top, -right, -bottom);
|
||||
int x = effectiveRect.x();
|
||||
int y = effectiveRect.y();
|
||||
int lineHeight = 0;
|
||||
//! [9]
|
||||
|
||||
//! [10]
|
||||
for (QLayoutItem* item : itemList) {
|
||||
QWidget* wid = item->widget();
|
||||
int spaceX = horizontalSpacing();
|
||||
if (spaceX == -1)
|
||||
spaceX = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Horizontal);
|
||||
int spaceY = verticalSpacing();
|
||||
if (spaceY == -1)
|
||||
spaceY = wid->style()->layoutSpacing(QSizePolicy::PushButton, QSizePolicy::PushButton, Qt::Vertical);
|
||||
//! [10]
|
||||
//! [11]
|
||||
int nextX = x + item->sizeHint().width() + spaceX;
|
||||
if (nextX - spaceX > effectiveRect.right() && lineHeight > 0) {
|
||||
x = effectiveRect.x();
|
||||
y = y + lineHeight + spaceY;
|
||||
nextX = x + item->sizeHint().width() + spaceX;
|
||||
lineHeight = 0;
|
||||
}
|
||||
|
||||
if (!testOnly) item->setGeometry(QRect(QPoint(x, y), item->sizeHint()));
|
||||
|
||||
x = nextX;
|
||||
lineHeight = qMax(lineHeight, item->sizeHint().height());
|
||||
}
|
||||
return y + lineHeight - rect.y() + bottom;
|
||||
}
|
||||
//! [11]
|
||||
//! [12]
|
||||
int FlowLayout::smartSpacing(QStyle::PixelMetric pm) const {
|
||||
QObject* parent = this->parent();
|
||||
if (!parent) {
|
||||
return -1;
|
||||
}
|
||||
else if (parent->isWidgetType()) {
|
||||
QWidget *pw = static_cast<QWidget *>(parent);
|
||||
return pw->style()->pixelMetric(pm, 0, pw);
|
||||
}
|
||||
else {
|
||||
return static_cast<QLayout *>(parent)->spacing();
|
||||
}
|
||||
}
|
||||
//! [12]
|
||||
@@ -1,84 +0,0 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the examples of the Qt Toolkit.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef FLOWLAYOUT_H
|
||||
#define FLOWLAYOUT_H
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#include <QLayout>
|
||||
#include <QWidget>
|
||||
#include <QStyle>
|
||||
#include <QList>
|
||||
#include <QSize>
|
||||
#include <QLayoutItem>
|
||||
#include <QRect>
|
||||
|
||||
//! [0]
|
||||
class FlowLayout : public QLayout {
|
||||
public:
|
||||
FlowLayout(QWidget* parent, int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
FlowLayout(int margin = -1, int hSpacing = -1, int vSpacing = -1);
|
||||
~FlowLayout();
|
||||
|
||||
void addItem(QLayoutItem *item);
|
||||
int horizontalSpacing() const;
|
||||
int verticalSpacing() const;
|
||||
Qt::Orientations expandingDirections() const;
|
||||
bool hasHeightForWidth() const;
|
||||
int heightForWidth(int) const;
|
||||
int count() const;
|
||||
QLayoutItem *itemAt(int index) const;
|
||||
QSize minimumSize() const;
|
||||
void setGeometry(const QRect &rect);
|
||||
QSize sizeHint() const;
|
||||
QLayoutItem *takeAt(int index);
|
||||
|
||||
private:
|
||||
int doLayout(const QRect &rect, bool testOnly) const;
|
||||
int smartSpacing(QStyle::PixelMetric pm) const;
|
||||
|
||||
QList<QLayoutItem *> itemList;
|
||||
int m_hSpace;
|
||||
int m_vSpace;
|
||||
};
|
||||
//! [0]
|
||||
|
||||
#endif
|
||||
@@ -31,34 +31,24 @@
|
||||
#include "core/logging.h"
|
||||
#include "iconloader.h"
|
||||
|
||||
QList<int> IconLoader::sizes_;
|
||||
QString IconDefault(":/icons/64x64/strawberry.png");
|
||||
|
||||
void IconLoader::Init() {
|
||||
|
||||
sizes_.clear();
|
||||
sizes_ << 22 << 32 << 48 << 64;
|
||||
|
||||
if (!QFile::exists(IconDefault)) {
|
||||
qLog(Error) << "Default icon does not exist" << IconDefault;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
QIcon IconLoader::Load(const QString &name) {
|
||||
QIcon IconLoader::Load(const QString &name, const int size) {
|
||||
|
||||
QIcon ret;
|
||||
|
||||
QList<int> sizes;
|
||||
sizes.clear();
|
||||
if (size == 0) { sizes << 22 << 32 << 48 << 64; }
|
||||
else sizes << size;
|
||||
|
||||
if (name.isEmpty()) {
|
||||
qLog(Warning) << "Icon name is empty!";
|
||||
ret.addFile(IconDefault, QSize(64, 64));
|
||||
qLog(Error) << "Icon name is empty!";
|
||||
return ret;
|
||||
}
|
||||
|
||||
const QString path(":icons/%1x%2/%3.png");
|
||||
for (int size : sizes_) {
|
||||
QString filename(path.arg(size).arg(size).arg(name));
|
||||
if (QFile::exists(filename)) ret.addFile(filename, QSize(size, size));
|
||||
for (int s : sizes) {
|
||||
QString filename(path.arg(s).arg(s).arg(name));
|
||||
if (QFile::exists(filename)) ret.addFile(filename, QSize(s, s));
|
||||
}
|
||||
|
||||
// Load icon from system theme only if it hasn't been found
|
||||
@@ -68,10 +58,6 @@ QIcon IconLoader::Load(const QString &name) {
|
||||
qLog(Warning) << "Couldn't load icon" << name;
|
||||
}
|
||||
|
||||
if (ret.isNull()) {
|
||||
ret.addFile(IconDefault, QSize(64, 64));
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
@@ -27,14 +27,10 @@
|
||||
|
||||
class IconLoader {
|
||||
public:
|
||||
|
||||
static void Init();
|
||||
static QIcon Load(const QString &name);
|
||||
|
||||
static QIcon Load(const QString &name, const int size = 0);
|
||||
private:
|
||||
IconLoader() {}
|
||||
|
||||
static QList<int> sizes_;
|
||||
};
|
||||
|
||||
#endif // ICONLOADER_H
|
||||
|
||||
|
||||
@@ -200,9 +200,6 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
// Resources
|
||||
Q_INIT_RESOURCE(data);
|
||||
|
||||
// Icons
|
||||
IconLoader::Init();
|
||||
|
||||
Application app;
|
||||
|
||||
|
||||
@@ -89,12 +89,13 @@
|
||||
#include "widgets/fancytabwidget.h"
|
||||
#include "widgets/playingwidget.h"
|
||||
#include "widgets/sliderwidget.h"
|
||||
#include "widgets/statusview.h"
|
||||
#include "widgets/fileview.h"
|
||||
#include "widgets/multiloadingindicator.h"
|
||||
#include "widgets/osd.h"
|
||||
#include "widgets/stylehelper.h"
|
||||
#include "widgets/trackslider.h"
|
||||
#include "context/contextview.h"
|
||||
#include "collection/collectionview.h"
|
||||
#include "collection/collection.h"
|
||||
#include "collection/collectionbackend.h"
|
||||
#include "collection/collectiondirectorymodel.h"
|
||||
@@ -158,12 +159,12 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
osd_(osd),
|
||||
edit_tag_dialog_(std::bind(&MainWindow::CreateEditTagDialog, this)),
|
||||
global_shortcuts_(new GlobalShortcuts(this)),
|
||||
context_view_(new ContextView(this)),
|
||||
collection_view_(new CollectionViewContainer(this)),
|
||||
status_view_(new StatusView(collection_view_, this)),
|
||||
file_view_(new FileView(this)),
|
||||
playlist_list_(new PlaylistListContainer(this)),
|
||||
device_view_container_(new DeviceViewContainer(this)),
|
||||
device_view_(device_view_container_->view()),
|
||||
playlist_list_(new PlaylistListContainer(this)),
|
||||
settings_dialog_(std::bind(&MainWindow::CreateSettingsDialog, this)),
|
||||
cover_manager_([=]() {
|
||||
AlbumCoverManager *cover_manager = new AlbumCoverManager(app, app->collection_backend());
|
||||
@@ -195,7 +196,8 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
collection_sort_model_(new QSortFilterProxyModel(this)),
|
||||
track_position_timer_(new QTimer(this)),
|
||||
track_slider_timer_(new QTimer(this)),
|
||||
was_maximized_(false),
|
||||
initialised_(false),
|
||||
was_maximized_(true),
|
||||
saved_playback_position_(0),
|
||||
saved_playback_state_(Engine::Empty),
|
||||
doubleclick_addmode_(AddBehaviour_Append),
|
||||
@@ -214,7 +216,8 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
#endif
|
||||
|
||||
ui_->multi_loading_indicator->SetTaskManager(app_->task_manager());
|
||||
status_view_->SetApplication(app_);
|
||||
context_view_->SetApplication(app_);
|
||||
context_view_->SetCollectionView(collection_view_->view());
|
||||
ui_->widget_playing->SetApplication(app_);
|
||||
|
||||
int volume = app_->player()->GetVolume();
|
||||
@@ -225,7 +228,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
StyleHelper::setBaseColor(palette().color(QPalette::Highlight).darker());
|
||||
|
||||
// Add tabs to the fancy tab widget
|
||||
ui_->tabs->addTab(status_view_, IconLoader::Load("strawberry"), tr("Status"));
|
||||
ui_->tabs->addTab(context_view_, IconLoader::Load("strawberry"), tr("Context"));
|
||||
ui_->tabs->addTab(collection_view_, IconLoader::Load("vinyl"), tr("Collection"));
|
||||
ui_->tabs->addTab(file_view_, IconLoader::Load("document-open"), tr("Files"));
|
||||
ui_->tabs->addTab(playlist_list_, IconLoader::Load("view-media-playlist"), tr("Playlists"));
|
||||
@@ -435,6 +438,10 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
connect(ui_->playlist->view(), SIGNAL(BackgroundPropertyChanged()), SLOT(RefreshStyleSheet()));
|
||||
|
||||
connect(ui_->track_slider, SIGNAL(ValueChangedSeconds(int)), app_->player(), SLOT(SeekTo(int)));
|
||||
|
||||
// Context connections
|
||||
|
||||
connect(context_view_->albums(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
|
||||
// Collection connections
|
||||
connect(collection_view_->view(), SIGNAL(AddToPlaylistSignal(QMimeData*)), SLOT(AddToPlaylist(QMimeData*)));
|
||||
@@ -581,8 +588,12 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
connect(ui_->tabs, SIGNAL(CurrentChanged(int)), SLOT(TabSwitched()));
|
||||
connect(ui_->tabs, SIGNAL(CurrentChanged(int)), SLOT(SaveGeometry()));
|
||||
|
||||
// Status
|
||||
ConnectStatusView(status_view_);
|
||||
// Context
|
||||
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)), context_view_, SLOT(SongChanged(Song)));
|
||||
connect(app_->player(), SIGNAL(PlaylistFinished()), context_view_, SLOT(Stopped()));
|
||||
connect(app_->player(), SIGNAL(Playing()), context_view_, SLOT(Playing()));
|
||||
connect(app_->player(), SIGNAL(Stopped()), context_view_, SLOT(Stopped()));
|
||||
connect(app_->player(), SIGNAL(Error()), context_view_, SLOT(Error()));
|
||||
|
||||
// Analyzer
|
||||
//ui_->analyzer->SetEngine(app_->player()->engine());
|
||||
@@ -611,8 +622,12 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
// Playing widget
|
||||
qLog(Debug) << "Creating playing widget";
|
||||
ui_->widget_playing->set_ideal_height(ui_->status_bar->sizeHint().height() + ui_->player_controls->sizeHint().height());
|
||||
connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)), ui_->widget_playing, SLOT(SongChanged(Song)));
|
||||
connect(app_->player(), SIGNAL(PlaylistFinished()), ui_->widget_playing, SLOT(Stopped()));
|
||||
connect(app_->player(), SIGNAL(Playing()), ui_->widget_playing, SLOT(Playing()));
|
||||
connect(app_->player(), SIGNAL(Stopped()), ui_->widget_playing, SLOT(Stopped()));
|
||||
//connect(ui_->widget_playing, SIGNAL(ShowAboveStatusBarChanged(bool)), SLOT(PlayingWidgetPositionChanged(bool)));
|
||||
connect(app_->player(), SIGNAL(Error()), ui_->widget_playing, SLOT(Error()));
|
||||
|
||||
connect(ui_->action_console, SIGNAL(triggered()), SLOT(ShowConsole()));
|
||||
PlayingWidgetPositionChanged();
|
||||
|
||||
@@ -622,7 +637,7 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
const_cast<QPalette&>(Appearance::kDefaultPalette) = QApplication::palette();
|
||||
app_->appearance()->LoadUserTheme();
|
||||
StyleSheetLoader *css_loader = new StyleSheetLoader(this);
|
||||
css_loader->SetStyleSheet(this, ":style/mainwindow.css");
|
||||
css_loader->SetStyleSheet(this, ":/style/strawberry.css");
|
||||
RefreshStyleSheet();
|
||||
|
||||
// Load playlists
|
||||
@@ -643,15 +658,15 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
|
||||
// Set last used geometry to position window on the correct monitor
|
||||
// Set window state only if the window was last maximized
|
||||
was_maximized_ = settings_.value("maximized", false).toBool();
|
||||
restoreGeometry(settings_.value("geometry").toByteArray());
|
||||
if (was_maximized_) {
|
||||
setWindowState(windowState() | Qt::WindowMaximized);
|
||||
}
|
||||
was_maximized_ = settings_.value("maximized", true).toBool();
|
||||
|
||||
if (was_maximized_) setWindowState(windowState() | Qt::WindowMaximized);
|
||||
else restoreGeometry(settings_.value("geometry").toByteArray());
|
||||
|
||||
if (!ui_->splitter->restoreState(settings_.value("splitter_state").toByteArray())) {
|
||||
ui_->splitter->setSizes(QList<int>() << 300 << width() - 300);
|
||||
ui_->splitter->setSizes(QList<int>() << 250 << width() - 250);
|
||||
}
|
||||
|
||||
ui_->tabs->setCurrentIndex(settings_.value("current_tab", 1 /* Collection tab */ ).toInt());
|
||||
FancyTabWidget::Mode default_mode = FancyTabWidget::Mode_LargeSidebar;
|
||||
ui_->tabs->SetMode(FancyTabWidget::Mode(settings_.value("tab_mode", default_mode).toInt()));
|
||||
@@ -715,6 +730,8 @@ MainWindow::MainWindow(Application *app, SystemTrayIcon *tray_icon, OSD *osd, co
|
||||
|
||||
qLog(Debug) << "Started";
|
||||
RefreshStyleSheet();
|
||||
|
||||
initialised_ = true;
|
||||
|
||||
}
|
||||
|
||||
@@ -733,8 +750,6 @@ void MainWindow::ReloadSettings() {
|
||||
bool showtrayicon = settings.value("showtrayicon", true).toBool();
|
||||
settings.endGroup();
|
||||
|
||||
//qLog(Debug) << "showtrayicon" << showtrayicon;
|
||||
|
||||
tray_icon_->SetVisible(showtrayicon);
|
||||
if (!showtrayicon && !isVisible()) show();
|
||||
#endif
|
||||
@@ -766,7 +781,7 @@ void MainWindow::RefreshStyleSheet() {
|
||||
setStyleSheet(styleSheet());
|
||||
}
|
||||
void MainWindow::MediaStopped() {
|
||||
|
||||
|
||||
setWindowTitle("Strawberry Music Player");
|
||||
|
||||
ui_->action_stop->setEnabled(false);
|
||||
@@ -828,7 +843,6 @@ void MainWindow::VolumeChanged(int volume) {
|
||||
|
||||
void MainWindow::SongChanged(const Song &song) {
|
||||
|
||||
//setWindowTitle(song.PrettyTitleWithArtist() + " --- Strawberry Music Player");
|
||||
setWindowTitle(song.PrettyTitleWithArtist());
|
||||
tray_icon_->SetProgress(0);
|
||||
|
||||
@@ -853,7 +867,14 @@ void MainWindow::TrackSkipped(PlaylistItemPtr item) {
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent*) { SaveGeometry(); }
|
||||
void MainWindow::changeEvent(QEvent *event) {
|
||||
if (!initialised_) return;
|
||||
SaveGeometry();
|
||||
}
|
||||
|
||||
void MainWindow::resizeEvent(QResizeEvent *event) {
|
||||
SaveGeometry();
|
||||
}
|
||||
|
||||
void MainWindow::TabSwitched() {
|
||||
|
||||
@@ -870,10 +891,8 @@ void MainWindow::SaveGeometry() {
|
||||
|
||||
was_maximized_ = isMaximized();
|
||||
settings_.setValue("maximized", was_maximized_);
|
||||
// Save the geometry only when mainwindow is not in maximized state
|
||||
if (!was_maximized_) {
|
||||
settings_.setValue("geometry", saveGeometry());
|
||||
}
|
||||
if (was_maximized_) settings_.remove("geometry");
|
||||
else settings_.setValue("geometry", saveGeometry());
|
||||
settings_.setValue("splitter_state", ui_->splitter->saveState());
|
||||
settings_.setValue("current_tab", ui_->tabs->currentIndex());
|
||||
settings_.setValue("tab_mode", ui_->tabs->mode());
|
||||
@@ -2104,34 +2123,6 @@ void MainWindow::ShowQueueManager() {
|
||||
queue_manager_->show();
|
||||
}
|
||||
|
||||
#if 0
|
||||
void MainWindow::ConnectInfoView(SongInfoBase *view) {
|
||||
|
||||
QObject::connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)), view, SLOT(SongChanged(Song)));
|
||||
QObject::connect(app_->player(), SIGNAL(PlaylistFinished()), view, SLOT(SongFinished()));
|
||||
QObject::connect(app_->player(), SIGNAL(Stopped()), view, SLOT(SongFinished()));
|
||||
|
||||
QObject::connect(view, SIGNAL(ShowSettingsDialog()), SLOT(ShowSongInfoConfig()));
|
||||
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::ConnectStatusView(StatusView *statusview) {
|
||||
|
||||
QObject::connect(app_->playlist_manager(), SIGNAL(CurrentSongChanged(Song)), statusview, SLOT(SongChanged(Song)));
|
||||
QObject::connect(app_->player(), SIGNAL(PlaylistFinished()), statusview, SLOT(SongFinished()));
|
||||
QObject::connect(app_->player(), SIGNAL(Stopped()), statusview, SLOT(SongFinished()));
|
||||
|
||||
//QObject::connect(statusview, SIGNAL(ShowSettingsDialog()), SLOT(ShowSongInfoConfig()));
|
||||
|
||||
}
|
||||
|
||||
#if 0
|
||||
void MainWindow::ShowSongInfoConfig() {
|
||||
OpenSettingsDialogAtPage(SettingsDialog::Page_SongInformation);
|
||||
}
|
||||
#endif
|
||||
|
||||
void MainWindow::PlaylistViewSelectionModelChanged() {
|
||||
|
||||
connect(ui_->playlist->view()->selectionModel(),SIGNAL(currentChanged(QModelIndex, QModelIndex)), SLOT(PlaylistCurrentChanged(QModelIndex)));
|
||||
|
||||
@@ -59,6 +59,7 @@
|
||||
class About;
|
||||
class AlbumCoverManager;;
|
||||
class Application;
|
||||
class ContextView;
|
||||
class CollectionViewContainer;
|
||||
class CommandlineOptions;
|
||||
class DeviceView;
|
||||
@@ -73,7 +74,6 @@ class OrganiseDialog;
|
||||
class PlaylistListContainer;
|
||||
class QueueManager;
|
||||
class Song;
|
||||
class StatusView;
|
||||
class SystemTrayIcon;
|
||||
#if defined(HAVE_GSTREAMER) && defined(HAVE_CHROMAPRINT)
|
||||
class TagFetcher;
|
||||
@@ -129,6 +129,7 @@ class MainWindow : public QMainWindow, public PlatformInterface {
|
||||
|
||||
protected:
|
||||
void keyPressEvent(QKeyEvent *event);
|
||||
void changeEvent(QEvent *event);
|
||||
void resizeEvent(QResizeEvent *event);
|
||||
void closeEvent(QCloseEvent *event);
|
||||
|
||||
@@ -270,7 +271,6 @@ signals:
|
||||
void SearchForAlbum();
|
||||
|
||||
private:
|
||||
void ConnectStatusView(StatusView *statusview);
|
||||
|
||||
void ApplyAddBehaviour(AddBehaviour b, MimeData *data) const;
|
||||
void ApplyPlayBehaviour(PlayBehaviour b, MimeData *data) const;
|
||||
@@ -292,12 +292,12 @@ signals:
|
||||
|
||||
GlobalShortcuts *global_shortcuts_;
|
||||
|
||||
ContextView *context_view_;
|
||||
CollectionViewContainer *collection_view_;
|
||||
StatusView *status_view_;
|
||||
FileView *file_view_;
|
||||
PlaylistListContainer *playlist_list_;
|
||||
DeviceViewContainer *device_view_container_;
|
||||
DeviceView *device_view_;
|
||||
PlaylistListContainer *playlist_list_;
|
||||
|
||||
Lazy<SettingsDialog> settings_dialog_;
|
||||
Lazy<AlbumCoverManager> cover_manager_;
|
||||
@@ -354,6 +354,7 @@ signals:
|
||||
QTimer *track_slider_timer_;
|
||||
QSettings settings_;
|
||||
|
||||
bool initialised_;
|
||||
bool was_maximized_;
|
||||
int saved_playback_position_;
|
||||
Engine::State saved_playback_state_;
|
||||
|
||||
@@ -431,6 +431,7 @@ void Player::EngineStateChanged(Engine::State state) {
|
||||
emit Playing();
|
||||
break;
|
||||
case Engine::Error:
|
||||
emit Error();
|
||||
case Engine::Empty:
|
||||
case Engine::Idle:
|
||||
emit Stopped();
|
||||
|
||||
@@ -95,10 +95,11 @@ class PlayerInterface : public QObject {
|
||||
virtual void Play() = 0;
|
||||
virtual void ShowOSD() = 0;
|
||||
|
||||
signals:
|
||||
signals:
|
||||
void Playing();
|
||||
void Paused();
|
||||
void Stopped();
|
||||
void Error();
|
||||
void PlaylistFinished();
|
||||
void VolumeChanged(int volume);
|
||||
void Error(const QString &message);
|
||||
|
||||
@@ -47,12 +47,12 @@ QtSystemTrayIcon::QtSystemTrayIcon(QObject *parent)
|
||||
action_mute_(nullptr)
|
||||
{
|
||||
|
||||
QIcon theme_icon = IconLoader::Load("strawberry-panel");
|
||||
QIcon theme_icon_grey = IconLoader::Load("strawberry-panel-grey");
|
||||
QIcon theme_icon = IconLoader::Load("strawberry", 48);
|
||||
QIcon theme_icon_grey = IconLoader::Load("strawberry-grey", 48);
|
||||
|
||||
if (theme_icon.isNull() || theme_icon_grey.isNull()) {
|
||||
// Load the default icon
|
||||
QIcon icon(":/icons/64x64/strawberry-panel.png");
|
||||
QIcon icon(":/icons/48x48/strawberry.png");
|
||||
normal_icon_ = icon.pixmap(48, QIcon::Normal);
|
||||
grey_icon_ = icon.pixmap(48, QIcon::Disabled);
|
||||
}
|
||||
|
||||
@@ -693,7 +693,7 @@ void Song::InitFromFilePartial(const QString &filename) {
|
||||
|
||||
TagLib::FileRef fileref(filename.toUtf8().constData());
|
||||
//if (TagLib::FileRef::defaultFileExtensions().contains(suffix.toUtf8().constData())) {
|
||||
if (fileref.file()) d->valid_ = true;
|
||||
if (fileref.file() || (suffix == "dsf")) d->valid_ = true;
|
||||
else {
|
||||
d->valid_ = false;
|
||||
qLog(Error) << "File" << filename << "is not recognized by TagLib as a valid audio file.";
|
||||
|
||||
@@ -118,9 +118,10 @@ SongLoader::Result SongLoader::Load(const QUrl &url) {
|
||||
return LoadLocal(url_.toLocalFile());
|
||||
}
|
||||
|
||||
if (sRawUriSchemes.contains(url_.scheme()) || player_->HandlerForUrl(url) != nullptr) {
|
||||
if (sRawUriSchemes.contains(url_.scheme()) || player_->HandlerForUrl(url)) {
|
||||
// The URI scheme indicates that it can't possibly be a playlist,
|
||||
// or we have a custom handler for the URL, so add it as a raw stream. AddAsRawStream();
|
||||
// or we have a custom handler for the URL, so add it as a raw stream.
|
||||
AddAsRawStream();
|
||||
return Success;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user