mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-09 21:50:58 +02:00
Compare commits
47 Commits
rtmp-strea
...
doubleVlc
Author | SHA1 | Date | |
---|---|---|---|
|
9a5750c6f4 | ||
|
3b6ba36e83 | ||
|
cf6a37ae45 | ||
|
690a87f1eb | ||
|
6842da7240 | ||
|
6910e5dd3b | ||
|
584aa76582 | ||
|
7e96285132 | ||
|
c996a8b90e | ||
|
c705013ee1 | ||
|
84360aed2f | ||
|
ada03e1a8d | ||
|
3a71da5705 | ||
|
214e310c91 | ||
|
ed9a027644 | ||
|
3e2d74128d | ||
|
84ed59f4be | ||
|
5dd36cbd4e | ||
|
7e38d94fe5 | ||
|
28ee9180c8 | ||
|
09e9a6e960 | ||
|
ffa098e52d | ||
|
a439427ca5 | ||
|
a9505f75c5 | ||
|
7e54e506df | ||
|
abc00b4758 | ||
|
77e9b69679 | ||
|
58b640d389 | ||
|
1a5f073437 | ||
|
c9ef7e74d8 | ||
|
34448b1b46 | ||
|
4408ba275c | ||
|
dfd71d7010 | ||
|
170e2e1c86 | ||
|
0047763188 | ||
|
525068a706 | ||
|
85657e40a6 | ||
|
af459afb0b | ||
|
5bbc39e6a5 | ||
|
c88640268a | ||
|
8749a04e23 | ||
|
d45917d14a | ||
|
c87b1390e5 | ||
|
bf28f6856e | ||
|
ceab0f9cf2 | ||
|
a562e75937 | ||
|
81eb226146 |
@@ -315,9 +315,6 @@ if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR APPLE) AND LIBCPP_FOUND)
|
||||
tomahawk_add_cxx_flags( "-stdlib=libc++" )
|
||||
endif()
|
||||
|
||||
macro_optional_find_package(Echonest 2.3.0)
|
||||
macro_log_feature(ECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 2.3.0 is needed for dynamic playlists and the infosystem")
|
||||
|
||||
find_package(Boost REQUIRED COMPONENTS filesystem system)
|
||||
macro_log_feature(Boost_FOUND "Boost" "Provides free peer-reviewed portable C++ source libraries" "http://www.boost.org" TRUE "" "") #FIXME: give useful explanation
|
||||
|
||||
|
@@ -1,42 +0,0 @@
|
||||
# - Find libechonest
|
||||
# Find the libechonest includes and the libechonest libraries
|
||||
# This module defines
|
||||
# ECHONEST_INCLUDE_DIR, root echonest include dir. Include echonest includes with echonest/foo.h
|
||||
# ECHONEST_LIBRARIES, the path to libechonest
|
||||
# ECHONEST_FOUND, whether libechonest was found
|
||||
|
||||
FIND_PACKAGE(PkgConfig QUIET)
|
||||
|
||||
if( TOMAHAWK_QT5 )
|
||||
set(LIBECHONEST_SUFFIX "5")
|
||||
endif()
|
||||
|
||||
PKG_CHECK_MODULES(PC_ECHONEST QUIET libechonest${LIBECHONEST_SUFFIX})
|
||||
|
||||
FIND_PATH(ECHONEST_INCLUDE_DIR NAMES echonest${LIBECHONEST_SUFFIX}/Track.h
|
||||
HINTS
|
||||
${PC_ECHONEST_INCLUDEDIR}
|
||||
${PC_ECHONEST_INCLUDE_DIRS}
|
||||
${CMAKE_INSTALL_INCLUDEDIR}
|
||||
${KDE4_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
FIND_LIBRARY(ECHONEST_LIBRARIES NAMES echonest${LIBECHONEST_SUFFIX}
|
||||
HINTS
|
||||
${PC_ECHONEST_LIBDIR}
|
||||
${PC_ECHONEST_LIBRARY_DIRS}
|
||||
${CMAKE_INSTALL_LIBDIR}
|
||||
${KDE4_LIB_DIR}
|
||||
)
|
||||
|
||||
IF(ECHONEST_LIBRARIES AND ECHONEST_INCLUDE_DIR AND NOT PC_ECHONEST_VERSION)
|
||||
MESSAGE(WARNING "You don't have pkg-config and so the libechonest version check does not work!")
|
||||
set(PC_ECHONEST_VERSION "999.9.9")
|
||||
ENDIF()
|
||||
|
||||
INCLUDE(FindPackageHandleStandardArgs)
|
||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Echonest
|
||||
REQUIRED_VARS ECHONEST_LIBRARIES ECHONEST_INCLUDE_DIR
|
||||
VERSION_VAR PC_ECHONEST_VERSION)
|
||||
|
||||
MARK_AS_ADVANCED(ECHONEST_INCLUDE_DIR ECHONEST_LIBRARIES)
|
@@ -79,7 +79,6 @@ Required dependencies:
|
||||
* [TagLib 1.8](https://taglib.github.io/)
|
||||
* [Boost 1.3](http://www.boost.org/)
|
||||
* [Lucene++ 3.0.6](https://github.com/luceneplusplus/LucenePlusPlus/)
|
||||
* [libechonest 2.3.1](http://projects.kde.org/projects/playground/libs/libechonest/)
|
||||
* [Attica 5.6.0](http://ftp.kde.org/stable/attica/)
|
||||
* [QuaZip 0.4.3](http://quazip.sourceforge.net/)
|
||||
* [liblastfm 1.0.9](https://github.com/lastfm/liblastfm/)
|
||||
|
@@ -275,6 +275,9 @@ Tomahawk.Resolver = {
|
||||
getStreamUrl: function (params) {
|
||||
return params;
|
||||
},
|
||||
getDownloadUrl: function (params) {
|
||||
return params;
|
||||
},
|
||||
resolve: function() {
|
||||
},
|
||||
_adapter_resolve: function (params) {
|
||||
@@ -1763,6 +1766,9 @@ Tomahawk.Collection = {
|
||||
this.settings.capabilities = [Tomahawk.Collection.BrowseCapability.Artists,
|
||||
Tomahawk.Collection.BrowseCapability.Albums,
|
||||
Tomahawk.Collection.BrowseCapability.Tracks];
|
||||
if (!this.settings.weight && this.resolver && this.resolver.settings.weight) {
|
||||
this.settings.weight = this.resolver.settings.weight;
|
||||
}
|
||||
return this.settings;
|
||||
},
|
||||
|
||||
@@ -1771,6 +1777,14 @@ Tomahawk.Collection = {
|
||||
return this.resolver.getStreamUrl(params);
|
||||
}
|
||||
|
||||
return params;
|
||||
},
|
||||
|
||||
getDownloadUrl: function(params) {
|
||||
if(this.resolver) {
|
||||
return this.resolver.getDownloadUrl(params);
|
||||
}
|
||||
|
||||
return params;
|
||||
}
|
||||
};
|
||||
|
@@ -44,12 +44,12 @@ namespace Tomahawk {
|
||||
void publishTune( QUrl url, Tomahawk::InfoSystem::InfoStringHash trackInfo );
|
||||
|
||||
public slots:
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) override;
|
||||
|
||||
protected slots:
|
||||
void init();
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
||||
void init() override;
|
||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData ) override;
|
||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) override;
|
||||
|
||||
private slots:
|
||||
void audioStarted( const Tomahawk::InfoSystem::PushInfoPair& pushInfoPair );
|
||||
|
@@ -54,14 +54,14 @@ public:
|
||||
Account::ConnectionState connectionState() const;
|
||||
|
||||
public slots:
|
||||
void connectPlugin();
|
||||
void disconnectPlugin();
|
||||
void connectPlugin() override;
|
||||
void disconnectPlugin() override;
|
||||
|
||||
void advertise();
|
||||
|
||||
virtual void sendSipInfos( const Tomahawk::peerinfo_ptr& /* receiver */, const QList<SipInfo>& /* info */ ) {}
|
||||
virtual void sendSipInfos( const Tomahawk::peerinfo_ptr& /* receiver */, const QList<SipInfo>& /* info */ ) override {}
|
||||
void broadcastMsg( const QString& ) {}
|
||||
bool addContact( const QString&, AddContactOptions, const QString& ) { return false; }
|
||||
bool addContact( const QString&, AddContactOptions, const QString& ) override { return false; }
|
||||
|
||||
private slots:
|
||||
void lanHostFound( const QString& host, int port, const QString& name, const QString& nodeid );
|
||||
|
@@ -1,5 +1,4 @@
|
||||
include_directories(
|
||||
${ECHONEST_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR}
|
||||
)
|
||||
if(WIN32 OR APPLE)
|
||||
@@ -15,14 +14,13 @@ endif()
|
||||
endif(WIN32 OR APPLE)
|
||||
|
||||
list(APPEND simple_plugins
|
||||
Echonest
|
||||
Charts
|
||||
NewReleases
|
||||
Spotify
|
||||
#Spotify
|
||||
Hypem
|
||||
MusixMatch
|
||||
MusicBrainz
|
||||
Rovi
|
||||
#Rovi
|
||||
Discogs
|
||||
)
|
||||
|
||||
|
@@ -80,7 +80,7 @@ FdoNotifyPlugin::FdoNotifyPlugin()
|
||||
, m_wmSupportsBodyMarkup( false )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||
m_supportedPushTypes << InfoNotifyUser << InfoNowPlaying << InfoTrackUnresolved << InfoNowStopped << InfoInboxReceived;
|
||||
m_supportedPushTypes << InfoNotifyUser << InfoNowPlaying << InfoNowResumed << InfoTrackUnresolved << InfoNowStopped << InfoInboxReceived;
|
||||
|
||||
// Query the window manager for its capabilties in styling notifications.
|
||||
notifications_interface = new org::freedesktop::Notifications( "org.freedesktop.Notifications", "/org/freedesktop/Notifications",
|
||||
@@ -139,6 +139,7 @@ FdoNotifyPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
return;
|
||||
|
||||
case Tomahawk::InfoSystem::InfoNowPlaying:
|
||||
case Tomahawk::InfoSystem::InfoNowResumed:
|
||||
nowPlaying( pushData.infoPair.second );
|
||||
return;
|
||||
|
||||
|
@@ -120,9 +120,12 @@ ActionCollection::initActions()
|
||||
m_actionCollection[ "createPlaylist" ] = new QAction( tr( "Create Playlist" ), this );
|
||||
m_actionCollection[ "createPlaylist" ]->setShortcut( QKeySequence( "Ctrl+N" ) );
|
||||
m_actionCollection[ "createPlaylist" ]->setShortcutContext( Qt::ApplicationShortcut );
|
||||
// echonest is dead, disable stations
|
||||
/*
|
||||
m_actionCollection[ "createStation" ] = new QAction( tr( "Create Station" ), this );
|
||||
m_actionCollection[ "createStation" ]->setShortcut( QKeySequence( "Ctrl+S" ) );
|
||||
m_actionCollection[ "createStation" ]->setShortcutContext( Qt::ApplicationShortcut );
|
||||
*/
|
||||
#ifdef Q_OS_MAC
|
||||
m_actionCollection[ "minimize" ] = new QAction( tr( "Minimize" ), this );
|
||||
m_actionCollection[ "minimize" ]->setShortcut( QKeySequence( "Ctrl+M" ) );
|
||||
@@ -171,7 +174,8 @@ ActionCollection::createMenuBar( QWidget *parent )
|
||||
controlsMenu->addAction( m_actionCollection[ "showOfflineSources" ] );
|
||||
controlsMenu->addSeparator();
|
||||
controlsMenu->addAction( m_actionCollection[ "createPlaylist" ] );
|
||||
controlsMenu->addAction( m_actionCollection[ "createStation" ] );
|
||||
// echonest is dead, disable stations
|
||||
// controlsMenu->addAction( m_actionCollection[ "createStation" ] );
|
||||
controlsMenu->addAction( m_actionCollection[ "importPlaylist" ] );
|
||||
controlsMenu->addAction( m_actionCollection[ "updateCollection" ] );
|
||||
controlsMenu->addAction( m_actionCollection[ "rescanCollection" ] );
|
||||
|
@@ -74,9 +74,6 @@ set( libGuiSources
|
||||
playlist/dynamic/DynamicPlaylist.cpp
|
||||
playlist/dynamic/DynamicView.cpp
|
||||
playlist/dynamic/DynamicModel.cpp
|
||||
playlist/dynamic/echonest/EchonestGenerator.cpp
|
||||
playlist/dynamic/echonest/EchonestControl.cpp
|
||||
playlist/dynamic/echonest/EchonestSteerer.cpp
|
||||
playlist/dynamic/widgets/DynamicWidget.cpp
|
||||
playlist/dynamic/widgets/DynamicControlWrapper.cpp
|
||||
playlist/dynamic/widgets/DynamicControlList.cpp
|
||||
@@ -146,6 +143,7 @@ set( libGuiSources
|
||||
widgets/ClickableLabel.cpp
|
||||
widgets/ComboBox.cpp
|
||||
widgets/DropDownButton.cpp
|
||||
widgets/DownloadButton.cpp
|
||||
widgets/ElidedLabel.cpp
|
||||
widgets/FilterHeader.cpp
|
||||
widgets/CaptionLabel.cpp
|
||||
@@ -207,7 +205,6 @@ list(APPEND libSources
|
||||
PlaylistInterface.cpp
|
||||
UrlHandler.cpp
|
||||
|
||||
EchonestCatalogSynchronizer.cpp
|
||||
|
||||
accounts/AccountManager.cpp
|
||||
accounts/Account.cpp
|
||||
@@ -412,7 +409,6 @@ include_directories(
|
||||
|
||||
${QT_INCLUDE_DIR}
|
||||
${QJSON_INCLUDE_DIR}
|
||||
${ECHONEST_INCLUDE_DIR}
|
||||
${LUCENEPP_INCLUDE_DIRS}
|
||||
${LIBVLC_INCLUDE_DIR}
|
||||
${Boost_INCLUDE_DIR}
|
||||
@@ -534,7 +530,6 @@ TARGET_LINK_LIBRARIES( ${TOMAHAWK_LIBRARY}
|
||||
# External deps
|
||||
${QJSON_LIBRARIES}
|
||||
${LUCENEPP_LIBRARIES}
|
||||
${ECHONEST_LIBRARIES}
|
||||
${QT_QTSQL_LIBRARY}
|
||||
${QT_QTUITOOLS_LIBRARY}
|
||||
${QT_QTGUI_LIBRARY}
|
||||
@@ -578,7 +573,7 @@ file( GLOB networkHeaders "network/*.h" )
|
||||
file( GLOB playlistHeaders "playlist/*.h" )
|
||||
file( GLOB playlistDynamicHeaders "playlist/dynamic/*.h" )
|
||||
file( GLOB playlistDynamicDatabaseHeaders "playlist/dynamic/database/*.h" )
|
||||
file( GLOB playlistDynamicEchonestHeaders "playlist/dynamic/echonest/*.h" )
|
||||
# file( GLOB playlistDynamicEchonestHeaders "playlist/dynamic/echonest/*.h" )
|
||||
file( GLOB playlistDynamicWidgetsHeaders "playlist/dynamic/widgets/*.h" )
|
||||
file( GLOB resolversHeaders "resolvers/*.h" )
|
||||
file( GLOB sipHeaders "sip/*.h" )
|
||||
@@ -607,7 +602,7 @@ install( FILES ${networkHeaders} DESTINATION include/libtomahawk/network )
|
||||
install( FILES ${playlistHeaders} DESTINATION include/libtomahawk/playlist )
|
||||
install( FILES ${playlistDynamicHeaders} DESTINATION include/libtomahawk/playlist/dynamic )
|
||||
install( FILES ${playlistDynamicDatabaseHeaders} DESTINATION include/libtomahawk/playlist/dynamic/database )
|
||||
install( FILES ${playlistDynamicEchonestHeaders} DESTINATION include/libtomahawk/playlist/dynamic/echonest )
|
||||
# install( FILES ${playlistDynamicEchonestHeaders} DESTINATION include/libtomahawk/playlist/dynamic/echonest )
|
||||
install( FILES ${playlistDynamicWidgetsHeaders} DESTINATION include/libtomahawk/playlist/dynamic/widgets )
|
||||
install( FILES ${resolversHeaders} DESTINATION include/libtomahawk/resolvers )
|
||||
install( FILES ${sipHeaders} DESTINATION include/libtomahawk/sip )
|
||||
|
@@ -226,8 +226,7 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
if ( m_supportedActions & ActionOpenFileManager &&
|
||||
queries.length() == 1 &&
|
||||
queries.first()->numResults() &&
|
||||
queries.first()->results().first()->resolvedByCollection() &&
|
||||
queries.first()->results().first()->resolvedByCollection()->isLocal() )
|
||||
queries.first()->results().first()->isLocal() )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( ImageRegistry::instance()->icon( RESPATH "images/folder.svg" ),
|
||||
tr( "Open Folder in File Manager..." ) ), ActionOpenFileManager );
|
||||
|
@@ -118,7 +118,7 @@ DownloadJob::localFile() const
|
||||
|
||||
|
||||
QString
|
||||
DownloadJob::localPath() const
|
||||
DownloadJob::localPath( const Tomahawk::album_ptr& album )
|
||||
{
|
||||
QDir dir = TomahawkSettings::instance()->downloadsPath();
|
||||
|
||||
@@ -127,7 +127,7 @@ DownloadJob::localPath() const
|
||||
dir.mkpath( "." );
|
||||
}
|
||||
|
||||
QString path = QString( "%1/%2" ).arg( safeEncode( m_track->artist(), true ) ).arg( safeEncode( m_track->album(), true ) );
|
||||
QString path = QString( "%1/%2" ).arg( safeEncode( album->artist()->name(), true ) ).arg( safeEncode( album->name(), true ) );
|
||||
dir.mkpath( path );
|
||||
|
||||
return QString( dir.path() + "/" + path ).replace( "//", "/" );
|
||||
@@ -138,7 +138,7 @@ QUrl
|
||||
DownloadJob::prepareFilename()
|
||||
{
|
||||
QString filename = QString( "%1. %2.%3" ).arg( m_track->albumpos() ).arg( safeEncode( m_track->track() ) ).arg( m_format.extension );
|
||||
QString path = localPath();
|
||||
QString path = localPath( m_track->albumPtr() );
|
||||
QString localFile = QString( path + "/" + filename );
|
||||
|
||||
if ( !m_tryResuming )
|
||||
@@ -206,22 +206,17 @@ DownloadJob::download()
|
||||
{
|
||||
if ( m_state == Running )
|
||||
return true;
|
||||
|
||||
setState( Running );
|
||||
|
||||
if ( m_result->resolvedByCollection() )
|
||||
{
|
||||
Tomahawk::ScriptCollection* collection = qobject_cast<Tomahawk::ScriptCollection*>( m_result->resolvedByCollection().data() );
|
||||
if ( collection )
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments[ "url" ] = m_format.url;
|
||||
|
||||
// HACK: *shrug* WIP.
|
||||
Tomahawk::ScriptJob* job = collection->scriptObject()->invoke( "getStreamUrl", arguments );
|
||||
connect( job, SIGNAL( done(QVariantMap) ), SLOT( onUrlRetrieved(QVariantMap) ) );
|
||||
job->start();
|
||||
}
|
||||
if (m_result->resolvedBy() != nullptr) {
|
||||
Tomahawk::ScriptJob *job = m_result->resolvedBy()->getDownloadUrl( m_result, m_format );
|
||||
connect( job, SIGNAL( done(QVariantMap) ), SLOT( onUrlRetrieved(QVariantMap) ) );
|
||||
job->start();
|
||||
} else {
|
||||
onUrlRetrieved({{"url", m_format.url}});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -444,7 +439,7 @@ DownloadJob::checkForResumedFile()
|
||||
|
||||
|
||||
QString
|
||||
DownloadJob::safeEncode( const QString& filename, bool removeTrailingDots ) const
|
||||
DownloadJob::safeEncode( const QString& filename, bool removeTrailingDots )
|
||||
{
|
||||
//FIXME: make it a regexp
|
||||
QString res = QString( filename ).toLatin1().replace( "/", "_" ).replace( "\\", "_" )
|
||||
|
@@ -58,7 +58,7 @@ public:
|
||||
long receivedSize() const { return m_rcvdSize; }
|
||||
long fileSize() const { return m_fileSize; }
|
||||
|
||||
QString localPath() const;
|
||||
static QString localPath( const Tomahawk::album_ptr& album );
|
||||
QString localFile() const;
|
||||
DownloadFormat format() const;
|
||||
|
||||
@@ -90,7 +90,7 @@ private slots:
|
||||
|
||||
private:
|
||||
void storeState();
|
||||
QString safeEncode( const QString& filename, bool removeTrailingDots = false ) const;
|
||||
static QString safeEncode( const QString& filename, bool removeTrailingDots = false );
|
||||
bool checkForResumedFile();
|
||||
QUrl prepareFilename();
|
||||
|
||||
|
@@ -24,6 +24,8 @@
|
||||
#include "TomahawkSettings.h"
|
||||
#include "infosystem/InfoSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "Result.h"
|
||||
#include "Query.h"
|
||||
|
||||
DownloadManager* DownloadManager::s_instance = 0;
|
||||
|
||||
@@ -85,6 +87,36 @@ DownloadManager::localFileForDownload( const QString& url ) const
|
||||
}
|
||||
|
||||
|
||||
QUrl
|
||||
DownloadManager::localUrlForDownload( const Tomahawk::query_ptr& query ) const
|
||||
{
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result )
|
||||
{
|
||||
return localUrlForDownload( result );
|
||||
}
|
||||
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
|
||||
QUrl
|
||||
DownloadManager::localUrlForDownload( const Tomahawk::result_ptr& result ) const
|
||||
{
|
||||
if ( result && !result->downloadFormats().isEmpty() &&
|
||||
!localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
return QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ) ).absolutePath() );
|
||||
}
|
||||
else if ( result && result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
return QUrl::fromLocalFile( QFileInfo( result->downloadJob()->localFile() ).absolutePath() );
|
||||
}
|
||||
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadManager::storeJobs( const QList<downloadjob_ptr>& jobs )
|
||||
{
|
||||
|
@@ -45,6 +45,8 @@ public:
|
||||
|
||||
void storeJobs( const QList<downloadjob_ptr>& jobs );
|
||||
QString localFileForDownload( const QString& url ) const;
|
||||
QUrl localUrlForDownload( const Tomahawk::result_ptr& result ) const;
|
||||
QUrl localUrlForDownload( const Tomahawk::query_ptr& query ) const;
|
||||
|
||||
public slots:
|
||||
bool addJob( const downloadjob_ptr& job );
|
||||
|
@@ -980,7 +980,7 @@ DropJob::removeRemoteSources()
|
||||
|
||||
foreach ( const Tomahawk::result_ptr& result, item->results() )
|
||||
{
|
||||
if ( !result->resolvedByCollection().isNull() && !result->resolvedByCollection()->isLocal() )
|
||||
if ( !result->isLocal() )
|
||||
{
|
||||
list.append( item );
|
||||
break;
|
||||
|
@@ -1,14 +1,14 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -20,7 +20,6 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "GlobalActionManager.h"
|
||||
|
||||
#include "accounts/AccountManager.h"
|
||||
@@ -47,12 +46,6 @@
|
||||
#include "TomahawkSettings.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <echonest5/Playlist.h>
|
||||
#else
|
||||
#include <echonest/Playlist.h>
|
||||
#endif
|
||||
|
||||
#include <QMessageBox>
|
||||
#include <QFileInfo>
|
||||
|
||||
@@ -913,144 +906,144 @@ GlobalActionManager::loadDynamicPlaylist( const QUrl& url, bool station )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "artist_limitto" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "description" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Description" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "variety" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Variety" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "tempo" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Tempo" );
|
||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "duration" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Duration" );
|
||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "loudness" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Loudness" );
|
||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "danceability" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Danceability" );
|
||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "energy" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Energy" );
|
||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "artist_familiarity" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Familiarity" );
|
||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "artist_hotttnesss" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Hotttnesss" );
|
||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinHotttnesss + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinHotttnesss + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "song_hotttnesss" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Song Hotttnesss" );
|
||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "longitude" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Longitude" );
|
||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first.startsWith( "latitude" ) )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Latitude" );
|
||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "key" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Key" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "mode" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Mode" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "mood" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Mood" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mood ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mood ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "style" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Style" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Style ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Style ) );
|
||||
// controls << c;
|
||||
}
|
||||
else if ( param.first == "song" )
|
||||
{
|
||||
dyncontrol_ptr c = pl->generator()->createControl( "Song" );
|
||||
c->setInput( param.second );
|
||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongRadioType ) );
|
||||
controls << c;
|
||||
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongRadioType ) );
|
||||
// controls << c;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLOBALACTIONMANAGER_H
|
||||
#define GLOBALACTIONMANAGER_H
|
||||
|
@@ -194,7 +194,7 @@ Query::addResults( const QList< Tomahawk::result_ptr >& newresults )
|
||||
}*/
|
||||
|
||||
d->results << newresults;
|
||||
qStableSort( d->results.begin(), d->results.end(), std::bind( &Query::resultSorter, this, std::placeholders::_1, std::placeholders::_2 ) );
|
||||
sortResults();
|
||||
|
||||
// hook up signals, and check solved status
|
||||
foreach( const result_ptr& rp, newresults )
|
||||
@@ -258,7 +258,7 @@ Query::onResultStatusChanged()
|
||||
Q_D( Query );
|
||||
QMutexLocker lock( &d->mutex );
|
||||
if ( !d->results.isEmpty() )
|
||||
qStableSort( d->results.begin(), d->results.end(), std::bind( &Query::resultSorter, this, std::placeholders::_1, std::placeholders::_2 ) );
|
||||
sortResults();
|
||||
}
|
||||
|
||||
checkResults();
|
||||
@@ -273,6 +273,11 @@ Query::removeResult( const Tomahawk::result_ptr& result )
|
||||
Q_D( Query );
|
||||
QMutexLocker lock( &d->mutex );
|
||||
d->results.removeAll( result );
|
||||
if ( d->preferredResult == result )
|
||||
{
|
||||
d->preferredResult.clear();
|
||||
}
|
||||
sortResults();
|
||||
}
|
||||
|
||||
emit resultsRemoved( result );
|
||||
@@ -396,12 +401,21 @@ Query::id() const
|
||||
bool
|
||||
Query::resultSorter( const result_ptr& left, const result_ptr& right )
|
||||
{
|
||||
Q_D( Query );
|
||||
if ( !d->preferredResult.isNull() )
|
||||
{
|
||||
if ( d->preferredResult == left )
|
||||
return true;
|
||||
if ( d->preferredResult == right )
|
||||
return false;
|
||||
}
|
||||
|
||||
const float ls = left->isOnline() ? howSimilar( left ) : 0.0;
|
||||
const float rs = right->isOnline() ? howSimilar( right ) : 0.0;
|
||||
|
||||
if ( ls == rs )
|
||||
{
|
||||
if ( right->resolvedByCollection() && right->resolvedByCollection()->isLocal() )
|
||||
if ( right->isLocal() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
@@ -427,6 +441,30 @@ Query::resultSorter( const result_ptr& left, const result_ptr& right )
|
||||
}
|
||||
|
||||
|
||||
result_ptr
|
||||
Query::preferredResult() const
|
||||
{
|
||||
Q_D( const Query );
|
||||
return d->preferredResult;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Query::setPreferredResult( const result_ptr& result )
|
||||
{
|
||||
{
|
||||
Q_D( Query );
|
||||
QMutexLocker lock( &d->mutex );
|
||||
|
||||
Q_ASSERT( d->results.contains( result ) );
|
||||
d->preferredResult = result;
|
||||
sortResults();
|
||||
}
|
||||
|
||||
emit resultsChanged();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Query::setCurrentResolver( Tomahawk::Resolver* resolver )
|
||||
{
|
||||
@@ -622,6 +660,10 @@ float
|
||||
Query::howSimilar( const Tomahawk::result_ptr& r )
|
||||
{
|
||||
Q_D( Query );
|
||||
if (d->howSimilarCache.find(r->id()) != d->howSimilarCache.end())
|
||||
{
|
||||
return d->howSimilarCache[r->id()];
|
||||
}
|
||||
// result values
|
||||
const QString& rArtistname = r->track()->artistSortname();
|
||||
const QString& rAlbumname = r->track()->albumSortname();
|
||||
@@ -643,10 +685,12 @@ Query::howSimilar( const Tomahawk::result_ptr& r )
|
||||
qTrackname = queryTrack()->trackSortname();
|
||||
}
|
||||
|
||||
static const QRegExp filterOutChars = QRegExp(QString::fromUtf8("[-`´~!@#$%^&*\\(\\)_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]"));
|
||||
|
||||
//Cleanup symbols for minor naming differences
|
||||
qArtistname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
||||
qTrackname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
||||
qAlbumname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
||||
qArtistname.remove(filterOutChars);
|
||||
qTrackname.remove(filterOutChars);
|
||||
qAlbumname.remove(filterOutChars);
|
||||
|
||||
// normal edit distance
|
||||
const int artdist = TomahawkUtils::levenshtein( qArtistname, rArtistname );
|
||||
@@ -678,12 +722,16 @@ Query::howSimilar( const Tomahawk::result_ptr& r )
|
||||
const int mlatr = qMax( artistTrackname.length(), rArtistTrackname.length() );
|
||||
const float dcatr = (float)( mlatr - atrdist ) / mlatr;
|
||||
|
||||
return qMax( dctrk, qMax( dcatr, qMax( dcart, dcalb ) ) );
|
||||
float resultScore = qMax( dctrk, qMax( dcatr, qMax( dcart, dcalb ) ) );
|
||||
d->howSimilarCache[r->id()] = resultScore;
|
||||
return resultScore;
|
||||
}
|
||||
else
|
||||
{
|
||||
// weighted, so album match is worth less than track title
|
||||
return ( dcart * 4 + dcalb + dctrk * 5 ) / 10;
|
||||
float resultScore = ( dcart * 4 + dcalb + dctrk * 5 ) / 10;
|
||||
d->howSimilarCache[r->id()] = resultScore;
|
||||
return resultScore;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -734,3 +782,11 @@ Query::setWeakRef( QWeakPointer<Query> weakRef )
|
||||
Q_D( Query );
|
||||
d->ownRef = weakRef;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Query::sortResults()
|
||||
{
|
||||
Q_D( Query );
|
||||
qStableSort( d->results.begin(), d->results.end(), std::bind( &Query::resultSorter, this, std::placeholders::_1, std::placeholders::_2 ) );
|
||||
}
|
||||
|
@@ -112,6 +112,8 @@ public:
|
||||
|
||||
/// sorter for list of results
|
||||
bool resultSorter( const result_ptr& left, const result_ptr& right );
|
||||
result_ptr preferredResult() const;
|
||||
void setPreferredResult( const result_ptr& result );
|
||||
|
||||
signals:
|
||||
void resultsAdded( const QList<Tomahawk::result_ptr>& );
|
||||
@@ -158,6 +160,7 @@ private:
|
||||
void setCurrentResolver( Tomahawk::Resolver* resolver );
|
||||
void clearResults();
|
||||
void checkResults();
|
||||
void sortResults();
|
||||
};
|
||||
|
||||
} //ns
|
||||
|
@@ -4,6 +4,7 @@
|
||||
#include "Query.h"
|
||||
|
||||
#include <QMutex>
|
||||
#include <map>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@@ -39,6 +40,7 @@ private:
|
||||
QList< Tomahawk::artist_ptr > artists;
|
||||
QList< Tomahawk::album_ptr > albums;
|
||||
QList< Tomahawk::result_ptr > results;
|
||||
Tomahawk::result_ptr preferredResult;
|
||||
|
||||
float score;
|
||||
bool solved;
|
||||
@@ -58,6 +60,8 @@ private:
|
||||
|
||||
mutable QMutex mutex;
|
||||
QWeakPointer< Tomahawk::Query > ownRef;
|
||||
|
||||
std::map<QString, float> howSimilarCache;
|
||||
};
|
||||
|
||||
} // Tomahawk
|
||||
|
@@ -234,6 +234,13 @@ Result::playable() const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Result::isLocal() const
|
||||
{
|
||||
return resolvedByCollection().isNull() ? false : resolvedByCollection()->isLocal();
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
Result::toVariant() const
|
||||
{
|
||||
|
@@ -94,6 +94,12 @@ public:
|
||||
bool isOnline() const;
|
||||
bool playable() const;
|
||||
|
||||
/**
|
||||
* @brief whether this result isLocal, i.e. resolved by a local collection
|
||||
* @return isLocal
|
||||
*/
|
||||
bool isLocal() const;
|
||||
|
||||
QString url() const;
|
||||
/**
|
||||
* Has the given url been checked that it is accessible/valid.
|
||||
|
@@ -1764,3 +1764,15 @@ TomahawkSettings::setPlaydarKey( const QByteArray& key )
|
||||
setValue( "playdar/key", key );
|
||||
}
|
||||
|
||||
QString
|
||||
TomahawkSettings::vlcArguments() const
|
||||
{
|
||||
return value( "vlc/cmdline_args" ).value< QString >();
|
||||
}
|
||||
|
||||
void
|
||||
TomahawkSettings::setVlcArguments( const QString& args )
|
||||
{
|
||||
setValue( "vlc/cmdline_args", args);
|
||||
}
|
||||
|
||||
|
@@ -253,6 +253,10 @@ public:
|
||||
QByteArray playdarKey() const;
|
||||
void setPlaydarKey( const QByteArray& key );
|
||||
|
||||
// VLC Settings
|
||||
QString vlcArguments() const;
|
||||
void setVlcArguments( const QString& arguments );
|
||||
|
||||
signals:
|
||||
void changed();
|
||||
void recentlyPlayedPlaylistAdded( const QString& playlistId, int sourceId );
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
*
|
||||
@@ -572,10 +572,10 @@ AudioEngine::onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type )
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
AudioEngine::loadTrack( const Tomahawk::result_ptr& result, bool preload )
|
||||
{
|
||||
Q_D( AudioEngine );
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() );
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ) << " preload:" << preload;
|
||||
|
||||
|
||||
if ( !d->audioOutput->isInitialized() )
|
||||
@@ -589,36 +589,82 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
return;
|
||||
}
|
||||
|
||||
// We do this to stop the audio as soon as a user activated another track
|
||||
// If we don't block the audioOutput signals, the state change will trigger
|
||||
// loading yet another track
|
||||
d->audioOutput->blockSignals( true );
|
||||
d->audioOutput->stop();
|
||||
d->audioOutput->blockSignals( false );
|
||||
if (preload && d->preloadedTrack == result)
|
||||
return;
|
||||
|
||||
setCurrentTrack( result );
|
||||
if (preload)
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << "not preloaded yet, preloading";
|
||||
|
||||
if (preload)
|
||||
{
|
||||
setPreloadTrack( result );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We do this to stop the audio as soon as a user activated another track
|
||||
// If we don't block the audioOutput signals, the state change will trigger
|
||||
// loading yet another track
|
||||
d->audioOutput->blockSignals( true );
|
||||
d->audioOutput->stop();
|
||||
d->audioOutput->blockSignals( false );
|
||||
|
||||
setCurrentTrack( result );
|
||||
if ( result == d->preloadedTrack )
|
||||
{
|
||||
setPreloadTrack( Tomahawk::result_ptr(nullptr) );
|
||||
d->state = Loading;
|
||||
emit loading( d->currentTrack );
|
||||
d->audioOutput->switchToPreloadedMedia();
|
||||
if ( !d->input.isNull() )
|
||||
{
|
||||
d->input->close();
|
||||
d->input.clear();
|
||||
}
|
||||
d->input = d->inputPreloaded;
|
||||
|
||||
d->audioOutput->play();
|
||||
|
||||
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
|
||||
{
|
||||
d->currentTrack->track()->startPlaying();
|
||||
}
|
||||
|
||||
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
|
||||
return;
|
||||
}
|
||||
setPreloadTrack( Tomahawk::result_ptr(nullptr) );
|
||||
}
|
||||
|
||||
ScriptJob* job = result->resolvedBy()->getStreamUrl( result );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( gotStreamUrl( QVariantMap ) ) );
|
||||
job->setProperty( "result", QVariant::fromValue( result ) );
|
||||
job->setProperty( "isPreload", QVariant::fromValue(preload) );
|
||||
tDebug() << "preload:" << preload << ", for result:" << result;
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::gotStreamUrl( const QVariantMap& data )
|
||||
{
|
||||
QString streamUrl = data[ "url" ].toString();
|
||||
QVariantMap headers = data[ "headers" ].toMap();
|
||||
Tomahawk::result_ptr result = sender()->property( "result" ).value<result_ptr>();
|
||||
bool isPreload = sender()->property( "isPreload" ).value<bool>();
|
||||
|
||||
if ( streamUrl.isEmpty() || !( TomahawkUtils::isHttpResult( streamUrl ) || TomahawkUtils::isHttpsResult( streamUrl ) ) )
|
||||
tDebug() << Q_FUNC_INFO << " is preload:" << isPreload << ", for result:" << result;
|
||||
|
||||
if ( streamUrl.isEmpty() || headers.isEmpty() ||
|
||||
!( TomahawkUtils::isHttpResult( streamUrl ) || TomahawkUtils::isHttpsResult( streamUrl ) ) )
|
||||
{
|
||||
// Not an http(s) or RTMP URL, get IO device
|
||||
// We can't supply custom headers to VLC - but prefer using its HTTP streaming due to improved seeking ability
|
||||
// Not an RTMP or HTTP-with-headers URL, get IO device
|
||||
QSharedPointer< QIODevice > sp;
|
||||
performLoadIODevice( result, streamUrl );
|
||||
performLoadIODevice( result, streamUrl, isPreload );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need our own QIODevice for streaming
|
||||
// TODO: just make this part of the http(s) IoDeviceFactory (?)
|
||||
QUrl url = QUrl::fromEncoded( streamUrl.toUtf8() );
|
||||
QNetworkRequest req( url );
|
||||
@@ -640,35 +686,42 @@ AudioEngine::gotStreamUrl( const QVariantMap& data )
|
||||
|
||||
tDebug() << "Creating a QNetworkReply with url:" << req.url().toString();
|
||||
NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( req ) );
|
||||
NewClosure( reply, SIGNAL( finalUrlReached() ), this, SLOT( gotRedirectedStreamUrl( Tomahawk::result_ptr, NetworkReply* )), result, reply );
|
||||
NewClosure( reply, SIGNAL( finalUrlReached() ), this, SLOT( gotRedirectedStreamUrl( Tomahawk::result_ptr, NetworkReply* ) ), result, reply );
|
||||
}
|
||||
|
||||
sender()->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::gotRedirectedStreamUrl( const Tomahawk::result_ptr& result, NetworkReply* reply )
|
||||
{
|
||||
Q_D( AudioEngine );
|
||||
// std::functions cannot accept temporaries as parameters
|
||||
QSharedPointer< QIODevice > sp ( reply->reply(), &QObject::deleteLater );
|
||||
QString url = reply->reply()->url().toString();
|
||||
reply->disconnectFromReply();
|
||||
reply->deleteLater();
|
||||
|
||||
performLoadTrack( result, url, sp );
|
||||
bool isPreload = result == d->preloadedTrack;
|
||||
tDebug() << Q_FUNC_INFO << " is preload:" << isPreload;
|
||||
|
||||
performLoadTrack( result, url, sp, isPreload );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::onPositionChanged( float new_position )
|
||||
{
|
||||
if ( new_position >= 0.90 )
|
||||
loadNextTrack(true);
|
||||
// tDebug() << Q_FUNC_INFO << new_position << state();
|
||||
emit trackPosition( new_position );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url )
|
||||
AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url, bool preload )
|
||||
{
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : url );
|
||||
|
||||
@@ -678,37 +731,39 @@ AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url )
|
||||
std::function< void ( const QString, QSharedPointer< QIODevice > ) > callback =
|
||||
std::bind( &AudioEngine::performLoadTrack, this, result,
|
||||
std::placeholders::_1,
|
||||
std::placeholders::_2 );
|
||||
std::placeholders::_2,
|
||||
preload );
|
||||
Tomahawk::UrlHandler::getIODeviceForUrl( result, url, callback );
|
||||
}
|
||||
else
|
||||
{
|
||||
QSharedPointer< QIODevice > io;
|
||||
performLoadTrack( result, url, io );
|
||||
performLoadTrack( result, url, io, preload );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io )
|
||||
AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io, bool preload )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "performLoadTrack", Qt::QueuedConnection,
|
||||
Q_ARG( const Tomahawk::result_ptr, result ),
|
||||
Q_ARG( const QString, url ),
|
||||
Q_ARG( QSharedPointer< QIODevice >, io )
|
||||
Q_ARG( QSharedPointer< QIODevice >, io ),
|
||||
Q_ARG( bool, preload )
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Q_D( AudioEngine );
|
||||
if ( currentTrack() != result )
|
||||
if ( !preload && currentTrack() != result )
|
||||
{
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Track loaded too late, skip.";
|
||||
return;
|
||||
}
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() );
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ) << preload;
|
||||
QSharedPointer< QIODevice > ioToKeep = io;
|
||||
|
||||
bool err = false;
|
||||
@@ -722,9 +777,16 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
||||
|
||||
if ( !err )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Starting new song:" << url;
|
||||
d->state = Loading;
|
||||
emit loading( d->currentTrack );
|
||||
if (preload)
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Preloading new song:" << url;
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Starting new song:" << url;
|
||||
d->state = Loading;
|
||||
emit loading( d->currentTrack );
|
||||
}
|
||||
|
||||
if ( !TomahawkUtils::isLocalResult( url )
|
||||
&& !( TomahawkUtils::isHttpResult( url ) && io.isNull() )
|
||||
@@ -733,18 +795,18 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
||||
QSharedPointer<QNetworkReply> qnr = io.objectCast<QNetworkReply>();
|
||||
if ( !qnr.isNull() )
|
||||
{
|
||||
d->audioOutput->setCurrentSource( new QNR_IODeviceStream( qnr, this ) );
|
||||
d->audioOutput->setCurrentSource( new QNR_IODeviceStream( qnr, this ), preload );
|
||||
// We keep track of the QNetworkReply in QNR_IODeviceStream
|
||||
// and AudioOutput handles the deletion of the
|
||||
// QNR_IODeviceStream object
|
||||
ioToKeep.clear();
|
||||
d->audioOutput->setAutoDelete( true );
|
||||
d->audioOutput->setAutoDelete( true, preload );
|
||||
}
|
||||
else
|
||||
{
|
||||
d->audioOutput->setCurrentSource( io.data() );
|
||||
d->audioOutput->setCurrentSource( io.data(), preload);
|
||||
// We handle the deletion via tracking in d->input
|
||||
d->audioOutput->setAutoDelete( false );
|
||||
d->audioOutput->setAutoDelete( false, preload);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -763,7 +825,7 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
||||
}
|
||||
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Passing to VLC:" << furl;
|
||||
d->audioOutput->setCurrentSource( furl );
|
||||
d->audioOutput->setCurrentSource( furl, preload );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -772,26 +834,37 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
||||
furl = furl.right( furl.length() - 7 );
|
||||
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Passing to VLC:" << QUrl::fromLocalFile( furl );
|
||||
d->audioOutput->setCurrentSource( QUrl::fromLocalFile( furl ) );
|
||||
d->audioOutput->setCurrentSource( QUrl::fromLocalFile( furl ), preload );
|
||||
}
|
||||
|
||||
d->audioOutput->setAutoDelete( true );
|
||||
d->audioOutput->setAutoDelete( true, preload );
|
||||
}
|
||||
|
||||
if ( !d->input.isNull() )
|
||||
if ( preload ) {
|
||||
if ( !d->inputPreloaded.isNull() )
|
||||
{
|
||||
d->inputPreloaded->close();
|
||||
d->inputPreloaded.clear();
|
||||
}
|
||||
d->inputPreloaded = ioToKeep;
|
||||
}
|
||||
else
|
||||
{
|
||||
d->input->close();
|
||||
d->input.clear();
|
||||
}
|
||||
d->input = ioToKeep;
|
||||
d->audioOutput->play();
|
||||
if ( !d->input.isNull() )
|
||||
{
|
||||
d->input->close();
|
||||
d->input.clear();
|
||||
}
|
||||
d->input = ioToKeep;
|
||||
d->audioOutput->play();
|
||||
|
||||
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
|
||||
{
|
||||
d->currentTrack->track()->startPlaying();
|
||||
}
|
||||
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
|
||||
{
|
||||
d->currentTrack->track()->startPlaying();
|
||||
}
|
||||
|
||||
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
|
||||
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -801,7 +874,10 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
||||
return;
|
||||
}
|
||||
|
||||
d->waitingOnNewTrack = false;
|
||||
if ( !preload )
|
||||
{
|
||||
d->waitingOnNewTrack = false;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -833,18 +909,19 @@ AudioEngine::loadPreviousTrack()
|
||||
}
|
||||
|
||||
if ( result )
|
||||
loadTrack( result );
|
||||
loadTrack( result, false );
|
||||
else
|
||||
stop();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::loadNextTrack()
|
||||
AudioEngine::loadNextTrack( bool preload )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
QMetaObject::invokeMethod( this, "loadNextTrack", Qt::QueuedConnection );
|
||||
QMetaObject::invokeMethod( this, "loadNextTrack", Qt::QueuedConnection,
|
||||
Q_ARG( bool, preload ));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -858,8 +935,11 @@ AudioEngine::loadNextTrack()
|
||||
{
|
||||
if ( d->stopAfterTrack->track()->equals( d->currentTrack->track() ) )
|
||||
{
|
||||
d->stopAfterTrack.clear();
|
||||
stop();
|
||||
if ( !preload )
|
||||
{
|
||||
d->stopAfterTrack.clear();
|
||||
stop();
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -877,17 +957,24 @@ AudioEngine::loadNextTrack()
|
||||
|
||||
if ( d->playlist.data()->nextResult() )
|
||||
{
|
||||
result = d->playlist.data()->setSiblingResult( 1 );
|
||||
setCurrentTrackPlaylist( d->playlist );
|
||||
if ( preload )
|
||||
{
|
||||
result = d->playlist.data()->nextResult();
|
||||
}
|
||||
else
|
||||
{
|
||||
result = d->playlist.data()->setSiblingResult( 1 );
|
||||
setCurrentTrackPlaylist( d->playlist );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( result )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Got next item, loading track";
|
||||
loadTrack( result );
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Got next item, loading track, preload:" << preload;
|
||||
loadTrack( result, preload );
|
||||
}
|
||||
else
|
||||
else if ( !preload )
|
||||
{
|
||||
if ( !d->playlist.isNull() && d->playlist.data()->retryMode() == Tomahawk::PlaylistModes::Retry )
|
||||
d->waitingOnNewTrack = true;
|
||||
@@ -956,7 +1043,7 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
|
||||
|
||||
if ( result )
|
||||
{
|
||||
loadTrack( result );
|
||||
loadTrack( result, false );
|
||||
}
|
||||
else if ( !d->playlist.isNull() && d->playlist.data()->retryMode() == PlaylistModes::Retry )
|
||||
{
|
||||
@@ -1231,6 +1318,14 @@ AudioEngine::setStopAfterTrack( const query_ptr& query )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::setPreloadTrack( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
Q_D( AudioEngine );
|
||||
|
||||
d->preloadedTrack = result;
|
||||
}
|
||||
|
||||
void
|
||||
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
||||
{
|
||||
@@ -1257,7 +1352,6 @@ AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::setState( AudioState state )
|
||||
{
|
||||
|
@@ -135,10 +135,10 @@ public slots:
|
||||
void toggleMute();
|
||||
|
||||
void play( const QUrl& url );
|
||||
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery = Tomahawk::query_ptr() );
|
||||
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query );
|
||||
void playItem( const Tomahawk::artist_ptr& artist );
|
||||
void playItem( const Tomahawk::album_ptr& album );
|
||||
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery = Tomahawk::query_ptr());
|
||||
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query);
|
||||
void playItem( const Tomahawk::artist_ptr& artist);
|
||||
void playItem( const Tomahawk::album_ptr& album);
|
||||
void playPlaylistInterface( const Tomahawk::playlistinterface_ptr& playlist );
|
||||
void setPlaylist( Tomahawk::playlistinterface_ptr playlist );
|
||||
void setQueue( const Tomahawk::playlistinterface_ptr& queue );
|
||||
@@ -182,21 +182,22 @@ signals:
|
||||
void error( AudioEngine::AudioErrorCode errorCode );
|
||||
|
||||
private slots:
|
||||
void loadTrack( const Tomahawk::result_ptr& result ); //async!
|
||||
void loadTrack( const Tomahawk::result_ptr& result, bool preload ); //async!
|
||||
void gotStreamUrl( const QVariantMap& data );
|
||||
void gotRedirectedStreamUrl( const Tomahawk::result_ptr& result, NetworkReply* reply );
|
||||
|
||||
|
||||
void performLoadIODevice( const Tomahawk::result_ptr& result, const QString& url ); //only call from loadTrack kthxbi
|
||||
void performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io ); //only call from loadTrack or performLoadIODevice kthxbi
|
||||
void performLoadIODevice( const Tomahawk::result_ptr& result, const QString& url, bool preload ); //only call from loadTrack kthxbi
|
||||
void performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io, bool preload ); //only call from loadTrack or performLoadIODevice kthxbi
|
||||
void loadPreviousTrack();
|
||||
void loadNextTrack();
|
||||
void loadNextTrack(bool preload = false);
|
||||
|
||||
void onVolumeChanged( qreal volume );
|
||||
void timerTriggered( qint64 time );
|
||||
void onPositionChanged( float new_position );
|
||||
|
||||
void setCurrentTrack( const Tomahawk::result_ptr& result );
|
||||
void setPreloadTrack( const Tomahawk::result_ptr& result );
|
||||
void onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type );
|
||||
void onPlaylistNextTrackAvailable();
|
||||
|
||||
|
@@ -28,9 +28,11 @@ public slots:
|
||||
|
||||
private:
|
||||
QSharedPointer<QIODevice> input;
|
||||
QSharedPointer<QIODevice> inputPreloaded;
|
||||
|
||||
Tomahawk::query_ptr stopAfterTrack;
|
||||
Tomahawk::result_ptr currentTrack;
|
||||
Tomahawk::result_ptr preloadedTrack;
|
||||
Tomahawk::playlistinterface_ptr playlist;
|
||||
Tomahawk::playlistinterface_ptr currentTrackPlaylist;
|
||||
Tomahawk::playlistinterface_ptr queue;
|
||||
|
@@ -22,6 +22,7 @@
|
||||
#include "AudioEngine.h"
|
||||
#include "AudioOutput.h"
|
||||
#include "TomahawkVersion.h"
|
||||
#include "TomahawkSettings.h"
|
||||
|
||||
#include "audio/MediaStream.h"
|
||||
#include "utils/Logger.h"
|
||||
@@ -35,10 +36,12 @@
|
||||
|
||||
#include <vlc/libvlc.h>
|
||||
#include <vlc/libvlc_media.h>
|
||||
#include <vlc/libvlc_media_player.h>
|
||||
#include <vlc/libvlc_events.h>
|
||||
#include <vlc/libvlc_media_player.h>
|
||||
#include <vlc/libvlc_version.h>
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
AudioOutput* AudioOutput::s_instance = 0;
|
||||
|
||||
|
||||
@@ -53,9 +56,11 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_currentState( Stopped )
|
||||
, m_currentStream( nullptr )
|
||||
, m_preloadedStream( nullptr )
|
||||
, m_seekable( true )
|
||||
, m_muted( false )
|
||||
, m_autoDelete( true )
|
||||
, m_preloadedAutoDelete( true )
|
||||
, m_volume( 1.0 )
|
||||
, m_currentTime( 0 )
|
||||
, m_totalTime( 0 )
|
||||
@@ -65,6 +70,8 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
, m_vlcInstance( nullptr )
|
||||
, m_vlcPlayer( nullptr )
|
||||
, m_vlcMedia( nullptr )
|
||||
, m_vlcPreloadedPlayer( nullptr )
|
||||
, m_vlcPreloadedMedia( nullptr )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
@@ -72,7 +79,7 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
|
||||
qRegisterMetaType<AudioOutput::AudioState>("AudioOutput::AudioState");
|
||||
|
||||
const char* vlcArgs[] = {
|
||||
QVector<const char*> vlcArgs = {
|
||||
"--ignore-config",
|
||||
"--extraintf=logger",
|
||||
qApp->arguments().contains( "--verbose" ) ? "--verbose=3" : "",
|
||||
@@ -84,11 +91,28 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
// "--no-snapshot-preview",
|
||||
// "--services-discovery=''",
|
||||
"--no-video",
|
||||
//"--network-caching=10000",
|
||||
//"--file-caching=10000",
|
||||
//"--clock-synchro=0",
|
||||
//"--cr-average=10000",
|
||||
//"--clock-jitter=1",
|
||||
"--no-xlib"
|
||||
};
|
||||
TomahawkSettings* s = TomahawkSettings::instance();
|
||||
//Save a list of Latin1 byte arrays for additional args
|
||||
auto additionalVlcArgs = s->vlcArguments().split(",");
|
||||
QVector<QByteArray> additionalArgsChar;
|
||||
|
||||
std::transform(additionalVlcArgs.begin(), additionalVlcArgs.end(),
|
||||
std::back_inserter(additionalArgsChar), [](QString str) { return str.toLatin1(); });
|
||||
|
||||
for (auto&& str : additionalArgsChar)
|
||||
{
|
||||
vlcArgs.append(str.constData());
|
||||
}
|
||||
|
||||
// Create and initialize a libvlc instance (it should be done only once)
|
||||
m_vlcInstance = libvlc_new( sizeof(vlcArgs) / sizeof(*vlcArgs), vlcArgs );
|
||||
m_vlcInstance = libvlc_new( vlcArgs.size(), vlcArgs.constData() );
|
||||
if ( !m_vlcInstance )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "libVLC: could not initialize";
|
||||
@@ -103,37 +127,46 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
#endif
|
||||
|
||||
m_vlcPlayer = libvlc_media_player_new( m_vlcInstance );
|
||||
libvlc_event_manager_t* manager = libvlc_media_player_event_manager( m_vlcPlayer );
|
||||
libvlc_event_type_t events[] = {
|
||||
libvlc_MediaPlayerMediaChanged,
|
||||
libvlc_MediaPlayerNothingSpecial,
|
||||
libvlc_MediaPlayerOpening,
|
||||
libvlc_MediaPlayerBuffering,
|
||||
libvlc_MediaPlayerPlaying,
|
||||
libvlc_MediaPlayerPaused,
|
||||
libvlc_MediaPlayerStopped,
|
||||
libvlc_MediaPlayerForward,
|
||||
libvlc_MediaPlayerBackward,
|
||||
libvlc_MediaPlayerEndReached,
|
||||
libvlc_MediaPlayerEncounteredError,
|
||||
libvlc_MediaPlayerTimeChanged,
|
||||
libvlc_MediaPlayerPositionChanged,
|
||||
libvlc_MediaPlayerSeekableChanged,
|
||||
libvlc_MediaPlayerPausableChanged,
|
||||
libvlc_MediaPlayerTitleChanged,
|
||||
libvlc_MediaPlayerSnapshotTaken,
|
||||
//libvlc_MediaPlayerLengthChanged,
|
||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||
libvlc_MediaPlayerAudioVolume,
|
||||
libvlc_MediaPlayerMuted,
|
||||
libvlc_MediaPlayerUnmuted,
|
||||
#endif
|
||||
libvlc_MediaPlayerVout
|
||||
};
|
||||
const int eventCount = sizeof(events) / sizeof( *events );
|
||||
for ( int i = 0; i < eventCount; i++ )
|
||||
m_vlcPreloadedPlayer = libvlc_media_player_new( m_vlcInstance );
|
||||
|
||||
for( auto player : { m_vlcPlayer, m_vlcPreloadedPlayer } )
|
||||
{
|
||||
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
||||
libvlc_audio_set_mute( player, 0 );
|
||||
{
|
||||
libvlc_event_manager_t* current_manager = libvlc_media_player_event_manager( player );
|
||||
libvlc_event_manager_t* new_manager = libvlc_media_player_event_manager( player );
|
||||
static libvlc_event_type_t events[] = {
|
||||
libvlc_MediaPlayerMediaChanged,
|
||||
libvlc_MediaPlayerNothingSpecial,
|
||||
libvlc_MediaPlayerOpening,
|
||||
libvlc_MediaPlayerBuffering,
|
||||
libvlc_MediaPlayerPlaying,
|
||||
libvlc_MediaPlayerPaused,
|
||||
libvlc_MediaPlayerStopped,
|
||||
libvlc_MediaPlayerForward,
|
||||
libvlc_MediaPlayerBackward,
|
||||
libvlc_MediaPlayerEndReached,
|
||||
libvlc_MediaPlayerEncounteredError,
|
||||
libvlc_MediaPlayerTimeChanged,
|
||||
libvlc_MediaPlayerPositionChanged,
|
||||
libvlc_MediaPlayerSeekableChanged,
|
||||
libvlc_MediaPlayerPausableChanged,
|
||||
libvlc_MediaPlayerTitleChanged,
|
||||
libvlc_MediaPlayerSnapshotTaken,
|
||||
//libvlc_MediaPlayerLengthChanged,
|
||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||
libvlc_MediaPlayerAudioVolume,
|
||||
libvlc_MediaPlayerMuted,
|
||||
libvlc_MediaPlayerUnmuted,
|
||||
#endif
|
||||
libvlc_MediaPlayerVout
|
||||
};
|
||||
const int eventCount = sizeof(events) / sizeof( *events );
|
||||
for ( int i = 0; i < eventCount; i++ )
|
||||
{
|
||||
libvlc_event_attach( new_manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: play silent ogg file and set volume on that to workaround vlc not allowing to set volume before a file is played
|
||||
@@ -141,7 +174,9 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
Q_ASSERT( m_silenceFile.exists() );
|
||||
Q_ASSERT( m_silenceFile.open( QIODevice::ReadOnly ) );
|
||||
|
||||
setCurrentSource( new MediaStream( &m_silenceFile, true ) );
|
||||
setCurrentSource( new MediaStream( &m_silenceFile, true ), false );
|
||||
setCurrentSource( new MediaStream( &m_silenceFile, true ), true );
|
||||
|
||||
libvlc_media_player_play( m_vlcPlayer );
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,4,0)
|
||||
@@ -149,24 +184,71 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
QTimer::singleShot( 15000, [&]()
|
||||
{
|
||||
if ( !m_initialized ) {
|
||||
m_initialized = true;
|
||||
m_initialized = 2;
|
||||
emit initialized();
|
||||
}
|
||||
} );
|
||||
#endif
|
||||
}
|
||||
|
||||
void AudioOutput::switchToPreloadedMedia( void )
|
||||
{
|
||||
|
||||
//Swap
|
||||
auto tempPlayer = m_vlcPreloadedPlayer;
|
||||
m_vlcPreloadedPlayer = m_vlcPlayer;
|
||||
m_vlcPlayer = tempPlayer;
|
||||
|
||||
libvlc_media_player_stop( m_vlcPreloadedPlayer );
|
||||
|
||||
if ( m_vlcMedia != nullptr )
|
||||
{
|
||||
libvlc_media_release( m_vlcMedia );
|
||||
}
|
||||
//Now Media
|
||||
{
|
||||
if ( m_autoDelete && m_currentStream != nullptr )
|
||||
{
|
||||
delete m_currentStream;
|
||||
}
|
||||
|
||||
m_vlcMedia = m_vlcPreloadedMedia;
|
||||
m_vlcPreloadedMedia = nullptr;
|
||||
m_currentStream = m_preloadedStream;
|
||||
m_preloadedStream = nullptr;
|
||||
m_autoDelete = m_preloadedAutoDelete;
|
||||
|
||||
m_totalTime = libvlc_media_get_duration( m_vlcMedia );
|
||||
|
||||
m_currentTime = 0;
|
||||
m_justSeeked = false;
|
||||
m_seekable = true;
|
||||
}
|
||||
|
||||
libvlc_media_player_set_position( m_vlcPlayer, 0.0 );
|
||||
}
|
||||
|
||||
AudioOutput::~AudioOutput()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
if ( m_vlcPreloadedPlayer != nullptr )
|
||||
{
|
||||
libvlc_media_player_stop( m_vlcPreloadedPlayer );
|
||||
libvlc_media_player_release( m_vlcPreloadedPlayer );
|
||||
m_vlcPreloadedPlayer = nullptr;
|
||||
}
|
||||
if ( m_vlcPlayer != nullptr )
|
||||
{
|
||||
libvlc_media_player_stop( m_vlcPlayer );
|
||||
libvlc_media_player_release( m_vlcPlayer );
|
||||
m_vlcPlayer = nullptr;
|
||||
}
|
||||
if ( m_vlcPreloadedMedia != nullptr )
|
||||
{
|
||||
libvlc_media_release( m_vlcPreloadedMedia );
|
||||
m_vlcPreloadedMedia = nullptr;
|
||||
}
|
||||
if ( m_vlcMedia != nullptr )
|
||||
{
|
||||
libvlc_media_release( m_vlcMedia );
|
||||
@@ -188,11 +270,19 @@ AudioOutput::onInitVlcEvent( const libvlc_event_t* event )
|
||||
setVolume( volume() );
|
||||
setMuted( isMuted() );
|
||||
|
||||
m_initialized = true;
|
||||
m_silenceFile.close();
|
||||
m_initialized ++;
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "Init OK";
|
||||
emit initialized();
|
||||
if (m_initialized >=2)
|
||||
{
|
||||
m_silenceFile.close();
|
||||
emit initialized();
|
||||
}
|
||||
else
|
||||
{
|
||||
switchToPreloadedMedia();
|
||||
libvlc_media_player_play( m_vlcPlayer );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -202,23 +292,26 @@ AudioOutput::onInitVlcEvent( const libvlc_event_t* event )
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::setAutoDelete( bool ad )
|
||||
AudioOutput::setAutoDelete( bool ad, bool preload )
|
||||
{
|
||||
m_autoDelete = ad;
|
||||
if (preload)
|
||||
m_preloadedAutoDelete = ad;
|
||||
else
|
||||
m_autoDelete = ad;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::setCurrentSource( const QUrl& stream )
|
||||
AudioOutput::setCurrentSource( const QUrl& stream, bool preload )
|
||||
{
|
||||
setCurrentSource( new MediaStream( stream ) );
|
||||
setCurrentSource( new MediaStream( stream ), preload );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::setCurrentSource( QIODevice* stream )
|
||||
AudioOutput::setCurrentSource( QIODevice* stream, bool preload )
|
||||
{
|
||||
setCurrentSource( new MediaStream( stream ) );
|
||||
setCurrentSource( new MediaStream( stream ), preload );
|
||||
}
|
||||
|
||||
|
||||
@@ -238,29 +331,24 @@ readDoneCallback( void* data, const char* cookie, size_t bufferSize, void* buffe
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::setCurrentSource( MediaStream* stream )
|
||||
AudioOutput::setCurrentSource( MediaStream* stream, bool preload )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
tDebug() << Q_FUNC_INFO << ", preload = " << preload;
|
||||
|
||||
setState( Loading );
|
||||
if ( !preload )
|
||||
setState( Loading );
|
||||
|
||||
if ( m_vlcMedia != nullptr )
|
||||
{
|
||||
// Ensure playback is stopped, then release media
|
||||
libvlc_media_player_stop( m_vlcPlayer );
|
||||
libvlc_media_release( m_vlcMedia );
|
||||
m_vlcMedia = nullptr;
|
||||
if ( m_vlcPreloadedMedia ) {
|
||||
libvlc_media_player_stop( m_vlcPreloadedPlayer );
|
||||
libvlc_media_release( m_vlcPreloadedMedia );
|
||||
m_vlcPreloadedMedia = nullptr;
|
||||
}
|
||||
if ( m_autoDelete && m_currentStream != nullptr )
|
||||
if ( m_preloadedAutoDelete && m_preloadedStream != nullptr )
|
||||
{
|
||||
delete m_currentStream;
|
||||
delete m_preloadedStream;
|
||||
}
|
||||
|
||||
m_currentStream = stream;
|
||||
m_totalTime = 0;
|
||||
m_currentTime = 0;
|
||||
m_justSeeked = false;
|
||||
m_seekable = true;
|
||||
m_preloadedStream = stream;
|
||||
|
||||
QByteArray url;
|
||||
switch ( stream->type() )
|
||||
@@ -294,34 +382,19 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "MediaStream::Final Url:" << url;
|
||||
|
||||
m_vlcMedia = libvlc_media_new_location( m_vlcInstance, url.constData() );
|
||||
libvlc_event_manager_t* manager = libvlc_media_event_manager( m_vlcMedia );
|
||||
libvlc_event_type_t events[] = {
|
||||
libvlc_MediaDurationChanged,
|
||||
};
|
||||
const int eventCount = sizeof(events) / sizeof( *events );
|
||||
for ( int i = 0; i < eventCount; i++ )
|
||||
m_vlcPreloadedMedia = libvlc_media_new_location( m_vlcInstance, url.constData() );
|
||||
if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice )
|
||||
{
|
||||
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
||||
}
|
||||
|
||||
libvlc_media_player_set_media( m_vlcPlayer, m_vlcMedia );
|
||||
|
||||
if ( stream->type() == MediaStream::Url )
|
||||
{
|
||||
m_totalTime = libvlc_media_get_duration( m_vlcMedia );
|
||||
}
|
||||
else if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice )
|
||||
{
|
||||
libvlc_media_add_option_flag(m_vlcMedia, "imem-cat=4", libvlc_media_option_trusted);
|
||||
const char* imemData = QString( "imem-data=%1" ).arg( (uintptr_t)stream ).toLatin1().constData();
|
||||
libvlc_media_add_option_flag(m_vlcMedia, imemData, libvlc_media_option_trusted);
|
||||
const char* imemGet = QString( "imem-get=%1" ).arg( (uintptr_t)&readCallback ).toLatin1().constData();
|
||||
libvlc_media_add_option_flag(m_vlcMedia, imemGet, libvlc_media_option_trusted);
|
||||
const char* imemRelease = QString( "imem-release=%1" ).arg( (uintptr_t)&readDoneCallback ).toLatin1().constData();
|
||||
libvlc_media_add_option_flag(m_vlcMedia, imemRelease, libvlc_media_option_trusted);
|
||||
const char* imemSeek = QString( "imem-seek=%1" ).arg( (uintptr_t)&MediaStream::seekCallback ).toLatin1().constData();
|
||||
libvlc_media_add_option_flag(m_vlcMedia, imemSeek, libvlc_media_option_trusted);
|
||||
QString tempString;
|
||||
libvlc_media_add_option_flag(m_vlcPreloadedMedia, "imem-cat=4", libvlc_media_option_trusted);
|
||||
tempString = QString( "imem-data=%1" ).arg( (uintptr_t)stream );
|
||||
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||
tempString = QString( "imem-get=%1" ).arg( (uintptr_t)&readCallback );
|
||||
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||
tempString = QString( "imem-release=%1" ).arg( (uintptr_t)&readDoneCallback );
|
||||
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||
tempString = QString( "imem-seek=%1" ).arg( (uintptr_t)&MediaStream::seekCallback );
|
||||
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||
}
|
||||
if ( qApp->arguments().contains( "--chromecast-ip" ) )
|
||||
{
|
||||
@@ -337,7 +410,7 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
||||
{
|
||||
QString castIP = qApp->arguments().at( qApp->arguments().indexOf( "--chromecast-ip" ) + 1 );
|
||||
QString sout( ":sout=#transcode{vcodec=none,acodec=vorb,ab=320,channels=2,samplerate=44100}:chromecast{ip=%1,mux=webm}" );
|
||||
libvlc_media_add_option( m_vlcMedia, sout.arg( castIP ).toLatin1().constData() );
|
||||
libvlc_media_add_option( m_vlcPreloadedMedia, sout.arg( castIP ).toLatin1().constData() );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -345,6 +418,24 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
||||
}
|
||||
}
|
||||
|
||||
libvlc_event_manager_t* manager = libvlc_media_event_manager( m_vlcPreloadedMedia );
|
||||
static libvlc_event_type_t events[] = {
|
||||
libvlc_MediaDurationChanged,
|
||||
};
|
||||
const int eventCount = sizeof(events) / sizeof( *events );
|
||||
for ( int i = 0; i < eventCount; i++ )
|
||||
{
|
||||
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
||||
}
|
||||
|
||||
libvlc_media_player_set_media( m_vlcPreloadedPlayer, m_vlcPreloadedMedia );
|
||||
|
||||
libvlc_audio_set_volume( m_vlcPreloadedPlayer, 0.0 );
|
||||
libvlc_media_player_play( m_vlcPreloadedPlayer );
|
||||
|
||||
if ( !preload )
|
||||
switchToPreloadedMedia();
|
||||
|
||||
// setState( Stopped );
|
||||
}
|
||||
|
||||
@@ -352,7 +443,7 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
||||
bool
|
||||
AudioOutput::isInitialized() const
|
||||
{
|
||||
return m_initialized;
|
||||
return m_initialized > 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -505,7 +596,7 @@ AudioOutput::seek( qint64 milliseconds )
|
||||
bool
|
||||
AudioOutput::isSeekable() const
|
||||
{
|
||||
// tDebug() << Q_FUNC_INFO << m_seekable << m_havePosition << m_totalTime << libvlc_media_player_is_seekable( m_vlcPlayer );
|
||||
tDebug() << Q_FUNC_INFO << m_seekable << m_havePosition << m_totalTime << libvlc_media_player_is_seekable( m_vlcPlayer );
|
||||
return m_havePosition || (libvlc_media_player_is_seekable( m_vlcPlayer ) && m_totalTime > 0 );
|
||||
}
|
||||
|
||||
@@ -555,64 +646,107 @@ AudioOutput::setVolume( qreal vol )
|
||||
void
|
||||
AudioOutput::onVlcEvent( const libvlc_event_t* event )
|
||||
{
|
||||
switch ( event->type )
|
||||
if ( event->p_obj == m_vlcPlayer || event->p_obj == m_vlcMedia )
|
||||
{
|
||||
case libvlc_MediaPlayerTimeChanged:
|
||||
setCurrentTime( event->u.media_player_time_changed.new_time );
|
||||
break;
|
||||
case libvlc_MediaPlayerPositionChanged:
|
||||
setCurrentPosition( event->u.media_player_position_changed.new_position );
|
||||
break;
|
||||
case libvlc_MediaPlayerSeekableChanged:
|
||||
// tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable;
|
||||
break;
|
||||
case libvlc_MediaDurationChanged:
|
||||
setTotalTime( event->u.media_duration_changed.new_duration );
|
||||
break;
|
||||
case libvlc_MediaPlayerLengthChanged:
|
||||
// tDebug() << Q_FUNC_INFO << " : length changed : " << event->u.media_player_length_changed.new_length;
|
||||
break;
|
||||
case libvlc_MediaPlayerPlaying:
|
||||
setState( Playing );
|
||||
break;
|
||||
case libvlc_MediaPlayerPaused:
|
||||
setState( Paused );
|
||||
break;
|
||||
case libvlc_MediaPlayerEndReached:
|
||||
setState( Stopped );
|
||||
break;
|
||||
case libvlc_MediaPlayerEncounteredError:
|
||||
tDebug() << Q_FUNC_INFO << "LibVLC error: MediaPlayerEncounteredError. Stopping";
|
||||
// Don't call stop() here - it will deadlock libvlc
|
||||
setState( Error );
|
||||
break;
|
||||
switch ( event->type )
|
||||
{
|
||||
case libvlc_MediaPlayerTimeChanged:
|
||||
setCurrentTime( event->u.media_player_time_changed.new_time );
|
||||
break;
|
||||
case libvlc_MediaPlayerPositionChanged:
|
||||
setCurrentPosition( event->u.media_player_position_changed.new_position );
|
||||
break;
|
||||
case libvlc_MediaPlayerSeekableChanged:
|
||||
// tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable;
|
||||
break;
|
||||
case libvlc_MediaDurationChanged:
|
||||
setTotalTime( event->u.media_duration_changed.new_duration );
|
||||
break;
|
||||
case libvlc_MediaPlayerLengthChanged:
|
||||
// tDebug() << Q_FUNC_INFO << " : length changed : " << event->u.media_player_length_changed.new_length;
|
||||
break;
|
||||
case libvlc_MediaPlayerPlaying:
|
||||
setState( Playing );
|
||||
break;
|
||||
case libvlc_MediaPlayerPaused:
|
||||
setState( Paused );
|
||||
break;
|
||||
case libvlc_MediaPlayerEndReached:
|
||||
setState( Stopped );
|
||||
break;
|
||||
case libvlc_MediaPlayerEncounteredError:
|
||||
tDebug() << Q_FUNC_INFO << "LibVLC error: MediaPlayerEncounteredError. Stopping";
|
||||
// Don't call stop() here - it will deadlock libvlc
|
||||
setState( Error );
|
||||
break;
|
||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||
case libvlc_MediaPlayerAudioVolume:
|
||||
m_volume = event->u.media_player_audio_volume.volume;
|
||||
emit volumeChanged( volume() );
|
||||
break;
|
||||
case libvlc_MediaPlayerMuted:
|
||||
m_muted = true;
|
||||
emit mutedChanged( true );
|
||||
break;
|
||||
case libvlc_MediaPlayerUnmuted:
|
||||
m_muted = false;
|
||||
emit mutedChanged( false );
|
||||
break;
|
||||
case libvlc_MediaPlayerAudioVolume:
|
||||
m_volume = event->u.media_player_audio_volume.volume;
|
||||
tDebug() << Q_FUNC_INFO << "Got signal in current player that volume changed to:" << m_volume;
|
||||
emit volumeChanged( volume() );
|
||||
break;
|
||||
case libvlc_MediaPlayerMuted:
|
||||
m_muted = true;
|
||||
emit mutedChanged( true );
|
||||
break;
|
||||
case libvlc_MediaPlayerUnmuted:
|
||||
m_muted = false;
|
||||
emit mutedChanged( false );
|
||||
break;
|
||||
#endif
|
||||
case libvlc_MediaPlayerNothingSpecial:
|
||||
case libvlc_MediaPlayerOpening:
|
||||
case libvlc_MediaPlayerBuffering:
|
||||
case libvlc_MediaPlayerStopped:
|
||||
case libvlc_MediaPlayerVout:
|
||||
case libvlc_MediaPlayerMediaChanged:
|
||||
case libvlc_MediaPlayerForward:
|
||||
case libvlc_MediaPlayerBackward:
|
||||
case libvlc_MediaPlayerPausableChanged:
|
||||
case libvlc_MediaPlayerTitleChanged:
|
||||
case libvlc_MediaPlayerSnapshotTaken:
|
||||
default:
|
||||
break;
|
||||
case libvlc_MediaPlayerNothingSpecial:
|
||||
case libvlc_MediaPlayerOpening:
|
||||
case libvlc_MediaPlayerBuffering:
|
||||
case libvlc_MediaPlayerStopped:
|
||||
case libvlc_MediaPlayerVout:
|
||||
case libvlc_MediaPlayerMediaChanged:
|
||||
case libvlc_MediaPlayerForward:
|
||||
case libvlc_MediaPlayerBackward:
|
||||
case libvlc_MediaPlayerPausableChanged:
|
||||
case libvlc_MediaPlayerTitleChanged:
|
||||
case libvlc_MediaPlayerSnapshotTaken:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
tDebug() << "Event for preloaded: " << libvlc_event_type_name(event->type);
|
||||
switch ( event->type )
|
||||
{
|
||||
case libvlc_MediaPlayerPausableChanged:
|
||||
case libvlc_MediaPlayerPlaying:
|
||||
case libvlc_MediaPlayerMediaChanged:
|
||||
case libvlc_MediaPlayerTitleChanged:
|
||||
case libvlc_MediaPlayerSeekableChanged:
|
||||
case libvlc_MediaDurationChanged:
|
||||
case libvlc_MediaPlayerPositionChanged:
|
||||
case libvlc_MediaPlayerPaused:
|
||||
case libvlc_MediaPlayerBuffering:
|
||||
libvlc_media_player_set_pause( m_vlcPreloadedPlayer, 1 );
|
||||
libvlc_audio_set_volume( m_vlcPreloadedPlayer, 0.0 );
|
||||
libvlc_media_player_set_position( m_vlcPreloadedPlayer, 0.0 );
|
||||
break;
|
||||
case libvlc_MediaPlayerTimeChanged:
|
||||
case libvlc_MediaPlayerLengthChanged:
|
||||
case libvlc_MediaPlayerOpening:
|
||||
case libvlc_MediaPlayerEndReached:
|
||||
case libvlc_MediaPlayerEncounteredError:
|
||||
//TODO
|
||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||
case libvlc_MediaPlayerAudioVolume:
|
||||
case libvlc_MediaPlayerMuted:
|
||||
case libvlc_MediaPlayerUnmuted:
|
||||
#endif
|
||||
case libvlc_MediaPlayerNothingSpecial:
|
||||
case libvlc_MediaPlayerStopped:
|
||||
case libvlc_MediaPlayerVout:
|
||||
case libvlc_MediaPlayerForward:
|
||||
case libvlc_MediaPlayerBackward:
|
||||
case libvlc_MediaPlayerSnapshotTaken:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -49,9 +49,10 @@ public:
|
||||
bool isInitialized() const;
|
||||
AudioState state() const;
|
||||
|
||||
void setCurrentSource( const QUrl& stream );
|
||||
void setCurrentSource( QIODevice* stream );
|
||||
void setCurrentSource( MediaStream* stream );
|
||||
void setCurrentSource( const QUrl& stream, bool preload );
|
||||
void setCurrentSource( QIODevice* stream, bool preload );
|
||||
void setCurrentSource( MediaStream* stream, bool preload );
|
||||
void setPreloadedSourceAsCurrent( void );
|
||||
|
||||
void play();
|
||||
void pause();
|
||||
@@ -65,13 +66,15 @@ public:
|
||||
qreal volume() const;
|
||||
qint64 currentTime() const;
|
||||
qint64 totalTime() const;
|
||||
void setAutoDelete ( bool ad );
|
||||
void setAutoDelete ( bool ad, bool preload );
|
||||
|
||||
void setDspCallback( std::function< void( int, int, float*, int, int ) > cb );
|
||||
|
||||
static AudioOutput* instance();
|
||||
libvlc_instance_t* vlcInstance() const;
|
||||
|
||||
void switchToPreloadedMedia( void );
|
||||
|
||||
public slots:
|
||||
|
||||
signals:
|
||||
@@ -90,6 +93,7 @@ private:
|
||||
void setCurrentPosition( float position );
|
||||
void setTotalTime( qint64 time );
|
||||
|
||||
|
||||
void onVlcEvent( const libvlc_event_t* event );
|
||||
static void vlcEventCallback( const libvlc_event_t* event, void* opaque );
|
||||
static void s_dspCallback( int frameNumber, float* samples, int nb_channels, int nb_samples );
|
||||
@@ -97,9 +101,11 @@ private:
|
||||
static AudioOutput* s_instance;
|
||||
AudioState m_currentState;
|
||||
MediaStream* m_currentStream;
|
||||
MediaStream* m_preloadedStream;
|
||||
bool m_seekable;
|
||||
bool m_muted;
|
||||
bool m_autoDelete;
|
||||
bool m_preloadedAutoDelete;
|
||||
bool m_havePosition;
|
||||
bool m_haveTiming;
|
||||
qreal m_volume;
|
||||
@@ -107,7 +113,7 @@ private:
|
||||
qint64 m_totalTime;
|
||||
bool m_justSeeked;
|
||||
|
||||
bool m_initialized;
|
||||
int m_initialized;
|
||||
QFile m_silenceFile;
|
||||
|
||||
std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback;
|
||||
@@ -115,6 +121,9 @@ private:
|
||||
libvlc_instance_t* m_vlcInstance;
|
||||
libvlc_media_player_t* m_vlcPlayer;
|
||||
libvlc_media_t* m_vlcMedia;
|
||||
libvlc_media_player_t* m_vlcBackPlayer;
|
||||
libvlc_media_player_t* m_vlcPreloadedPlayer;
|
||||
libvlc_media_t* m_vlcPreloadedMedia;
|
||||
};
|
||||
|
||||
#endif // AUDIOOUTPUT_H
|
||||
|
@@ -151,7 +151,6 @@ int
|
||||
MediaStream::readDoneCallback ( const char *cookie, size_t bufferSize, void *buffer )
|
||||
{
|
||||
Q_UNUSED(cookie);
|
||||
Q_UNUSED(bufferSize);
|
||||
|
||||
if ( ( m_type == Stream ) && buffer != nullptr && bufferSize > 0 ) {
|
||||
delete[] reinterpret_cast< char* >( buffer );
|
||||
|
@@ -128,10 +128,13 @@ DatabaseCollection::playlists()
|
||||
QList< dynplaylist_ptr >
|
||||
DatabaseCollection::autoPlaylists()
|
||||
{
|
||||
// echonest is dead, disable all echonest code
|
||||
/*
|
||||
if ( Collection::autoPlaylists().isEmpty() )
|
||||
{
|
||||
loadAutoPlaylists();
|
||||
}
|
||||
*/
|
||||
|
||||
return Collection::autoPlaylists();
|
||||
}
|
||||
@@ -140,10 +143,13 @@ DatabaseCollection::autoPlaylists()
|
||||
QList< dynplaylist_ptr >
|
||||
DatabaseCollection::stations()
|
||||
{
|
||||
// echonest is dead, disable all echonest code
|
||||
/*
|
||||
if ( Collection::stations().isEmpty() )
|
||||
{
|
||||
loadStations();
|
||||
}
|
||||
*/
|
||||
|
||||
return Collection::stations();
|
||||
}
|
||||
|
@@ -59,10 +59,10 @@ public:
|
||||
void setLimit( unsigned int amount ) { m_amount = amount; }
|
||||
void setSortOrder( DatabaseCommand_AllArtists::SortOrder order ) { m_sortOrder = order; }
|
||||
void setSortDescending( bool descending ) { m_sortDescending = descending; }
|
||||
void setFilter( const QString& filter ) { m_filter = filter; }
|
||||
void setFilter( const QString& filter ) override { m_filter = filter; }
|
||||
|
||||
signals:
|
||||
void artists( const QList<Tomahawk::artist_ptr>& );
|
||||
void artists( const QList<Tomahawk::artist_ptr>& ) override;
|
||||
void done();
|
||||
|
||||
private:
|
||||
|
@@ -74,7 +74,7 @@ public:
|
||||
|
||||
signals:
|
||||
void tracks( const QList<Tomahawk::query_ptr>&, const QVariant& data );
|
||||
void tracks( const QList<Tomahawk::query_ptr>& );
|
||||
void tracks( const QList<Tomahawk::query_ptr>& ) override;
|
||||
void done( const Tomahawk::collection_ptr& );
|
||||
|
||||
private:
|
||||
|
@@ -21,7 +21,6 @@
|
||||
#include "Source.h"
|
||||
#include "network/Servent.h"
|
||||
#include "SourceList.h"
|
||||
#include "EchonestCatalogSynchronizer.h"
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
@@ -76,9 +75,11 @@ DatabaseCommand_SetCollectionAttributes::exec( DatabaseImpl *lib )
|
||||
void
|
||||
DatabaseCommand_SetCollectionAttributes::postCommitHook()
|
||||
{
|
||||
/*
|
||||
if ( m_type == EchonestSongCatalog ||
|
||||
m_type == EchonestArtistCatalog )
|
||||
Tomahawk::EchonestCatalogSynchronizer::instance()->knownCatalogsChanged();
|
||||
*/
|
||||
|
||||
if ( source()->isLocal() )
|
||||
Servent::instance()->triggerDBSync();
|
||||
|
@@ -34,11 +34,11 @@ public:
|
||||
explicit DatabaseResolver( int weight );
|
||||
|
||||
QString name() const override;
|
||||
virtual unsigned int weight() const { return m_weight; }
|
||||
virtual unsigned int timeout() const { return 0; }
|
||||
virtual unsigned int weight() const override{ return m_weight; }
|
||||
virtual unsigned int timeout() const override{ return 0; }
|
||||
|
||||
public slots:
|
||||
virtual void resolve( const Tomahawk::query_ptr& query );
|
||||
virtual void resolve( const Tomahawk::query_ptr& query ) override;
|
||||
|
||||
private slots:
|
||||
void gotResults( const Tomahawk::QID qid, QList< Tomahawk::result_ptr> results );
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LocalCollection.h"
|
||||
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOCALCOLLECTION_H
|
||||
#define LOCALCOLLECTION_H
|
||||
|
@@ -240,7 +240,7 @@ MetadataEditor::loadResult( const Tomahawk::result_ptr& result )
|
||||
return;
|
||||
|
||||
m_result = result;
|
||||
setEditable( result->resolvedByCollection() && result->resolvedByCollection()->isLocal() );
|
||||
setEditable( result->isLocal() );
|
||||
|
||||
setTitle( result->track()->track() );
|
||||
setArtist( result->track()->artist() );
|
||||
@@ -250,7 +250,7 @@ MetadataEditor::loadResult( const Tomahawk::result_ptr& result )
|
||||
setYear( result->track()->year() );
|
||||
setBitrate( result->bitrate() );
|
||||
|
||||
if ( result->resolvedByCollection() && result->resolvedByCollection()->isLocal() )
|
||||
if ( result->isLocal() )
|
||||
{
|
||||
QString furl = m_result->url();
|
||||
if ( furl.startsWith( "file://" ) )
|
||||
|
@@ -40,6 +40,11 @@ using namespace Tomahawk;
|
||||
void
|
||||
DirLister::go()
|
||||
{
|
||||
if ( m_dirs.isEmpty() )
|
||||
{
|
||||
emit finished();
|
||||
return;
|
||||
}
|
||||
foreach ( const QString& dir, m_dirs )
|
||||
{
|
||||
m_opcount++;
|
||||
|
@@ -42,8 +42,8 @@ public:
|
||||
explicit DBSyncConnection( Servent* s, const Tomahawk::source_ptr& src );
|
||||
virtual ~DBSyncConnection();
|
||||
|
||||
void setup();
|
||||
Connection* clone();
|
||||
void setup() override;
|
||||
Connection* clone() override;
|
||||
|
||||
signals:
|
||||
void stateChanged( Tomahawk::DBSyncConnectionState newstate, Tomahawk::DBSyncConnectionState oldstate, const QString& info );
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/DpiScaler.h"
|
||||
#include "ViewManager.h"
|
||||
#include "widgets/DownloadButton.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
@@ -164,6 +165,10 @@ ColumnViewPreviewWidget::ColumnViewPreviewWidget( ColumnView* parent )
|
||||
m_ageValue->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
|
||||
gridLayout->addWidget( m_ageValue, 4, 1 );
|
||||
|
||||
|
||||
m_downloadButton = new DownloadButton( this );
|
||||
mainLayout->addWidget( m_downloadButton );
|
||||
|
||||
mainLayout->addStretch();
|
||||
|
||||
TomahawkUtils::unmarginLayout( mainLayout );
|
||||
@@ -217,6 +222,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
||||
m_bitrateValue->setText( tr( "%1 kbps" ).arg( query->results().first()->bitrate() ) );
|
||||
m_durationValue->setText( TomahawkUtils::timeToString( query->track()->duration() ) );
|
||||
m_ageValue->setText( TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) ) );
|
||||
m_downloadButton->setQuery( query );
|
||||
|
||||
m_yearValue->setVisible( query->track()->year() > 0 );
|
||||
m_yearLabel->setVisible( query->track()->year() > 0 );
|
||||
@@ -226,6 +232,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
||||
m_durationValue->setVisible( query->track()->duration() > 0 );
|
||||
m_ageLabel->setVisible( query->results().first()->modificationTime() > 0 );
|
||||
m_ageValue->setVisible( query->results().first()->modificationTime() > 0 );
|
||||
m_downloadButton->setVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -237,6 +244,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
||||
m_durationValue->setVisible( false );
|
||||
m_ageLabel->setVisible( false );
|
||||
m_ageValue->setVisible( false );
|
||||
m_downloadButton->setVisible( false );
|
||||
}
|
||||
|
||||
setMinimumHeight( sizeHint().height() );
|
||||
|
@@ -30,6 +30,7 @@ class QueryLabel;
|
||||
class PlayableCover;
|
||||
class QLabel;
|
||||
class ScrollingLabel;
|
||||
class DownloadButton;
|
||||
|
||||
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
|
||||
{
|
||||
@@ -71,6 +72,8 @@ private:
|
||||
ScrollingLabel* m_trackLabel;
|
||||
|
||||
QueryLabel* m_artistLabel;
|
||||
|
||||
DownloadButton* m_downloadButton;
|
||||
};
|
||||
|
||||
#endif // COLUMNVIEWPREVIEWWIDGET_H
|
||||
|
@@ -19,16 +19,6 @@
|
||||
|
||||
#include "GridItemDelegate.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QPainter>
|
||||
#include <QAbstractItemView>
|
||||
#include <QMouseEvent>
|
||||
#include <QTimeLine>
|
||||
|
||||
#include "DownloadManager.h"
|
||||
#include "DownloadJob.h"
|
||||
|
||||
#include "Artist.h"
|
||||
#include "Query.h"
|
||||
#include "Result.h"
|
||||
@@ -39,17 +29,22 @@
|
||||
#include "playlist/PlayableItem.h"
|
||||
#include "playlist/PlayableProxyModel.h"
|
||||
#include "widgets/HoverControls.h"
|
||||
#include "widgets/DropDownButton.h"
|
||||
#include "widgets/DownloadButton.h"
|
||||
#include "widgets/ImageButton.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/PixmapDelegateFader.h"
|
||||
#include "utils/Closure.h"
|
||||
#include "utils/AnimatedSpinner.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/DpiScaler.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QAbstractItemView>
|
||||
#include <QMouseEvent>
|
||||
#include <QTimeLine>
|
||||
|
||||
namespace {
|
||||
static const int FADE_DURATION = 400;
|
||||
};
|
||||
@@ -325,41 +320,10 @@ GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
QRect r = textRect;
|
||||
r.setY( textRect.y() + textRect.height() + 8 );
|
||||
r.setHeight( 32 );
|
||||
m_buyButtonRects[ index ] = r;
|
||||
|
||||
QString text;
|
||||
if ( item->result() &&
|
||||
( ( !item->result()->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() ) ||
|
||||
( item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished ) ) )
|
||||
if( DownloadButton::drawPrimitive(painter, r, item->query(), m_hoveringOverBuyButton == index ) )
|
||||
{
|
||||
text = tr( "View in Finder" );
|
||||
}
|
||||
else if ( item->query() && item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
{
|
||||
text = tr( "Download %1" ).arg( item->query()->results().first()->downloadFormats().first().extension.toUpper() );
|
||||
}
|
||||
else if ( item->query()->numResults( true ) && !item->query()->results().first()->purchaseUrl().isEmpty() )
|
||||
{
|
||||
text = tr( "Buy" );
|
||||
}
|
||||
|
||||
if ( !item->result() || !item->result()->downloadJob() )
|
||||
{
|
||||
if ( !text.isEmpty() )
|
||||
DropDownButton::drawPrimitive( painter, r, text, m_hoveringOverBuyButton == index, false );
|
||||
else
|
||||
m_buyButtonRects.remove( index );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( r.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = r.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
m_buyButtonRects[ index ] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -621,23 +585,7 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
|
||||
|
||||
if ( hoveringBuyButton )
|
||||
{
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
|
||||
if ( !item )
|
||||
return false;
|
||||
|
||||
if ( item->query() && item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
{
|
||||
m_view->edit( index );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
}
|
||||
}
|
||||
return DownloadButton::handleEditorEvent( event, m_view, m_model, index );
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -867,63 +815,7 @@ GridItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& opt
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
if ( item->result() && !item->result()->downloadFormats().isEmpty() &&
|
||||
!DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ) ).absolutePath() ) );
|
||||
}
|
||||
else if ( item->result() && item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( item->result()->downloadJob()->localFile() ).absolutePath() ) );
|
||||
}
|
||||
else if ( item->result() &&
|
||||
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
|
||||
{
|
||||
QStringList formats;
|
||||
foreach ( const DownloadFormat& format, item->result()->downloadFormats() )
|
||||
{
|
||||
formats << tr( "Download %1" ).arg( format.extension.toUpper() );
|
||||
}
|
||||
|
||||
DropDownButton* editor = new DropDownButton( parent );
|
||||
editor->addItems( formats );
|
||||
|
||||
NewClosure( editor, SIGNAL( clicked() ),
|
||||
const_cast<GridItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
|
||||
NewClosure( editor, SIGNAL( activated( int ) ),
|
||||
const_cast<GridItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
return editor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GridItemDelegate::addDownloadJob( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
if ( !item->result()->downloadFormats().isEmpty() )
|
||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().at( cb->currentIndex() ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GridItemDelegate::closeEditor( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
editor->deleteLater();
|
||||
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
|
||||
}
|
||||
|
||||
|
||||
@@ -932,13 +824,13 @@ GridItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewI
|
||||
{
|
||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||
|
||||
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
|
||||
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
|
||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||
|
||||
if ( m_downloadDropDownRects.contains( index ) )
|
||||
if ( m_buyButtonRects.contains( index ) )
|
||||
{
|
||||
editor->setGeometry( m_downloadDropDownRects.value( index ) );
|
||||
editor->setGeometry( m_buyButtonRects.value( index ) );
|
||||
}
|
||||
|
||||
if ( !comboBox->property( "shownPopup" ).toBool() )
|
||||
|
@@ -87,9 +87,6 @@ private slots:
|
||||
void fadingFrameChanged( const QPersistentModelIndex& );
|
||||
void fadingFrameFinished( const QPersistentModelIndex& );
|
||||
|
||||
void closeEditor( const QModelIndex& index, QWidget* editor );
|
||||
void addDownloadJob( const QModelIndex& index, QWidget* editor );
|
||||
|
||||
private:
|
||||
QTimeLine* createTimeline( QTimeLine::Direction direction, int startFrame = 0 );
|
||||
void clearButtons();
|
||||
@@ -104,7 +101,6 @@ private:
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_albumNameRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
|
||||
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_covers;
|
||||
|
||||
QPersistentModelIndex m_hoverIndex;
|
||||
|
@@ -59,7 +59,7 @@ public:
|
||||
|
||||
PlayableModel* sourceModel() const { return m_model; }
|
||||
virtual void setSourcePlayableModel( PlayableModel* sourceModel );
|
||||
virtual void setSourceModel( QAbstractItemModel* model );
|
||||
virtual void setSourceModel( QAbstractItemModel* model ) override;
|
||||
|
||||
virtual bool isLoading() const;
|
||||
|
||||
@@ -91,9 +91,9 @@ public:
|
||||
|
||||
QList< double > columnWeights() const;
|
||||
|
||||
virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const;
|
||||
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
|
||||
virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
|
||||
virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const override;
|
||||
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override;
|
||||
virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
|
||||
|
||||
virtual void setFilter( const QString& pattern );
|
||||
virtual void updateDetailedInfo( const QModelIndex& index );
|
||||
@@ -120,7 +120,7 @@ signals:
|
||||
|
||||
protected:
|
||||
bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const Q_DECL_OVERRIDE;
|
||||
virtual bool lessThan( const QModelIndex& left, const QModelIndex& right ) const;
|
||||
virtual bool lessThan( const QModelIndex& left, const QModelIndex& right ) const override;
|
||||
|
||||
Tomahawk::playlistinterface_ptr m_playlistInterface;
|
||||
|
||||
|
@@ -20,15 +20,6 @@
|
||||
|
||||
#include "PlaylistItemDelegate.h"
|
||||
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDesktopServices>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QDesktopServices>
|
||||
#include <QToolTip>
|
||||
|
||||
#include "Query.h"
|
||||
#include "Result.h"
|
||||
#include "Artist.h"
|
||||
@@ -36,8 +27,6 @@
|
||||
#include "Source.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
#include "DownloadManager.h"
|
||||
#include "DownloadJob.h"
|
||||
#include "PlayableModel.h"
|
||||
#include "PlayableItem.h"
|
||||
#include "PlayableProxyModel.h"
|
||||
@@ -45,16 +34,22 @@
|
||||
#include "ViewHeader.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include "widgets/DropDownButton.h"
|
||||
#include "widgets/DownloadButton.h"
|
||||
#include "audio/AudioEngine.h"
|
||||
#include "utils/ImageRegistry.h"
|
||||
#include "utils/PixmapDelegateFader.h"
|
||||
#include "utils/Closure.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QToolTip>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
@@ -125,63 +120,7 @@ PlaylistItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem&
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
if ( /*index.column() == PlayableModel::Download &&*/ item->result() && !item->result()->downloadFormats().isEmpty() &&
|
||||
!DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ) ).absolutePath() ) );
|
||||
}
|
||||
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() && item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( item->result()->downloadJob()->localFile() ).absolutePath() ) );
|
||||
}
|
||||
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() &&
|
||||
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
|
||||
{
|
||||
QStringList formats;
|
||||
foreach ( const DownloadFormat& format, item->result()->downloadFormats() )
|
||||
{
|
||||
formats << tr( "Download %1" ).arg( format.extension );
|
||||
}
|
||||
|
||||
DropDownButton* editor = new DropDownButton( parent );
|
||||
editor->addItems( formats );
|
||||
|
||||
NewClosure( editor, SIGNAL( clicked() ),
|
||||
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
|
||||
NewClosure( editor, SIGNAL( activated( int ) ),
|
||||
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
return editor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItemDelegate::addDownloadJob( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
if ( !item->result()->downloadFormats().isEmpty() )
|
||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().at( cb->currentIndex() ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItemDelegate::closeEditor( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
editor->deleteLater();
|
||||
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +129,7 @@ PlaylistItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionV
|
||||
{
|
||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||
|
||||
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
|
||||
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
|
||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||
|
||||
@@ -277,69 +216,7 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
|
||||
else */
|
||||
if ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download )
|
||||
{
|
||||
if ( item->result() && !item->result()->downloadFormats().isEmpty() )
|
||||
{
|
||||
QStyleOptionComboBox optc;
|
||||
optc.rect = opt.rect.adjusted( 4, 0, -4, 0 );
|
||||
optc.editable = false;
|
||||
optc.currentText = tr( "Download %1" ).arg( item->result()->downloadFormats().first().extension );
|
||||
optc.palette = m_view->palette();
|
||||
|
||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
||||
optc.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
||||
else
|
||||
optc.state = QStyle::State_Active | QStyle::State_Enabled;
|
||||
|
||||
if ( !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
painter->setPen( opt.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
|
||||
painter->drawText( opt.rect, text, textOption );
|
||||
}
|
||||
else if ( !item->result()->downloadJob() )
|
||||
{
|
||||
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
|
||||
|
||||
/* QApplication::style()->drawComplexControl( QStyle::CC_ComboBox, &optc, painter, 0 );
|
||||
optc.rect.adjust( 4, 0, 0, 0 );
|
||||
QApplication::style()->drawControl( QStyle::CE_ComboBoxLabel, &optc, painter, 0 );*/
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( item->result()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
painter->setPen( opt.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
|
||||
painter->drawText( opt.rect, text, textOption );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( optc.rect.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = optc.rect.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
|
||||
/* QStyleOptionProgressBarV2 optp;
|
||||
optp.rect = optc.rect;
|
||||
optp.minimum = 0;
|
||||
optp.maximum = 100;
|
||||
optp.progress = item->result()->downloadJob()->progressPercentage();
|
||||
optp.palette = m_view->palette();
|
||||
optp.palette.setColor( QPalette::Highlight, QColor( "#E61878" ) );
|
||||
|
||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
||||
optp.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
||||
else
|
||||
optp.state = QStyle::State_Active | QStyle::State_Enabled;
|
||||
|
||||
QApplication::style()->drawControl( QStyle::CE_ProgressBar, &optp, painter, 0 );*/
|
||||
}
|
||||
}
|
||||
}
|
||||
DownloadButton::drawPrimitive( painter, opt.rect.adjusted( 4, 0, -4, 0 ), item->query(), hoveringOver() == index );
|
||||
}
|
||||
else if ( item->isPlaying() )
|
||||
{
|
||||
@@ -657,67 +534,14 @@ PlaylistItemDelegate::drawTrack( QPainter* painter, const QStyleOptionViewItem&
|
||||
|
||||
stateWidth += r.width() + 16;
|
||||
}
|
||||
|
||||
if ( hasOnlineResults && !item->query()->results().first()->purchaseUrl().isEmpty() )
|
||||
{
|
||||
QRect r = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
||||
r.setWidth( 144 );
|
||||
DropDownButton::drawPrimitive( painter, r, tr( "Buy" ), m_hoveringOverBuyButton == index, false );
|
||||
|
||||
m_buyButtonRects[ index ] = r;
|
||||
|
||||
stateWidth += r.width() + 16;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasOnlineResults && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
QRect downloadButtonRect = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
||||
downloadButtonRect.setWidth( 144 );
|
||||
stateWidth += downloadButtonRect.width() + 16;
|
||||
if ( DownloadButton::drawPrimitive( painter, downloadButtonRect, item->query(), m_hoveringOverDownloadButton == index ) )
|
||||
{
|
||||
painter->save();
|
||||
QStyleOptionComboBox optc;
|
||||
optc.rect = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
||||
optc.rect.setWidth( 144 );
|
||||
m_downloadDropDownRects[ index ] = optc.rect;
|
||||
stateWidth += optc.rect.width() + 16;
|
||||
optc.editable = false;
|
||||
optc.currentText = tr( "Download %1" ).arg( item->query()->results().first()->downloadFormats().first().extension.toUpper() );
|
||||
optc.palette = m_view->palette();
|
||||
|
||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
||||
optc.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
||||
else
|
||||
optc.state = QStyle::State_Active | QStyle::State_Enabled;
|
||||
|
||||
if ( !DownloadManager::instance()->localFileForDownload( item->query()->results().first()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
painter->setPen( optc.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, optc.rect.width() - 3 );
|
||||
painter->drawText( optc.rect, text, QTextOption( Qt::AlignCenter ) );
|
||||
}
|
||||
else if ( !item->query()->results().first()->downloadJob() )
|
||||
{
|
||||
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( item->query()->results().first()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
painter->setPen( optc.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, optc.rect.width() - 3 );
|
||||
painter->drawText( optc.rect, text, QTextOption( Qt::AlignCenter ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( optc.rect.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = optc.rect.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float(item->query()->results().first()->downloadJob()->progressPercentage()) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
}
|
||||
}
|
||||
painter->restore();
|
||||
m_downloadDropDownRects[ index ] = downloadButtonRect;
|
||||
}
|
||||
|
||||
const int remWidth = r.width() - numberWidth - durationWidth;
|
||||
@@ -835,7 +659,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
bool hoveringArtist = false;
|
||||
bool hoveringInfo = false;
|
||||
bool hoveringLove = false;
|
||||
bool hoveringBuy = false;
|
||||
bool hoveringDownloadDropDown = false;
|
||||
Tomahawk::source_ptr hoveredAvatar;
|
||||
QRect hoveredAvatarRect;
|
||||
@@ -858,12 +681,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||
hoveringLove = loveRect.contains( ev->pos() );
|
||||
}
|
||||
if ( m_buyButtonRects.contains( index ) )
|
||||
{
|
||||
const QRect buyRect = m_buyButtonRects[ index ];
|
||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||
hoveringBuy = buyRect.contains( ev->pos() );
|
||||
}
|
||||
if ( m_downloadDropDownRects.contains( index ) )
|
||||
{
|
||||
const QRect downloadDropDownRect = m_downloadDropDownRects[ index ];
|
||||
@@ -887,7 +704,7 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
|
||||
if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringBuy )
|
||||
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringDownloadDropDown )
|
||||
m_view->setCursor( Qt::PointingHandCursor );
|
||||
else
|
||||
m_view->setCursor( Qt::ArrowCursor );
|
||||
@@ -911,19 +728,19 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
emit updateIndex( m_hoveringOverArtist );
|
||||
m_hoveringOverArtist = QModelIndex();
|
||||
}
|
||||
if ( hoveringBuy && m_hoveringOverBuyButton != index )
|
||||
if ( hoveringDownloadDropDown && m_hoveringOverDownloadButton != index )
|
||||
{
|
||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
||||
m_hoveringOverBuyButton = index;
|
||||
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
|
||||
m_hoveringOverDownloadButton = index;
|
||||
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||
item->requestRepaint();
|
||||
emit updateIndex( m_hoveringOverBuyButton );
|
||||
emit updateIndex( m_hoveringOverDownloadButton );
|
||||
}
|
||||
if ( !hoveringBuy && m_hoveringOverBuyButton.isValid() )
|
||||
if ( !hoveringDownloadDropDown && m_hoveringOverDownloadButton.isValid() )
|
||||
{
|
||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
||||
m_hoveringOverBuyButton = QModelIndex();
|
||||
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
|
||||
m_hoveringOverDownloadButton = QModelIndex();
|
||||
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||
item->requestRepaint();
|
||||
@@ -957,10 +774,10 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
{
|
||||
item->query()->queryTrack()->setLoved( !item->query()->queryTrack()->loved() );
|
||||
}
|
||||
else if ( hoveringBuy )
|
||||
else if ( hoveringDownloadDropDown || ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) )
|
||||
{
|
||||
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
if ( DownloadButton::handleEditorEvent( event , m_view, m_model, index ) )
|
||||
return true;
|
||||
}
|
||||
else if ( hoveringInfo )
|
||||
{
|
||||
@@ -996,13 +813,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) || hoveringDownloadDropDown )
|
||||
{
|
||||
m_model->sourceModel()->setAllColumnsEditable( true );
|
||||
m_view->edit( index );
|
||||
m_model->sourceModel()->setAllColumnsEditable( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
event->accept();
|
||||
return true;
|
||||
@@ -1022,10 +832,9 @@ PlaylistItemDelegate::resetHoverIndex()
|
||||
|
||||
m_hoveringOver = QModelIndex();
|
||||
m_hoveringOverArtist = QModelIndex();
|
||||
m_hoveringOverBuyButton = QModelIndex();
|
||||
m_hoveringOverDownloadButton = QModelIndex();
|
||||
m_infoButtonRects.clear();
|
||||
m_loveButtonRects.clear();
|
||||
m_buyButtonRects.clear();
|
||||
m_artistNameRects.clear();
|
||||
|
||||
QModelIndex itemIdx = m_model->mapToSource( idx );
|
||||
|
@@ -57,8 +57,6 @@ signals:
|
||||
|
||||
private slots:
|
||||
void doUpdateIndex( const QPersistentModelIndex& index );
|
||||
void closeEditor( const QModelIndex& index, QWidget* editor );
|
||||
void addDownloadJob( const QModelIndex& index, QWidget* editor );
|
||||
|
||||
protected:
|
||||
void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, PlayableItem* item ) const;
|
||||
@@ -116,13 +114,12 @@ private:
|
||||
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_infoButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_loveButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
||||
mutable QHash< QPersistentModelIndex, QHash< Tomahawk::source_ptr, QRect > > m_avatarBoxRects;
|
||||
QPersistentModelIndex m_hoveringOver;
|
||||
QPersistentModelIndex m_hoveringOverArtist;
|
||||
QPersistentModelIndex m_hoveringOverBuyButton;
|
||||
QPersistentModelIndex m_hoveringOverDownloadButton;
|
||||
mutable QPersistentModelIndex m_nowPlaying;
|
||||
|
||||
TrackView* m_view;
|
||||
|
@@ -18,12 +18,6 @@
|
||||
|
||||
#include "TrackDetailView.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
#include <QSizePolicy>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Album.h"
|
||||
#include "Track.h"
|
||||
#include "audio/AudioEngine.h"
|
||||
@@ -39,6 +33,13 @@
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
#include <QSizePolicy>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDesktopServices>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
TrackDetailView::TrackDetailView( QWidget* parent )
|
||||
@@ -197,7 +198,7 @@ TrackDetailView::setQuery( const Tomahawk::query_ptr& query )
|
||||
|
||||
connect( m_query->track().data(), SIGNAL( updated() ), SLOT( onCoverUpdated() ) );
|
||||
connect( m_query->track().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) );
|
||||
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( onResultsChanged() ) );
|
||||
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( onResultsChanged() ), Qt::QueuedConnection );
|
||||
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( onAlbumUpdated() ) );
|
||||
}
|
||||
|
||||
@@ -219,8 +220,44 @@ TrackDetailView::onAlbumUpdated()
|
||||
{
|
||||
if ( m_query->track()->albumPtr()->purchased() )
|
||||
{
|
||||
m_buyButton->setText( tr( "Download Album" ) );
|
||||
m_buyButton->setVisible( true );
|
||||
m_allTracksAvailableLocally = true;
|
||||
foreach( const query_ptr& currentQuery, m_playlistInterface->tracks() )
|
||||
{
|
||||
if ( currentQuery->results().isEmpty() )
|
||||
{
|
||||
m_allTracksAvailableLocally = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_allTracksAvailableLocally = false;
|
||||
foreach ( const result_ptr& currentResult, currentQuery->results() )
|
||||
{
|
||||
QList< DownloadFormat > formats = currentResult->downloadFormats();
|
||||
bool isDownloaded = formats.isEmpty() ? false : !DownloadManager::instance()->localFileForDownload( currentResult->downloadFormats().first().url.toString() ).isEmpty();
|
||||
if ( currentResult->isLocal() || isDownloaded )
|
||||
{
|
||||
m_allTracksAvailableLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !m_allTracksAvailableLocally )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_allTracksAvailableLocally )
|
||||
{
|
||||
m_buyButton->setText( tr( "View in Folder" ) );
|
||||
m_buyButton->setVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buyButton->setText( tr( "Download Album" ) );
|
||||
m_buyButton->setVisible( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -251,7 +288,14 @@ TrackDetailView::onBuyButtonClicked()
|
||||
{
|
||||
if ( m_query->track()->albumPtr()->purchased() )
|
||||
{
|
||||
emit downloadAll();
|
||||
if ( m_allTracksAvailableLocally )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( DownloadJob::localPath( m_query->track()->albumPtr() ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
emit downloadAll();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -344,7 +388,7 @@ TrackDetailView::onResultsChanged()
|
||||
resolverIcon->setFixedWidth( 12 );
|
||||
resolverIcon->setPixmap( result->sourceIcon( TomahawkUtils::RoundedCorners, QSize( 12, 12 ) ) );
|
||||
|
||||
QLabel* resolverLabel = new ClickableLabel( this );
|
||||
ClickableLabel* resolverLabel = new ClickableLabel( this );
|
||||
resolverLabel->setFont( f );
|
||||
resolverLabel->setStyleSheet( "QLabel { color: rgba( 0, 0, 0, 50% ) }" );
|
||||
resolverLabel->setText( QString( "%1 - %2" ).arg( result->track()->track() ).arg( result->track()->artist() ) );
|
||||
@@ -359,8 +403,8 @@ TrackDetailView::onResultsChanged()
|
||||
;
|
||||
resolverLabel->setFixedWidth( width() - 32 - 4 );
|
||||
|
||||
NewClosure( resolverLabel, SIGNAL( clicked() ), const_cast< AudioEngine* >( AudioEngine::instance() ),
|
||||
SLOT( playItem( Tomahawk::playlistinterface_ptr, Tomahawk::result_ptr, Tomahawk::query_ptr ) ),
|
||||
NewClosure( resolverLabel, SIGNAL( clicked() ), const_cast< TrackDetailView* >( this ),
|
||||
SLOT( onResultClicked( Tomahawk::playlistinterface_ptr, Tomahawk::result_ptr, Tomahawk::query_ptr ) ),
|
||||
m_playlistInterface, result, m_query )->setAutoDelete( false );
|
||||
|
||||
QWidget* hbox = new QWidget;
|
||||
@@ -397,3 +441,13 @@ TrackDetailView::setBuyButtonVisible( bool visible )
|
||||
{
|
||||
m_buyButtonVisible = visible;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackDetailView::onResultClicked( const Tomahawk::playlistinterface_ptr& playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery )
|
||||
{
|
||||
fromQuery->setPreferredResult( result );
|
||||
if (AudioEngine::instance()->isPlaying() && fromQuery->results().contains( AudioEngine::instance()->currentTrack() )) {
|
||||
AudioEngine::instance()->playItem( playlist, result, fromQuery );
|
||||
}
|
||||
}
|
||||
|
@@ -64,6 +64,8 @@ private slots:
|
||||
void onBuyButtonClicked();
|
||||
void onDownloadManagerStateChanged( DownloadManager::DownloadManagerState newState, DownloadManager::DownloadManagerState oldState );
|
||||
|
||||
void onResultClicked( const Tomahawk::playlistinterface_ptr& playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery );
|
||||
|
||||
private:
|
||||
void setSocialActions();
|
||||
|
||||
@@ -77,6 +79,7 @@ private:
|
||||
CaptionLabel* m_resultsBoxLabel;
|
||||
QPushButton* m_buyButton;
|
||||
bool m_buyButtonVisible;
|
||||
bool m_allTracksAvailableLocally;
|
||||
|
||||
QWidget* m_infoBox;
|
||||
QWidget* m_resultsBox;
|
||||
|
@@ -383,6 +383,8 @@ void
|
||||
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
|
||||
{
|
||||
QTreeView::currentChanged( current, previous );
|
||||
if ( !m_model )
|
||||
return;
|
||||
|
||||
PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
|
||||
if ( item && item->query() )
|
||||
|
@@ -247,8 +247,8 @@ TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent
|
||||
if ( !item->result()->isOnline() && ti->result()->isOnline() )
|
||||
return false;
|
||||
|
||||
if ( ( item->result()->resolvedByCollection().isNull() || !item->result()->resolvedByCollection()->isLocal() ) &&
|
||||
!ti->result()->resolvedByCollection().isNull() && ti->result()->resolvedByCollection()->isLocal() )
|
||||
if ( ( !item->result()->isLocal() ) &&
|
||||
!ti->result()->isLocal() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -190,7 +190,7 @@ JSAccount::reportNativeScriptJobResult( int resultId, const QVariantMap& result
|
||||
.arg( serializeQVariantMap( result ) );
|
||||
|
||||
// Remove when new scripting api turned out to work reliably
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << eval;
|
||||
//tDebug( LOGVERBOSE ) << Q_FUNC_INFO << eval;
|
||||
|
||||
evaluateJavaScript( eval );
|
||||
}
|
||||
|
@@ -711,3 +711,14 @@ JSResolver::getStreamUrl( const result_ptr& result )
|
||||
|
||||
return scriptObject()->invoke( "getStreamUrl", arguments );
|
||||
}
|
||||
|
||||
ScriptJob*
|
||||
JSResolver::getDownloadUrl( const result_ptr& result, const DownloadFormat& format )
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments["url"] = format.url.toString();
|
||||
arguments["extension"] = format.extension;
|
||||
arguments["mimetype"] = format.mimetype;
|
||||
|
||||
return scriptObject()->invoke( "getDownloadUrl", arguments );
|
||||
}
|
||||
|
@@ -76,6 +76,8 @@ public:
|
||||
ScriptAccount* scriptAccount() const;
|
||||
|
||||
ScriptJob* getStreamUrl( const result_ptr& result ) override;
|
||||
ScriptJob* getDownloadUrl( const result_ptr& result, const DownloadFormat &format ) override;
|
||||
|
||||
|
||||
public slots:
|
||||
void resolve( const Tomahawk::query_ptr& query ) override;
|
||||
|
@@ -45,3 +45,12 @@ Tomahawk::Resolver::getStreamUrl( const result_ptr& result )
|
||||
|
||||
return new SyncScriptJob( data );
|
||||
}
|
||||
|
||||
Tomahawk::ScriptJob*
|
||||
Tomahawk::Resolver::getDownloadUrl( const result_ptr& result, const DownloadFormat& format )
|
||||
{
|
||||
QVariantMap data;
|
||||
data[ "url" ] = format.url.toString();
|
||||
|
||||
return new SyncScriptJob( data );
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@
|
||||
|
||||
#include "Typedefs.h"
|
||||
#include "DllMacro.h"
|
||||
#include "../DownloadJob.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
@@ -52,6 +53,7 @@ public:
|
||||
|
||||
virtual void resolve( const Tomahawk::query_ptr& query ) = 0;
|
||||
virtual ScriptJob* getStreamUrl( const result_ptr& result );
|
||||
virtual ScriptJob* getDownloadUrl( const result_ptr& result, const DownloadFormat& format );
|
||||
};
|
||||
|
||||
} //ns
|
||||
|
@@ -1,12 +1,12 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -17,6 +17,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptAccount.h"
|
||||
|
||||
#include "ScriptObject.h"
|
||||
@@ -31,11 +32,11 @@
|
||||
#include "ScriptLinkGeneratorPlugin.h"
|
||||
#include "ScriptInfoPlugin.h"
|
||||
|
||||
// TODO:
|
||||
#include "../Artist.h"
|
||||
#include "../Album.h"
|
||||
#include "../Result.h"
|
||||
#include "../Track.h"
|
||||
|
||||
#include <QTime>
|
||||
|
||||
|
||||
|
@@ -1,12 +1,12 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -53,6 +53,7 @@ ScriptCollection::ScriptCollection( const scriptobject_ptr& scriptObject,
|
||||
qDebug() << Q_FUNC_INFO << scriptAccount->name() << Collection::name();
|
||||
|
||||
m_servicePrettyName = scriptAccount->name();
|
||||
m_weight = readMetaData().value( "weight", 99 ).toUInt();
|
||||
}
|
||||
|
||||
|
||||
@@ -235,6 +236,16 @@ ScriptCollection::getStreamUrl( const result_ptr& result )
|
||||
return scriptObject()->invoke( "getStreamUrl", arguments );
|
||||
}
|
||||
|
||||
ScriptJob*
|
||||
ScriptCollection::getDownloadUrl( const result_ptr& result, const DownloadFormat& format )
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments["url"] = format.url.toString();
|
||||
arguments["extension"] = format.extension;
|
||||
arguments["mimetype"] = format.mimetype;
|
||||
|
||||
return scriptObject()->invoke( "getDownloadUrl", arguments );
|
||||
}
|
||||
|
||||
void
|
||||
ScriptCollection::parseMetaData( const QVariantMap& metadata )
|
||||
@@ -350,7 +361,7 @@ ScriptCollection::timeout() const
|
||||
unsigned int
|
||||
ScriptCollection::weight() const
|
||||
{
|
||||
return 0;
|
||||
return m_weight;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -96,6 +96,7 @@ public:
|
||||
unsigned int timeout() const override;
|
||||
void resolve( const Tomahawk::query_ptr& query ) override;
|
||||
ScriptJob* getStreamUrl( const result_ptr& result ) override;
|
||||
ScriptJob* getDownloadUrl( const result_ptr& result, const DownloadFormat &format ) override;
|
||||
|
||||
private slots:
|
||||
void onIconFetched();
|
||||
@@ -106,6 +107,7 @@ private:
|
||||
QString m_servicePrettyName;
|
||||
QString m_description;
|
||||
int m_trackCount;
|
||||
int m_weight;
|
||||
QPixmap m_icon;
|
||||
bool m_isOnline;
|
||||
};
|
||||
|
@@ -41,12 +41,12 @@ public:
|
||||
void setFilter( const QString& filter ) override;
|
||||
|
||||
signals:
|
||||
void albums( const QList< Tomahawk::album_ptr >& );
|
||||
void done();
|
||||
void albums( const QList< Tomahawk::album_ptr >& ) override;
|
||||
void done() override;
|
||||
|
||||
protected:
|
||||
virtual void exec();
|
||||
virtual void reportFailure();
|
||||
virtual void exec() override;
|
||||
virtual void reportFailure() override;
|
||||
|
||||
private slots:
|
||||
void onAlbumsJobDone( const QVariantMap& result );
|
||||
|
@@ -42,8 +42,8 @@ public:
|
||||
void setFilter( const QString& filter ) override;
|
||||
|
||||
signals:
|
||||
void artists( const QList< Tomahawk::artist_ptr >& );
|
||||
void done();
|
||||
void artists( const QList< Tomahawk::artist_ptr >& ) override;
|
||||
void done() override;
|
||||
|
||||
protected:
|
||||
void exec() override;
|
||||
|
@@ -39,8 +39,8 @@ public:
|
||||
void enqueue() override;
|
||||
|
||||
signals:
|
||||
void tracks( const QList< Tomahawk::query_ptr >& );
|
||||
void done();
|
||||
void tracks( const QList< Tomahawk::query_ptr >& ) override;
|
||||
void done() override;
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void exec() override;
|
||||
|
@@ -45,7 +45,7 @@ public:
|
||||
|
||||
signals:
|
||||
void information( const QString& url, const QSharedPointer<QObject>& variant );
|
||||
void done();
|
||||
void done() override;
|
||||
|
||||
protected:
|
||||
void exec() override;
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptPlugin.h"
|
||||
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,4 +15,5 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptPluginFactory.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SyncScriptJob.h"
|
||||
|
||||
#include "../Typedefs.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptCollectionFactory.h"
|
||||
|
||||
#include "SourceList.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptInfoPluginFactory.h"
|
||||
|
||||
#include "SourceList.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,15 +1,15 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright (C) 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,11 +1,12 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LinkGeneratorPlugin.h"
|
||||
|
||||
#include "LinkGenerator.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -96,7 +96,14 @@ NetworkReply::metaDataChanged()
|
||||
}
|
||||
else
|
||||
{
|
||||
load( redir.toUrl() );
|
||||
QUrl url = redir.toUrl();
|
||||
if (url.path().isEmpty())
|
||||
{
|
||||
//Default cookie jar gets confused if path is empty
|
||||
url.setPath("/");
|
||||
}
|
||||
|
||||
load( url );
|
||||
}
|
||||
emit redirected();
|
||||
}
|
||||
@@ -148,10 +155,14 @@ NetworkReply::load( const QUrl& url )
|
||||
m_formerUrls << url.toString();
|
||||
QNetworkRequest request( url );
|
||||
|
||||
//Carryover User-Agent
|
||||
if ( m_reply->request().hasRawHeader( "User-Agent" ))
|
||||
//Carryover some headers if set
|
||||
static QList<QByteArray> headersToCarryOver = { "User-Agent", "Accept-Language" };
|
||||
for (auto&& header : headersToCarryOver)
|
||||
{
|
||||
request.setRawHeader( "User-Agent", m_reply->request().rawHeader( "User-Agent" ) );
|
||||
if ( m_reply->request().hasRawHeader( header ))
|
||||
{
|
||||
request.setRawHeader( header, m_reply->request().rawHeader( header ) );
|
||||
}
|
||||
}
|
||||
|
||||
Q_ASSERT( Tomahawk::Utils::nam() != 0 );
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,15 +1,15 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -20,6 +20,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TomaHkLinkGeneratorPlugin.h"
|
||||
|
||||
#include "../playlist/dynamic/GeneratorInterface.h"
|
||||
@@ -30,12 +31,6 @@
|
||||
#include "../resolvers/SyncScriptJob.h"
|
||||
#include "../utils/Logger.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <echonest5/Playlist.h>
|
||||
#else
|
||||
#include <echonest/Playlist.h>
|
||||
#endif
|
||||
|
||||
QString
|
||||
Tomahawk::Utils::TomaHkLinkGeneratorPlugin::hostname() const
|
||||
{
|
||||
@@ -82,6 +77,7 @@ Tomahawk::Utils::TomaHkLinkGeneratorPlugin::openLink( const Tomahawk::album_ptr&
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Tomahawk::ScriptJob*
|
||||
Tomahawk::Utils::TomaHkLinkGeneratorPlugin::openLink( const Tomahawk::dynplaylist_ptr& playlist ) const
|
||||
{
|
||||
@@ -130,3 +126,4 @@ Tomahawk::Utils::TomaHkLinkGeneratorPlugin::openLink( const Tomahawk::dynplaylis
|
||||
|
||||
return new SyncScriptJob( data );
|
||||
}
|
||||
*/
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -37,7 +37,8 @@ public:
|
||||
ScriptJob* openLink( const QString& title, const QString& artist, const QString& album ) const override;
|
||||
ScriptJob* openLink( const Tomahawk::artist_ptr& artist ) const override;
|
||||
ScriptJob* openLink( const Tomahawk::album_ptr& album ) const override;
|
||||
ScriptJob* openLink( const Tomahawk::dynplaylist_ptr& playlist ) const override;
|
||||
// echonest is dead, disable all echonest code
|
||||
// ScriptJob* openLink( const Tomahawk::dynplaylist_ptr& playlist ) const override;
|
||||
|
||||
private:
|
||||
QString hostname() const;
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "XspfGenerator.h"
|
||||
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XSPFGENERATOR_H
|
||||
#define XSPFGENERATOR_H
|
||||
|
282
src/libtomahawk/widgets/DownloadButton.cpp
Normal file
282
src/libtomahawk/widgets/DownloadButton.cpp
Normal file
@@ -0,0 +1,282 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "DownloadButton.h"
|
||||
|
||||
#include "Artist.h"
|
||||
#include "Album.h"
|
||||
#include "Result.h"
|
||||
#include "DownloadManager.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QEvent>
|
||||
#include <QAbstractItemView>
|
||||
#include <QDesktopServices>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
DownloadButton::DownloadButton( const Tomahawk::query_ptr& query, QWidget* parent, QAbstractItemView* view, const QModelIndex& index )
|
||||
: DropDownButton( parent )
|
||||
, m_view( view )
|
||||
, m_index( index )
|
||||
{
|
||||
init();
|
||||
|
||||
setQuery( query );
|
||||
}
|
||||
|
||||
|
||||
DownloadButton::DownloadButton( QWidget* parent )
|
||||
: DropDownButton( parent )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadButton::init()
|
||||
{
|
||||
connect( this, SIGNAL( clicked() ), this, SLOT( addDownloadJob() ) );
|
||||
connect( this, SIGNAL( activated( int ) ), this, SLOT( addDownloadJob() ) );
|
||||
}
|
||||
|
||||
|
||||
DownloadButton::~DownloadButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadButton::setQuery( const query_ptr& query )
|
||||
{
|
||||
if ( !m_query.isNull() )
|
||||
{
|
||||
m_query->disconnect( this );
|
||||
}
|
||||
if ( !m_result.isNull() )
|
||||
{
|
||||
m_result->disconnect( this );
|
||||
}
|
||||
|
||||
clear();
|
||||
m_result.clear();
|
||||
|
||||
m_query = query;
|
||||
|
||||
if ( query.isNull() )
|
||||
return;
|
||||
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result.isNull() )
|
||||
return;
|
||||
|
||||
QStringList formats;
|
||||
foreach ( const DownloadFormat& format, result->downloadFormats() )
|
||||
{
|
||||
formats << QObject::tr( "Download %1" ).arg( format.extension.toUpper() );
|
||||
}
|
||||
|
||||
addItems( formats );
|
||||
}
|
||||
|
||||
void
|
||||
DownloadButton::addDownloadJob()
|
||||
{
|
||||
if ( m_query.isNull() )
|
||||
return;
|
||||
|
||||
Tomahawk::result_ptr result = m_query->numResults( true ) ? m_query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result.isNull() )
|
||||
return;
|
||||
|
||||
if ( handleClickPreDownload( m_query ) )
|
||||
return;
|
||||
|
||||
if ( !result->downloadFormats().isEmpty() )
|
||||
{
|
||||
if ( m_view && m_index.isValid() )
|
||||
{
|
||||
m_view->closePersistentEditor( m_index );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_result = result;
|
||||
connect( result.data(), SIGNAL( updated() ), SLOT( update() ) );
|
||||
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( update() ) );
|
||||
}
|
||||
|
||||
DownloadManager::instance()->addJob( result->toDownloadJob( result->downloadFormats().at( currentIndex() ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
handleClickPostDownload( m_query );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadButton::paintEvent( QPaintEvent* event )
|
||||
{
|
||||
QPainter p( this );
|
||||
setupPainter( &p );
|
||||
|
||||
if ( DownloadButton::drawPrimitive( &p, contentsRect(), m_query, m_hovering ) )
|
||||
setCursor( Qt::PointingHandCursor );
|
||||
else
|
||||
setCursor( Qt::ArrowCursor );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DownloadButton::drawPrimitive( QPainter* painter, const QRect& rect, const Tomahawk::query_ptr& query, bool hovering )
|
||||
{
|
||||
if ( query.isNull() )
|
||||
return false;
|
||||
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result.isNull() )
|
||||
return false;
|
||||
|
||||
if ( result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
|
||||
{
|
||||
// if downloadJob exists and is not finished, paint a progress bar
|
||||
painter->save();
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( rect.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = rect.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float( result->downloadJob()->progressPercentage() ) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
painter->restore();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString text;
|
||||
bool itemsAvailable = false;
|
||||
if ( result &&
|
||||
( ( !result->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() ) ||
|
||||
( result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished ) ) )
|
||||
{
|
||||
text = QObject::tr( "View in Finder" );
|
||||
}
|
||||
else if ( !result->downloadFormats().isEmpty() )
|
||||
{
|
||||
text = tr( "Download %1" ).arg( query->results().first()->downloadFormats().first().extension.toUpper() );
|
||||
itemsAvailable = true;
|
||||
}
|
||||
else if ( !result->purchaseUrl().isEmpty() )
|
||||
{
|
||||
text = tr( "Buy" );
|
||||
}
|
||||
|
||||
if ( !text.isEmpty() )
|
||||
DropDownButton::drawPrimitive( painter, rect, text, hovering, itemsAvailable );
|
||||
else
|
||||
{
|
||||
// this result can neither be bought nor downloaded
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DownloadButton::handleEditorEvent(QEvent* event , QAbstractItemView* view, PlayableProxyModel* model, const QModelIndex& index)
|
||||
{
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
PlayableItem* item = model->sourceModel()->itemFromIndex( model->mapToSource( index ) );
|
||||
if ( !item && ! item->query() )
|
||||
return false;
|
||||
|
||||
if ( handleClickPreDownload( item->query() ) )
|
||||
return true;
|
||||
|
||||
if( item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
{
|
||||
model->sourceModel()->setAllColumnsEditable( true );
|
||||
view->edit( index );
|
||||
model->sourceModel()->setAllColumnsEditable( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
return handleClickPostDownload( item->query() );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DownloadButton::handleClickPreDownload( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
// view in folder
|
||||
if ( !DownloadManager::instance()->localUrlForDownload( query ).isEmpty() )
|
||||
{
|
||||
QDesktopServices::openUrl( DownloadManager::instance()->localUrlForDownload( query ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
// download in progress
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result && result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
|
||||
{
|
||||
// do nothing, handled
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DownloadButton::handleClickPostDownload( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
// handle buy click
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result && !result->purchaseUrl().isEmpty() )
|
||||
{
|
||||
WebPopup* popup = new WebPopup( result->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( result.data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
DownloadButton::handleCreateEditor( QWidget* parent, const query_ptr& query, QAbstractItemView* view, const QModelIndex& index )
|
||||
{
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result && !result->downloadFormats().isEmpty() && !result->downloadJob() )
|
||||
{
|
||||
return new DownloadButton( query, parent, view, index );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
61
src/libtomahawk/widgets/DownloadButton.h
Normal file
61
src/libtomahawk/widgets/DownloadButton.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DOWNLOADBUTTON_H
|
||||
#define DOWNLOADBUTTON_H
|
||||
|
||||
#include "DropDownButton.h"
|
||||
#include "playlist/PlayableProxyModel.h"
|
||||
|
||||
#include "Typedefs.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
class DLLEXPORT DownloadButton : public DropDownButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadButton( const Tomahawk::query_ptr& query, QWidget* parent = nullptr, QAbstractItemView* view = nullptr, const QModelIndex& index = QModelIndex() );
|
||||
explicit DownloadButton( QWidget* parent = nullptr );
|
||||
virtual ~DownloadButton();
|
||||
|
||||
void setQuery( const Tomahawk::query_ptr& query );
|
||||
|
||||
static bool drawPrimitive( QPainter* p, const QRect& rect, const Tomahawk::query_ptr& query, bool hovering );
|
||||
static bool handleEditorEvent( QEvent* event, QAbstractItemView* view, PlayableProxyModel* model, const QModelIndex& index );
|
||||
static QWidget* handleCreateEditor( QWidget* parent, const Tomahawk::query_ptr& query , QAbstractItemView* view, const QModelIndex& index );
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent* event );
|
||||
|
||||
private slots:
|
||||
void addDownloadJob();
|
||||
|
||||
private:
|
||||
static bool handleClickPreDownload( const Tomahawk::query_ptr& query );
|
||||
static bool handleClickPostDownload( const Tomahawk::query_ptr& query );
|
||||
void init();
|
||||
|
||||
Tomahawk::query_ptr m_query;
|
||||
Tomahawk::result_ptr m_result;
|
||||
QAbstractItemView* m_view;
|
||||
QModelIndex m_index;
|
||||
};
|
||||
|
||||
#endif // DOWNLOADBUTTON_H
|
@@ -47,7 +47,7 @@ protected:
|
||||
|
||||
private slots:
|
||||
|
||||
private:
|
||||
protected:
|
||||
static void setupPainter( QPainter* p );
|
||||
|
||||
bool m_hovering;
|
||||
|
@@ -100,7 +100,6 @@ INCLUDE_DIRECTORIES(
|
||||
${THIRDPARTY_DIR}/kdsingleapplicationguard/
|
||||
|
||||
${LIBATTICA_INCLUDE_DIR}
|
||||
${ECHONEST_INCLUDE_DIR}
|
||||
${LIBLASTFM_INCLUDE_DIRS}
|
||||
${Boost_INCLUDE_DIR}
|
||||
)
|
||||
@@ -202,7 +201,6 @@ TARGET_LINK_LIBRARIES( ${TOMAHAWK_APPLICATION_TARGET}
|
||||
${OS_SPECIFIC_LINK_LIBRARIES}
|
||||
${QT_LIBRARIES}
|
||||
${MAC_EXTRA_LIBS}
|
||||
${ECHONEST_LIBRARIES}
|
||||
${Boost_LIBRARIES}
|
||||
)
|
||||
|
||||
|
@@ -30,7 +30,6 @@
|
||||
#include "infosystem/InfoSystem.h"
|
||||
#include "infosystem/InfoSystemCache.h"
|
||||
#include "playlist/dynamic/GeneratorFactory.h"
|
||||
#include "playlist/dynamic/echonest/EchonestGenerator.h"
|
||||
#include "playlist/dynamic/database/DatabaseGenerator.h"
|
||||
#include "playlist/XspfUpdater.h"
|
||||
#include "network/Servent.h"
|
||||
@@ -45,7 +44,6 @@
|
||||
#include "Pipeline.h"
|
||||
#include "DropJob.h"
|
||||
#include "DownloadManager.h"
|
||||
#include "EchonestCatalogSynchronizer.h"
|
||||
#include "database/DatabaseImpl.h"
|
||||
#include "network/Msg.h"
|
||||
#include "utils/NetworkAccessManager.h"
|
||||
@@ -243,10 +241,13 @@ TomahawkApp::init()
|
||||
QByteArray wand = QByteArray::fromBase64( QCoreApplication::applicationName().toLatin1() );
|
||||
int length = magic.length(), n2 = wand.length();
|
||||
for ( int i = 0; i < length; i++ ) magic[i] = magic[i] ^ wand[i%n2];
|
||||
// echonest is dead, disable all echonest code
|
||||
/*
|
||||
Echonest::Config::instance()->setAPIKey( magic );
|
||||
|
||||
tDebug() << "Init Echonest Factory.";
|
||||
GeneratorFactory::registerFactory( "echonest", new EchonestFactory );
|
||||
*/
|
||||
tDebug() << "Init Database Factory.";
|
||||
GeneratorFactory::registerFactory( "database", new DatabaseFactory );
|
||||
|
||||
@@ -634,8 +635,11 @@ TomahawkApp::onInfoSystemReady()
|
||||
|
||||
TomahawkSettings* s = TomahawkSettings::instance();
|
||||
|
||||
// echonest is dead, disable all echonest code
|
||||
/*
|
||||
Echonest::Config::instance()->setNetworkAccessManager( Tomahawk::Utils::nam() );
|
||||
EchonestGenerator::setupCatalogs();
|
||||
*/
|
||||
|
||||
m_scanManager = QPointer<ScanManager>( new ScanManager( this ) );
|
||||
if ( !m_headless )
|
||||
@@ -681,8 +685,11 @@ TomahawkApp::onInfoSystemReady()
|
||||
m_scrobbler = new Scrobbler( this );
|
||||
#endif
|
||||
|
||||
// echonest is dead, disable all echonest code
|
||||
/*
|
||||
// Set up echonest catalog synchronizer
|
||||
Tomahawk::EchonestCatalogSynchronizer::instance();
|
||||
*/
|
||||
|
||||
PlaylistUpdaterInterface::registerUpdaterFactory( new XspfUpdaterFactory );
|
||||
// PlaylistUpdaterInterface::registerUpdaterFactory( new SpotifyUpdaterFactory );
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2012, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
|
||||
@@ -683,7 +683,8 @@ TomahawkWindow::setupSignals()
|
||||
connect( ac->getAction( "quit" ), SIGNAL( triggered() ), qApp, SLOT( quit() ) );
|
||||
connect( ac->getAction( "showOfflineSources" ), SIGNAL( triggered() ), SLOT( showOfflineSources() ) );
|
||||
connect( ac->getAction( "createPlaylist" ), SIGNAL( triggered() ), SLOT( createPlaylist() ) );
|
||||
connect( ac->getAction( "createStation" ), SIGNAL( triggered() ), SLOT( createStation() ) );
|
||||
// echonest is dead, disable stations
|
||||
// connect( ac->getAction( "createStation" ), SIGNAL( triggered() ), SLOT( createStation() ) );
|
||||
|
||||
#if defined( Q_OS_MAC )
|
||||
connect( ac->getAction( "minimize" ), SIGNAL( triggered() ), SLOT( minimize() ) );
|
||||
@@ -722,11 +723,13 @@ TomahawkWindow::eventFilter( QObject* obj, QEvent* event )
|
||||
{
|
||||
case Qt::XButton1:
|
||||
m_backAction->trigger();
|
||||
break;
|
||||
event->accept();
|
||||
return true;
|
||||
|
||||
case Qt::XButton2:
|
||||
m_forwardAction->trigger();
|
||||
break;
|
||||
event->accept();
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -849,7 +852,7 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState )
|
||||
Q_UNUSED(newState);
|
||||
#else
|
||||
updatePreview();
|
||||
|
||||
|
||||
QWinThumbnailToolButton *play = m_taskbarList->buttons()[ TP_PLAY_PAUSE ];
|
||||
switch ( newState )
|
||||
{
|
||||
@@ -890,6 +893,7 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState )
|
||||
#endif//Q_OS_WIN
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkWindow::onHistoryBackAvailable( bool avail )
|
||||
{
|
||||
|
@@ -126,6 +126,8 @@ SettingsDialog::SettingsDialog(QObject *parent )
|
||||
m_advancedWidgetUi->enableProxyCheckBox->setChecked( useProxy );
|
||||
m_advancedWidgetUi->proxyButton->setEnabled( useProxy );
|
||||
|
||||
m_advancedWidgetUi->vlcArgsLineEdit->setText( s->vlcArguments() );
|
||||
|
||||
m_advancedWidgetUi->aclEntryClearButton->setEnabled( TomahawkSettings::instance()->aclEntries().size() > 0 );
|
||||
connect( m_advancedWidgetUi->aclEntryClearButton, SIGNAL( clicked( bool ) ), this, SLOT( aclEntryClearButtonClicked() ) );
|
||||
|
||||
@@ -297,6 +299,9 @@ SettingsDialog::SettingsDialog(QObject *parent )
|
||||
|
||||
connect( m_dialog, SIGNAL( accepted() ), SLOT( saveSettings() ) );
|
||||
connect( m_dialog, SIGNAL( rejected() ), SLOT( onRejected() ) );
|
||||
|
||||
// Echonest is dead, make catalog upload checkbox invisible
|
||||
m_collectionWidgetUi->enableEchonestCatalog->setVisible( false );
|
||||
}
|
||||
|
||||
|
||||
@@ -332,6 +337,9 @@ SettingsDialog::saveSettings()
|
||||
s->applyChanges();
|
||||
s->sync();
|
||||
|
||||
m_restartRequired = m_restartRequired || m_advancedWidgetUi->vlcArgsLineEdit->text() != s->vlcArguments();
|
||||
s->setVlcArguments( m_advancedWidgetUi->vlcArgsLineEdit->text() );
|
||||
|
||||
if ( m_restartRequired )
|
||||
QMessageBox::information( 0, tr( "Information" ), tr( "Some changed settings will not take effect until %applicationName is restarted" ) );
|
||||
|
||||
|
@@ -6,8 +6,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>515</width>
|
||||
<height>475</height>
|
||||
<width>540</width>
|
||||
<height>520</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -250,6 +250,36 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="vlcGroupBox">
|
||||
<property name="title">
|
||||
<string>VLC settings</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Additional command line arguments</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>(separate with comma)</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="vlcArgsLineEdit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer_4">
|
||||
<property name="orientation">
|
||||
|
@@ -223,7 +223,6 @@ SourcesModel::index( int row, int column, const QModelIndex& parent ) const
|
||||
}
|
||||
|
||||
return QModelIndex();
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CategoryItems.h"
|
||||
@@ -33,12 +33,6 @@
|
||||
#include "utils/ImageRegistry.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
||||
#include <echonest5/Playlist.h>
|
||||
#else
|
||||
#include <echonest/Playlist.h>
|
||||
#endif
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
|
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CATEGORY_ITEM_H
|
||||
|
@@ -30,9 +30,9 @@ public:
|
||||
explicit CollectionItem( SourcesModel* model, SourceTreeItem* parent, const Tomahawk::collection_ptr& collection );
|
||||
virtual ~CollectionItem();
|
||||
|
||||
virtual QString text() const;
|
||||
virtual QIcon icon() const;
|
||||
virtual int peerSortValue() const;
|
||||
virtual QString text() const override;
|
||||
virtual QIcon icon() const override;
|
||||
virtual int peerSortValue() const override;
|
||||
void setSortValue( int value );
|
||||
|
||||
bool isBeingPlayed() const override;
|
||||
@@ -40,7 +40,7 @@ public:
|
||||
int trackCount() const;
|
||||
|
||||
public slots:
|
||||
virtual void activate();
|
||||
virtual void activate() override;
|
||||
|
||||
private:
|
||||
int m_sortValue;
|
||||
|
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "GenericPageItems.h"
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user