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:
Jonas Kvinge
2018-08-29 21:42:24 +02:00
parent 3b30e66e87
commit ac6cac8da1
96 changed files with 4361 additions and 3135 deletions

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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");
}

View File

@@ -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]

View File

@@ -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

View File

@@ -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;
}

View File

@@ -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

View File

@@ -200,9 +200,6 @@ int main(int argc, char* argv[]) {
// Resources
Q_INIT_RESOURCE(data);
// Icons
IconLoader::Init();
Application app;

View File

@@ -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)));

View File

@@ -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_;

View File

@@ -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();

View File

@@ -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);

View File

@@ -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);
}

View File

@@ -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.";

View 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;
}