Fix paths
- Use QStandardPaths - Load settings in StatusView widget - Update about - Remove redundant code - Temporary hide missing audiopanorama error as workaround for windows build
This commit is contained in:
1
3rdparty/qtsingleapplication/qtlocalpeer.cpp
vendored
1
3rdparty/qtsingleapplication/qtlocalpeer.cpp
vendored
@@ -108,7 +108,6 @@ bool QtLocalPeer::isClient()
|
|||||||
if (lockFile.isLocked())
|
if (lockFile.isLocked())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
//if (!lockFile.lock(QtLP_Private::QtLockedFile::WriteLock, false))
|
|
||||||
if (!lockFile.lock(QtLockedFile::WriteLock, false))
|
if (!lockFile.lock(QtLockedFile::WriteLock, false))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
|||||||
@@ -49,8 +49,7 @@ Qt::HANDLE QtLockedFile::getMutexHandle(int idx, bool doCreate)
|
|||||||
{
|
{
|
||||||
if (mutexname.isEmpty()) {
|
if (mutexname.isEmpty()) {
|
||||||
QFileInfo fi(*this);
|
QFileInfo fi(*this);
|
||||||
mutexname = QString::fromLatin1(MUTEX_PREFIX)
|
mutexname = QString::fromLatin1(MUTEX_PREFIX) + fi.absoluteFilePath().toLower();
|
||||||
+ fi.absoluteFilePath().toLower();
|
|
||||||
}
|
}
|
||||||
QString mname(mutexname);
|
QString mname(mutexname);
|
||||||
if (idx >= 0)
|
if (idx >= 0)
|
||||||
@@ -151,8 +150,7 @@ bool QtLockedFile::lock(LockMode mode, bool block)
|
|||||||
rmutexes.append(mutex);
|
rmutexes.append(mutex);
|
||||||
}
|
}
|
||||||
if (rmutexes.size()) {
|
if (rmutexes.size()) {
|
||||||
DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(),
|
DWORD res = WaitForMultipleObjects(rmutexes.size(), rmutexes.constData(), TRUE, block ? INFINITE : 0);
|
||||||
TRUE, block ? INFINITE : 0);
|
|
||||||
if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
|
if (res != WAIT_OBJECT_0 && res != WAIT_ABANDONED) {
|
||||||
if (res != WAIT_TIMEOUT)
|
if (res != WAIT_TIMEOUT)
|
||||||
qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
|
qErrnoWarning("QtLockedFile::lock(): WaitForMultipleObjects failed");
|
||||||
|
|||||||
26
README
26
README
@@ -2,23 +2,23 @@ Strawberry Music Player
|
|||||||
=======================
|
=======================
|
||||||
README
|
README
|
||||||
|
|
||||||
Strawberry is a modern audio player and music collection organiser. It was forked from Clementine in 2013, and has a diffrent goal.
|
Strawberry is a audio player and music collection organiser. It was forked from Clementine in 2013 with a diffrent goal.
|
||||||
It's written in C++ and Qt5 and runs on Linux. The name is inspired by the band Strawbs.
|
It's written in C++ and Qt 5 and runs on Linux. The name is inspired by the band Strawbs.
|
||||||
The main goal was to create a player for playing local music files that looked a bit more like Amarok 1.4 amd with advanced soundcard options.
|
|
||||||
You will find that Strawberry is lacking internet services and some other features found in Clementine.
|
|
||||||
|
|
||||||
Some differences between Strawberry and Clementine are:
|
Features:
|
||||||
|
|
||||||
- Status widget similar to context in Amarok 1.4
|
* Play and organize music
|
||||||
- Settings have been reorganized
|
* Edit tags on music files
|
||||||
- Advanced backend settings with support for several backends and advanced options
|
* Album cover art from Lastfm, Musicbrainz, Discogs and Amazon
|
||||||
- No Smart playlists, visualizations or cd ripping support
|
* Native desktop notifications
|
||||||
- No LastFM, podcast or internet features except for fetching album covers
|
* Playlists in multiple formats
|
||||||
|
* Transfer music to iPod, iPhone, MTP or mass-storage USB player
|
||||||
There are no plans to add internet streaming features, but if we would add something it has to be a service providing high quality audio and not low audio quality like Spotify.
|
* Support for multiple backends
|
||||||
|
|
||||||
You can obtain and view the sourcecode on github at: https://github.com/jonaski/strawberry
|
You can obtain and view the sourcecode on github at: https://github.com/jonaski/strawberry
|
||||||
|
|
||||||
|
It has so far been tested on Linux and cross compiled for Windows. I have not had a chance to test it on Mac OS X since I don't have a mac.
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
@@ -27,7 +27,7 @@ To build Strawberry from source you need the following installed on your system:
|
|||||||
|
|
||||||
* glib2, glib2-devel, git, cmake, make, gcc and gcc-c++
|
* glib2, glib2-devel, git, cmake, make, gcc and gcc-c++
|
||||||
* protobuf and development packages
|
* protobuf and development packages
|
||||||
* boost development package
|
* boost development headers
|
||||||
|
|
||||||
* The following Qt5 components are required with additional development packages:
|
* The following Qt5 components are required with additional development packages:
|
||||||
|
|
||||||
|
|||||||
2
dist/strawberry.spec.in
vendored
2
dist/strawberry.spec.in
vendored
@@ -80,7 +80,7 @@ Requires: gstreamer1.0(decoder-audio/x-wav)
|
|||||||
%endif
|
%endif
|
||||||
|
|
||||||
%description
|
%description
|
||||||
Strawberry is a modern audio player and music collection organiser.
|
Strawberry is a audio player and music collection organiser.
|
||||||
It is a fork of Clementine. The name is inspired by the band Strawbs.
|
It is a fork of Clementine. The name is inspired by the band Strawbs.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
|
|
||||||
#include "database.h"
|
#include "database.h"
|
||||||
#include "scopedtransaction.h"
|
#include "scopedtransaction.h"
|
||||||
#include "utilities.h"
|
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "core/taskmanager.h"
|
#include "core/taskmanager.h"
|
||||||
@@ -32,6 +31,7 @@
|
|||||||
#include <sqlite3.h>
|
#include <sqlite3.h>
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#include <QLibraryInfo>
|
#include <QLibraryInfo>
|
||||||
@@ -225,7 +225,7 @@ Database::Database(Application *app, QObject *parent, const QString &database_na
|
|||||||
connection_id_ = sNextConnectionId++;
|
connection_id_ = sNextConnectionId++;
|
||||||
}
|
}
|
||||||
|
|
||||||
directory_ = QDir::toNativeSeparators(Utilities::GetConfigPath(Utilities::Path_Root));
|
directory_ = QDir::toNativeSeparators(QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation));
|
||||||
|
|
||||||
QMutexLocker l(&mutex_);
|
QMutexLocker l(&mutex_);
|
||||||
Connect();
|
Connect();
|
||||||
|
|||||||
@@ -120,8 +120,8 @@ int main(int argc, char* argv[]) {
|
|||||||
QCoreApplication::setOrganizationDomain("strawbs.org");
|
QCoreApplication::setOrganizationDomain("strawbs.org");
|
||||||
|
|
||||||
// This makes us show up nicely in gnome-volume-control
|
// This makes us show up nicely in gnome-volume-control
|
||||||
#if !GLIB_CHECK_VERSION(2, 36, 0)
|
#if !GLIB_CHECK_VERSION(2, 36, 0) // Deprecated in glib 2.36.0
|
||||||
g_type_init(); // Deprecated in glib 2.36.0
|
g_type_init();
|
||||||
#endif
|
#endif
|
||||||
g_set_application_name(QCoreApplication::applicationName().toLocal8Bit());
|
g_set_application_name(QCoreApplication::applicationName().toLocal8Bit());
|
||||||
|
|
||||||
@@ -156,7 +156,7 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
// Must happen after QCoreApplication::setOrganizationName().
|
// Must happen after QCoreApplication::setOrganizationName().
|
||||||
setenv("XDG_CONFIG_HOME", Utilities::GetConfigPath(Utilities::Path_Root).toLocal8Bit().constData(), 1);
|
setenv("XDG_CONFIG_HOME", QStandardPaths::writableLocation(QStandardPaths::AppConfigLocation).toLocal8Bit().constData(), 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Output the version, so when people attach log output to bug reports they don't have to tell us which version they're using.
|
// Output the version, so when people attach log output to bug reports they don't have to tell us which version they're using.
|
||||||
|
|||||||
@@ -23,13 +23,14 @@
|
|||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QStandardPaths>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
#include <QNetworkDiskCache>
|
#include <QNetworkDiskCache>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
|
||||||
#include "core/closure.h"
|
#include "core/closure.h"
|
||||||
#include "utilities.h"
|
#include "core/logging.h"
|
||||||
|
|
||||||
QMutex ThreadSafeNetworkDiskCache::sMutex;
|
QMutex ThreadSafeNetworkDiskCache::sMutex;
|
||||||
QNetworkDiskCache *ThreadSafeNetworkDiskCache::sCache = nullptr;
|
QNetworkDiskCache *ThreadSafeNetworkDiskCache::sCache = nullptr;
|
||||||
@@ -39,7 +40,11 @@ ThreadSafeNetworkDiskCache::ThreadSafeNetworkDiskCache(QObject *parent)
|
|||||||
QMutexLocker l(&sMutex);
|
QMutexLocker l(&sMutex);
|
||||||
if (!sCache) {
|
if (!sCache) {
|
||||||
sCache = new QNetworkDiskCache;
|
sCache = new QNetworkDiskCache;
|
||||||
sCache->setCacheDirectory(Utilities::GetConfigPath(Utilities::Path_NetworkCache));
|
#ifdef Q_OS_WIN32
|
||||||
|
sCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::TempLocation) + "/strawberry/networkcache");
|
||||||
|
#else
|
||||||
|
sCache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/networkcache");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,18 +98,15 @@ QNetworkReply *NetworkAccessManager::createRequest(Operation op, const QNetworkR
|
|||||||
QByteArray user_agent = QString("%1 %2").arg(QCoreApplication::applicationName(), QCoreApplication::applicationVersion()).toUtf8();
|
QByteArray user_agent = QString("%1 %2").arg(QCoreApplication::applicationName(), QCoreApplication::applicationVersion()).toUtf8();
|
||||||
|
|
||||||
if (request.hasRawHeader("User-Agent")) {
|
if (request.hasRawHeader("User-Agent")) {
|
||||||
// Append the existing user-agent set by a client collection (such as
|
// Append the existing user-agent set by a client collection (such as libmygpo-qt).
|
||||||
// libmygpo-qt).
|
|
||||||
user_agent += " " + request.rawHeader("User-Agent");
|
user_agent += " " + request.rawHeader("User-Agent");
|
||||||
}
|
}
|
||||||
|
|
||||||
QNetworkRequest new_request(request);
|
QNetworkRequest new_request(request);
|
||||||
new_request.setRawHeader("User-Agent", user_agent);
|
new_request.setRawHeader("User-Agent", user_agent);
|
||||||
|
|
||||||
if (op == QNetworkAccessManager::PostOperation &&
|
if (op == QNetworkAccessManager::PostOperation && !new_request.header(QNetworkRequest::ContentTypeHeader).isValid()) {
|
||||||
!new_request.header(QNetworkRequest::ContentTypeHeader).isValid()) {
|
new_request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
|
||||||
new_request.setHeader(QNetworkRequest::ContentTypeHeader,
|
|
||||||
"application/x-www-form-urlencoded");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prefer the cache unless the caller has changed the setting already
|
// Prefer the cache unless the caller has changed the setting already
|
||||||
|
|||||||
@@ -87,8 +87,7 @@ QString PrettyTimeDelta(int seconds) {
|
|||||||
|
|
||||||
QString PrettyTime(int seconds) {
|
QString PrettyTime(int seconds) {
|
||||||
|
|
||||||
// last.fm sometimes gets the track length wrong, so you end up with
|
// last.fm sometimes gets the track length wrong, so you end up with negative times.
|
||||||
// negative times.
|
|
||||||
seconds = qAbs(seconds);
|
seconds = qAbs(seconds);
|
||||||
|
|
||||||
int hours = seconds / (60 * 60);
|
int hours = seconds / (60 * 60);
|
||||||
@@ -181,9 +180,7 @@ quint64 FileSystemCapacity(const QString &path) {
|
|||||||
return quint64(fs_info.f_blocks) * quint64(fs_info.f_bsize);
|
return quint64(fs_info.f_blocks) * quint64(fs_info.f_bsize);
|
||||||
#elif defined(Q_OS_WIN32)
|
#elif defined(Q_OS_WIN32)
|
||||||
_ULARGE_INTEGER ret;
|
_ULARGE_INTEGER ret;
|
||||||
if (GetDiskFreeSpaceEx(
|
if (GetDiskFreeSpaceEx(QDir::toNativeSeparators(path).toLocal8Bit().constData(), nullptr,&ret, nullptr) != 0)
|
||||||
QDir::toNativeSeparators(path).toLocal8Bit().constData(), nullptr,
|
|
||||||
&ret, nullptr) != 0)
|
|
||||||
return ret.QuadPart;
|
return ret.QuadPart;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -199,9 +196,7 @@ quint64 FileSystemFreeSpace(const QString &path) {
|
|||||||
return quint64(fs_info.f_bavail) * quint64(fs_info.f_bsize);
|
return quint64(fs_info.f_bavail) * quint64(fs_info.f_bsize);
|
||||||
#elif defined(Q_OS_WIN32)
|
#elif defined(Q_OS_WIN32)
|
||||||
_ULARGE_INTEGER ret;
|
_ULARGE_INTEGER ret;
|
||||||
if (GetDiskFreeSpaceEx(
|
if (GetDiskFreeSpaceEx(QDir::toNativeSeparators(path).toLocal8Bit().constData(), &ret, nullptr, nullptr) != 0)
|
||||||
QDir::toNativeSeparators(path).toLocal8Bit().constData(), &ret,
|
|
||||||
nullptr, nullptr) != 0)
|
|
||||||
return ret.QuadPart;
|
return ret.QuadPart;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -346,66 +341,6 @@ QString ColorToRgba(const QColor &c) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QString GetConfigPath(ConfigPath config) {
|
|
||||||
|
|
||||||
switch (config) {
|
|
||||||
|
|
||||||
case Path_Root: {
|
|
||||||
if (Application::kIsPortable) {
|
|
||||||
return QString("%1/data").arg(QCoreApplication::applicationDirPath());
|
|
||||||
}
|
|
||||||
#ifdef Q_OS_DARWIN
|
|
||||||
return mac::GetApplicationSupportPath() + "/strawberry";
|
|
||||||
#else
|
|
||||||
return QString("%1/.config/strawberry").arg(QDir::homePath());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Path_CacheRoot: {
|
|
||||||
if (Application::kIsPortable) {
|
|
||||||
return GetConfigPath(Path_Root) + "/cache";
|
|
||||||
}
|
|
||||||
#if defined(Q_OS_UNIX) && !defined(Q_OS_DARWIN)
|
|
||||||
char *xdg = getenv("XDG_CACHE_HOME");
|
|
||||||
if (!xdg || !*xdg) {
|
|
||||||
return QString("%1/.cache/strawberry").arg(QDir::homePath());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return QString("%1/strawberry").arg(xdg);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
return GetConfigPath(Path_Root);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case Path_Icons:
|
|
||||||
return GetConfigPath(Path_Root) + "/customiconset";
|
|
||||||
|
|
||||||
case Path_AlbumCovers:
|
|
||||||
return GetConfigPath(Path_Root) + "/albumcovers";
|
|
||||||
|
|
||||||
case Path_NetworkCache:
|
|
||||||
return GetConfigPath(Path_CacheRoot) + "/networkcache";
|
|
||||||
|
|
||||||
case Path_GstreamerRegistry:
|
|
||||||
return GetConfigPath(Path_Root) + QString("/gst-registry-%1-bin").arg(QCoreApplication::applicationVersion());
|
|
||||||
|
|
||||||
case Path_DefaultMusicCollection:
|
|
||||||
#ifdef Q_OS_DARWIN
|
|
||||||
return mac::GetMusicDirectory();
|
|
||||||
#else
|
|
||||||
return QDir::homePath();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
default:
|
|
||||||
qFatal("%s", Q_FUNC_INFO);
|
|
||||||
return QString::null;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
qint32 GetMacVersion() {
|
qint32 GetMacVersion() {
|
||||||
|
|
||||||
@@ -801,8 +736,7 @@ void SetEnv(const char *key, const QString &value) {
|
|||||||
void IncreaseFDLimit() {
|
void IncreaseFDLimit() {
|
||||||
|
|
||||||
#ifdef Q_OS_DARWIN
|
#ifdef Q_OS_DARWIN
|
||||||
// Bump the soft limit for the number of file descriptors from the default of 256 to
|
// Bump the soft limit for the number of file descriptors from the default of 256 to the maximum (usually 10240).
|
||||||
// the maximum (usually 10240).
|
|
||||||
struct rlimit limit;
|
struct rlimit limit;
|
||||||
getrlimit(RLIMIT_NOFILE, &limit);
|
getrlimit(RLIMIT_NOFILE, &limit);
|
||||||
|
|
||||||
|
|||||||
@@ -126,19 +126,6 @@ void SetEnv(const char *key, const QString &value);
|
|||||||
void IncreaseFDLimit();
|
void IncreaseFDLimit();
|
||||||
void CheckPortable();
|
void CheckPortable();
|
||||||
|
|
||||||
enum ConfigPath {
|
|
||||||
Path_Root,
|
|
||||||
Path_Icons,
|
|
||||||
Path_AlbumCovers,
|
|
||||||
Path_NetworkCache,
|
|
||||||
Path_GstreamerRegistry,
|
|
||||||
Path_DefaultMusicCollection,
|
|
||||||
Path_LocalSpotifyBlob,
|
|
||||||
Path_MoodbarCache,
|
|
||||||
Path_CacheRoot,
|
|
||||||
};
|
|
||||||
QString GetConfigPath(ConfigPath config);
|
|
||||||
|
|
||||||
// Returns the minor version of OS X (ie. 6 for Snow Leopard, 7 for Lion).
|
// Returns the minor version of OS X (ie. 6 for Snow Leopard, 7 for Lion).
|
||||||
qint32 GetMacVersion();
|
qint32 GetMacVersion();
|
||||||
|
|
||||||
|
|||||||
@@ -211,8 +211,7 @@ void AlbumCoverChoiceController::ShowCover(const Song &song) {
|
|||||||
// add (WxHpx) to the title before possibly resizing
|
// add (WxHpx) to the title before possibly resizing
|
||||||
title_text += " (" + QString::number(label->pixmap()->width()) + "x" + QString::number(label->pixmap()->height()) + "px)";
|
title_text += " (" + QString::number(label->pixmap()->width()) + "x" + QString::number(label->pixmap()->height()) + "px)";
|
||||||
|
|
||||||
// if the cover is larger than the screen, resize the window
|
// if the cover is larger than the screen, resize the window 85% seems to be enough to account for title bar and taskbar etc.
|
||||||
// 85% seems to be enough to account for title bar and taskbar etc.
|
|
||||||
QDesktopWidget desktop;
|
QDesktopWidget desktop;
|
||||||
int current_screen = desktop.screenNumber(this);
|
int current_screen = desktop.screenNumber(this);
|
||||||
int desktop_height = desktop.screenGeometry(current_screen).height();
|
int desktop_height = desktop.screenGeometry(current_screen).height();
|
||||||
@@ -222,15 +221,13 @@ void AlbumCoverChoiceController::ShowCover(const Song &song) {
|
|||||||
if (desktop_width < desktop_height) {
|
if (desktop_width < desktop_height) {
|
||||||
const int new_width = (double)desktop_width * 0.95;
|
const int new_width = (double)desktop_width * 0.95;
|
||||||
if (new_width < label->pixmap()->width()) {
|
if (new_width < label->pixmap()->width()) {
|
||||||
label->setPixmap(
|
label->setPixmap(label->pixmap()->scaledToWidth(new_width, Qt::SmoothTransformation));
|
||||||
label->pixmap()->scaledToWidth(new_width, Qt::SmoothTransformation));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
const int new_height = (double)desktop_height * 0.85;
|
const int new_height = (double)desktop_height * 0.85;
|
||||||
if (new_height < label->pixmap()->height()) {
|
if (new_height < label->pixmap()->height()) {
|
||||||
label->setPixmap(label->pixmap()->scaledToHeight(
|
label->setPixmap(label->pixmap()->scaledToHeight(new_height, Qt::SmoothTransformation));
|
||||||
new_height, Qt::SmoothTransformation));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -22,18 +22,22 @@
|
|||||||
|
|
||||||
#include "albumcoverloader.h"
|
#include "albumcoverloader.h"
|
||||||
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QDir>
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
#include <QString>
|
||||||
|
#include <QDir>
|
||||||
#include <QUrl>
|
#include <QUrl>
|
||||||
#include <QNetworkReply>
|
#include <QNetworkReply>
|
||||||
|
#include <QImage>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QMutexLocker>
|
||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "core/closure.h"
|
#include "core/closure.h"
|
||||||
#include "core/logging.h"
|
#include "core/logging.h"
|
||||||
#include "core/network.h"
|
#include "core/network.h"
|
||||||
#include "core/tagreaderclient.h"
|
#include "core/tagreaderclient.h"
|
||||||
#include "core/utilities.h"
|
|
||||||
|
|
||||||
AlbumCoverLoader::AlbumCoverLoader(QObject *parent)
|
AlbumCoverLoader::AlbumCoverLoader(QObject *parent)
|
||||||
: QObject(parent),
|
: QObject(parent),
|
||||||
@@ -42,7 +46,7 @@ AlbumCoverLoader::AlbumCoverLoader(QObject *parent)
|
|||||||
network_(new NetworkAccessManager(this)){}
|
network_(new NetworkAccessManager(this)){}
|
||||||
|
|
||||||
QString AlbumCoverLoader::ImageCacheDir() {
|
QString AlbumCoverLoader::ImageCacheDir() {
|
||||||
return Utilities::GetConfigPath(Utilities::Path_AlbumCovers);
|
return QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + "/albumcovers";
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlbumCoverLoader::CancelTask(quint64 id) {
|
void AlbumCoverLoader::CancelTask(quint64 id) {
|
||||||
@@ -139,6 +143,7 @@ void AlbumCoverLoader::NextState(Task *task) {
|
|||||||
emit ImageLoaded(task->id, task->options.default_output_image_);
|
emit ImageLoaded(task->id, task->options.default_output_image_);
|
||||||
emit ImageLoaded(task->id, task->options.default_output_image_, task->options.default_output_image_);
|
emit ImageLoaded(task->id, task->options.default_output_image_, task->options.default_output_image_);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AlbumCoverLoader::TryLoadResult AlbumCoverLoader::TryLoadImage(const Task &task) {
|
AlbumCoverLoader::TryLoadResult AlbumCoverLoader::TryLoadImage(const Task &task) {
|
||||||
@@ -241,6 +246,7 @@ QImage AlbumCoverLoader::ScaleAndPad(const AlbumCoverLoaderOptions &options, con
|
|||||||
p.end();
|
p.end();
|
||||||
|
|
||||||
return padded_image;
|
return padded_image;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QPixmap AlbumCoverLoader::TryLoadPixmap(const QString &automatic, const QString &manual, const QString &filename) {
|
QPixmap AlbumCoverLoader::TryLoadPixmap(const QString &automatic, const QString &manual, const QString &filename) {
|
||||||
@@ -255,4 +261,5 @@ QPixmap AlbumCoverLoader::TryLoadPixmap(const QString &automatic, const QString
|
|||||||
ret.load(automatic);
|
ret.load(automatic);
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -772,6 +772,7 @@ void AlbumCoverManager::SaveAndSetCover(QListWidgetItem *item, const QImage &ima
|
|||||||
quint64 id = app_->album_cover_loader()->LoadImageAsync(cover_loader_options_, QString(), path);
|
quint64 id = app_->album_cover_loader()->LoadImageAsync(cover_loader_options_, QString(), path);
|
||||||
item->setData(Role_PathManual, path);
|
item->setData(Role_PathManual, path);
|
||||||
cover_loading_tasks_[id] = item;
|
cover_loading_tasks_[id] = item;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AlbumCoverManager::ExportCovers() {
|
void AlbumCoverManager::ExportCovers() {
|
||||||
|
|||||||
@@ -64,8 +64,6 @@ About::About(QWidget *parent):QDialog(parent) {
|
|||||||
title_font.setPointSize(title_font.pointSize() + 4);
|
title_font.setPointSize(title_font.pointSize() + 4);
|
||||||
ui_.title->setFont(title_font);
|
ui_.title->setFont(title_font);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ui_.text->setWordWrap(true);
|
ui_.text->setWordWrap(true);
|
||||||
ui_.text->setText(MakeHtml());
|
ui_.text->setText(MakeHtml());
|
||||||
|
|
||||||
@@ -77,16 +75,17 @@ QString About::MakeHtml() const {
|
|||||||
|
|
||||||
QString ret = "";
|
QString ret = "";
|
||||||
|
|
||||||
ret = tr("<p>Version %1</p>").arg(QCoreApplication::applicationVersion());
|
ret = tr("<p>Version %1</p>").arg(QCoreApplication::applicationVersion());
|
||||||
|
|
||||||
ret += tr("<p>");
|
ret += tr("<p>");
|
||||||
ret += tr("Strawberry is a fork of Clementine created in 2013, it's written in C++ and Qt5. So far it works on Linux, it is currently untested on Mac OS X and Windows.<br />");
|
|
||||||
ret += tr("The main goal was to create a player for playing local music files that looked a bit more like Amarok 1.4.");
|
ret += tr("Strawberry is a audio player and music collection organiser.<br />");
|
||||||
|
ret += tr("It is a fork of Clementine. The name is inspired by the band Strawbs.");
|
||||||
ret += tr("</p>");
|
ret += tr("</p>");
|
||||||
|
|
||||||
//ret += tr("<p><a href=\"%1\">%2</a></p><p><b>%3:</b>").arg(kUrl, kUrl, tr("Authors"));
|
//ret += tr("<p><a href=\"%1\">%2</a></p><p><b>%3:</b>").arg(kUrl, kUrl, tr("Authors"));
|
||||||
|
|
||||||
ret += QString("<p><b>%1</b>").arg(tr("Authors"));
|
ret += QString("<p><b>%1</b>").arg(tr("Strawberry Authors"));
|
||||||
|
|
||||||
for (const Person &person : authors_) {
|
for (const Person &person : authors_) {
|
||||||
ret += "<br />" + MakeHtml(person);
|
ret += "<br />" + MakeHtml(person);
|
||||||
|
|||||||
@@ -33,14 +33,15 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
#include <QTimer>
|
|
||||||
#include <QRegExp>
|
|
||||||
#include <QFile>
|
|
||||||
#include <QSettings>
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QTimeLine>
|
#include <QStandardPaths>
|
||||||
#include <QDir>
|
|
||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
|
#include <QSettings>
|
||||||
|
#include <QDir>
|
||||||
|
#include <QFile>
|
||||||
|
#include <QRegExp>
|
||||||
|
#include <QTimer>
|
||||||
|
#include <QTimeLine>
|
||||||
|
|
||||||
#include "enginetype.h"
|
#include "enginetype.h"
|
||||||
#include "enginebase.h"
|
#include "enginebase.h"
|
||||||
@@ -169,7 +170,7 @@ void GstEngine::SetEnvironment() {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN)
|
#if defined(Q_OS_WIN32) || defined(Q_OS_DARWIN)
|
||||||
registry_filename = Utilities::GetConfigPath(Utilities::Path_GstreamerRegistry);
|
registry_filename = QStandardPaths::writableLocation(QStandardPaths::AppLocalDataLocation) + QString("/gst-registry-%1-bin").arg(QCoreApplication::applicationVersion());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!scanner_path.isEmpty()) Utilities::SetEnv("GST_PLUGIN_SCANNER", scanner_path);
|
if (!scanner_path.isEmpty()) Utilities::SetEnv("GST_PLUGIN_SCANNER", scanner_path);
|
||||||
@@ -750,7 +751,7 @@ void GstEngine::NewMetaData(int pipeline_id, const Engine::SimpleMetaBundle &bun
|
|||||||
emit MetaData(bundle);
|
emit MetaData(bundle);
|
||||||
}
|
}
|
||||||
|
|
||||||
GstElement *GstEngine::CreateElement(const QString &factoryName, GstElement *bin) {
|
GstElement *GstEngine::CreateElement(const QString &factoryName, GstElement *bin, bool showerror) {
|
||||||
|
|
||||||
// Make a unique name
|
// Make a unique name
|
||||||
QString name = factoryName + "-" + QString::number(next_element_id_++);
|
QString name = factoryName + "-" + QString::number(next_element_id_++);
|
||||||
@@ -758,7 +759,7 @@ GstElement *GstEngine::CreateElement(const QString &factoryName, GstElement *bin
|
|||||||
GstElement *element = gst_element_factory_make(factoryName.toUtf8().constData(), name.toUtf8().constData());
|
GstElement *element = gst_element_factory_make(factoryName.toUtf8().constData(), name.toUtf8().constData());
|
||||||
|
|
||||||
if (!element) {
|
if (!element) {
|
||||||
emit Error(QString("GStreamer could not create the element: %1. Please make sure that you have installed all necessary GStreamer plugins").arg(factoryName));
|
if (showerror) emit Error(QString("GStreamer could not create the element: %1. Please make sure that you have installed all necessary GStreamer plugins").arg(factoryName));
|
||||||
gst_object_unref(GST_OBJECT(bin));
|
gst_object_unref(GST_OBJECT(bin));
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ class GstEngine : public Engine::Base, public BufferConsumer {
|
|||||||
|
|
||||||
static bool ALSADeviceSupport(const QString &name);
|
static bool ALSADeviceSupport(const QString &name);
|
||||||
|
|
||||||
GstElement *CreateElement(const QString &factoryName, GstElement *bin = 0);
|
GstElement *CreateElement(const QString &factoryName, GstElement *bin = 0, bool showerror = true);
|
||||||
|
|
||||||
// BufferConsumer
|
// BufferConsumer
|
||||||
void ConsumeBuffer(GstBuffer *buffer, int pipeline_id);
|
void ConsumeBuffer(GstBuffer *buffer, int pipeline_id);
|
||||||
|
|||||||
@@ -230,7 +230,7 @@ bool GstEnginePipeline::InitAudioBin() {
|
|||||||
audio_queue = engine_->CreateElement("queue", audiobin_);
|
audio_queue = engine_->CreateElement("queue", audiobin_);
|
||||||
equalizer_preamp_ = engine_->CreateElement("volume", audiobin_);
|
equalizer_preamp_ = engine_->CreateElement("volume", audiobin_);
|
||||||
equalizer_ = engine_->CreateElement("equalizer-nbands", audiobin_);
|
equalizer_ = engine_->CreateElement("equalizer-nbands", audiobin_);
|
||||||
stereo_panorama_ = engine_->CreateElement("audiopanorama", audiobin_);
|
stereo_panorama_ = engine_->CreateElement("audiopanorama", audiobin_, false);
|
||||||
volume_ = engine_->CreateElement("volume", audiobin_);
|
volume_ = engine_->CreateElement("volume", audiobin_);
|
||||||
audioscale_ = engine_->CreateElement("audioresample", audiobin_);
|
audioscale_ = engine_->CreateElement("audioresample", audiobin_);
|
||||||
convert = engine_->CreateElement("audioconvert", audiobin_);
|
convert = engine_->CreateElement("audioconvert", audiobin_);
|
||||||
|
|||||||
@@ -47,9 +47,6 @@ class PlaylistBackend : public QObject {
|
|||||||
QString ui_path;
|
QString ui_path;
|
||||||
bool favorite;
|
bool favorite;
|
||||||
int last_played;
|
int last_played;
|
||||||
|
|
||||||
// Special playlists have different behaviour, eg. the "spotify-search"
|
|
||||||
// type has a spotify search box at the top, replacing the ordinary filter.
|
|
||||||
QString special_type;
|
QString special_type;
|
||||||
};
|
};
|
||||||
typedef QList<Playlist> PlaylistList;
|
typedef QList<Playlist> PlaylistList;
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ void BackendSettingsPage::Load() {
|
|||||||
configloaded_ = false;
|
configloaded_ = false;
|
||||||
engineloaded_ = Engine::None;
|
engineloaded_ = Engine::None;
|
||||||
|
|
||||||
Engine::EngineType enginetype = Engine::EngineTypeFromName(s_.value("engine", EngineText_Xine).toString());
|
Engine::EngineType enginetype = Engine::EngineTypeFromName(s_.value("engine", EngineText_GStreamer).toString());
|
||||||
|
|
||||||
ui_->combobox_engine->clear();
|
ui_->combobox_engine->clear();
|
||||||
#ifdef HAVE_XINE
|
#ifdef HAVE_XINE
|
||||||
|
|||||||
@@ -22,16 +22,15 @@
|
|||||||
|
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
#include <QFileDialog>
|
#include <QFileDialog>
|
||||||
#include <QMessageBox>
|
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QtConcurrentRun>
|
#include <QtConcurrentRun>
|
||||||
|
#include <QStandardPaths>
|
||||||
|
|
||||||
#include "collectionsettingspage.h"
|
#include "collectionsettingspage.h"
|
||||||
#include "ui_collectionsettingspage.h"
|
#include "ui_collectionsettingspage.h"
|
||||||
|
|
||||||
#include "settings/settingsdialog.h"
|
#include "settings/settingsdialog.h"
|
||||||
#include "core/application.h"
|
#include "core/application.h"
|
||||||
#include "core/utilities.h"
|
|
||||||
#include "core/iconloader.h"
|
#include "core/iconloader.h"
|
||||||
#include "playlist/playlistdelegates.h"
|
#include "playlist/playlistdelegates.h"
|
||||||
|
|
||||||
@@ -65,7 +64,7 @@ void CollectionSettingsPage::Add() {
|
|||||||
QSettings settings;
|
QSettings settings;
|
||||||
settings.beginGroup(kSettingsGroup);
|
settings.beginGroup(kSettingsGroup);
|
||||||
|
|
||||||
QString path(settings.value("last_path", Utilities::GetConfigPath(Utilities::Path_DefaultMusicCollection)).toString());
|
QString path(settings.value("last_path", QStandardPaths::writableLocation(QStandardPaths::MusicLocation)).toString());
|
||||||
path = QFileDialog::getExistingDirectory(this, tr("Add directory..."), path);
|
path = QFileDialog::getExistingDirectory(this, tr("Add directory..."), path);
|
||||||
|
|
||||||
if (!path.isNull()) {
|
if (!path.isNull()) {
|
||||||
|
|||||||
@@ -78,15 +78,11 @@ PlayingWidget::PlayingWidget(QWidget *parent)
|
|||||||
previous_track_opacity_(0.0),
|
previous_track_opacity_(0.0),
|
||||||
downloading_covers_(false) {
|
downloading_covers_(false) {
|
||||||
|
|
||||||
enabled_ = false;
|
|
||||||
visible_ = false;
|
|
||||||
active_ = false;
|
|
||||||
|
|
||||||
// Load settings
|
// Load settings
|
||||||
QSettings s;
|
QSettings s;
|
||||||
s.beginGroup(kSettingsGroup);
|
s.beginGroup(kSettingsGroup);
|
||||||
mode_ = Mode(s.value("mode", LargeSongDetails).toInt());
|
mode_ = Mode(s.value("mode", LargeSongDetails).toInt());
|
||||||
album_cover_choice_controller_->search_cover_auto_action()->setChecked(s.value("search_for_cover_auto", false).toBool());
|
album_cover_choice_controller_->search_cover_auto_action()->setChecked(s.value("search_for_cover_auto", true).toBool());
|
||||||
fit_width_ = s.value("fit_cover_width", false).toBool();
|
fit_width_ = s.value("fit_cover_width", false).toBool();
|
||||||
|
|
||||||
// Accept drops for setting album art
|
// Accept drops for setting album art
|
||||||
@@ -473,7 +469,6 @@ void PlayingWidget::SearchCoverAutomatically() {
|
|||||||
s.beginGroup(kSettingsGroup);
|
s.beginGroup(kSettingsGroup);
|
||||||
s.setValue("search_for_cover_auto", album_cover_choice_controller_->search_cover_auto_action()->isChecked());
|
s.setValue("search_for_cover_auto", album_cover_choice_controller_->search_cover_auto_action()->isChecked());
|
||||||
|
|
||||||
// Search for cover automatically?
|
|
||||||
GetCoverAutomatically();
|
GetCoverAutomatically();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,12 @@ StatusView::StatusView(CollectionViewContainer *collectionviewcontainer, QWidget
|
|||||||
NoSong();
|
NoSong();
|
||||||
AddActions();
|
AddActions();
|
||||||
|
|
||||||
|
// Load settings
|
||||||
|
QSettings s;
|
||||||
|
s.beginGroup(kSettingsGroup);
|
||||||
|
album_cover_choice_controller_->search_cover_auto_action()->setChecked(s.value("search_for_cover_auto", true).toBool());
|
||||||
|
s.endGroup();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
StatusView::~StatusView() {
|
StatusView::~StatusView() {
|
||||||
@@ -620,7 +626,6 @@ void StatusView::SearchCoverAutomatically() {
|
|||||||
s.beginGroup(kSettingsGroup);
|
s.beginGroup(kSettingsGroup);
|
||||||
s.setValue("search_for_cover_auto", album_cover_choice_controller_->search_cover_auto_action()->isChecked());
|
s.setValue("search_for_cover_auto", album_cover_choice_controller_->search_cover_auto_action()->isChecked());
|
||||||
|
|
||||||
// Search for cover automatically?
|
|
||||||
GetCoverAutomatically();
|
GetCoverAutomatically();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user