mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-14 16:02:33 +02:00
Compare commits
2 Commits
open-in-fi
...
linkparser
Author | SHA1 | Date | |
---|---|---|---|
|
8ddc270c8c | ||
|
47e09fbaca |
@@ -307,10 +307,11 @@ else()
|
||||
message(STATUS "${CMAKE_CXX_COMPILER} does not support C++11, please use a
|
||||
different compiler")
|
||||
endif()
|
||||
if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR APPLE) AND LIBCPP_FOUND)
|
||||
if(LIBCPP_FOUND AND APPLE)
|
||||
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")
|
||||
|
||||
@@ -403,7 +404,7 @@ if( WIN32 )
|
||||
endif( WIN32 )
|
||||
|
||||
if( WIN32 OR APPLE )
|
||||
macro_optional_find_package(LibsnoreQt5 0.6.0 QUIET)
|
||||
macro_optional_find_package(LibsnoreQt5 0.5.70 QUIET)
|
||||
macro_log_feature(LibsnoreQt5_FOUND "Libsnore" "Library for notifications" "https://projects.kde.org/projects/playground/libs/snorenotify" FALSE "" "")
|
||||
endif()
|
||||
|
||||
|
@@ -18,10 +18,11 @@
|
||||
!ifndef MINGW_ROOT
|
||||
!define MINGW_ROOT "/usr/i686-w64-mingw32/sys-root/mingw"
|
||||
!endif
|
||||
!define APPLICATION_NAME "@CPACK_PACKAGE_NAME@"
|
||||
!define TARGET_NAME "@CPACK_PACKAGE_TARGET_NAME@"
|
||||
|
||||
!define APPLICATION_NAME "Tomahawk"
|
||||
!define TARGET_NAME "tomahawk"
|
||||
;define app id needed for Windows 8 notifications
|
||||
!define AppUserModelId "@TOMAHAWK_APPLICATION_PACKAGE_NAME@"
|
||||
!define AppUserModelId @TOMAHAWK_APPLICATION_PACKAGE_NAME@
|
||||
|
||||
!define MINGW_BIN "${MINGW_ROOT}/bin"
|
||||
!define MINGW_LIB "${MINGW_ROOT}/lib"
|
||||
@@ -346,108 +347,105 @@ Section "${APPLICATION_NAME}" SEC_TOMAHAWK_PLAYER
|
||||
File "${QT_DLL_PATH}\icudata56.dll"
|
||||
File "${QT_DLL_PATH}\icui18n56.dll"
|
||||
|
||||
;SQLite driver
|
||||
SetOutPath "$INSTDIR\sqldrivers"
|
||||
File "${SQLITE_DLL_PATH}\qsqlite.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${MINGW_BIN}\libsqlite3-0.dll"
|
||||
;SQLite driver
|
||||
SetOutPath "$INSTDIR\sqldrivers"
|
||||
File "${SQLITE_DLL_PATH}\qsqlite.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${MINGW_BIN}\libsqlite3-0.dll"
|
||||
|
||||
;Qt platform plugins
|
||||
SetOutPath "$INSTDIR\platforms"
|
||||
File "${MINGW_LIB}/qt5/plugins/platforms/qwindows.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
;Qt platform plugins
|
||||
SetOutPath "$INSTDIR\platforms"
|
||||
File "${MINGW_LIB}/qt5/plugins/platforms/qwindows.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;Image plugins
|
||||
SetOutPath "$INSTDIR\imageformats"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qgif.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qjpeg.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qsvg.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
;Image plugins
|
||||
SetOutPath "$INSTDIR\imageformats"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qgif.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qjpeg.dll"
|
||||
File "${IMAGEFORMATS_DLL_PATH}\qsvg.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;Qt qml plugins
|
||||
SetOutPath "$INSTDIR\QtQuick.2"
|
||||
File /r /x *.debug "${QT_QML_PATH}\QtQuick.2\*"
|
||||
SetOutPath "$INSTDIR\QtQuick\Window.2"
|
||||
File /r /x *.debug "${QT_QML_PATH}\QtQuick\Window.2\*"
|
||||
SetOutPath "$INSTDIR"
|
||||
;Qt qml plugins
|
||||
SetOutPath "$INSTDIR\QtQuick.2"
|
||||
File /r /x *.debug "${QT_QML_PATH}\QtQuick.2\*"
|
||||
SetOutPath "$INSTDIR\QtQuick\Window.2"
|
||||
File /r /x *.debug "${QT_QML_PATH}\QtQuick\Window.2\*"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
;Cygwin/c++ stuff
|
||||
File "${MINGW_BIN}\libgcc_s_sjlj-1.dll"
|
||||
File "${MINGW_BIN}\libstdc++-6.dll"
|
||||
;Cygwin/c++ stuff
|
||||
File "${MINGW_BIN}\libgcc_s_sjlj-1.dll"
|
||||
File "${MINGW_BIN}\libstdc++-6.dll"
|
||||
|
||||
;VLC
|
||||
File "${VLC_BIN}\libvlc.dll"
|
||||
File "${VLC_BIN}\libvlccore.dll"
|
||||
SetOutPath "$INSTDIR\plugins"
|
||||
File /r "${VLC_PLUGIN_PATH}\*.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
;VLC
|
||||
File "${VLC_BIN}\libvlc.dll"
|
||||
File "${VLC_BIN}\libvlccore.dll"
|
||||
SetOutPath "$INSTDIR\plugins"
|
||||
File /r "${VLC_PLUGIN_PATH}\*.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
|
||||
; Other
|
||||
File "${MINGW_BIN}\libtag.dll"
|
||||
File "${MINGW_BIN}\libpng16-16.dll"
|
||||
File "${MINGW_BIN}\libjpeg-8.dll"
|
||||
File "${MINGW_BIN}\zlib1.dll"
|
||||
File "${MINGW_BIN}\libfreetype-6.dll"
|
||||
File "${MINGW_BIN}\libglib-2.0-0.dll"
|
||||
File "${MINGW_BIN}\libharfbuzz-0.dll"
|
||||
; Other
|
||||
File "${MINGW_BIN}\libtag.dll"
|
||||
File "${MINGW_BIN}\libpng16-16.dll"
|
||||
File "${MINGW_BIN}\libjpeg-8.dll"
|
||||
File "${MINGW_BIN}\zlib1.dll"
|
||||
File "${MINGW_BIN}\libfreetype-6.dll"
|
||||
File "${MINGW_BIN}\libglib-2.0-0.dll"
|
||||
File "${MINGW_BIN}\libharfbuzz-0.dll"
|
||||
|
||||
; ANGLE
|
||||
File "${MINGW_BIN}\D3DCompiler_43.dll"
|
||||
File "${MINGW_BIN}\libechonest5.dll"
|
||||
File "${MINGW_BIN}\liblastfm5.dll"
|
||||
File "${MINGW_BIN}\libquazip5.dll"
|
||||
File "${MINGW_BIN}\libqt5keychain.dll"
|
||||
|
||||
File "${MINGW_BIN}\libechonest5.dll"
|
||||
File "${MINGW_BIN}\liblastfm5.dll"
|
||||
File "${MINGW_BIN}\libquazip5.dll"
|
||||
File "${MINGW_BIN}\libqt5keychain.dll"
|
||||
; GnuTLS
|
||||
File "${MINGW_BIN}\libgnutls-28.dll"
|
||||
File "${MINGW_BIN}\libtasn1-6.dll"
|
||||
File "${MINGW_BIN}\libgmp-10.dll"
|
||||
File "${MINGW_BIN}\libhogweed-2-4.dll"
|
||||
File "${MINGW_BIN}\libintl-8.dll"
|
||||
File "${MINGW_BIN}\libnettle-4-6.dll"
|
||||
File "${MINGW_BIN}\libp11-kit-0.dll"
|
||||
File "${MINGW_BIN}\libffi-6.dll"
|
||||
|
||||
; GnuTLS
|
||||
File "${MINGW_BIN}\libgnutls-28.dll"
|
||||
File "${MINGW_BIN}\libtasn1-6.dll"
|
||||
File "${MINGW_BIN}\libgmp-10.dll"
|
||||
File "${MINGW_BIN}\libhogweed-4-1.dll"
|
||||
File "${MINGW_BIN}\libintl-8.dll"
|
||||
File "${MINGW_BIN}\libnettle-6-1.dll"
|
||||
File "${MINGW_BIN}\libp11-kit-0.dll"
|
||||
File "${MINGW_BIN}\libffi-6.dll"
|
||||
; Snorenotify
|
||||
File "${MINGW_BIN}\SnoreToast.exe"
|
||||
File "${MINGW_BIN}\libsnore-qt5.dll"
|
||||
File "${MINGW_BIN}\libsnoresettings-qt5.dll"
|
||||
File "${MINGW_BIN}\snoresettings.exe"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_growl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_settings_backend_growl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_snarl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_settings_backend_snarl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_snore.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_settings_backend_snore.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_windowstoast.dll"
|
||||
|
||||
; Snorenotify
|
||||
File "${MINGW_BIN}\SnoreToast.exe"
|
||||
File "${MINGW_BIN}\libsnore-qt5.dll"
|
||||
File "${MINGW_BIN}\libsnoresettings-qt5.dll"
|
||||
File "${MINGW_BIN}\snoresettings.exe"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_growl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_settings_backend_growl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_snarl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_settings_backend_snarl.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_snore.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_settings_backend_snore.dll"
|
||||
File "${MINGW_LIB}\plugins\libsnore-qt5\libsnore_backend_windowstoast.dll"
|
||||
|
||||
; Snoregrowl
|
||||
File "${MINGW_BIN}\libsnoregrowl++.dll"
|
||||
File "${MINGW_BIN}\libsnoregrowl.dll"
|
||||
; Snoregrowl
|
||||
File "${MINGW_BIN}\libsnoregrowl++.dll"
|
||||
File "${MINGW_BIN}\libsnoregrowl.dll"
|
||||
|
||||
; Jabber
|
||||
File "${MINGW_BIN}\libjreen-qt5.dll"
|
||||
File "${MINGW_BIN}\libidn-11.dll"
|
||||
File "${MINGW_BIN}\libgsasl-7.dll"
|
||||
File "${MINGW_BIN}\libqca-qt5.dll"
|
||||
SetOutPath "$INSTDIR\crypto"
|
||||
File "${MINGW_LIB}\qca-qt5\crypto\libqca-ossl.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${MINGW_BIN}\libssl-10.dll"
|
||||
File "${MINGW_BIN}\libcrypto-10.dll"
|
||||
File "${MINGW_BIN}\libjreen-qt5.dll"
|
||||
File "${MINGW_BIN}\libidn-11.dll"
|
||||
File "${MINGW_BIN}\libgsasl-7.dll"
|
||||
File "${MINGW_BIN}\libqca-qt5.dll"
|
||||
SetOutPath "$INSTDIR\crypto"
|
||||
File "${MINGW_LIB}\qca-qt5\crypto\libqca-ossl.dll"
|
||||
SetOutPath "$INSTDIR"
|
||||
File "${MINGW_BIN}\libssl-10.dll"
|
||||
File "${MINGW_BIN}\libcrypto-10.dll"
|
||||
|
||||
; LucenePlusPlus
|
||||
File "${MINGW_BIN}\liblucene++.dll"
|
||||
File "${MINGW_BIN}\libboost_system-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_filesystem-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_iostreams-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_regex-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_thread-mt.dll"
|
||||
File "${MINGW_BIN}\libbz2-1.dll"
|
||||
; LucenePlusPlus
|
||||
File "${MINGW_BIN}\liblucene++.dll"
|
||||
File "${MINGW_BIN}\libboost_system-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_filesystem-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_iostreams-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_regex-mt.dll"
|
||||
File "${MINGW_BIN}\libboost_thread-mt.dll"
|
||||
File "${MINGW_BIN}\libbz2-1.dll"
|
||||
|
||||
File "${MINGW_BIN}\libqtsparkle-qt5.dll"
|
||||
File "${MINGW_BIN}\libKF5Attica.dll"
|
||||
File "${MINGW_BIN}\libqtsparkle-qt5.dll"
|
||||
File "${MINGW_BIN}\libKF5Attica.dll"
|
||||
SectionEnd
|
||||
|
||||
SectionGroup "Shortcuts"
|
||||
|
@@ -2,7 +2,7 @@ INCLUDE( InstallRequiredSystemLibraries )
|
||||
|
||||
SET( CPACK_PACKAGE_CONTACT "Dominik Schmidt <domme@tomahawk-player.org>" )
|
||||
|
||||
SET( CPACK_PACKAGE_FILE_NAME "${TOMAHAWK_TARGET_NAME}-${TOMAHAWK_VERSION}" ) # Package file name without extension. Also a directory of installer cmake-2.5.0-Linux-i686
|
||||
SET( CPACK_PACKAGE_FILE_NAME "${TOMAHAWK_APPLICATION_NAME}-${TOMAHAWK_VERSION}" ) # Package file name without extension. Also a directory of installer cmake-2.5.0-Linux-i686
|
||||
|
||||
# CPACK_GENERATOR CPack generator to be used STGZ;TGZ;TZ
|
||||
# CPACK_INCLUDE_TOPLEVEL_DIRECTORY Controls whether CPack adds a top-level directory, usually of the form ProjectName-Version-OS, to the top of package tree. 0 to disable, 1 to enable
|
||||
@@ -13,9 +13,7 @@ SET( CPACK_PACKAGE_DESCRIPTION_SUMMARY ${TOMAHAWK_DESCRIPTION_SUMMARY} ) # Des
|
||||
SET( CPACK_PACKAGE_INSTALL_DIRECTORY ${TOMAHAWK_APPLICATION_NAME} ) # Installation directory on the target system -> C:\Program Files\fellody
|
||||
SET( CPACK_PACKAGE_INSTALL_REGISTRY_KEY ${TOMAHAWK_APPLICATION_NAME} ) # Registry key used when installing this project CMake 2.5.0
|
||||
SET( CPACK_PACKAGE_NAME ${TOMAHAWK_APPLICATION_NAME} ) # Package name, defaults to the project name
|
||||
SET( CPACK_PACKAGE_TARGET_NAME ${TOMAHAWK_TARGET_NAME} ) # Used to build library and executable names
|
||||
SET( CPACK_PACKAGE_VENDOR ${TOMAHAWK_ORGANIZATION_NAME} ) # Package vendor name
|
||||
SET( TOMAHAWK_APPLICATION_PACKAGE_NAME ${TOMAHAWK_APPLICATION_PACKAGE_NAME} )
|
||||
SET( CPACK_PACKAGE_VERSION_MAJOR ${TOMAHAWK_VERSION_MAJOR} )
|
||||
SET( CPACK_PACKAGE_VERSION_MINOR ${TOMAHAWK_VERSION_MINOR} )
|
||||
SET( CPACK_PACKAGE_VERSION_PATCH ${TOMAHAWK_VERSION_PATCH} )
|
||||
|
@@ -273,29 +273,19 @@ Tomahawk.Resolver = {
|
||||
getStreamUrl: function (params) {
|
||||
return params;
|
||||
},
|
||||
resolve: function() {
|
||||
},
|
||||
_adapter_resolve: function (params) {
|
||||
return RSVP.Promise.resolve(this.resolve(params)).then(function (results) {
|
||||
if(Array.isArray(results)) {
|
||||
return {
|
||||
'tracks': results
|
||||
};
|
||||
}
|
||||
|
||||
return results;
|
||||
return {
|
||||
'tracks': results
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
_adapter_search: function (params) {
|
||||
return RSVP.Promise.resolve(this.search(params)).then(function (results) {
|
||||
if(Array.isArray(results)) {
|
||||
return {
|
||||
'tracks': results
|
||||
};
|
||||
}
|
||||
|
||||
return results;
|
||||
return {
|
||||
'tracks': results
|
||||
};
|
||||
});
|
||||
},
|
||||
|
||||
|
@@ -24,6 +24,13 @@ include_directories(
|
||||
|
||||
add_definitions(-D_WEBSOCKETPP_CPP11_STL_)
|
||||
|
||||
if(APPLE)
|
||||
# http://stackoverflow.com/questions/7226753/osx-lion-xcode-4-1-how-do-i-setup-a-c0x-project/7236451#7236451
|
||||
add_definitions(-std=c++11 -stdlib=libc++ -U__STRICT_ANSI__)
|
||||
set(PLATFORM_SPECIFIC_LINK_LIBRARIES "/usr/lib/libc++.dylib")
|
||||
else()
|
||||
add_definitions(-std=c++0x)
|
||||
endif()
|
||||
|
||||
tomahawk_add_plugin(hatchet
|
||||
TYPE account
|
||||
|
@@ -69,13 +69,6 @@ Tomahawk::InfoSystem::XmppInfoPlugin::init()
|
||||
}
|
||||
|
||||
|
||||
const QString
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::friendlyName() const
|
||||
{
|
||||
return "xmpp";
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Tomahawk::InfoSystem::XmppInfoPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
||||
{
|
||||
|
@@ -38,8 +38,6 @@ namespace Tomahawk {
|
||||
XmppInfoPlugin(XmppSipPlugin* parent);
|
||||
virtual ~XmppInfoPlugin();
|
||||
|
||||
const QString friendlyName() const override;
|
||||
|
||||
signals:
|
||||
void publishTune( QUrl url, Tomahawk::InfoSystem::InfoStringHash trackInfo );
|
||||
|
||||
|
@@ -194,9 +194,9 @@ InfoSystem::InfoPluginPtr
|
||||
XmppSipPlugin::infoPlugin()
|
||||
{
|
||||
if ( m_infoPlugin.isNull() )
|
||||
m_infoPlugin = QSharedPointer< Tomahawk::InfoSystem::XmppInfoPlugin >( new Tomahawk::InfoSystem::XmppInfoPlugin( this ) );
|
||||
m_infoPlugin = QPointer< Tomahawk::InfoSystem::XmppInfoPlugin >( new Tomahawk::InfoSystem::XmppInfoPlugin( this ) );
|
||||
|
||||
return m_infoPlugin;
|
||||
return InfoSystem::InfoPluginPtr( m_infoPlugin.data() );
|
||||
}
|
||||
|
||||
|
||||
@@ -285,7 +285,7 @@ XmppSipPlugin::onConnect()
|
||||
// load XmppInfoPlugin
|
||||
if ( infoPlugin() && Tomahawk::InfoSystem::InfoSystem::instance()->workerThread() )
|
||||
{
|
||||
infoPlugin()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
infoPlugin().data()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin() );
|
||||
}
|
||||
|
||||
@@ -359,6 +359,7 @@ XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
|
||||
if ( !m_infoPlugin.isNull() )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( infoPlugin() );
|
||||
delete m_infoPlugin;
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -128,7 +128,7 @@ private:
|
||||
int m_currentPort;
|
||||
QString m_currentResource;
|
||||
|
||||
QSharedPointer< Tomahawk::InfoSystem::XmppInfoPlugin > m_infoPlugin;
|
||||
QPointer< Tomahawk::InfoSystem::XmppInfoPlugin > m_infoPlugin;
|
||||
Tomahawk::Accounts::Account::ConnectionState m_state;
|
||||
|
||||
// sort out
|
||||
|
@@ -34,7 +34,7 @@ public:
|
||||
* Creates a Playdar HTTP interface
|
||||
* @param ha Address to listen on
|
||||
* @param port Port to listen on with HTTP
|
||||
* @param sport Port to listen on with HTTPS
|
||||
* @param sport Pot to listen on with HTTPS
|
||||
* @param parent
|
||||
*/
|
||||
explicit PlaydarApi( QHostAddress ha, qint16 port, qint16 sport, QObject *parent = 0 );
|
||||
|
@@ -33,7 +33,6 @@
|
||||
|
||||
#include <QReadWriteLock>
|
||||
#include <QPixmapCache>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -76,7 +75,6 @@ Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCr
|
||||
}
|
||||
|
||||
album_ptr album = album_ptr( new Album( name, artist ), &Album::deleteLater );
|
||||
album->moveToThread( QCoreApplication::instance()->thread() );
|
||||
album->setWeakRef( album.toWeakRef() );
|
||||
album->loadId( autoCreate );
|
||||
s_albumsByName.insert( key, album );
|
||||
|
@@ -36,7 +36,6 @@
|
||||
|
||||
#include <QReadWriteLock>
|
||||
#include <QPixmapCache>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -110,7 +109,6 @@ Artist::get( unsigned int id, const QString& name )
|
||||
}
|
||||
|
||||
artist_ptr a = artist_ptr( new Artist( id, name ), &Artist::deleteLater );
|
||||
a->moveToThread( QCoreApplication::instance()->thread() );
|
||||
a->setWeakRef( a.toWeakRef() );
|
||||
s_artistsByName.insert( key, a );
|
||||
|
||||
|
@@ -67,7 +67,7 @@ AtticaManager::AtticaManager( QObject* parent )
|
||||
connect( &m_manager, SIGNAL( providerAdded( Attica::Provider ) ), this, SLOT( providerAdded( Attica::Provider ) ) );
|
||||
|
||||
// resolvers
|
||||
// m_manager.addProviderFile( QUrl( "http://v09.bakery.tomahawk-player.org/resolvers/providers.xml" ) );
|
||||
// m_manager.addProviderFile( QUrl( "http://bakery.tomahawk-player.org/resolvers/providers.xml" ) );
|
||||
|
||||
const QString url = QString( "%1/resolvers/providers.xml?version=%2" ).arg( hostname() ).arg( TomahawkUtils::appFriendlyVersion() );
|
||||
QNetworkReply* reply = Tomahawk::Utils::nam()->get( QNetworkRequest( QUrl( url ) ) );
|
||||
@@ -116,7 +116,7 @@ AtticaManager::fetchMissingIcons()
|
||||
QString
|
||||
AtticaManager::hostname() const
|
||||
{
|
||||
return "http://v09.bakery.tomahawk-player.org";
|
||||
return "http://bakery.tomahawk-player.org";
|
||||
}
|
||||
|
||||
|
||||
|
@@ -37,7 +37,6 @@ set( libGuiSources
|
||||
jobview/ErrorStatusMessage.cpp
|
||||
jobview/IndexingJobItem.cpp
|
||||
jobview/InboxJobItem.cpp
|
||||
jobview/ScriptErrorStatusMessage.cpp
|
||||
|
||||
playlist/InboxModel.cpp
|
||||
playlist/InboxView.cpp
|
||||
@@ -127,6 +126,8 @@ set( libGuiSources
|
||||
utils/LinkGenerator.cpp
|
||||
utils/LinkGeneratorPlugin.cpp
|
||||
utils/TomaHkLinkGeneratorPlugin.cpp
|
||||
utils/LinkParser.cpp
|
||||
utils/LinkParserPlugin.cpp
|
||||
|
||||
viewpages/SearchViewPage.cpp
|
||||
viewpages/SourceViewPage.cpp
|
||||
@@ -351,8 +352,6 @@ list(APPEND libSources
|
||||
resolvers/ScriptCommand_AllArtists.cpp
|
||||
resolvers/ScriptCommand_AllAlbums.cpp
|
||||
resolvers/ScriptCommand_AllTracks.cpp
|
||||
resolvers/ScriptCommand_LookupUrl.cpp
|
||||
resolvers/ScriptCommandQueue.cpp
|
||||
resolvers/ScriptPluginFactory.cpp
|
||||
|
||||
# ScriptPlugins
|
||||
@@ -360,6 +359,8 @@ list(APPEND libSources
|
||||
resolvers/plugins/ScriptCollectionFactory.cpp
|
||||
resolvers/ScriptInfoPlugin.cpp
|
||||
resolvers/plugins/ScriptInfoPluginFactory.cpp
|
||||
resolvers/plugins/ScriptLinkParserPlugin.cpp
|
||||
resolvers/plugins/ScriptLinkParserPluginFactory.cpp
|
||||
|
||||
|
||||
sip/SipPlugin.cpp
|
||||
@@ -367,6 +368,7 @@ list(APPEND libSources
|
||||
sip/PeerInfo.cpp
|
||||
sip/SipStatusMessage.cpp
|
||||
|
||||
utils/UrlType.cpp
|
||||
utils/Cloudstream.cpp
|
||||
utils/Json.cpp
|
||||
utils/TomahawkUtils.cpp
|
||||
@@ -418,7 +420,7 @@ include_directories(
|
||||
${Boost_INCLUDE_DIR}
|
||||
|
||||
${LIBPORTFWD_INCLUDE_DIR}
|
||||
${QUAZIP_INCLUDE_DIRS}
|
||||
${QUAZIP_INCLUDE_DIR}
|
||||
${QTKEYCHAIN_INCLUDE_DIRS}
|
||||
)
|
||||
|
||||
|
@@ -37,9 +37,6 @@
|
||||
#include "utils/ImageRegistry.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
@@ -54,7 +51,7 @@ ContextMenu::ContextMenu( QWidget* parent )
|
||||
m_sigmap = new QSignalMapper( this );
|
||||
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) );
|
||||
|
||||
clear();
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionPlaylist | ActionCopyLink | ActionLove | ActionStopAfter | ActionPage | ActionEditMetadata | ActionSend;
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +69,7 @@ ContextMenu::clear()
|
||||
m_albums.clear();
|
||||
m_artists.clear();
|
||||
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionPlaylist | ActionCopyLink | ActionLove | ActionStopAfter | ActionPage | ActionEditMetadata | ActionSend | ActionOpenFileManager;
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionPlaylist | ActionCopyLink | ActionLove | ActionStopAfter | ActionPage | ActionEditMetadata | ActionSend;
|
||||
}
|
||||
|
||||
|
||||
@@ -242,13 +239,6 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
m_sigmap->setMapping( addAction( tr( "Mark as &Listened" ) ), ActionMarkListened );
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionOpenFileManager && queries.length() == 1 && m_queries.first()->results().first()->resolvedByCollection()->isLocal() )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Open Folder in File Manager..." ) ), ActionOpenFileManager );
|
||||
}
|
||||
|
||||
if ( m_supportedActions & ActionDelete )
|
||||
m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Remove Items" ) : tr( "&Remove Item" ) ), ActionDelete );
|
||||
|
||||
@@ -404,15 +394,6 @@ ContextMenu::onTriggered( int action )
|
||||
}
|
||||
break;
|
||||
|
||||
case ActionOpenFileManager:
|
||||
{
|
||||
result_ptr result = m_queries.first()->results().first();
|
||||
QString path = QFileInfo( result->url() ).path();
|
||||
tLog() << Q_FUNC_INFO << "open directory" << path;
|
||||
QDesktopServices::openUrl( path );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
emit triggered( action );
|
||||
}
|
||||
|
@@ -37,22 +37,21 @@ Q_OBJECT
|
||||
public:
|
||||
enum MenuActions
|
||||
{
|
||||
ActionPlay = 1,
|
||||
ActionQueue = 2,
|
||||
ActionDelete = 4,
|
||||
ActionCopyLink = 8,
|
||||
ActionLove = 16,
|
||||
ActionStopAfter = 32,
|
||||
ActionPage = 64,
|
||||
ActionTrackPage = 128,
|
||||
ActionArtistPage = 256,
|
||||
ActionAlbumPage = 512,
|
||||
ActionEditMetadata = 1024,
|
||||
ActionPlaylist = 2048,
|
||||
ActionSend = 4096,
|
||||
ActionMarkListened = 8192,
|
||||
ActionDownload = 16384,
|
||||
ActionOpenFileManager = 32768
|
||||
ActionPlay = 1,
|
||||
ActionQueue = 2,
|
||||
ActionDelete = 4,
|
||||
ActionCopyLink = 8,
|
||||
ActionLove = 16,
|
||||
ActionStopAfter = 32,
|
||||
ActionPage = 64,
|
||||
ActionTrackPage = 128,
|
||||
ActionArtistPage = 256,
|
||||
ActionAlbumPage = 512,
|
||||
ActionEditMetadata = 1024,
|
||||
ActionPlaylist = 2048,
|
||||
ActionSend = 4096,
|
||||
ActionMarkListened = 8192,
|
||||
ActionDownload = 16384
|
||||
};
|
||||
|
||||
explicit ContextMenu( QWidget* parent = 0 );
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2012, 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
|
||||
@@ -35,6 +36,7 @@
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
#include "utils/XspfLoader.h"
|
||||
#include "utils/LinkParser.h"
|
||||
|
||||
#include "Artist.h"
|
||||
#include "Album.h"
|
||||
@@ -172,12 +174,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
||||
if ( url.contains( "grooveshark.com" ) && url.contains( "playlist" ) )
|
||||
return true;
|
||||
|
||||
// Check Scriptresolvers
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
{
|
||||
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypePlaylist ) )
|
||||
return true;
|
||||
}
|
||||
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypePlaylist );
|
||||
}
|
||||
|
||||
if ( acceptedType.testFlag( Track ) )
|
||||
@@ -198,12 +195,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
||||
|| url.contains( "playlists" ) ) ) )
|
||||
return true;
|
||||
|
||||
// Check Scriptresolvers
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
{
|
||||
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeTrack ) )
|
||||
return true;
|
||||
}
|
||||
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypeTrack );
|
||||
}
|
||||
|
||||
if ( acceptedType.testFlag( Album ) )
|
||||
@@ -215,12 +207,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
||||
if ( url.contains( "rdio.com" ) && ( url.contains( "artist" ) && url.contains( "album" ) && !url.contains( "track" ) ) )
|
||||
return true;
|
||||
|
||||
// Check Scriptresolvers
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
{
|
||||
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeAlbum ) )
|
||||
return true;
|
||||
}
|
||||
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypeAlbum );
|
||||
}
|
||||
|
||||
if ( acceptedType.testFlag( Artist ) )
|
||||
@@ -232,12 +219,7 @@ DropJob::acceptsMimeData( const QMimeData* data, DropJob::DropTypes acceptedType
|
||||
if ( url.contains( "rdio.com" ) && ( url.contains( "artist" ) && !url.contains( "album" ) && !url.contains( "track" ) ) )
|
||||
return true;
|
||||
|
||||
// Check Scriptresolvers
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
{
|
||||
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeArtist ) )
|
||||
return true;
|
||||
}
|
||||
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypeArtist );
|
||||
}
|
||||
|
||||
// We whitelist certain url-shorteners since they do some link checking. Often playable (e.g. spotify) links hide behind them,
|
||||
@@ -263,14 +245,9 @@ bool
|
||||
DropJob::validateLocalFiles(const QString &paths, const QString &suffix)
|
||||
{
|
||||
QStringList filePaths = paths.split( QRegExp( "\\s+" ), QString::SkipEmptyParts );
|
||||
QStringList::iterator it = filePaths.begin();
|
||||
while ( it != filePaths.end() )
|
||||
{
|
||||
for ( QStringList::iterator it = filePaths.begin(); it != filePaths.end(); ++it )
|
||||
if ( !validateLocalFile( *it, suffix ) )
|
||||
it = filePaths.erase( it );
|
||||
else
|
||||
++it;
|
||||
}
|
||||
filePaths.erase( it );
|
||||
return !filePaths.isEmpty();
|
||||
}
|
||||
|
||||
@@ -308,15 +285,7 @@ DropJob::isDropType( DropJob::DropType desired, const QMimeData* data )
|
||||
if ( ShortenedLinkParser::handlesUrl( url ) )
|
||||
return true;
|
||||
|
||||
// Check Scriptresolvers
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
{
|
||||
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypePlaylist ) )
|
||||
{
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Accepting current drop as a playlist" << resolver->name();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return Tomahawk::Utils::LinkParser::instance()->canParseUrl( url, Tomahawk::Utils::UrlTypePlaylist );
|
||||
|
||||
}
|
||||
|
||||
@@ -766,16 +735,12 @@ DropJob::handleTrackUrls( const QString& urls )
|
||||
|
||||
foreach ( QString track, tracks )
|
||||
{
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
QList< QSharedPointer< Utils::LinkParserPlugin > > parserPlugins = Utils::LinkParser::instance()->parserPluginsForUrl( track, Utils::UrlTypeAny );
|
||||
if( !parserPlugins.isEmpty() )
|
||||
{
|
||||
if ( resolver->canParseUrl( track, ExternalResolver::UrlTypeAny ) )
|
||||
{
|
||||
ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, track );
|
||||
connect( cmd, SIGNAL( information( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
|
||||
cmd->enqueue();
|
||||
m_queryCount++;
|
||||
break;
|
||||
}
|
||||
Tomahawk::Utils::LinkParser::instance()->lookupUrl( track, parserPlugins );
|
||||
connect( Tomahawk::Utils::LinkParser::instance(), SIGNAL( informationFound( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
|
||||
m_queryCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
* 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) 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
|
||||
@@ -35,13 +36,13 @@
|
||||
#include "playlist/TrackView.h"
|
||||
#include "playlist/PlayableModel.h"
|
||||
#include "resolvers/ExternalResolver.h"
|
||||
#include "resolvers/ScriptCommand_LookupUrl.h"
|
||||
#include "utils/JspfLoader.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/SpotifyParser.h"
|
||||
#include "utils/XspfLoader.h"
|
||||
#include "utils/XspfGenerator.h"
|
||||
#include "viewpages/SearchViewPage.h"
|
||||
#include "utils/LinkParser.h"
|
||||
|
||||
#include "Pipeline.h"
|
||||
#include "TomahawkSettings.h"
|
||||
@@ -162,27 +163,12 @@ GlobalActionManager::openUrl( const QString& url )
|
||||
else if ( url.contains( "open.spotify.com" ) || url.startsWith( "spotify:" ) )
|
||||
return openSpotifyLink( url );
|
||||
|
||||
// Can we parse the Url using a ScriptResolver?
|
||||
bool canParse = false;
|
||||
QList< QPointer< ExternalResolver > > possibleResolvers;
|
||||
foreach ( QPointer<ExternalResolver> resolver, Pipeline::instance()->scriptResolvers() )
|
||||
// Can we parse the Url using LinkParser?
|
||||
QList< QSharedPointer< Utils::LinkParserPlugin > > parserPlugins = Utils::LinkParser::instance()->parserPluginsForUrl( url, Utils::UrlTypeAny );
|
||||
if( !parserPlugins.isEmpty() )
|
||||
{
|
||||
if ( resolver->canParseUrl( url, ExternalResolver::UrlTypeAny ) )
|
||||
{
|
||||
canParse = true;
|
||||
possibleResolvers << resolver;
|
||||
}
|
||||
}
|
||||
if ( canParse )
|
||||
{
|
||||
m_queuedUrl = url;
|
||||
foreach ( QPointer<ExternalResolver> resolver, possibleResolvers )
|
||||
{
|
||||
ScriptCommand_LookupUrl* cmd = new ScriptCommand_LookupUrl( resolver, url );
|
||||
connect( cmd, SIGNAL( information( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ) );
|
||||
cmd->enqueue();
|
||||
}
|
||||
|
||||
Tomahawk::Utils::LinkParser::instance()->lookupUrl( url, parserPlugins );
|
||||
connect( Tomahawk::Utils::LinkParser::instance(), SIGNAL( informationFound( QString, QSharedPointer<QObject> ) ), this, SLOT( informationForUrl( QString, QSharedPointer<QObject> ) ), Qt::UniqueConnection );
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -595,8 +595,8 @@ Pipeline::shunt( const query_ptr& q )
|
||||
// we get here if we disable a resolver while a query is resolving
|
||||
// OR we are just out of resolvers while query is still resolving
|
||||
|
||||
// since we seem to at least tried to kick off all of the resolvers,
|
||||
// remove the '.keep' entry
|
||||
//since we seem to at least tried to kick off all of the resolvers,
|
||||
//remove the '.keep' entry
|
||||
decQIDState( q, nullptr );
|
||||
return;
|
||||
}
|
||||
@@ -636,7 +636,7 @@ Pipeline::checkQIDState( const Tomahawk::query_ptr& query )
|
||||
Q_D( Pipeline );
|
||||
QMutexLocker lock( &d->mut );
|
||||
|
||||
tDebug() << Q_FUNC_INFO << query->id() << d->qidsState.count( query->id() );
|
||||
tDebug() << Q_FUNC_INFO << " " << query->id() << " " << d->qidsState.count( query->id() );
|
||||
|
||||
if ( d->qidsState.contains( query->id() ) )
|
||||
{
|
||||
|
@@ -33,7 +33,6 @@
|
||||
|
||||
#include <QtAlgorithms>
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -48,7 +47,6 @@ Query::get( const QString& artist, const QString& track, const QString& album, c
|
||||
autoResolve = false;
|
||||
|
||||
query_ptr q = query_ptr( new Query( Track::get( artist, track, album ), qid, autoResolve ), &QObject::deleteLater );
|
||||
q->moveToThread( QCoreApplication::instance()->thread() );
|
||||
q->setWeakRef( q.toWeakRef() );
|
||||
|
||||
if ( autoResolve )
|
||||
@@ -405,17 +403,12 @@ Query::resultSorter( const result_ptr& left, const result_ptr& right )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( left->isPreview() != right->isPreview() )
|
||||
if ( !right->isPreview() )
|
||||
{
|
||||
return !left->isPreview();
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( left->resolvedBy() != nullptr && right->resolvedBy() != nullptr )
|
||||
{
|
||||
return left->resolvedBy()->weight() > right->resolvedBy()->weight();
|
||||
}
|
||||
|
||||
return left->id() > right->id();
|
||||
return true;
|
||||
}
|
||||
|
||||
if ( left->isPreview() != right->isPreview() )
|
||||
@@ -643,11 +636,6 @@ Query::howSimilar( const Tomahawk::result_ptr& r )
|
||||
qTrackname = queryTrack()->trackSortname();
|
||||
}
|
||||
|
||||
//Cleanup symbols for minor naming differences
|
||||
qArtistname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
||||
qTrackname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
||||
qAlbumname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
||||
|
||||
// normal edit distance
|
||||
const int artdist = TomahawkUtils::levenshtein( qArtistname, rArtistname );
|
||||
const int trkdist = TomahawkUtils::levenshtein( qTrackname, rTrackname );
|
||||
|
@@ -35,8 +35,6 @@
|
||||
#include "Track.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
static QHash< QString, result_wptr > s_results;
|
||||
@@ -71,7 +69,6 @@ Result::get( const QString& url, const track_ptr& track )
|
||||
}
|
||||
|
||||
result_ptr r = result_ptr( new Result( url, track ), &Result::deleteLater );
|
||||
r->moveToThread( QCoreApplication::instance()->thread() );
|
||||
r->setWeakRef( r.toWeakRef() );
|
||||
s_results.insert( url, r );
|
||||
|
||||
@@ -135,19 +132,11 @@ Result::deleteLater()
|
||||
void
|
||||
Result::onResolverRemoved( Tomahawk::Resolver* resolver )
|
||||
{
|
||||
m_mutex.lock();
|
||||
|
||||
if ( m_resolver.data() == resolver )
|
||||
{
|
||||
m_resolver = 0;
|
||||
m_mutex.unlock();
|
||||
|
||||
emit statusChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,8 +150,6 @@ Result::resolvedByCollection() const
|
||||
QString
|
||||
Result::url() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_url;
|
||||
}
|
||||
|
||||
@@ -170,8 +157,6 @@ Result::url() const
|
||||
bool
|
||||
Result::checked() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_checked;
|
||||
}
|
||||
|
||||
@@ -179,8 +164,6 @@ Result::checked() const
|
||||
bool
|
||||
Result::isPreview() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_isPreview;
|
||||
}
|
||||
|
||||
@@ -188,8 +171,6 @@ Result::isPreview() const
|
||||
QString
|
||||
Result::mimetype() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_mimetype;
|
||||
}
|
||||
|
||||
@@ -197,8 +178,6 @@ Result::mimetype() const
|
||||
RID
|
||||
Result::id() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
if ( m_rid.isEmpty() )
|
||||
m_rid = uuid();
|
||||
|
||||
@@ -215,8 +194,6 @@ Result::isOnline() const
|
||||
}
|
||||
else
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return !m_resolver.isNull();
|
||||
}
|
||||
}
|
||||
@@ -237,26 +214,24 @@ Result::playable() const
|
||||
QVariant
|
||||
Result::toVariant() const
|
||||
{
|
||||
track_ptr t = track();
|
||||
|
||||
QVariantMap m;
|
||||
m.insert( "artist", t->artist() );
|
||||
m.insert( "album", t->album() );
|
||||
m.insert( "track", t->track() );
|
||||
m.insert( "artist", m_track->artist() );
|
||||
m.insert( "album", m_track->album() );
|
||||
m.insert( "track", m_track->track() );
|
||||
m.insert( "source", friendlySource() );
|
||||
m.insert( "mimetype", mimetype() );
|
||||
m.insert( "size", size() );
|
||||
m.insert( "bitrate", bitrate() );
|
||||
m.insert( "duration", t->duration() );
|
||||
m.insert( "duration", m_track->duration() );
|
||||
// m.insert( "score", score() );
|
||||
m.insert( "sid", id() );
|
||||
m.insert( "discnumber", t->discnumber() );
|
||||
m.insert( "albumpos", t->albumpos() );
|
||||
m.insert( "discnumber", m_track->discnumber() );
|
||||
m.insert( "albumpos", m_track->albumpos() );
|
||||
m.insert( "preview", isPreview() );
|
||||
m.insert( "purchaseUrl", purchaseUrl() );
|
||||
|
||||
if ( !t->composer().isEmpty() )
|
||||
m.insert( "composer", t->composer() );
|
||||
if ( !m_track->composer().isEmpty() )
|
||||
m.insert( "composer", m_track->composer() );
|
||||
|
||||
return m;
|
||||
}
|
||||
@@ -265,25 +240,20 @@ Result::toVariant() const
|
||||
QString
|
||||
Result::toString() const
|
||||
{
|
||||
m_mutex.lock();
|
||||
track_ptr track = m_track;
|
||||
QString url = m_url;
|
||||
m_mutex.unlock();
|
||||
|
||||
if ( track )
|
||||
if ( m_track )
|
||||
{
|
||||
return QString( "Result(%1) %2 - %3%4 (%5)" )
|
||||
.arg( id() )
|
||||
.arg( track->artist() )
|
||||
.arg( track->track() )
|
||||
.arg( track->album().isEmpty() ? QString() : QString( " on %1" ).arg( track->album() ) )
|
||||
.arg( url );
|
||||
.arg( m_track->artist() )
|
||||
.arg( m_track->track() )
|
||||
.arg( m_track->album().isEmpty() ? QString() : QString( " on %1" ).arg( m_track->album() ) )
|
||||
.arg( m_url );
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString( "Result(%1) (%2)" )
|
||||
.arg( id() )
|
||||
.arg( url );
|
||||
.arg( m_url );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -291,8 +261,6 @@ Result::toString() const
|
||||
Tomahawk::query_ptr
|
||||
Result::toQuery()
|
||||
{
|
||||
QMutexLocker l( &m_mutex );
|
||||
|
||||
if ( m_query.isNull() )
|
||||
{
|
||||
query_ptr query = Tomahawk::Query::get( m_track );
|
||||
@@ -302,15 +270,12 @@ Result::toQuery()
|
||||
m_query = query->weakRef();
|
||||
|
||||
QList<Tomahawk::result_ptr> rl;
|
||||
rl << m_ownRef.toStrongRef();
|
||||
m_mutex.unlock();
|
||||
rl << weakRef().toStrongRef();
|
||||
query->addResults( rl );
|
||||
m_mutex.lock();
|
||||
query->setResolveFinished( true );
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
return m_query.toStrongRef();
|
||||
}
|
||||
|
||||
@@ -330,10 +295,9 @@ Result::onOffline()
|
||||
|
||||
|
||||
void
|
||||
Result::setResolvedByCollection( const Tomahawk::collection_ptr& collection, bool emitOnlineEvents )
|
||||
Result::setResolvedByCollection( const Tomahawk::collection_ptr& collection , bool emitOnlineEvents )
|
||||
{
|
||||
m_collection = collection;
|
||||
|
||||
if ( emitOnlineEvents )
|
||||
{
|
||||
Q_ASSERT( !collection.isNull() );
|
||||
@@ -347,8 +311,6 @@ Result::setResolvedByCollection( const Tomahawk::collection_ptr& collection, boo
|
||||
void
|
||||
Result::setFriendlySource( const QString& s )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_friendlySource = s;
|
||||
}
|
||||
|
||||
@@ -356,8 +318,6 @@ Result::setFriendlySource( const QString& s )
|
||||
void
|
||||
Result::setPreview( bool isPreview )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_isPreview = isPreview;
|
||||
}
|
||||
|
||||
@@ -365,8 +325,6 @@ Result::setPreview( bool isPreview )
|
||||
void
|
||||
Result::setPurchaseUrl( const QString& u )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_purchaseUrl = u;
|
||||
}
|
||||
|
||||
@@ -374,8 +332,6 @@ Result::setPurchaseUrl( const QString& u )
|
||||
void
|
||||
Result::setLinkUrl( const QString& u )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_linkUrl = u;
|
||||
}
|
||||
|
||||
@@ -383,8 +339,6 @@ Result::setLinkUrl( const QString& u )
|
||||
void
|
||||
Result::setChecked( bool checked )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_checked = checked;
|
||||
}
|
||||
|
||||
@@ -392,8 +346,6 @@ Result::setChecked( bool checked )
|
||||
void
|
||||
Result::setMimetype( const QString& mimetype )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_mimetype = mimetype;
|
||||
}
|
||||
|
||||
@@ -401,8 +353,6 @@ Result::setMimetype( const QString& mimetype )
|
||||
void
|
||||
Result::setBitrate( unsigned int bitrate )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_bitrate = bitrate;
|
||||
}
|
||||
|
||||
@@ -410,8 +360,6 @@ Result::setBitrate( unsigned int bitrate )
|
||||
void
|
||||
Result::setSize( unsigned int size )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_size = size;
|
||||
}
|
||||
|
||||
@@ -419,8 +367,6 @@ Result::setSize( unsigned int size )
|
||||
void
|
||||
Result::setModificationTime( unsigned int modtime )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_modtime = modtime;
|
||||
}
|
||||
|
||||
@@ -428,8 +374,6 @@ Result::setModificationTime( unsigned int modtime )
|
||||
void
|
||||
Result::setTrack( const track_ptr& track )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_track = track;
|
||||
}
|
||||
|
||||
@@ -437,8 +381,6 @@ Result::setTrack( const track_ptr& track )
|
||||
unsigned int
|
||||
Result::fileId() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_fileId;
|
||||
}
|
||||
|
||||
@@ -448,8 +390,6 @@ Result::friendlySource() const
|
||||
{
|
||||
if ( resolvedByCollection().isNull() )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_friendlySource;
|
||||
}
|
||||
else
|
||||
@@ -460,8 +400,6 @@ Result::friendlySource() const
|
||||
QString
|
||||
Result::purchaseUrl() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_purchaseUrl;
|
||||
}
|
||||
|
||||
@@ -469,8 +407,6 @@ Result::purchaseUrl() const
|
||||
QString
|
||||
Result::linkUrl() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_linkUrl;
|
||||
}
|
||||
|
||||
@@ -480,8 +416,6 @@ Result::sourceIcon( TomahawkUtils::ImageMode style, const QSize& desiredSize ) c
|
||||
{
|
||||
if ( resolvedByCollection().isNull() )
|
||||
{
|
||||
//QMutexLocker lock( &m_mutex );
|
||||
|
||||
const ExternalResolver* resolver = qobject_cast< ExternalResolver* >( m_resolver.data() );
|
||||
if ( !resolver )
|
||||
{
|
||||
@@ -532,8 +466,6 @@ Result::sourceIcon( TomahawkUtils::ImageMode style, const QSize& desiredSize ) c
|
||||
unsigned int
|
||||
Result::bitrate() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_bitrate;
|
||||
}
|
||||
|
||||
@@ -541,8 +473,6 @@ Result::bitrate() const
|
||||
unsigned int
|
||||
Result::size() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_size;
|
||||
}
|
||||
|
||||
@@ -550,8 +480,6 @@ Result::size() const
|
||||
unsigned int
|
||||
Result::modificationTime() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_modtime;
|
||||
}
|
||||
|
||||
@@ -559,8 +487,6 @@ Result::modificationTime() const
|
||||
void
|
||||
Result::setFileId( unsigned int id )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_fileId = id;
|
||||
}
|
||||
|
||||
@@ -568,8 +494,6 @@ Result::setFileId( unsigned int id )
|
||||
Tomahawk::Resolver*
|
||||
Result::resolvedBy() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
if ( !m_collection.isNull() )
|
||||
return m_collection.data();
|
||||
|
||||
@@ -580,16 +504,12 @@ Result::resolvedBy() const
|
||||
void
|
||||
Result::setResolvedByResolver( Tomahawk::Resolver* resolver )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_resolver = QPointer< Tomahawk::Resolver >( resolver );
|
||||
}
|
||||
|
||||
|
||||
QPointer< Resolver > Result::resolvedByResolver() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_resolver;
|
||||
}
|
||||
|
||||
@@ -605,29 +525,16 @@ Result::doneEditing()
|
||||
track_ptr
|
||||
Result::track() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_track;
|
||||
}
|
||||
|
||||
|
||||
QList< DownloadFormat >
|
||||
Result::downloadFormats() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_formats;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
Result::setDownloadFormats( const QList<DownloadFormat>& formats )
|
||||
{
|
||||
if ( formats.isEmpty() )
|
||||
return;
|
||||
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_formats.clear();
|
||||
foreach ( const DownloadFormat& format, formats )
|
||||
{
|
||||
@@ -655,7 +562,7 @@ Result::setDownloadFormats( const QList<DownloadFormat>& formats )
|
||||
void
|
||||
Result::onSettingsChanged()
|
||||
{
|
||||
if ( TomahawkSettings::instance()->downloadsPreferredFormat().toLower() != downloadFormats().first().extension.toLower() )
|
||||
if ( TomahawkSettings::instance()->downloadsPreferredFormat().toLower() != m_formats.first().extension.toLower() )
|
||||
{
|
||||
setDownloadFormats( downloadFormats() );
|
||||
emit updated();
|
||||
@@ -692,8 +599,6 @@ Result::onDownloadJobStateChanged( DownloadJob::TrackState newState, DownloadJob
|
||||
QWeakPointer<Result>
|
||||
Result::weakRef()
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_ownRef;
|
||||
}
|
||||
|
||||
@@ -701,7 +606,5 @@ Result::weakRef()
|
||||
void
|
||||
Result::setWeakRef( QWeakPointer<Result> weakRef )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
m_ownRef = weakRef;
|
||||
}
|
||||
|
@@ -31,7 +31,6 @@
|
||||
#include <QPixmap>
|
||||
#include <QPointer>
|
||||
#include <QVariant>
|
||||
#include <QMutex>
|
||||
|
||||
class MetadataEditor;
|
||||
|
||||
@@ -132,7 +131,7 @@ public:
|
||||
|
||||
track_ptr track() const;
|
||||
|
||||
QList< DownloadFormat > downloadFormats() const;
|
||||
QList<DownloadFormat> downloadFormats() const { return m_formats; }
|
||||
void setDownloadFormats( const QList<DownloadFormat>& formats );
|
||||
|
||||
downloadjob_ptr downloadJob() const { return m_downloadJob; }
|
||||
@@ -162,8 +161,6 @@ private:
|
||||
explicit Result( const QString& url, const Tomahawk::track_ptr& track );
|
||||
explicit Result();
|
||||
|
||||
mutable QMutex m_mutex;
|
||||
|
||||
mutable RID m_rid;
|
||||
collection_wptr m_collection;
|
||||
QPointer< Tomahawk::Resolver > m_resolver;
|
||||
|
@@ -37,7 +37,6 @@
|
||||
#include <QtAlgorithms>
|
||||
#include <QDateTime>
|
||||
#include <QReadWriteLock>
|
||||
#include <QCoreApplication>
|
||||
|
||||
|
||||
using namespace Tomahawk;
|
||||
@@ -93,7 +92,6 @@ Track::get( const QString& artist, const QString& track, const QString& album, c
|
||||
}
|
||||
|
||||
track_ptr t = track_ptr( new Track( artist, track, album, albumArtist, duration, composer, albumpos, discnumber ), &Track::deleteLater );
|
||||
t->moveToThread( QCoreApplication::instance()->thread() );
|
||||
t->setWeakRef( t.toWeakRef() );
|
||||
s_tracksByName.insert( key, t );
|
||||
|
||||
|
@@ -19,7 +19,8 @@
|
||||
|
||||
#include "TrackData.h"
|
||||
|
||||
|
||||
#include <QtAlgorithms>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
#include "audio/AudioEngine.h"
|
||||
#include "collection/Collection.h"
|
||||
@@ -40,10 +41,6 @@
|
||||
#include "PlaylistEntry.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
#include <QtAlgorithms>
|
||||
#include <QReadWriteLock>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
QHash< QString, trackdata_wptr > TrackData::s_trackDatasByName = QHash< QString, trackdata_wptr >();
|
||||
@@ -87,7 +84,6 @@ TrackData::get( unsigned int id, const QString& artist, const QString& track )
|
||||
}
|
||||
|
||||
trackdata_ptr t = trackdata_ptr( new TrackData( id, artist, track ), &TrackData::deleteLater );
|
||||
t->moveToThread( QCoreApplication::instance()->thread() );
|
||||
t->setWeakRef( t.toWeakRef() );
|
||||
s_trackDatasByName.insert( key, t );
|
||||
|
||||
|
@@ -253,7 +253,7 @@ namespace Tomahawk
|
||||
typedef QHash< QString, QString > InfoStringHash;
|
||||
typedef QPair< QVariantMap, QVariant > PushInfoPair;
|
||||
|
||||
typedef QSharedPointer< InfoPlugin > InfoPluginPtr;
|
||||
typedef QPointer< InfoPlugin > InfoPluginPtr;
|
||||
}
|
||||
|
||||
namespace Network
|
||||
|
@@ -79,7 +79,7 @@ ResolverAccountFactory::createFromPath( const QString& path )
|
||||
}
|
||||
|
||||
|
||||
ResolverAccount*
|
||||
Account*
|
||||
ResolverAccountFactory::createFromPath( const QString& path, const QString& factory, bool isAttica )
|
||||
{
|
||||
qDebug() << "Creating ResolverAccount from path:" << path << "is attica" << isAttica;
|
||||
@@ -110,8 +110,57 @@ ResolverAccountFactory::createFromPath( const QString& path, const QString& fact
|
||||
|
||||
if ( pathInfo.suffix() == "axe" )
|
||||
{
|
||||
if ( !installAxe( realPath, configuration ) )
|
||||
QString uniqueName = uuid();
|
||||
QDir dir( TomahawkUtils::extractScriptPayload( pathInfo.filePath(),
|
||||
uniqueName,
|
||||
MANUALRESOLVERS_DIR ) );
|
||||
if ( !( dir.exists() && dir.isReadable() ) ) //decompression fubar
|
||||
{
|
||||
displayError( tr( "Resolver installation error: cannot open bundle." ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !dir.cd( "content" ) ) //more fubar
|
||||
{
|
||||
displayError( tr( "Resolver installation error: incomplete bundle." ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString metadataFilePath = dir.absoluteFilePath( "metadata.json" );
|
||||
configuration = metadataFromJsonFile( metadataFilePath );
|
||||
|
||||
configuration[ "bundleDir" ] = uniqueName;
|
||||
|
||||
if ( !configuration[ "pluginName" ].isNull() && !configuration[ "pluginName" ].toString().isEmpty() )
|
||||
{
|
||||
dir.cdUp();
|
||||
if ( !dir.cdUp() ) //we're in MANUALRESOLVERS_DIR
|
||||
return 0;
|
||||
|
||||
QString name = configuration[ "pluginName" ].toString();
|
||||
|
||||
QString namePath = dir.absoluteFilePath( name );
|
||||
QFileInfo npI( namePath );
|
||||
|
||||
if ( npI.exists() && npI.isDir() )
|
||||
{
|
||||
TomahawkUtils::removeDirectory( namePath );
|
||||
}
|
||||
|
||||
dir.rename( uniqueName, name );
|
||||
|
||||
configuration[ "bundleDir" ] = name;
|
||||
|
||||
if ( !dir.cd( QString( "%1/content" ).arg( name ) ) ) //should work if it worked once
|
||||
return 0;
|
||||
}
|
||||
|
||||
expandPaths( dir, configuration );
|
||||
|
||||
realPath = configuration[ "path" ].toString();
|
||||
if ( realPath.isEmpty() )
|
||||
{
|
||||
displayError( tr( "Resolver installation error: bad metadata in bundle." ) );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -172,71 +221,6 @@ ResolverAccountFactory::createFromPath( const QString& path, const QString& fact
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ResolverAccountFactory::installAxe( QString& realPath, QVariantHash& configuration )
|
||||
{
|
||||
const QFileInfo pathInfo( realPath );
|
||||
QString uniqueName = uuid();
|
||||
QDir dir( TomahawkUtils::extractScriptPayload( pathInfo.filePath(),
|
||||
uniqueName,
|
||||
MANUALRESOLVERS_DIR ) );
|
||||
if ( !( dir.exists() && dir.isReadable() ) ) //decompression fubar
|
||||
{
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage(
|
||||
tr( "Resolver installation error: cannot open bundle." ) ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ( !dir.cd( "content" ) ) //more fubar
|
||||
{
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage(
|
||||
tr( "Resolver installation error: incomplete bundle." ) ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
QString metadataFilePath = dir.absoluteFilePath( "metadata.json" );
|
||||
configuration = metadataFromJsonFile( metadataFilePath );
|
||||
|
||||
configuration[ "bundleDir" ] = uniqueName;
|
||||
|
||||
if ( !configuration[ "pluginName" ].isNull() && !configuration[ "pluginName" ].toString().isEmpty() )
|
||||
{
|
||||
dir.cdUp();
|
||||
if ( !dir.cdUp() ) //we're in MANUALRESOLVERS_DIR
|
||||
return 0;
|
||||
|
||||
QString name = configuration[ "pluginName" ].toString();
|
||||
|
||||
QString namePath = dir.absoluteFilePath( name );
|
||||
QFileInfo npI( namePath );
|
||||
|
||||
if ( npI.exists() && npI.isDir() )
|
||||
{
|
||||
TomahawkUtils::removeDirectory( namePath );
|
||||
}
|
||||
|
||||
dir.rename( uniqueName, name );
|
||||
|
||||
configuration[ "bundleDir" ] = name;
|
||||
|
||||
if ( !dir.cd( QString( "%1/content" ).arg( name ) ) ) //should work if it worked once
|
||||
return 0;
|
||||
}
|
||||
|
||||
expandPaths( dir, configuration );
|
||||
|
||||
realPath = configuration[ "path" ].toString();
|
||||
if ( realPath.isEmpty() )
|
||||
{
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage(
|
||||
tr( "Resolver installation error: bad metadata in bundle." ) ) );
|
||||
return 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
QVariantHash
|
||||
ResolverAccountFactory::metadataFromJsonFile( const QString& path )
|
||||
{
|
||||
@@ -533,8 +517,7 @@ ResolverAccount::removeBundle()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ResolverAccount::testConfig()
|
||||
void ResolverAccount::testConfig()
|
||||
{
|
||||
// HACK: move to JSAccount once we have that properly
|
||||
JSResolver* resolver = qobject_cast< Tomahawk::JSResolver* >( m_resolver );
|
||||
@@ -552,13 +535,6 @@ ResolverAccount::testConfig()
|
||||
}
|
||||
|
||||
|
||||
ExternalResolverGui*
|
||||
ResolverAccount::resolver() const
|
||||
{
|
||||
return m_resolver;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ResolverAccount::onTestConfig( const QVariantMap& result )
|
||||
{
|
||||
|
@@ -33,8 +33,6 @@ class ExternalResolverGui;
|
||||
|
||||
namespace Accounts {
|
||||
|
||||
class ResolverAccount;
|
||||
|
||||
class DLLEXPORT ResolverAccountFactory : public AccountFactory
|
||||
{
|
||||
Q_OBJECT
|
||||
@@ -55,10 +53,7 @@ public:
|
||||
Account* createFromPath( const QString& path ) override;
|
||||
|
||||
// Internal use
|
||||
static ResolverAccount* createFromPath( const QString& path, const QString& factoryId, bool isAttica );
|
||||
// YES, non const parameters!
|
||||
static bool installAxe( QString& realPath, QVariantHash& configuration );
|
||||
|
||||
static Account* createFromPath( const QString& path, const QString& factoryId, bool isAttica );
|
||||
|
||||
private:
|
||||
static void displayError( const QString& error );
|
||||
@@ -106,8 +101,6 @@ public:
|
||||
|
||||
void testConfig() override;
|
||||
|
||||
ExternalResolverGui* resolver() const;
|
||||
|
||||
private slots:
|
||||
void resolverChanged();
|
||||
void onTestConfig( const QVariantMap& result );
|
||||
|
@@ -71,7 +71,7 @@ LastFmAccount::LastFmAccount( const QString& accountId )
|
||||
|
||||
if ( infoPlugin() && Tomahawk::InfoSystem::InfoSystem::instance()->workerThread() )
|
||||
{
|
||||
infoPlugin()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
infoPlugin().data()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin() );
|
||||
}
|
||||
}
|
||||
@@ -82,6 +82,7 @@ LastFmAccount::~LastFmAccount()
|
||||
if ( m_infoPlugin )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( infoPlugin() );
|
||||
delete m_infoPlugin;
|
||||
}
|
||||
|
||||
delete m_resolver.data();
|
||||
@@ -167,11 +168,9 @@ InfoPluginPtr
|
||||
LastFmAccount::infoPlugin()
|
||||
{
|
||||
if ( m_infoPlugin.isNull() )
|
||||
{
|
||||
m_infoPlugin = QSharedPointer< LastFmInfoPlugin>( new LastFmInfoPlugin( this ) );
|
||||
}
|
||||
m_infoPlugin = QPointer< LastFmInfoPlugin >( new LastFmInfoPlugin( this ) );
|
||||
|
||||
return m_infoPlugin;
|
||||
return InfoPluginPtr( m_infoPlugin.data() );
|
||||
}
|
||||
|
||||
bool
|
||||
|
@@ -105,7 +105,7 @@ private:
|
||||
void hookupResolver();
|
||||
|
||||
QPointer<Tomahawk::ExternalResolverGui> m_resolver;
|
||||
QSharedPointer<Tomahawk::InfoSystem::LastFmInfoPlugin> m_infoPlugin;
|
||||
QPointer<Tomahawk::InfoSystem::LastFmInfoPlugin> m_infoPlugin;
|
||||
QPointer<LastFmConfig> m_configWidget;
|
||||
};
|
||||
|
||||
|
@@ -116,12 +116,6 @@ SpotifyAccount::~SpotifyAccount()
|
||||
{
|
||||
clearUser();
|
||||
|
||||
if ( m_infoPlugin )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( infoPlugin() );
|
||||
}
|
||||
|
||||
|
||||
if ( m_spotifyResolver.isNull() )
|
||||
return;
|
||||
|
||||
@@ -141,7 +135,7 @@ SpotifyAccount::init()
|
||||
|
||||
if ( infoPlugin() && Tomahawk::InfoSystem::InfoSystem::instance()->workerThread() )
|
||||
{
|
||||
infoPlugin()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
infoPlugin().data()->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin() );
|
||||
}
|
||||
|
||||
@@ -372,10 +366,10 @@ SpotifyAccount::infoPlugin()
|
||||
{
|
||||
if ( m_infoPlugin.isNull() )
|
||||
{
|
||||
m_infoPlugin = QSharedPointer< InfoSystem::SpotifyInfoPlugin >( new InfoSystem::SpotifyInfoPlugin( this ) );
|
||||
m_infoPlugin = QPointer< InfoSystem::SpotifyInfoPlugin >( new InfoSystem::SpotifyInfoPlugin( this ) );
|
||||
}
|
||||
|
||||
return m_infoPlugin;
|
||||
return InfoSystem::InfoPluginPtr( m_infoPlugin.data() );
|
||||
}
|
||||
|
||||
|
||||
@@ -848,15 +842,28 @@ SpotifyAccount::resolverMessage( const QString &msgType, const QVariantMap &msg
|
||||
const QString qid = msg.value( "qid" ).toString();
|
||||
if ( m_qidToSlotMap.contains( qid ) )
|
||||
{
|
||||
QObject* receiver = m_qidToSlotMap[ qid ].first;
|
||||
QPointer< QObject > receiver = m_qidToSlotMap[ qid ].first;
|
||||
QString slot = m_qidToSlotMap[ qid ].second;
|
||||
m_qidToSlotMap.remove( qid );
|
||||
|
||||
|
||||
QVariant extraData;
|
||||
if ( m_qidToExtraData.contains( qid ) )
|
||||
extraData = m_qidToExtraData.take( qid );
|
||||
|
||||
QMetaObject::invokeMethod( receiver, slot.toLatin1(), Q_ARG( QString, msgType ), Q_ARG( QVariantMap, msg ), Q_ARG( QVariant, extraData ) );
|
||||
// FIXME: SpotifyParser is sometimes a dangling pointer, haven't found a real way to reproduce: happens sometimes when dropping a playlist url onto the sidebar
|
||||
//Q_ASSERT( !receiver.isNull() );
|
||||
|
||||
if ( !receiver.isNull() )
|
||||
{
|
||||
QMetaObject::invokeMethod( receiver, slot.toLatin1(), Q_ARG( QString, msgType ), Q_ARG( QVariantMap, msg ), Q_ARG( QVariant, extraData ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage(
|
||||
tr( "Spotify account could not finish action. Try again." )
|
||||
) );
|
||||
}
|
||||
}
|
||||
else if ( msgType == "allPlaylists" )
|
||||
{
|
||||
|
@@ -170,9 +170,9 @@ private:
|
||||
QPointer<SpotifyAccountConfig> m_configWidget;
|
||||
QPointer<QWidget> m_aboutWidget;
|
||||
QPointer<ScriptResolver> m_spotifyResolver;
|
||||
QSharedPointer< InfoSystem::SpotifyInfoPlugin > m_infoPlugin;
|
||||
QPointer< InfoSystem::SpotifyInfoPlugin > m_infoPlugin;
|
||||
|
||||
QMap<QString, QPair<QObject*, QString> > m_qidToSlotMap;
|
||||
QMap<QString, QPair< QPointer< QObject >, QString> > m_qidToSlotMap;
|
||||
QMap<QString, QVariant > m_qidToExtraData;
|
||||
|
||||
// List of synced spotify playlists in config UI
|
||||
|
@@ -277,7 +277,7 @@ SpotifyAccountConfig::showLoggedIn()
|
||||
m_ui->verticalLayout->insertWidget( 1, m_loggedInUser, 0, Qt::AlignCenter );
|
||||
}
|
||||
|
||||
qDebug() << "Showing logged in with username:" << m_verifiedUsername;
|
||||
qDebug() << "Showing logged in withuserame:" << m_verifiedUsername;
|
||||
m_loggedInUser->show();
|
||||
m_loggedInUser->setText( tr( "Logged in as %1" ).arg( m_verifiedUsername ) );
|
||||
|
||||
|
@@ -669,7 +669,7 @@ AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url )
|
||||
|
||||
|
||||
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 )
|
||||
{
|
||||
if ( QThread::currentThread() != thread() )
|
||||
{
|
||||
@@ -951,9 +951,9 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
|
||||
void
|
||||
AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query )
|
||||
{
|
||||
if ( query->resolvingFinished() || query->numResults( true ) )
|
||||
if ( query->resolvingFinished() )
|
||||
{
|
||||
if ( query->numResults( true ) )
|
||||
if ( query->numResults() && query->results().first()->isOnline() )
|
||||
{
|
||||
playItem( playlist, query->results().first(), query );
|
||||
return;
|
||||
@@ -969,7 +969,7 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
|
||||
{
|
||||
Pipeline::instance()->resolve( query );
|
||||
|
||||
NewClosure( query.data(), SIGNAL( resultsChanged() ),
|
||||
NewClosure( query.data(), SIGNAL( resolvingFinished( bool ) ),
|
||||
const_cast<AudioEngine*>(this), SLOT( playItem( Tomahawk::playlistinterface_ptr, Tomahawk::query_ptr ) ), playlist, query );
|
||||
}
|
||||
}
|
||||
|
@@ -186,7 +186,7 @@ private slots:
|
||||
|
||||
|
||||
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 performLoadTrack( const Tomahawk::result_ptr result, const QString url, QSharedPointer< QIODevice > io ); //only call from loadTrack or performLoadIODevice kthxbi
|
||||
void loadPreviousTrack();
|
||||
void loadNextTrack();
|
||||
|
||||
|
@@ -277,8 +277,8 @@ InfoSystem::addInfoPlugin( Tomahawk::InfoSystem::InfoPluginPtr plugin )
|
||||
|
||||
if ( plugin.data()->thread() != m_infoSystemWorkerThreadController->worker()->thread() )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "The object must be moved to the worker thread first, see InfoSystem::workerThread(): " << plugin->friendlyName();
|
||||
Q_ASSERT( false );
|
||||
tDebug() << Q_FUNC_INFO << "The object must be moved to the worker thread first, see InfoSystem::workerThread()";
|
||||
return;
|
||||
}
|
||||
|
||||
|
@@ -58,7 +58,13 @@ InfoSystemWorker::InfoSystemWorker()
|
||||
|
||||
InfoSystemWorker::~InfoSystemWorker()
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
tDebug() << Q_FUNC_INFO << " beginning";
|
||||
Q_FOREACH( InfoPluginPtr plugin, m_plugins )
|
||||
{
|
||||
if( plugin )
|
||||
delete plugin.data();
|
||||
}
|
||||
tDebug() << Q_FUNC_INFO << " finished";
|
||||
}
|
||||
|
||||
|
||||
@@ -130,6 +136,29 @@ InfoSystemWorker::addInfoPlugin( Tomahawk::InfoSystem::InfoPluginPtr plugin )
|
||||
|
||||
emit updatedSupportedGetTypes( QSet< InfoType >::fromList( m_infoGetMap.keys() ) );
|
||||
emit updatedSupportedPushTypes( QSet< InfoType >::fromList( m_infoPushMap.keys() ) );
|
||||
|
||||
connect( plugin.data(), SIGNAL( destroyed( QObject* ) ), SLOT( onInfoPluginDeleted() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
InfoSystemWorker::onInfoPluginDeleted()
|
||||
{
|
||||
foreach( const InfoPluginPtr& plugin, m_plugins )
|
||||
{
|
||||
if ( plugin.isNull() )
|
||||
{
|
||||
m_plugins.removeOne( plugin );
|
||||
foreach( InfoType type, m_infoGetMap.keys() )
|
||||
{
|
||||
m_infoGetMap[type].removeOne( plugin );
|
||||
}
|
||||
foreach( InfoType type, m_infoPushMap.keys() )
|
||||
{
|
||||
m_infoPushMap[type].removeOne( plugin );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -72,6 +72,7 @@ public slots:
|
||||
|
||||
private slots:
|
||||
void checkTimeoutsTimerFired();
|
||||
void onInfoPluginDeleted();
|
||||
|
||||
private:
|
||||
void registerInfoTypes( const InfoPluginPtr &plugin, const QSet< InfoType > &getTypes, const QSet< InfoType > &pushTypes );
|
||||
|
@@ -33,12 +33,6 @@ JobStatusItem::~JobStatusItem()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobStatusItem::activated()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JobStatusItem::allowMultiLine() const
|
||||
{
|
||||
|
@@ -53,8 +53,6 @@ public:
|
||||
virtual QString mainText() const = 0;
|
||||
virtual QString rightColumnText() const { return QString(); };
|
||||
|
||||
virtual void activated();
|
||||
|
||||
/**
|
||||
* If collapse item is true, sending multiple items of the same type will "collapse" them into one
|
||||
* instead of showing each individually. In this case, the right column from the item will be ignored
|
||||
|
@@ -118,7 +118,6 @@ JobStatusView::setModel( JobStatusSortModel* m )
|
||||
connect( m_view->model(), SIGNAL( customDelegateJobInserted( int, JobStatusItem* ) ), this, SLOT( customDelegateJobInserted( int, JobStatusItem* ) ) );
|
||||
connect( m_view->model(), SIGNAL( customDelegateJobRemoved( int ) ), this, SLOT( customDelegateJobRemoved( int ) ) );
|
||||
connect( m_view->model(), SIGNAL( refreshDelegates() ), this, SLOT( refreshDelegates() ) );
|
||||
connect( m_view, SIGNAL( activated( QModelIndex ) ), this, SLOT( onItemActivated( QModelIndex ) ) );
|
||||
|
||||
foreach ( const QPointer<JobStatusItem> item, s_jobItems )
|
||||
{
|
||||
@@ -185,21 +184,6 @@ JobStatusView::refreshDelegates()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobStatusView::onItemActivated( const QModelIndex& index )
|
||||
{
|
||||
QVariant itemVar = index.data( JobStatusModel::JobDataRole );
|
||||
if ( !itemVar.canConvert< JobStatusItem* >() || !itemVar.value< JobStatusItem* >() )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "unable to fetch JobStatusItem*";
|
||||
return;
|
||||
}
|
||||
|
||||
JobStatusItem* item = itemVar.value< JobStatusItem* >();
|
||||
item->activated();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JobStatusView::checkCount()
|
||||
{
|
||||
|
@@ -59,7 +59,6 @@ private slots:
|
||||
void customDelegateJobInserted( int row, JobStatusItem* item );
|
||||
void customDelegateJobRemoved( int row );
|
||||
void refreshDelegates();
|
||||
void onItemActivated( const QModelIndex& index );
|
||||
|
||||
private:
|
||||
QListView* m_view;
|
||||
|
@@ -118,10 +118,6 @@ ColumnView::setModel( QAbstractItemModel* model )
|
||||
void
|
||||
ColumnView::setTreeModel( TreeModel* model )
|
||||
{
|
||||
// HACK: without setting a new preview widget, the old preview widget is shown in the first column while loading the artists.
|
||||
m_previewWidget = new ColumnViewPreviewWidget( this );
|
||||
setPreviewWidget( m_previewWidget );
|
||||
|
||||
m_model = model;
|
||||
|
||||
if ( m_proxyModel )
|
||||
|
@@ -96,10 +96,8 @@ ContextView::ContextView( QWidget* parent, const QString& caption )
|
||||
|
||||
connect( m_captionLabel, SIGNAL( clicked() ), SIGNAL( closeClicked() ) );
|
||||
connect( m_trackView, SIGNAL( querySelected( Tomahawk::query_ptr ) ), SLOT( onQuerySelected( Tomahawk::query_ptr ) ) );
|
||||
connect( m_trackView, SIGNAL( modelChanged() ), SLOT( onModelChanged() ) );
|
||||
connect( m_trackView, SIGNAL( querySelected( Tomahawk::query_ptr ) ), m_detailView, SLOT( setQuery( Tomahawk::query_ptr ) ) );
|
||||
connect( m_detailView, SIGNAL( downloadAll() ), SLOT( onDownloadAll() ) );
|
||||
connect( m_detailView, SIGNAL( downloadCancel() ), SLOT( onDownloadCancel() ) );
|
||||
connect( m_trackView, SIGNAL( modelChanged() ), SLOT( onModelChanged() ) );
|
||||
|
||||
TomahawkUtils::fixMargins( this );
|
||||
}
|
||||
|
@@ -20,15 +20,11 @@
|
||||
#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,14 +35,12 @@
|
||||
#include "playlist/PlayableItem.h"
|
||||
#include "playlist/PlayableProxyModel.h"
|
||||
#include "widgets/HoverControls.h"
|
||||
#include "widgets/DropDownButton.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"
|
||||
|
||||
@@ -61,7 +55,6 @@ GridItemDelegate::GridItemDelegate( QAbstractItemView* parent, PlayableProxyMode
|
||||
, m_model( proxy )
|
||||
, m_itemWidth( 0 )
|
||||
, m_showPosition( false )
|
||||
, m_showBuyButtons( false )
|
||||
, m_wordWrapping( false )
|
||||
, m_margin( TomahawkUtils::DpiScaler::scaledY( parent, 32 ) )
|
||||
{
|
||||
@@ -100,8 +93,7 @@ GridItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelInde
|
||||
if ( !m_wordWrapping )
|
||||
return QSize( m_itemWidth, m_itemWidth + fm.height() + m_margin * 0.8 );
|
||||
|
||||
const int buyButtonHeight = m_showBuyButtons ? 40 : 0;
|
||||
return QSize( m_itemWidth, m_itemWidth + fm.height() + fms.height() + buyButtonHeight + m_margin * 0.8 );
|
||||
return QSize( m_itemWidth, m_itemWidth + fm.height() + fms.height() + m_margin * 0.8 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -283,11 +275,6 @@ GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
painter->setFont( f );
|
||||
}
|
||||
|
||||
if ( m_showBuyButtons && !item->query().isNull() )
|
||||
{
|
||||
textRect.adjust( 0, 0, 0, -40 );
|
||||
}
|
||||
|
||||
to.setAlignment( Qt::AlignLeft | Qt::AlignTop );
|
||||
text = painter->fontMetrics().elidedText( top, Qt::ElideRight, textRect.width() - m_margin / 4 );
|
||||
painter->drawText( textRect, text, to );
|
||||
@@ -299,7 +286,6 @@ GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
}
|
||||
painter->restore();
|
||||
|
||||
painter->save();
|
||||
painter->setOpacity( 0.6 );
|
||||
painter->setFont( m_smallFont );
|
||||
|
||||
@@ -318,48 +304,6 @@ GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
|
||||
// Calculate rect of artist on-hover button click area
|
||||
m_artistNameRects[ index ] = painter->fontMetrics().boundingRect( textRect, Qt::AlignLeft | Qt::AlignBottom, text );
|
||||
painter->restore();
|
||||
|
||||
if ( m_showBuyButtons && !item->query().isNull() )
|
||||
{
|
||||
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 ) ) )
|
||||
{
|
||||
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
|
||||
{
|
||||
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 );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
painter->restore();
|
||||
@@ -418,7 +362,6 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
|
||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||
bool hoveringArtist = false;
|
||||
bool hoveringAlbum = false;
|
||||
bool hoveringBuyButton = false;
|
||||
if ( m_artistNameRects.contains( index ) )
|
||||
{
|
||||
const QRect artistNameRect = m_artistNameRects[ index ];
|
||||
@@ -429,11 +372,6 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
|
||||
const QRect albumNameRect = m_albumNameRects[ index ];
|
||||
hoveringAlbum = albumNameRect.contains( ev->pos() );
|
||||
}
|
||||
if ( m_buyButtonRects.contains( index ) )
|
||||
{
|
||||
const QRect buyButtonRect = m_buyButtonRects[ index ];
|
||||
hoveringBuyButton = buyButtonRect.contains( ev->pos() );
|
||||
}
|
||||
|
||||
QRect coverRect = m_view->visualRect( index );
|
||||
coverRect.setHeight( coverRect.width() );
|
||||
@@ -441,7 +379,7 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
|
||||
|
||||
if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
if ( hoveringArtist || hoveringAlbum || hoveringBuyButton )
|
||||
if ( hoveringArtist || hoveringAlbum )
|
||||
m_view->setCursor( Qt::PointingHandCursor );
|
||||
else
|
||||
m_view->setCursor( Qt::ArrowCursor );
|
||||
@@ -497,17 +435,6 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
|
||||
|
||||
emit updateIndex( index );
|
||||
}
|
||||
if ( m_hoveringOverBuyButton != index || ( !hoveringBuyButton && m_hoveringOverBuyButton.isValid() ) )
|
||||
{
|
||||
emit updateIndex( m_hoveringOverBuyButton );
|
||||
|
||||
if ( hoveringBuyButton )
|
||||
m_hoveringOverBuyButton = index;
|
||||
else
|
||||
m_hoveringOverBuyButton = QPersistentModelIndex();
|
||||
|
||||
emit updateIndex( index );
|
||||
}
|
||||
|
||||
if ( m_hoverIndex != index || !hoveringCover )
|
||||
{
|
||||
@@ -617,27 +544,6 @@ 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 false;
|
||||
}
|
||||
|
||||
@@ -649,7 +555,6 @@ GridItemDelegate::modelChanged()
|
||||
m_albumNameRects.clear();
|
||||
m_hoveringOverArtist = QPersistentModelIndex();
|
||||
m_hoveringOverAlbum = QPersistentModelIndex();
|
||||
m_hoveringOverBuyButton = QPersistentModelIndex();
|
||||
m_hoverIndex = QPersistentModelIndex();
|
||||
|
||||
clearButtons();
|
||||
@@ -782,10 +687,6 @@ GridItemDelegate::resetHoverIndex()
|
||||
idx = m_hoveringOverAlbum;
|
||||
m_hoveringOverAlbum = QPersistentModelIndex();
|
||||
doUpdateIndex( idx );
|
||||
|
||||
idx = m_hoveringOverBuyButton;
|
||||
m_hoveringOverBuyButton = QPersistentModelIndex();
|
||||
doUpdateIndex( idx );
|
||||
}
|
||||
|
||||
|
||||
@@ -857,97 +758,3 @@ GridItemDelegate::eventFilter( QObject* obj, QEvent* event )
|
||||
else
|
||||
return QObject::eventFilter( obj, event );
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
GridItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GridItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||
|
||||
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
|
||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||
|
||||
if ( m_downloadDropDownRects.contains( index ) )
|
||||
{
|
||||
editor->setGeometry( m_downloadDropDownRects.value( index ) );
|
||||
}
|
||||
|
||||
if ( !comboBox->property( "shownPopup" ).toBool() )
|
||||
{
|
||||
comboBox->showPopup();
|
||||
comboBox->setProperty( "shownPopup", true );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GridItemDelegate::setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const
|
||||
{
|
||||
}
|
||||
|
@@ -48,7 +48,6 @@ public:
|
||||
|
||||
QSize itemSize() const;
|
||||
void setItemWidth( int width ) { m_itemWidth = width; }
|
||||
void setShowBuyButtons( bool enabled ) { m_showBuyButtons = enabled; }
|
||||
|
||||
public slots:
|
||||
void resetHoverIndex();
|
||||
@@ -62,10 +61,6 @@ protected:
|
||||
bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index );
|
||||
bool eventFilter( QObject* obj, QEvent* event );
|
||||
|
||||
QWidget* createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
void setModelData( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const;
|
||||
|
||||
signals:
|
||||
void updateIndex( const QModelIndex& idx );
|
||||
|
||||
@@ -87,9 +82,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();
|
||||
@@ -98,19 +90,15 @@ private:
|
||||
PlayableProxyModel* m_model;
|
||||
int m_itemWidth;
|
||||
bool m_showPosition;
|
||||
bool m_showBuyButtons;
|
||||
bool m_wordWrapping;
|
||||
|
||||
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;
|
||||
QPersistentModelIndex m_hoveringOverArtist;
|
||||
QPersistentModelIndex m_hoveringOverAlbum;
|
||||
QPersistentModelIndex m_hoveringOverBuyButton;
|
||||
|
||||
mutable QHash< QPersistentModelIndex, QWidget* > m_spinner;
|
||||
mutable QHash< QPersistentModelIndex, HoverControls* > m_hoverControls;
|
||||
|
@@ -255,8 +255,6 @@ void GridView::wheelEvent( QWheelEvent* e )
|
||||
// ^ scroll step is 1/8 of the estimated row height
|
||||
|
||||
QListView::wheelEvent( e );
|
||||
|
||||
m_delegate->resetHoverIndex();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -119,9 +119,8 @@ int
|
||||
PlayableModel::columnCount( const QModelIndex& parent ) const
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
Q_D( const PlayableModel );
|
||||
|
||||
return d->header.length();
|
||||
return 13;
|
||||
}
|
||||
|
||||
|
||||
@@ -445,21 +444,14 @@ PlayableModel::flags( const QModelIndex& index ) const
|
||||
|
||||
if ( index.isValid() )
|
||||
{
|
||||
Qt::ItemFlags returnFlags = defaultFlags;
|
||||
if ( index.column() == 0 )
|
||||
{
|
||||
returnFlags |= Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
|
||||
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
|
||||
}
|
||||
else if ( index.column() == PlayableModel::Download )
|
||||
{
|
||||
returnFlags |= Qt::ItemIsEditable | defaultFlags;
|
||||
return Qt::ItemIsEditable | defaultFlags;
|
||||
}
|
||||
|
||||
if ( areAllColumnsEditable() ) {
|
||||
returnFlags |= Qt::ItemIsEditable;
|
||||
}
|
||||
|
||||
return returnFlags;
|
||||
}
|
||||
|
||||
return Qt::ItemIsDropEnabled | defaultFlags;
|
||||
@@ -1027,7 +1019,7 @@ PlayableModel::appendAlbums( const QList< Tomahawk::album_ptr >& albums )
|
||||
void
|
||||
PlayableModel::appendAlbums( const Tomahawk::collection_ptr& collection )
|
||||
{
|
||||
startLoading();
|
||||
emit loadingStarted();
|
||||
insertAlbums( collection, rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
@@ -1042,7 +1034,7 @@ PlayableModel::appendQueries( const QList< Tomahawk::query_ptr >& queries )
|
||||
void
|
||||
PlayableModel::appendTracks( const QList< Tomahawk::track_ptr >& tracks, const QList< Tomahawk::PlaybackLog >& logs )
|
||||
{
|
||||
startLoading();
|
||||
emit loadingStarted();
|
||||
QList< Tomahawk::query_ptr > queries;
|
||||
foreach ( const track_ptr& track, tracks )
|
||||
{
|
||||
@@ -1056,7 +1048,7 @@ PlayableModel::appendTracks( const QList< Tomahawk::track_ptr >& tracks, const Q
|
||||
void
|
||||
PlayableModel::appendTracks( const Tomahawk::collection_ptr& collection )
|
||||
{
|
||||
startLoading();
|
||||
emit loadingStarted();
|
||||
insertTracks( collection, rowCount( QModelIndex() ) );
|
||||
}
|
||||
|
||||
@@ -1179,22 +1171,6 @@ PlayableModel::setIcon( const QPixmap& pixmap )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlayableModel::setAllColumnsEditable( bool editable )
|
||||
{
|
||||
Q_D( PlayableModel );
|
||||
d->areAllColumnsEditable = editable;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlayableModel::areAllColumnsEditable() const
|
||||
{
|
||||
Q_D( const PlayableModel );
|
||||
return d->areAllColumnsEditable;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PlayableModel::trackCount() const
|
||||
{
|
||||
|
@@ -96,11 +96,6 @@ public:
|
||||
virtual QPixmap icon() const;
|
||||
virtual void setIcon( const QPixmap& pixmap );
|
||||
|
||||
|
||||
// HACK: we need to set column 0 editable for DropDownButton in TrackView
|
||||
void setAllColumnsEditable( bool editable );
|
||||
bool areAllColumnsEditable() const;
|
||||
|
||||
virtual int trackCount() const;
|
||||
virtual int itemCount() const;
|
||||
|
||||
|
@@ -38,7 +38,6 @@ public:
|
||||
, rootItem( new PlayableItem( 0 ) )
|
||||
, readOnly( true )
|
||||
, loading( _loading )
|
||||
, areAllColumnsEditable( false )
|
||||
{
|
||||
}
|
||||
|
||||
@@ -59,7 +58,6 @@ private:
|
||||
QStringList header;
|
||||
|
||||
bool loading;
|
||||
bool areAllColumnsEditable;
|
||||
};
|
||||
|
||||
#endif // PLAYABLEMODEL_P_H
|
||||
|
@@ -607,7 +607,25 @@ PlayableProxyModel::columnCount( const QModelIndex& parent ) const
|
||||
{
|
||||
Q_UNUSED( parent );
|
||||
|
||||
return m_headerStyle[ m_style ].length();
|
||||
switch ( m_style )
|
||||
{
|
||||
case SingleColumn:
|
||||
return 1;
|
||||
break;
|
||||
|
||||
case Collection:
|
||||
return 10;
|
||||
break;
|
||||
|
||||
case Locker:
|
||||
return 11;
|
||||
break;
|
||||
|
||||
case Detailed:
|
||||
default:
|
||||
return 12;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -715,13 +733,6 @@ PlayableProxyModel::setFilter( const QString& pattern )
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
PlayableProxyModel::mapSourceColumnToColumn( PlayableModel::Columns column )
|
||||
{
|
||||
return m_headerStyle[ m_style ].indexOf( column );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlayableProxyModel::setCurrentIndex( const QModelIndex& index )
|
||||
{
|
||||
|
@@ -98,8 +98,6 @@ public:
|
||||
virtual void setFilter( const QString& pattern );
|
||||
virtual void updateDetailedInfo( const QModelIndex& index );
|
||||
|
||||
int mapSourceColumnToColumn( PlayableModel::Columns column );
|
||||
|
||||
signals:
|
||||
void filterChanged( const QString& filter );
|
||||
|
||||
|
@@ -23,7 +23,6 @@
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDesktopServices>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QDesktopServices>
|
||||
@@ -52,7 +51,6 @@
|
||||
#include "utils/Closure.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
@@ -125,16 +123,16 @@ 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() &&
|
||||
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 )
|
||||
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() &&
|
||||
else if ( index.column() == PlayableModel::Download && item->result() &&
|
||||
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
|
||||
{
|
||||
QStringList formats;
|
||||
@@ -194,14 +192,9 @@ PlaylistItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionV
|
||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||
|
||||
if ( m_downloadDropDownRects.contains( index ) )
|
||||
{
|
||||
editor->setGeometry( m_downloadDropDownRects.value( index ) );
|
||||
}
|
||||
|
||||
if ( !comboBox->property( "shownPopup" ).toBool() )
|
||||
{
|
||||
comboBox->showPopup();
|
||||
// comboBox->showPopup();
|
||||
comboBox->setProperty( "shownPopup", true );
|
||||
}
|
||||
}
|
||||
@@ -298,8 +291,7 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
|
||||
}
|
||||
else if ( !item->result()->downloadJob() )
|
||||
{
|
||||
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
|
||||
|
||||
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText );
|
||||
/* 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 );*/
|
||||
@@ -612,7 +604,6 @@ QRect
|
||||
PlaylistItemDelegate::drawTrack( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index, const QRect& rect, PlayableItem* item ) const
|
||||
{
|
||||
const track_ptr track = item->query()->track();
|
||||
const bool hasOnlineResults = ( item->query()->numResults( true ) > 0 );
|
||||
|
||||
painter->save();
|
||||
painter->setRenderHint( QPainter::TextAntialiasing );
|
||||
@@ -639,87 +630,21 @@ PlaylistItemDelegate::drawTrack( QPainter* painter, const QStyleOptionViewItem&
|
||||
|
||||
QRect numberRect = QRect( r.x(), r.y(), numberWidth, r.height() );
|
||||
QRect extraRect = QRect( r.x() + r.width() - durationWidth, r.y(), durationWidth, r.height() );
|
||||
QRect stateRect = extraRect.adjusted( 0, 0, 0, 0 );
|
||||
|
||||
if ( option.state & QStyle::State_Selected || hoveringOver() == index )
|
||||
QRect stateRect;
|
||||
if ( option.state & QStyle::State_Selected || hoveringOver() == index )
|
||||
{
|
||||
int h = extraRect.height() / 3;
|
||||
|
||||
if ( track->loved() )
|
||||
{
|
||||
painter->save();
|
||||
painter->setOpacity( 0.5 );
|
||||
QRect r = stateRect.adjusted( -16, extraRect.height() / 2 - h / 2, 0, 0 );
|
||||
r.setHeight( h );
|
||||
r.setWidth( r.height() );
|
||||
painter->drawPixmap( r, ImageRegistry::instance()->pixmap( RESPATH "images/love.svg", r.size() ) );
|
||||
painter->restore();
|
||||
int h = extraRect.height() / 3;
|
||||
stateRect = extraRect.adjusted( -16, extraRect.height() / 2 - h / 2, 0, 0 );
|
||||
stateRect.setHeight( h );
|
||||
stateRect.setWidth( stateRect.height() );
|
||||
painter->drawPixmap( stateRect, ImageRegistry::instance()->pixmap( RESPATH "images/love.svg", stateRect.size() ) );
|
||||
|
||||
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;
|
||||
stateWidth = stateRect.width() + 16;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasOnlineResults && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
const int remWidth = r.width() - numberWidth - durationWidth;
|
||||
|
||||
QRect titleRect = QRect( numberRect.x() + numberRect.width(), r.y(), (double)remWidth * 0.5, r.height() );
|
||||
@@ -783,7 +708,6 @@ PlaylistItemDelegate::drawTrack( QPainter* painter, const QStyleOptionViewItem&
|
||||
|
||||
int h = extraRect.height() / 2;
|
||||
QRect playIconRect = extraRect.adjusted( extraRect.width() - h - 8, h / 2, -8, -h / 2 );
|
||||
playIconRect.setWidth( playIconRect.height() );
|
||||
painter->drawPixmap( playIconRect, ImageRegistry::instance()->pixmap( RESPATH "images/play.svg", playIconRect.size() ) );
|
||||
|
||||
double duration = (double)AudioEngine::instance()->currentTrackTotalTime();
|
||||
@@ -835,11 +759,8 @@ 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;
|
||||
|
||||
if ( m_infoButtonRects.contains( index ) )
|
||||
{
|
||||
const QRect infoRect = m_infoButtonRects[ index ];
|
||||
@@ -858,18 +779,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 ];
|
||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||
hoveringDownloadDropDown = downloadDropDownRect.contains( ev->pos() );
|
||||
}
|
||||
if ( m_avatarBoxRects.contains( index ) )
|
||||
{
|
||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||
@@ -887,7 +796,7 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
|
||||
if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringBuy )
|
||||
if ( hoveringInfo || hoveringLove || hoveringArtist )
|
||||
m_view->setCursor( Qt::PointingHandCursor );
|
||||
else
|
||||
m_view->setCursor( Qt::ArrowCursor );
|
||||
@@ -911,23 +820,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
emit updateIndex( m_hoveringOverArtist );
|
||||
m_hoveringOverArtist = QModelIndex();
|
||||
}
|
||||
if ( hoveringBuy && m_hoveringOverBuyButton != index )
|
||||
{
|
||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
||||
m_hoveringOverBuyButton = index;
|
||||
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||
item->requestRepaint();
|
||||
emit updateIndex( m_hoveringOverBuyButton );
|
||||
}
|
||||
if ( !hoveringBuy && m_hoveringOverBuyButton.isValid() )
|
||||
{
|
||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
||||
m_hoveringOverBuyButton = QModelIndex();
|
||||
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||
item->requestRepaint();
|
||||
}
|
||||
|
||||
if ( m_hoveringOver != index )
|
||||
{
|
||||
@@ -957,11 +849,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
{
|
||||
item->query()->queryTrack()->setLoved( !item->query()->queryTrack()->loved() );
|
||||
}
|
||||
else if ( hoveringBuy )
|
||||
{
|
||||
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
}
|
||||
else if ( hoveringInfo )
|
||||
{
|
||||
if ( m_model->style() == PlayableProxyModel::SingleColumn )
|
||||
@@ -996,11 +883,9 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) || hoveringDownloadDropDown )
|
||||
else if ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download )
|
||||
{
|
||||
m_model->sourceModel()->setAllColumnsEditable( true );
|
||||
m_view->edit( index );
|
||||
m_model->sourceModel()->setAllColumnsEditable( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -1015,17 +900,15 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
void
|
||||
PlaylistItemDelegate::resetHoverIndex()
|
||||
{
|
||||
if ( !m_model || !m_hoveringOver.isValid() )
|
||||
if ( !m_model )
|
||||
return;
|
||||
|
||||
QPersistentModelIndex idx = m_hoveringOver;
|
||||
|
||||
m_hoveringOver = QModelIndex();
|
||||
m_hoveringOverArtist = QModelIndex();
|
||||
m_hoveringOverBuyButton = QModelIndex();
|
||||
m_infoButtonRects.clear();
|
||||
m_loveButtonRects.clear();
|
||||
m_buyButtonRects.clear();
|
||||
m_artistNameRects.clear();
|
||||
|
||||
QModelIndex itemIdx = m_model->mapToSource( idx );
|
||||
@@ -1037,6 +920,7 @@ PlaylistItemDelegate::resetHoverIndex()
|
||||
}
|
||||
|
||||
emit updateIndex( idx );
|
||||
m_view->repaint();
|
||||
}
|
||||
|
||||
|
||||
|
@@ -116,13 +116,10 @@ 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;
|
||||
mutable QPersistentModelIndex m_nowPlaying;
|
||||
|
||||
TrackView* m_view;
|
||||
|
@@ -19,7 +19,6 @@
|
||||
#include "TrackDetailView.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
#include <QSizePolicy>
|
||||
#include <QVBoxLayout>
|
||||
@@ -36,7 +35,6 @@
|
||||
#include "utils/ImageRegistry.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/Closure.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
@@ -44,7 +42,6 @@ using namespace Tomahawk;
|
||||
TrackDetailView::TrackDetailView( QWidget* parent )
|
||||
: QWidget( parent )
|
||||
, DpiScaler( this )
|
||||
, m_buyButtonVisible( false )
|
||||
{
|
||||
setFixedWidth( scaledX( 200 ) );
|
||||
setContentsMargins( 0, 0, 0, 0 );
|
||||
@@ -121,21 +118,11 @@ TrackDetailView::TrackDetailView( QWidget* parent )
|
||||
TomahawkStyle::styleScrollBar( m_resultsScrollArea->verticalScrollBar() );
|
||||
m_resultsScrollArea->hide();
|
||||
|
||||
m_buyButton = new QPushButton;
|
||||
m_buyButton->setStyleSheet( "QPushButton:hover { font-size: 12px; color: #ffffff; background: #000000; border-style: solid; border-radius: 0px; border-width: 2px; border-color: #2b2b2b; }"
|
||||
"QPushButton { font-size: 12px; color: #ffffff; background-color: #000000; border-style: solid; border-radius: 0px; border-width: 0px; }" );
|
||||
m_buyButton->setMinimumHeight( 30 );
|
||||
m_buyButton->setText( tr( "Buy Album" ) );
|
||||
m_buyButton->setVisible( false );
|
||||
connect( m_buyButton, SIGNAL( clicked() ), SLOT( onBuyButtonClicked() ) );
|
||||
|
||||
QVBoxLayout* layout = new QVBoxLayout;
|
||||
TomahawkUtils::unmarginLayout( layout );
|
||||
layout->addWidget( m_playableCover );
|
||||
layout->addSpacerItem( new QSpacerItem( 0, 8, QSizePolicy::Minimum, QSizePolicy::Fixed ) );
|
||||
layout->addWidget( m_nameLabel );
|
||||
layout->addSpacerItem( new QSpacerItem( 0, 4, QSizePolicy::Minimum, QSizePolicy::Fixed ) );
|
||||
layout->addWidget( m_buyButton );
|
||||
layout->addWidget( m_dateLabel );
|
||||
layout->addWidget( m_infoBox );
|
||||
layout->addSpacerItem( new QSpacerItem( 0, 32, QSizePolicy::Minimum, QSizePolicy::Fixed ) );
|
||||
@@ -147,9 +134,6 @@ TrackDetailView::TrackDetailView( QWidget* parent )
|
||||
|
||||
setLayout( layout );
|
||||
setQuery( query_ptr() );
|
||||
|
||||
connect( DownloadManager::instance(), SIGNAL( stateChanged( DownloadManager::DownloadManagerState, DownloadManager::DownloadManagerState ) ),
|
||||
SLOT( onDownloadManagerStateChanged( DownloadManager::DownloadManagerState, DownloadManager::DownloadManagerState ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -170,10 +154,6 @@ TrackDetailView::setQuery( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
if ( m_query )
|
||||
{
|
||||
if ( m_query->track()->albumPtr() && !m_query->track()->albumPtr()->name().isEmpty() )
|
||||
{
|
||||
disconnect( m_query->track()->albumPtr().data(), SIGNAL( updated() ), this, SLOT( onAlbumUpdated() ) );
|
||||
}
|
||||
disconnect( m_query->track().data(), SIGNAL( updated() ), this, SLOT( onCoverUpdated() ) );
|
||||
disconnect( m_query->track().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( onSocialActionsLoaded() ) );
|
||||
disconnect( m_query.data(), SIGNAL( resultsChanged() ), this, SLOT( onResultsChanged() ) );
|
||||
@@ -184,7 +164,6 @@ TrackDetailView::setQuery( const Tomahawk::query_ptr& query )
|
||||
onResultsChanged();
|
||||
setSocialActions();
|
||||
onCoverUpdated();
|
||||
onAlbumUpdated();
|
||||
|
||||
if ( !query )
|
||||
{
|
||||
@@ -195,85 +174,20 @@ TrackDetailView::setQuery( const Tomahawk::query_ptr& query )
|
||||
|
||||
m_dateLabel->setText( tr( "Unknown Release-Date" ) );
|
||||
|
||||
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( onAlbumUpdated() ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackDetailView::onAlbumUpdated()
|
||||
{
|
||||
if ( !m_query )
|
||||
return;
|
||||
|
||||
if ( m_query->track()->albumPtr() && !m_query->track()->albumPtr()->name().isEmpty() )
|
||||
{
|
||||
m_nameLabel->setType( QueryLabel::Album );
|
||||
m_nameLabel->setAlbum( m_query->track()->albumPtr() );
|
||||
|
||||
connect( m_query->track()->albumPtr().data(), SIGNAL( updated() ), SLOT( onAlbumUpdated() ), Qt::UniqueConnection );
|
||||
|
||||
if ( m_buyButtonVisible )
|
||||
{
|
||||
if ( m_query->track()->albumPtr()->purchased() )
|
||||
{
|
||||
m_buyButton->setText( tr( "Download Album" ) );
|
||||
m_buyButton->setVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buyButton->setText( tr( "Buy Album" ) );
|
||||
m_buyButton->setVisible( !m_query->track()->albumPtr()->purchaseUrl().isEmpty() );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nameLabel->setType( QueryLabel::Artist );
|
||||
m_nameLabel->setArtist( m_query->track()->artistPtr() );
|
||||
m_buyButton->setVisible( false );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackDetailView::onBuyButtonClicked()
|
||||
{
|
||||
if ( DownloadManager::instance()->state() == DownloadManager::Running )
|
||||
{
|
||||
emit downloadCancel();
|
||||
return;
|
||||
}
|
||||
|
||||
if ( m_query && m_query->track()->albumPtr() )
|
||||
{
|
||||
if ( m_query->track()->albumPtr()->purchased() )
|
||||
{
|
||||
emit downloadAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
WebPopup* popup = new WebPopup( m_query->track()->albumPtr()->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( m_query->track()->albumPtr().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackDetailView::onDownloadManagerStateChanged( DownloadManager::DownloadManagerState newState, DownloadManager::DownloadManagerState oldState )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
if ( newState == DownloadManager::Running )
|
||||
{
|
||||
m_buyButton->setText( tr( "Cancel Download" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
onAlbumUpdated();
|
||||
}
|
||||
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() ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -390,10 +304,3 @@ TrackDetailView::onResultsChanged()
|
||||
m_resultsScrollArea->hide();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackDetailView::setBuyButtonVisible( bool visible )
|
||||
{
|
||||
m_buyButtonVisible = visible;
|
||||
}
|
||||
|
@@ -23,7 +23,6 @@
|
||||
|
||||
#include "Query.h"
|
||||
#include "utils/DpiScaler.h"
|
||||
#include "DownloadManager.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
class QLabel;
|
||||
@@ -31,7 +30,6 @@ class CaptionLabel;
|
||||
class PlayableCover;
|
||||
class QueryLabel;
|
||||
class QScrollArea;
|
||||
class QPushButton;
|
||||
|
||||
class DLLEXPORT TrackDetailView : public QWidget, private TomahawkUtils::DpiScaler
|
||||
{
|
||||
@@ -41,29 +39,21 @@ public:
|
||||
explicit TrackDetailView( QWidget* parent = 0 );
|
||||
~TrackDetailView();
|
||||
|
||||
void setBuyButtonVisible( bool visible );
|
||||
|
||||
public slots:
|
||||
virtual void setQuery( const Tomahawk::query_ptr& query );
|
||||
void setPlaylistInterface( const Tomahawk::playlistinterface_ptr& playlistInterface );
|
||||
|
||||
signals:
|
||||
void downloadAll();
|
||||
void downloadCancel();
|
||||
|
||||
protected:
|
||||
|
||||
protected slots:
|
||||
|
||||
private slots:
|
||||
void onAlbumUpdated();
|
||||
void onCoverUpdated();
|
||||
void onSocialActionsLoaded();
|
||||
void onResultsChanged();
|
||||
|
||||
void onBuyButtonClicked();
|
||||
void onDownloadManagerStateChanged( DownloadManager::DownloadManagerState newState, DownloadManager::DownloadManagerState oldState );
|
||||
|
||||
private:
|
||||
void setSocialActions();
|
||||
|
||||
@@ -75,8 +65,6 @@ private:
|
||||
QLabel* m_lovedIcon;
|
||||
QLabel* m_lovedLabel;
|
||||
CaptionLabel* m_resultsBoxLabel;
|
||||
QPushButton* m_buyButton;
|
||||
bool m_buyButtonVisible;
|
||||
|
||||
QWidget* m_infoBox;
|
||||
QWidget* m_resultsBox;
|
||||
|
@@ -23,9 +23,7 @@
|
||||
#include "PlayableModel.h"
|
||||
#include "PlayableProxyModel.h"
|
||||
#include "PlayableItem.h"
|
||||
#include "DownloadManager.h"
|
||||
#include "DropJob.h"
|
||||
#include "Result.h"
|
||||
#include "Source.h"
|
||||
#include "TomahawkSettings.h"
|
||||
#include "audio/AudioEngine.h"
|
||||
@@ -47,9 +45,6 @@
|
||||
#include <QScrollBar>
|
||||
#include <QDrag>
|
||||
|
||||
// HACK
|
||||
#include <QTableView>
|
||||
|
||||
#define SCROLL_TIMEOUT 280
|
||||
|
||||
using namespace Tomahawk;
|
||||
@@ -88,13 +83,6 @@ TrackView::TrackView( QWidget* parent )
|
||||
setEditTriggers( NoEditTriggers );
|
||||
|
||||
setHeader( m_header );
|
||||
|
||||
// HACK: enable moving of first column: QTBUG-33974 / https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
|
||||
QTableView unused;
|
||||
unused.setVerticalHeader( header() );
|
||||
header()->setParent( this );
|
||||
unused.setVerticalHeader( new QHeaderView( Qt::Horizontal, &unused ) );
|
||||
|
||||
setSortingEnabled( true );
|
||||
sortByColumn( -1 );
|
||||
setContextMenuPolicy( Qt::CustomContextMenu );
|
||||
@@ -689,6 +677,7 @@ TrackView::wheelEvent( QWheelEvent* event )
|
||||
QTreeView::wheelEvent( event );
|
||||
|
||||
m_delegate->resetHoverIndex();
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
@@ -775,44 +764,6 @@ TrackView::onCustomContextMenu( const QPoint& pos )
|
||||
m_contextMenu->setSupportedActions( m_contextMenu->supportedActions() | ContextMenu::ActionMarkListened
|
||||
| ContextMenu::ActionDelete );
|
||||
|
||||
if ( proxyModel()->style() != PlayableProxyModel::Collection )
|
||||
{
|
||||
bool allDownloaded = true;
|
||||
bool noneDownloadable = true;
|
||||
bool downloadable = false;
|
||||
foreach ( const QModelIndex& index, selectedIndexes() )
|
||||
{
|
||||
if ( index.column() )
|
||||
continue;
|
||||
|
||||
PlayableItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) );
|
||||
|
||||
if( item->query()->results().isEmpty() )
|
||||
continue;
|
||||
|
||||
downloadable = !item->query()->results().first()->downloadFormats().isEmpty();
|
||||
if ( downloadable )
|
||||
{
|
||||
noneDownloadable = false;
|
||||
}
|
||||
|
||||
if ( downloadable && DownloadManager::instance()->localFileForDownload( item->query()->results().first()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
allDownloaded = false;
|
||||
}
|
||||
|
||||
if ( !allDownloaded || !noneDownloadable )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( !allDownloaded || !noneDownloadable )
|
||||
{
|
||||
m_contextMenu->setSupportedActions( m_contextMenu->supportedActions() | ContextMenu::ActionDownload );
|
||||
}
|
||||
}
|
||||
|
||||
QList<query_ptr> queries;
|
||||
foreach ( const QModelIndex& index, selectedIndexes() )
|
||||
{
|
||||
@@ -844,10 +795,6 @@ TrackView::onMenuTriggered( int action )
|
||||
deleteSelectedItems();
|
||||
break;
|
||||
|
||||
case ContextMenu::ActionDownload:
|
||||
downloadSelectedItems();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -923,30 +870,6 @@ TrackView::deleteSelectedItems()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::downloadSelectedItems()
|
||||
{
|
||||
foreach ( const QModelIndex& index, selectedIndexes() )
|
||||
{
|
||||
if ( index.column() )
|
||||
continue;
|
||||
|
||||
PlayableItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( index ) );
|
||||
|
||||
if ( !item )
|
||||
continue;
|
||||
|
||||
if ( item->query()->results().isEmpty() || item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
continue;
|
||||
|
||||
if ( !DownloadManager::instance()->localFileForDownload( item->query()->results().first()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
continue;
|
||||
|
||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TrackView::verifySize()
|
||||
{
|
||||
|
@@ -89,7 +89,6 @@ public:
|
||||
public slots:
|
||||
virtual void onItemActivated( const QModelIndex& index );
|
||||
|
||||
virtual void downloadSelectedItems();
|
||||
virtual void deleteSelectedItems();
|
||||
|
||||
void playItem();
|
||||
|
@@ -3,6 +3,7 @@
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.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
|
||||
@@ -24,8 +25,6 @@
|
||||
#include "Source.h"
|
||||
#include "DllMacro.h"
|
||||
#include "Resolver.h"
|
||||
#include "ScriptCommandQueue.h"
|
||||
#include "ScriptCommand_LookupUrl.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <QObject>
|
||||
@@ -45,7 +44,6 @@ class DLLEXPORT ExternalResolver : public Resolver
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
friend class ScriptCommandQueue;
|
||||
friend class ScriptCommand_LookupUrl;
|
||||
|
||||
public:
|
||||
@@ -61,26 +59,13 @@ public:
|
||||
Browsable = 0x1, // can be represented in one or more collection tree views
|
||||
PlaylistSync = 0x2, // can sync playlists
|
||||
AccountFactory = 0x4, // can configure multiple accounts at the same time
|
||||
UrlLookup = 0x8 // can be queried for information on an Url
|
||||
};
|
||||
Q_DECLARE_FLAGS( Capabilities, Capability )
|
||||
Q_FLAGS( Capabilities )
|
||||
|
||||
enum UrlType
|
||||
{
|
||||
UrlTypeAny = 0x00,
|
||||
UrlTypePlaylist = 0x01,
|
||||
UrlTypeTrack = 0x02,
|
||||
UrlTypeAlbum = 0x04,
|
||||
UrlTypeArtist = 0x08,
|
||||
UrlTypeXspf = 0x10
|
||||
};
|
||||
Q_DECLARE_FLAGS( UrlTypes, UrlType )
|
||||
Q_FLAGS( UrlTypes )
|
||||
|
||||
ExternalResolver( const QString& filePath )
|
||||
: m_commandQueue( new ScriptCommandQueue( this ) )
|
||||
{ m_filePath = filePath; }
|
||||
: m_filePath( filePath )
|
||||
{}
|
||||
|
||||
QString filePath() const { return m_filePath; }
|
||||
virtual void setIcon( const QPixmap& ) {}
|
||||
@@ -92,12 +77,6 @@ public:
|
||||
virtual bool running() const = 0;
|
||||
virtual Capabilities capabilities() const = 0;
|
||||
|
||||
// UrlLookup, sync call
|
||||
virtual bool canParseUrl( const QString& url, UrlType type ) = 0;
|
||||
|
||||
virtual void enqueue( const QSharedPointer< ScriptCommand >& req )
|
||||
{ m_commandQueue->enqueue( req ); }
|
||||
|
||||
public slots:
|
||||
virtual void start() = 0;
|
||||
virtual void stop() = 0;
|
||||
@@ -112,11 +91,6 @@ signals:
|
||||
|
||||
protected:
|
||||
void setFilePath( const QString& path ) { m_filePath = path; }
|
||||
ScriptCommandQueue* m_commandQueue;
|
||||
|
||||
// Should only be called by ScriptCommands
|
||||
// UrlLookup
|
||||
virtual void lookupUrl( const QString& url ) = 0;
|
||||
|
||||
private:
|
||||
QString m_filePath;
|
||||
|
@@ -67,14 +67,6 @@ JSAccount::scriptPluginFactory( const QString& type, const scriptobject_ptr& obj
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSAccount::showDebugger()
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << name() << "Show debugger";
|
||||
m_engine->showWebInspector();
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
JSAccount::serializeQVariantMap( const QVariantMap& map )
|
||||
{
|
||||
|
@@ -69,8 +69,6 @@ public:
|
||||
void setResolver( JSResolver* resolver );
|
||||
void scriptPluginFactory( const QString& type, const scriptobject_ptr& object ) override;
|
||||
|
||||
void showDebugger() override;
|
||||
|
||||
static QString serializeQVariantMap(const QVariantMap& map);
|
||||
|
||||
void reportNativeScriptJobResult( int resultId, const QVariantMap& result ) override;
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* 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
|
||||
@@ -45,10 +46,6 @@
|
||||
#include "ScriptInfoPlugin.h"
|
||||
#include "JSAccount.h"
|
||||
#include "ScriptJob.h"
|
||||
|
||||
// lookupUrl stuff
|
||||
#include "playlist/PlaylistTemplate.h"
|
||||
#include "playlist/XspfPlaylistTemplate.h"
|
||||
#include "database/Database.h"
|
||||
#include "database/DatabaseImpl.h"
|
||||
|
||||
@@ -322,191 +319,6 @@ JSResolver::start()
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
JSResolver::canParseUrl( const QString& url, UrlType type )
|
||||
{
|
||||
Q_D( const JSResolver );
|
||||
|
||||
if ( d->capabilities.testFlag( UrlLookup ) )
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments["url"] = url;
|
||||
arguments["type"] = (int) type;
|
||||
|
||||
return scriptObject()->syncInvoke( "canParseUrl", arguments ).toBool();
|
||||
}
|
||||
else
|
||||
{
|
||||
// We cannot do URL lookup.
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::lookupUrl( const QString& url )
|
||||
{
|
||||
Q_D( const JSResolver );
|
||||
|
||||
|
||||
if ( !d->capabilities.testFlag( UrlLookup ) )
|
||||
{
|
||||
emit informationFound( url, QSharedPointer<QObject>() );
|
||||
return;
|
||||
}
|
||||
|
||||
QVariantMap arguments;
|
||||
arguments["url"] = url;
|
||||
Tomahawk::ScriptJob* job = scriptObject()->invoke( "lookupUrl", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onLookupUrlRequestDone( QVariantMap ) ) );
|
||||
job->setProperty( "url", url );
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::onLookupUrlRequestDone( const QVariantMap& result )
|
||||
{
|
||||
sender()->deleteLater();
|
||||
|
||||
QString url = sender()->property( "url" ).toString();
|
||||
|
||||
tLog() << "ON LOOKUP URL REQUEST DONE" << url << result;
|
||||
|
||||
// It may seem a bit weird, but currently no slot should do anything
|
||||
// more as we starting on a new URL and not task are waiting for it yet.
|
||||
m_pendingUrl = QString();
|
||||
m_pendingAlbum = album_ptr();
|
||||
|
||||
UrlTypes type = (UrlTypes) result.value( "type" ).toInt();
|
||||
if ( type == UrlTypeArtist )
|
||||
{
|
||||
QString name = result.value( "name" ).toString();
|
||||
Q_ASSERT( !name.isEmpty() );
|
||||
emit informationFound( url, Artist::get( name, true ).objectCast<QObject>() );
|
||||
}
|
||||
else if ( type == UrlTypeAlbum )
|
||||
{
|
||||
QString name = result.value( "name" ).toString();
|
||||
QString artist = result.value( "artist" ).toString();
|
||||
album_ptr album = Album::get( Artist::get( artist, true ), name );
|
||||
m_pendingUrl = url;
|
||||
m_pendingAlbum = album;
|
||||
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
|
||||
SLOT( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
||||
if ( !album->tracks().isEmpty() )
|
||||
{
|
||||
emit informationFound( url, album.objectCast<QObject>() );
|
||||
}
|
||||
}
|
||||
else if ( type == UrlTypeTrack )
|
||||
{
|
||||
Tomahawk::query_ptr query = parseTrack( result );
|
||||
if ( query.isNull() )
|
||||
{
|
||||
// A valid track result shoud have non-empty title and artist.
|
||||
tLog() << Q_FUNC_INFO << name() << "Got empty track information for " << url;
|
||||
emit informationFound( url, QSharedPointer<QObject>() );
|
||||
}
|
||||
else
|
||||
{
|
||||
emit informationFound( url, query.objectCast<QObject>() );
|
||||
}
|
||||
}
|
||||
else if ( type == UrlTypePlaylist )
|
||||
{
|
||||
QString guid = result.value( "guid" ).toString();
|
||||
Q_ASSERT( !guid.isEmpty() );
|
||||
// Append nodeid to guid to make it globally unique.
|
||||
guid += instanceUUID();
|
||||
|
||||
// Do we already have this playlist loaded?
|
||||
{
|
||||
playlist_ptr playlist = Playlist::get( guid );
|
||||
if ( !playlist.isNull() )
|
||||
{
|
||||
emit informationFound( url, playlist.objectCast<QObject>() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all information to build a new playlist but do not build it until we know,
|
||||
// if it is really handled as a playlist and not as a set of tracks.
|
||||
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
||||
const QString title = result.value( "title" ).toString();
|
||||
const QString info = result.value( "info" ).toString();
|
||||
const QString creator = result.value( "creator" ).toString();
|
||||
QList<query_ptr> queries;
|
||||
foreach( QVariant track, result.value( "tracks" ).toList() )
|
||||
{
|
||||
query_ptr query = parseTrack( track.toMap() );
|
||||
if ( !query.isNull() )
|
||||
{
|
||||
queries << query;
|
||||
}
|
||||
}
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << name() << "Got playlist for " << url;
|
||||
playlisttemplate_ptr pltemplate( new PlaylistTemplate( source, guid, title, info, creator, false, queries ) );
|
||||
emit informationFound( url, pltemplate.objectCast<QObject>() );
|
||||
}
|
||||
else if ( type == UrlTypeXspf )
|
||||
{
|
||||
QString xspfUrl = result.value( "url" ).toString();
|
||||
Q_ASSERT( !xspfUrl.isEmpty() );
|
||||
QString guid = QString( "xspf-%1-%2" ).arg( xspfUrl.toUtf8().toBase64().constData() ).arg( instanceUUID() );
|
||||
|
||||
// Do we already have this playlist loaded?
|
||||
{
|
||||
playlist_ptr playlist = Playlist::get( guid );
|
||||
if ( !playlist.isNull() )
|
||||
{
|
||||
emit informationFound( url, playlist.objectCast<QObject>() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get all information to build a new playlist but do not build it until we know,
|
||||
// if it is really handled as a playlist and not as a set of tracks.
|
||||
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
||||
QSharedPointer<XspfPlaylistTemplate> pltemplate( new XspfPlaylistTemplate( xspfUrl, source, guid ) );
|
||||
NewClosure( pltemplate, SIGNAL( tracksLoaded( QList< Tomahawk::query_ptr > ) ),
|
||||
this, SLOT( pltemplateTracksLoadedForUrl( QString, Tomahawk::playlisttemplate_ptr ) ),
|
||||
url, pltemplate.objectCast<Tomahawk::PlaylistTemplate>() );
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << name() << "Got playlist for " << url;
|
||||
pltemplate->load();
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << name() << "No usable information found for " << url;
|
||||
emit informationFound( url, QSharedPointer<QObject>() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
query_ptr
|
||||
JSResolver::parseTrack( const QVariantMap& track )
|
||||
{
|
||||
QString title = track.value( "track" ).toString();
|
||||
QString artist = track.value( "artist" ).toString();
|
||||
QString album = track.value( "album" ).toString();
|
||||
if ( title.isEmpty() || artist.isEmpty() )
|
||||
{
|
||||
return query_ptr();
|
||||
}
|
||||
|
||||
Tomahawk::query_ptr query = Tomahawk::Query::get( artist, title, album );
|
||||
QString resultHint = track.value( "hint" ).toString();
|
||||
if ( !resultHint.isEmpty() )
|
||||
{
|
||||
query->setResultHint( resultHint );
|
||||
query->setSaveHTTPResultHint( true );
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::tracksAdded( const QList<query_ptr>&, const ModelMode, const collection_ptr&)
|
||||
{
|
||||
@@ -520,14 +332,6 @@ JSResolver::tracksAdded( const QList<query_ptr>&, const ModelMode, const collect
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
JSResolver::pltemplateTracksLoadedForUrl( const QString& url, const playlisttemplate_ptr& pltemplate )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO;
|
||||
emit informationFound( url, pltemplate.objectCast<QObject>() );
|
||||
}
|
||||
|
||||
|
||||
Tomahawk::ExternalResolver::ErrorState
|
||||
JSResolver::error() const
|
||||
{
|
||||
@@ -541,6 +345,7 @@ void
|
||||
JSResolver::resolve( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
ScriptJob* job = scriptAccount()->resolve( scriptObject(), query, "resolver" );
|
||||
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onResolveRequestDone( QVariantMap ) ) );
|
||||
|
||||
job->start();
|
||||
@@ -562,24 +367,15 @@ JSResolver::onResolveRequestDone( const QVariantMap& data )
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( !data.value( "artists" ).isNull() )
|
||||
{
|
||||
QList< artist_ptr > artists = scriptAccount()->parseArtistVariantList( data.value( "artists" ).toList() );
|
||||
Tomahawk::Pipeline::instance()->reportArtists( qid, artists );
|
||||
}
|
||||
|
||||
if ( !data.value( "albums" ).isNull() )
|
||||
{
|
||||
QList< album_ptr > albums = scriptAccount()->parseAlbumVariantList( data.value( "albums" ).toList() );
|
||||
Tomahawk::Pipeline::instance()->reportAlbums( qid, albums );
|
||||
}
|
||||
|
||||
QList< Tomahawk::result_ptr > results = scriptAccount()->parseResultVariantList( data.value( "tracks" ).toList() );
|
||||
|
||||
foreach( const result_ptr& result, results )
|
||||
{
|
||||
result->setResolvedByResolver( this );
|
||||
result->setFriendlySource( name() );
|
||||
}
|
||||
|
||||
Tomahawk::Pipeline::instance()->reportResults( qid, this, results );
|
||||
}
|
||||
|
||||
@@ -696,13 +492,6 @@ JSResolver::resolverUserConfig()
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
JSResolver::instanceUUID()
|
||||
{
|
||||
return Tomahawk::Database::instance()->impl()->dbid();
|
||||
}
|
||||
|
||||
|
||||
ScriptJob*
|
||||
JSResolver::getStreamUrl( const result_ptr& result )
|
||||
{
|
||||
|
@@ -4,6 +4,7 @@
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* 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
|
||||
@@ -69,8 +70,6 @@ public:
|
||||
|
||||
void setIcon( const QPixmap& icon ) override;
|
||||
|
||||
bool canParseUrl( const QString& url, UrlType type ) override;
|
||||
|
||||
QVariantMap loadDataFromWidgets();
|
||||
|
||||
ScriptAccount* scriptAccount() const;
|
||||
@@ -82,9 +81,6 @@ public slots:
|
||||
void stop() override;
|
||||
void start() override;
|
||||
|
||||
// For UrlLookup
|
||||
void lookupUrl( const QString& url ) override;
|
||||
|
||||
signals:
|
||||
void stopped();
|
||||
|
||||
@@ -93,7 +89,6 @@ protected:
|
||||
|
||||
private slots:
|
||||
void onResolveRequestDone(const QVariantMap& data);
|
||||
void onLookupUrlRequestDone(const QVariantMap& data);
|
||||
|
||||
private:
|
||||
void init();
|
||||
@@ -107,15 +102,11 @@ private:
|
||||
Q_DECLARE_PRIVATE( JSResolver )
|
||||
QScopedPointer<JSResolverPrivate> d_ptr;
|
||||
|
||||
|
||||
// TODO: move lookupUrl stuff to its own plugin type
|
||||
QString instanceUUID();
|
||||
static Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
||||
// TODO: collection stuff, get rid of collection scriptcommands
|
||||
QString m_pendingUrl;
|
||||
Tomahawk::album_ptr m_pendingAlbum;
|
||||
private slots:
|
||||
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks, const Tomahawk::ModelMode, const Tomahawk::collection_ptr& collection );
|
||||
void pltemplateTracksLoadedForUrl( const QString& url, const Tomahawk::playlisttemplate_ptr& pltemplate );
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* === 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) 2014-2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
@@ -23,6 +23,7 @@
|
||||
#include "../utils/Logger.h"
|
||||
#include "../Typedefs.h"
|
||||
|
||||
#include "plugins/ScriptLinkParserPluginFactory.h"
|
||||
#include "plugins/ScriptCollectionFactory.h"
|
||||
#include "plugins/ScriptInfoPluginFactory.h"
|
||||
|
||||
@@ -32,8 +33,6 @@
|
||||
#include "ScriptInfoPlugin.h"
|
||||
|
||||
// TODO:
|
||||
#include "../Artist.h"
|
||||
#include "../Album.h"
|
||||
#include "../Result.h"
|
||||
#include "../Track.h"
|
||||
#include <QTime>
|
||||
@@ -46,6 +45,7 @@ ScriptAccount::ScriptAccount( const QString& name )
|
||||
: QObject()
|
||||
, m_name( name )
|
||||
, m_stopped( true )
|
||||
, m_linkParserPluginFactory( new ScriptLinkParserPluginFactory() )
|
||||
, m_collectionFactory( new ScriptCollectionFactory() )
|
||||
, m_infoPluginFactory( new ScriptInfoPluginFactory() )
|
||||
{
|
||||
@@ -54,6 +54,7 @@ ScriptAccount::ScriptAccount( const QString& name )
|
||||
|
||||
ScriptAccount::~ScriptAccount()
|
||||
{
|
||||
delete m_linkParserPluginFactory;
|
||||
delete m_collectionFactory;
|
||||
delete m_infoPluginFactory;
|
||||
}
|
||||
@@ -64,6 +65,7 @@ ScriptAccount::start()
|
||||
{
|
||||
m_stopped = false;
|
||||
|
||||
m_linkParserPluginFactory->addAllPlugins();
|
||||
m_collectionFactory->addAllPlugins();
|
||||
m_infoPluginFactory->addAllPlugins();
|
||||
}
|
||||
@@ -74,6 +76,7 @@ ScriptAccount::stop()
|
||||
{
|
||||
m_stopped = true;
|
||||
|
||||
m_linkParserPluginFactory->removeAllPlugins();
|
||||
m_collectionFactory->removeAllPlugins();
|
||||
m_infoPluginFactory->removeAllPlugins();
|
||||
}
|
||||
@@ -195,7 +198,11 @@ ScriptAccount::unregisterScriptPlugin( const QString& type, const QString& objec
|
||||
return;
|
||||
}
|
||||
|
||||
if ( type == "collection" )
|
||||
if( type == "linkParser" )
|
||||
{
|
||||
m_linkParserPluginFactory->unregisterPlugin( object );
|
||||
}
|
||||
else if ( type == "collection" )
|
||||
{
|
||||
m_collectionFactory->unregisterPlugin( object );
|
||||
}
|
||||
@@ -203,10 +210,6 @@ ScriptAccount::unregisterScriptPlugin( const QString& type, const QString& objec
|
||||
{
|
||||
m_infoPluginFactory->unregisterPlugin( object );
|
||||
}
|
||||
else if( type == "linkParser" )
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog() << "This plugin type is not handled by Tomahawk or simply cannot be removed yet";
|
||||
@@ -239,7 +242,7 @@ ScriptAccount::scriptPluginFactory( const QString& type, const scriptobject_ptr&
|
||||
}
|
||||
else if( type == "linkParser" )
|
||||
{
|
||||
tLog() << "Plugin registered linkParser, which is not implemented yet. UrlLookup won't work";
|
||||
m_linkParserPluginFactory->registerPlugin( object, this );
|
||||
}
|
||||
else if ( type == "infoPlugin" )
|
||||
{
|
||||
@@ -257,12 +260,6 @@ ScriptAccount::scriptPluginFactory( const QString& type, const scriptobject_ptr&
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptAccount::showDebugger()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptAccount::onJobDeleted( const QString& jobId )
|
||||
{
|
||||
@@ -270,67 +267,15 @@ ScriptAccount::onJobDeleted( const QString& jobId )
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::artist_ptr >
|
||||
ScriptAccount::parseArtistVariantList( const QVariantList& artistList )
|
||||
{
|
||||
QList< Tomahawk::artist_ptr > artists;
|
||||
|
||||
QString artist;
|
||||
foreach( const QVariant& a, artistList )
|
||||
{
|
||||
artist = a.toString().trimmed();
|
||||
if ( artist.isEmpty() )
|
||||
continue;
|
||||
|
||||
artists << Tomahawk::Artist::get( artist );
|
||||
}
|
||||
|
||||
return artists;
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::album_ptr >
|
||||
ScriptAccount::parseAlbumVariantList( const QVariantList& albumList )
|
||||
{
|
||||
QList< Tomahawk::album_ptr > albums;
|
||||
|
||||
QString artistString;
|
||||
QString albumString;
|
||||
foreach( const QVariant& av, albumList )
|
||||
{
|
||||
QVariantMap m = av.toMap();
|
||||
|
||||
artistString = m.value( "artist" ).toString().trimmed();
|
||||
albumString = m.value( "album" ).toString().trimmed();
|
||||
if ( artistString.isEmpty() || albumString.isEmpty() )
|
||||
continue;
|
||||
|
||||
albums << Tomahawk::Album::get( Tomahawk::Artist::get( artistString ), albumString );
|
||||
}
|
||||
|
||||
return albums;
|
||||
}
|
||||
|
||||
|
||||
QList< Tomahawk::result_ptr >
|
||||
ScriptAccount::parseResultVariantList( const QVariantList& reslist )
|
||||
{
|
||||
QList< Tomahawk::result_ptr > results;
|
||||
|
||||
|
||||
foreach( const QVariant& rv, reslist )
|
||||
{
|
||||
QVariantMap m = rv.toMap();
|
||||
|
||||
const QString artistString = m.value("artist").toString().trimmed();
|
||||
const QString trackString = m.value("track").toString().trimmed();
|
||||
|
||||
if ( artistString.isEmpty() || trackString.isEmpty() )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << "Could not parse Track" << m;
|
||||
continue;
|
||||
}
|
||||
|
||||
int duration = m.value( "duration", 0 ).toInt();
|
||||
if ( duration <= 0 && m.contains( "durationString" ) )
|
||||
{
|
||||
@@ -338,8 +283,8 @@ ScriptAccount::parseResultVariantList( const QVariantList& reslist )
|
||||
duration = time.secsTo( QTime( 0, 0 ) ) * -1;
|
||||
}
|
||||
|
||||
Tomahawk::track_ptr track = Tomahawk::Track::get( artistString,
|
||||
trackString,
|
||||
Tomahawk::track_ptr track = Tomahawk::Track::get( m.value( "artist" ).toString(),
|
||||
m.value( "track" ).toString(),
|
||||
m.value( "album" ).toString(),
|
||||
m.value( "albumArtist" ).toString(),
|
||||
duration,
|
||||
@@ -370,17 +315,11 @@ ScriptAccount::parseResultVariantList( const QVariantList& reslist )
|
||||
// rp->track()->setAttributes( attr );
|
||||
}
|
||||
|
||||
|
||||
QString mimetype = m.value( "mimetype" ).toString();
|
||||
if ( mimetype.isEmpty() )
|
||||
rp->setMimetype( m.value( "mimetype" ).toString() );
|
||||
if ( rp->mimetype().isEmpty() )
|
||||
{
|
||||
mimetype = TomahawkUtils::extensionToMimetype( m.value( "extension" ).toString() );
|
||||
}
|
||||
Q_ASSERT( !mimetype.isEmpty() );
|
||||
|
||||
if ( !mimetype.isEmpty() )
|
||||
{
|
||||
rp->setMimetype( mimetype );
|
||||
rp->setMimetype( TomahawkUtils::extensionToMimetype( m.value( "extension" ).toString() ) );
|
||||
Q_ASSERT( !rp->mimetype().isEmpty() );
|
||||
}
|
||||
|
||||
rp->setFriendlySource( name() );
|
||||
|
@@ -1,7 +1,7 @@
|
||||
/* === 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) 2014-2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
@@ -39,6 +39,7 @@ namespace Tomahawk {
|
||||
|
||||
class ScriptObject;
|
||||
class ScriptJob;
|
||||
class ScriptLinkParserPluginFactory;
|
||||
class ScriptCollectionFactory;
|
||||
class ScriptInfoPluginFactory;
|
||||
|
||||
@@ -76,11 +77,7 @@ public:
|
||||
|
||||
virtual void scriptPluginFactory( const QString& type, const scriptobject_ptr& object );
|
||||
|
||||
virtual void showDebugger();
|
||||
|
||||
// helpers
|
||||
QList< Tomahawk::artist_ptr > parseArtistVariantList( const QVariantList& artistList );
|
||||
QList< Tomahawk::album_ptr > parseAlbumVariantList( const QVariantList& albumList );
|
||||
QList< Tomahawk::result_ptr > parseResultVariantList( const QVariantList& reslist );
|
||||
ScriptJob* resolve( const scriptobject_ptr& scriptObject, const query_ptr& query, const QString& resolveType );
|
||||
|
||||
@@ -98,6 +95,7 @@ private: // TODO: pimple, might be renamed before tho
|
||||
QHash< QString, scriptobject_ptr > m_objects;
|
||||
|
||||
// port to QScopedPointer when pimple'd
|
||||
ScriptLinkParserPluginFactory* m_linkParserPluginFactory;
|
||||
ScriptCollectionFactory* m_collectionFactory;
|
||||
ScriptInfoPluginFactory* m_infoPluginFactory;
|
||||
};
|
||||
|
@@ -34,7 +34,6 @@ signals:
|
||||
virtual void done() = 0;
|
||||
|
||||
protected:
|
||||
friend class ScriptCommandQueue;
|
||||
virtual void exec() = 0;
|
||||
virtual void reportFailure() = 0;
|
||||
};
|
||||
|
@@ -1,107 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* 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 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 "ScriptCommandQueue.h"
|
||||
|
||||
#include <QMetaType>
|
||||
#include <QMutex>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
ScriptCommandQueue::ScriptCommandQueue( QObject* parent )
|
||||
: QObject( parent )
|
||||
, m_timer( new QTimer( this ) )
|
||||
{
|
||||
m_timer->setSingleShot( true );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommandQueue::enqueue( const QSharedPointer< ScriptCommand >& req )
|
||||
{
|
||||
QMutexLocker locker( &m_mutex );
|
||||
m_queue.append( req );
|
||||
locker.unlock();
|
||||
|
||||
if ( m_queue.count() == 1 )
|
||||
nextCommand();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommandQueue::nextCommand()
|
||||
{
|
||||
if ( m_queue.isEmpty() )
|
||||
return;
|
||||
|
||||
QSharedPointer< ScriptCommand > req = m_queue.first();
|
||||
|
||||
connect( req.data(), SIGNAL( done() ),
|
||||
this, SLOT( onCommandDone() ) );
|
||||
connect( m_timer, SIGNAL( timeout() ),
|
||||
this, SLOT( onTimeout() ) );
|
||||
|
||||
m_timer->start( 20000 );
|
||||
|
||||
req->exec();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommandQueue::onCommandDone()
|
||||
{
|
||||
if ( m_queue.isEmpty() || !m_timer->isActive() ) //the timeout already happened or some other weird thing
|
||||
return; //nothing to do here
|
||||
|
||||
m_timer->stop();
|
||||
|
||||
QMutexLocker locker( &m_mutex );
|
||||
const QSharedPointer< ScriptCommand > req = m_queue.first();
|
||||
m_queue.removeAll( req );
|
||||
locker.unlock();
|
||||
|
||||
disconnect( req.data(), SIGNAL( done() ),
|
||||
this, SLOT( onCommandDone() ) );
|
||||
disconnect( m_timer, SIGNAL( timeout() ),
|
||||
this, SLOT( onTimeout() ) );
|
||||
|
||||
if ( !m_queue.isEmpty() )
|
||||
nextCommand();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommandQueue::onTimeout()
|
||||
{
|
||||
m_timer->stop();
|
||||
|
||||
QMutexLocker locker( &m_mutex );
|
||||
const QSharedPointer< ScriptCommand > req = m_queue.first();
|
||||
m_queue.removeAll( req );
|
||||
locker.unlock();
|
||||
|
||||
req->reportFailure();
|
||||
|
||||
disconnect( req.data(), SIGNAL( done() ),
|
||||
this, SLOT( onCommandDone() ) );
|
||||
disconnect( m_timer, SIGNAL( timeout() ),
|
||||
this, SLOT( onTimeout() ) );
|
||||
|
||||
if ( !m_queue.isEmpty() )
|
||||
nextCommand();
|
||||
}
|
@@ -1,57 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* 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 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 SCRIPTCOMMANDQUEUE_H
|
||||
#define SCRIPTCOMMANDQUEUE_H
|
||||
|
||||
#include "ScriptCommand.h"
|
||||
|
||||
#include <QQueue>
|
||||
#include <QSharedPointer>
|
||||
#include <QTimer>
|
||||
#include <QMetaType>
|
||||
#include <QMutex>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class ScriptCommandQueue : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScriptCommandQueue( QObject* parent = 0 );
|
||||
virtual ~ScriptCommandQueue() {}
|
||||
|
||||
void enqueue( const QSharedPointer< ScriptCommand >& req );
|
||||
|
||||
private slots:
|
||||
void nextCommand();
|
||||
void onCommandDone();
|
||||
void onTimeout();
|
||||
|
||||
private:
|
||||
QQueue< QSharedPointer< ScriptCommand > > m_queue;
|
||||
QTimer* m_timer;
|
||||
QMutex m_mutex;
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
||||
Q_DECLARE_METATYPE( QSharedPointer< Tomahawk::ScriptCommand > )
|
||||
|
||||
#endif // SCRIPTCOMMANDQUEUE_H
|
@@ -28,8 +28,6 @@
|
||||
#include "utils/Logger.h"
|
||||
#include "../Result.h"
|
||||
|
||||
#include <QtConcurrentRun>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
ScriptCommand_AllTracks::ScriptCommand_AllTracks( const Tomahawk::collection_ptr& collection,
|
||||
@@ -119,22 +117,20 @@ ScriptCommand_AllTracks::onTracksJobDone( const QVariantMap& result )
|
||||
QSharedPointer< ScriptCollection > collection = m_collection.objectCast< ScriptCollection >();
|
||||
Q_ASSERT( !collection.isNull() );
|
||||
|
||||
QtConcurrent::run( [] ( ScriptCommand_AllTracks* t, ScriptJob* job, const QVariantMap& result, const QSharedPointer< ScriptCollection >& collection )
|
||||
QList< Tomahawk::result_ptr > t = collection->scriptAccount()->parseResultVariantList( result[ "tracks" ].toList() );
|
||||
|
||||
|
||||
QList< Tomahawk::query_ptr > queries;
|
||||
foreach ( const Tomahawk::result_ptr& result, t )
|
||||
{
|
||||
QList< Tomahawk::result_ptr > results = collection->scriptAccount()->parseResultVariantList( result[ "tracks" ].toList() );
|
||||
result->setResolvedByCollection( m_collection );
|
||||
queries.append( result->toQuery() );
|
||||
}
|
||||
|
||||
QList< Tomahawk::query_ptr > queries;
|
||||
foreach ( const Tomahawk::result_ptr& result, results )
|
||||
{
|
||||
result->setResolvedByCollection( collection );
|
||||
queries.append( result->toQuery() );
|
||||
}
|
||||
tDebug() << Q_FUNC_INFO << "about to push" << queries.count() << "tracks";
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "about to push" << queries.count() << "tracks";
|
||||
emit tracks( queries );
|
||||
emit done();
|
||||
|
||||
emit t->tracks( queries );
|
||||
emit t->done();
|
||||
|
||||
job->deleteLater();
|
||||
}, this, job, result, collection );
|
||||
job->deleteLater();
|
||||
}
|
||||
|
@@ -1,78 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://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 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 "ScriptCommand_LookupUrl_p.h"
|
||||
|
||||
#include "PlaylistEntry.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
ScriptCommand_LookupUrl::ScriptCommand_LookupUrl( Tomahawk::ExternalResolver* resolver, const QString& url, QObject* parent )
|
||||
: ScriptCommand( parent )
|
||||
, d_ptr( new ScriptCommand_LookupUrlPrivate( this, resolver, url ) )
|
||||
{
|
||||
}
|
||||
|
||||
ScriptCommand_LookupUrl::~ScriptCommand_LookupUrl()
|
||||
{
|
||||
delete d_ptr;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::enqueue()
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
d->resolver->enqueue( QSharedPointer< ScriptCommand >( this ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::exec()
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
connect( d->resolver, SIGNAL( informationFound( QString , QSharedPointer<QObject> ) ),
|
||||
this, SLOT( onResolverDone( QString, QSharedPointer<QObject> ) ) );
|
||||
|
||||
d->resolver->lookupUrl( d->url );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::reportFailure()
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
emit information( d->url, QSharedPointer<QObject>() );
|
||||
emit done();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptCommand_LookupUrl::onResolverDone( const QString& url, const QSharedPointer<QObject>& _information )
|
||||
{
|
||||
Q_D( ScriptCommand_LookupUrl );
|
||||
|
||||
qDebug() << Q_FUNC_INFO << url << _information.isNull();
|
||||
if ( url != d->url )
|
||||
{
|
||||
// This data is not for us, skip.
|
||||
return;
|
||||
}
|
||||
emit information( d->url, _information );
|
||||
emit done();
|
||||
}
|
@@ -1,64 +0,0 @@
|
||||
/* === This file is part of Tomahawk Player - <http://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 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 SCRIPTCOMMAND_LOOKUPURL_H
|
||||
#define SCRIPTCOMMAND_LOOKUPURL_H
|
||||
|
||||
#include "ScriptCommand.h"
|
||||
|
||||
#include "DllMacro.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <QVariant>
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class ScriptCommand_LookupUrlPrivate;
|
||||
class ExternalResolver;
|
||||
|
||||
class DLLEXPORT ScriptCommand_LookupUrl : public ScriptCommand
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScriptCommand_LookupUrl( Tomahawk::ExternalResolver* resolver,
|
||||
const QString& url,
|
||||
QObject* parent = nullptr );
|
||||
virtual ~ScriptCommand_LookupUrl();
|
||||
|
||||
void enqueue();
|
||||
|
||||
signals:
|
||||
void information( const QString& url, const QSharedPointer<QObject>& variant );
|
||||
void done();
|
||||
|
||||
protected:
|
||||
void exec() override;
|
||||
void reportFailure() override;
|
||||
|
||||
private slots:
|
||||
void onResolverDone( const QString& url, const QSharedPointer<QObject>& information );
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE( ScriptCommand_LookupUrl )
|
||||
ScriptCommand_LookupUrlPrivate* d_ptr;
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
||||
#endif // SCRIPTCOMMAND_LOOKUPURL_H
|
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "ScriptEngine.h"
|
||||
|
||||
#include "jobview/ScriptErrorStatusMessage.h"
|
||||
#include "jobview/ErrorStatusMessage.h"
|
||||
#include "jobview/JobStatusModel.h"
|
||||
#include "jobview/JobStatusView.h"
|
||||
#include "utils/Logger.h"
|
||||
@@ -51,13 +51,13 @@ ScriptEngine::ScriptEngine( JSAccount* parent )
|
||||
settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
|
||||
settings()->setOfflineStorageDefaultQuota(100 * 1024 * 1024 /* 100 Mb */);
|
||||
settings()->setOfflineWebApplicationCacheQuota(100 * 1024 * 1024 /* 100 Mb */);
|
||||
settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
|
||||
|
||||
// HACK
|
||||
QStringList cmdArgs = QCoreApplication::instance()->arguments();
|
||||
int position = cmdArgs.indexOf( "--show-inspector" ) + 1;
|
||||
if ( position > 0 && !cmdArgs.at( position ).isEmpty() && parent->name().contains( cmdArgs.at( position ), Qt::CaseInsensitive ) ) {
|
||||
QMetaObject::invokeMethod( this, "showWebInspector", Qt::QueuedConnection );
|
||||
settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
|
||||
QMetaObject::invokeMethod( this, "initWebInspector", Qt::QueuedConnection );
|
||||
}
|
||||
|
||||
// Tomahawk is not a user agent
|
||||
@@ -74,13 +74,24 @@ ScriptEngine::ScriptEngine( JSAccount* parent )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptEngine::initWebInspector()
|
||||
{
|
||||
m_webInspector.reset( new QWebInspector() );
|
||||
m_webInspector->setPage( this );
|
||||
m_webInspector->setMinimumWidth( 800 );
|
||||
m_webInspector->setMinimumHeight( 600 );
|
||||
m_webInspector->show();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptEngine::javaScriptConsoleMessage( const QString& message, int lineNumber, const QString& sourceID )
|
||||
{
|
||||
tLog() << "JAVASCRIPT:" << QString( "%1:%2" ).arg( m_scriptPath ).arg( lineNumber ) << message << sourceID;
|
||||
#ifdef QT_DEBUG
|
||||
QFileInfo scriptPath( m_scriptPath );
|
||||
JobStatusView::instance()->model()->addJob( new ScriptErrorStatusMessage( tr( "%1:%2 %3" ).arg( scriptPath.fileName() ).arg( lineNumber ).arg( message ), m_parent ) );
|
||||
JobStatusView::instance()->model()->addJob( new ErrorStatusMessage( tr( "Resolver Error: %1:%2 %3" ).arg( scriptPath.fileName() ).arg( lineNumber ).arg( message ) ) );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -99,7 +110,7 @@ ScriptEngine::sslErrorHandler( QNetworkReply* qnr, const QList<QSslError>& errli
|
||||
|
||||
QMessageBox question( TomahawkUtils::tomahawkWindow() );
|
||||
question.setWindowTitle( tr( "SSL Error" ) );
|
||||
question.setText( tr( "You have asked %applicationName to connect securely to <b>%1</b>, but we can't confirm that your connection is secure:<br><br>"
|
||||
question.setText( tr( "You have asked Tomahawk to connect securely to <b>%1</b>, but we can't confirm that your connection is secure:<br><br>"
|
||||
"<b>%2</b><br><br>"
|
||||
"Do you want to trust this connection?" )
|
||||
.arg( qnr->url().host() )
|
||||
@@ -137,21 +148,6 @@ ScriptEngine::setScriptPath( const QString& scriptPath )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptEngine::showWebInspector()
|
||||
{
|
||||
if ( m_webInspector.isNull() )
|
||||
{
|
||||
m_webInspector.reset( new QWebInspector() );
|
||||
m_webInspector->setPage( this );
|
||||
m_webInspector->setMinimumWidth( 800 );
|
||||
m_webInspector->setMinimumHeight( 600 );
|
||||
}
|
||||
|
||||
m_webInspector->show();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ScriptEngine::shouldInterruptJavaScript()
|
||||
{
|
||||
|
@@ -49,13 +49,13 @@ public:
|
||||
|
||||
public slots:
|
||||
bool shouldInterruptJavaScript();
|
||||
void showWebInspector();
|
||||
|
||||
protected:
|
||||
virtual void javaScriptConsoleMessage( const QString& message, int lineNumber, const QString& sourceID );
|
||||
|
||||
private slots:
|
||||
void sslErrorHandler( QNetworkReply* qnr, const QList<QSslError>& errlist );
|
||||
void initWebInspector();
|
||||
|
||||
private:
|
||||
JSAccount* m_parent;
|
||||
|
@@ -42,7 +42,7 @@ ScriptJob*
|
||||
ScriptLinkGeneratorPlugin::openLink( const QString& title, const QString& artist, const QString& album ) const
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments[ "track" ] = QVariant( title );
|
||||
arguments[ "title" ] = QVariant( title );
|
||||
arguments[ "artist" ] = QVariant( artist );
|
||||
arguments[ "album" ] = QVariant( album );
|
||||
|
||||
|
@@ -3,6 +3,7 @@
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.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
|
||||
@@ -39,6 +40,7 @@
|
||||
#include <QFileInfo>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkProxy>
|
||||
#include <QTimer>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#include <shlwapi.h>
|
||||
|
@@ -3,6 +3,7 @@
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.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
|
||||
@@ -63,8 +64,6 @@ public:
|
||||
|
||||
void sendMessage( const QVariantMap& map );
|
||||
|
||||
bool canParseUrl( const QString&, UrlType ) Q_DECL_OVERRIDE { return false; }
|
||||
|
||||
signals:
|
||||
void terminated();
|
||||
void customMessage( const QString& msgType, const QVariantMap& msg );
|
||||
@@ -74,9 +73,6 @@ public slots:
|
||||
void resolve( const Tomahawk::query_ptr& query ) Q_DECL_OVERRIDE;
|
||||
void start() Q_DECL_OVERRIDE;
|
||||
|
||||
void lookupUrl( const QString& ) Q_DECL_OVERRIDE {}
|
||||
|
||||
|
||||
private slots:
|
||||
void readStderr();
|
||||
void readStdout();
|
||||
|
@@ -25,14 +25,14 @@ using namespace Tomahawk;
|
||||
void
|
||||
ScriptInfoPluginFactory::addPlugin( const QSharedPointer< ScriptInfoPlugin >& infoPlugin ) const
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->addInfoPlugin( infoPlugin.data() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptInfoPluginFactory::removePlugin( const QSharedPointer< ScriptInfoPlugin >& infoPlugin ) const
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( infoPlugin );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->removeInfoPlugin( infoPlugin.data() );
|
||||
}
|
||||
|
||||
|
||||
@@ -42,10 +42,10 @@ ScriptInfoPluginFactory::createPlugin( const scriptobject_ptr& object, ScriptAcc
|
||||
// create infoplugin instance
|
||||
ScriptInfoPlugin* scriptInfoPlugin = new ScriptInfoPlugin( object, scriptAccount->name() );
|
||||
|
||||
QSharedPointer< ScriptInfoPlugin > infoPlugin( scriptInfoPlugin );
|
||||
Tomahawk::InfoSystem::InfoPluginPtr infoPlugin( scriptInfoPlugin );
|
||||
|
||||
// move it to infosystem thread
|
||||
infoPlugin->moveToThread( Tomahawk::InfoSystem::InfoSystem::instance()->workerThread().data() );
|
||||
|
||||
return infoPlugin;
|
||||
return QSharedPointer< ScriptInfoPlugin >( scriptInfoPlugin );
|
||||
}
|
||||
|
228
src/libtomahawk/resolvers/plugins/ScriptLinkParserPlugin.cpp
Normal file
228
src/libtomahawk/resolvers/plugins/ScriptLinkParserPlugin.cpp
Normal file
@@ -0,0 +1,228 @@
|
||||
/* === This file is part of Tomahawk Player - <http://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 "ScriptLinkParserPlugin_p.h"
|
||||
|
||||
#include "../ScriptJob.h"
|
||||
#include "../ScriptObject.h"
|
||||
#include "../../utils/Logger.h"
|
||||
#include "../ScriptAccount.h"
|
||||
|
||||
#include "../../database/Database.h"
|
||||
#include "../../database/DatabaseImpl.h"
|
||||
#include "../../SourceList.h"
|
||||
#include "../../Artist.h"
|
||||
#include "../../Album.h"
|
||||
#include "../../playlist/PlaylistTemplate.h"
|
||||
#include "../../playlist/XspfPlaylistTemplate.h"
|
||||
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
ScriptLinkParserPlugin::ScriptLinkParserPlugin( const scriptobject_ptr& scriptObject, ScriptAccount* account )
|
||||
: Utils::LinkParserPlugin()
|
||||
, ScriptPlugin( scriptObject )
|
||||
, d_ptr( new ScriptLinkParserPluginPrivate( this, scriptObject, account ) )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
ScriptLinkParserPlugin::~ScriptLinkParserPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ScriptLinkParserPlugin::canParseUrl( const QString& url, Tomahawk::Utils::UrlType type ) const
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments["url"] = url;
|
||||
arguments["type"] = (int) type;
|
||||
|
||||
return scriptObject()->syncInvoke( "canParseUrl", arguments ).toBool();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptLinkParserPlugin::lookupUrl( const QString& url ) const
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments["url"] = url;
|
||||
Tomahawk::ScriptJob* job = scriptObject()->invoke( "lookupUrl", arguments );
|
||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onLookupUrlRequestDone( QVariantMap ) ) );
|
||||
job->setProperty( "url", url );
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
ScriptLinkParserPlugin::onLookupUrlRequestDone( const QVariantMap& result )
|
||||
{
|
||||
Q_D( ScriptLinkParserPlugin );
|
||||
|
||||
sender()->deleteLater();
|
||||
|
||||
QString url = sender()->property( "url" ).toString();
|
||||
|
||||
tLog() << "ON LOOKUP URL REQUEST DONE" << url << result;
|
||||
|
||||
// It may seem a bit weird, but currently no slot should do anything
|
||||
// more as we starting on a new URL and not task are waiting for it yet.
|
||||
d->pendingUrl = QString();
|
||||
d->pendingAlbum = album_ptr();
|
||||
|
||||
Utils::UrlType type = (Utils::UrlType) result.value( "type" ).toInt();
|
||||
if ( type == Utils::UrlTypeArtist )
|
||||
{
|
||||
QString name = result.value( "name" ).toString();
|
||||
Q_ASSERT( !name.isEmpty() );
|
||||
emit informationFound( url, Artist::get( name, true ).objectCast<QObject>() );
|
||||
}
|
||||
else if ( type == Utils::UrlTypeAlbum )
|
||||
{
|
||||
QString name = result.value( "name" ).toString();
|
||||
QString artist = result.value( "artist" ).toString();
|
||||
album_ptr album = Album::get( Artist::get( artist, true ), name );
|
||||
d->pendingUrl = url;
|
||||
d->pendingAlbum = album;
|
||||
connect( album.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ),
|
||||
SLOT( tracksAdded( QList<Tomahawk::query_ptr>, Tomahawk::ModelMode, Tomahawk::collection_ptr ) ) );
|
||||
if ( !album->tracks().isEmpty() )
|
||||
{
|
||||
emit informationFound( url, album.objectCast<QObject>() );
|
||||
}
|
||||
}
|
||||
else if ( type == Utils::UrlTypeTrack )
|
||||
{
|
||||
Tomahawk::query_ptr query = parseTrack( result );
|
||||
if ( query.isNull() )
|
||||
{
|
||||
// A valid track result shoud have non-empty title and artist.
|
||||
tLog() << Q_FUNC_INFO << d->scriptAccount->name() << "Got empty track information for " << url;
|
||||
emit informationFound( url, QSharedPointer<QObject>() );
|
||||
}
|
||||
else
|
||||
{
|
||||
emit informationFound( url, query.objectCast<QObject>() );
|
||||
}
|
||||
}
|
||||
else if ( type == Utils::UrlTypePlaylist )
|
||||
{
|
||||
QString guid = result.value( "guid" ).toString();
|
||||
Q_ASSERT( !guid.isEmpty() );
|
||||
// Append nodeid to guid to make it globally unique.
|
||||
guid += instanceUUID();
|
||||
|
||||
// Do we already have this playlist loaded?
|
||||
{
|
||||
playlist_ptr playlist = Playlist::get( guid );
|
||||
if ( !playlist.isNull() )
|
||||
{
|
||||
emit informationFound( url, playlist.objectCast<QObject>() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// Get all information to build a new playlist but do not build it until we know,
|
||||
// if it is really handled as a playlist and not as a set of tracks.
|
||||
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
||||
const QString title = result.value( "title" ).toString();
|
||||
const QString info = result.value( "info" ).toString();
|
||||
const QString creator = result.value( "creator" ).toString();
|
||||
QList<query_ptr> queries;
|
||||
foreach( QVariant track, result.value( "tracks" ).toList() )
|
||||
{
|
||||
query_ptr query = parseTrack( track.toMap() );
|
||||
if ( !query.isNull() )
|
||||
{
|
||||
queries << query;
|
||||
}
|
||||
}
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << d->scriptAccount->name() << "Got playlist for " << url;
|
||||
playlisttemplate_ptr pltemplate( new PlaylistTemplate( source, guid, title, info, creator, false, queries ) );
|
||||
emit informationFound( url, pltemplate.objectCast<QObject>() );
|
||||
}
|
||||
else if ( type == Utils::UrlTypeXspf )
|
||||
{
|
||||
QString xspfUrl = result.value( "url" ).toString();
|
||||
Q_ASSERT( !xspfUrl.isEmpty() );
|
||||
QString guid = QString( "xspf-%1-%2" ).arg( xspfUrl.toUtf8().toBase64().constData() ).arg( instanceUUID() );
|
||||
|
||||
// Do we already have this playlist loaded?
|
||||
{
|
||||
playlist_ptr playlist = Playlist::get( guid );
|
||||
if ( !playlist.isNull() )
|
||||
{
|
||||
emit informationFound( url, playlist.objectCast<QObject>() );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Get all information to build a new playlist but do not build it until we know,
|
||||
// if it is really handled as a playlist and not as a set of tracks.
|
||||
Tomahawk::source_ptr source = SourceList::instance()->getLocal();
|
||||
QSharedPointer<XspfPlaylistTemplate> pltemplate( new XspfPlaylistTemplate( xspfUrl, source, guid ) );
|
||||
NewClosure( pltemplate, SIGNAL( tracksLoaded( QList< Tomahawk::query_ptr > ) ),
|
||||
this, SLOT( pltemplateTracksLoadedForUrl( QString, Tomahawk::playlisttemplate_ptr ) ),
|
||||
url, pltemplate.objectCast<Tomahawk::PlaylistTemplate>() );
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << d->scriptAccount->name() << "Got playlist for " << url;
|
||||
pltemplate->load();
|
||||
}
|
||||
else
|
||||
{
|
||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << d->scriptAccount->name() << "No usable information found for " << url;
|
||||
emit informationFound( url, QSharedPointer<QObject>() );
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ScriptLinkParserPlugin::pltemplateTracksLoadedForUrl( const QString& url, const playlisttemplate_ptr& pltemplate )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO;
|
||||
emit informationFound( url, pltemplate.objectCast<QObject>() );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
ScriptLinkParserPlugin::instanceUUID()
|
||||
{
|
||||
return Tomahawk::Database::instance()->impl()->dbid();
|
||||
}
|
||||
|
||||
|
||||
Tomahawk::query_ptr
|
||||
ScriptLinkParserPlugin::parseTrack( const QVariantMap& track )
|
||||
{
|
||||
QString title = track.value( "track" ).toString();
|
||||
QString artist = track.value( "artist" ).toString();
|
||||
QString album = track.value( "album" ).toString();
|
||||
if ( title.isEmpty() || artist.isEmpty() )
|
||||
{
|
||||
return query_ptr();
|
||||
}
|
||||
|
||||
Tomahawk::query_ptr query = Tomahawk::Query::get( artist, title, album );
|
||||
QString resultHint = track.value( "hint" ).toString();
|
||||
if ( !resultHint.isEmpty() )
|
||||
{
|
||||
query->setResultHint( resultHint );
|
||||
query->setSaveHTTPResultHint( true );
|
||||
}
|
||||
|
||||
return query;
|
||||
}
|
61
src/libtomahawk/resolvers/plugins/ScriptLinkParserPlugin.h
Normal file
61
src/libtomahawk/resolvers/plugins/ScriptLinkParserPlugin.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* === This file is part of Tomahawk Player - <http://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 TOMAHAWK_SCRIPTLINKPARSERPLUGIN_H
|
||||
#define TOMAHAWK_SCRIPTLINKPARSERPLUGIN_H
|
||||
|
||||
#include "../../resolvers/ScriptPlugin.h"
|
||||
#include "../../utils/LinkParserPlugin.h"
|
||||
|
||||
#include <QObject>
|
||||
|
||||
#include "DllMacro.h"
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class ScriptObject;
|
||||
class ScriptLinkParserPluginPrivate;
|
||||
|
||||
class DLLEXPORT ScriptLinkParserPlugin : public Utils::LinkParserPlugin, public ScriptPlugin
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ScriptLinkParserPlugin( const scriptobject_ptr& scriptObject, ScriptAccount* account );
|
||||
virtual ~ScriptLinkParserPlugin();
|
||||
|
||||
bool canParseUrl( const QString& url, Tomahawk::Utils::UrlType type ) const override;
|
||||
void lookupUrl( const QString& url ) const override;
|
||||
|
||||
private slots:
|
||||
void onLookupUrlRequestDone( const QVariantMap& result );
|
||||
void pltemplateTracksLoadedForUrl( const QString& url, const playlisttemplate_ptr& pltemplate );
|
||||
|
||||
private:
|
||||
QString instanceUUID();
|
||||
static Tomahawk::query_ptr parseTrack( const QVariantMap& track );
|
||||
|
||||
private:
|
||||
Q_DECLARE_PRIVATE( ScriptLinkParserPlugin )
|
||||
QScopedPointer<ScriptLinkParserPluginPrivate> d_ptr;
|
||||
};
|
||||
|
||||
}; // ns: Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_SCRIPTLINKPARSERPLUGIN_H
|
@@ -0,0 +1,39 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 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 2 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 "ScriptLinkParserPluginFactory.h"
|
||||
|
||||
#include "../ScriptAccount.h"
|
||||
#include "../../utils/LinkParser.h"
|
||||
#include "../../utils/LinkParserPlugin.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
void ScriptLinkParserPluginFactory::addPlugin( const QSharedPointer <ScriptLinkParserPlugin >& plugin ) const
|
||||
{
|
||||
Tomahawk::Utils::LinkParser::instance()->addPlugin( plugin );
|
||||
}
|
||||
|
||||
void ScriptLinkParserPluginFactory::removePlugin( const QSharedPointer< ScriptLinkParserPlugin >& plugin ) const
|
||||
{
|
||||
Tomahawk::Utils::LinkParser::instance()->removePlugin( plugin );
|
||||
}
|
||||
|
||||
QSharedPointer< ScriptLinkParserPlugin > ScriptLinkParserPluginFactory::createPlugin( const scriptobject_ptr& object, ScriptAccount* scriptAccount )
|
||||
{
|
||||
return QSharedPointer< ScriptLinkParserPlugin >( new ScriptLinkParserPlugin( object, scriptAccount ) );
|
||||
}
|
@@ -0,0 +1,41 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 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 2 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef TOMAHAWK_SCRIPTLINKPARSERPLUGINFACTORY_H
|
||||
#define TOMAHAWK_SCRIPTLINKPARSERPLUGINFACTORY_H
|
||||
|
||||
#include "Typedefs.h"
|
||||
#include "ScriptLinkParserPlugin.h"
|
||||
#include "../ScriptPluginFactory.h"
|
||||
|
||||
|
||||
namespace Tomahawk
|
||||
{
|
||||
class ScriptAccount;
|
||||
|
||||
class DLLEXPORT ScriptLinkParserPluginFactory : public ScriptPluginFactory< ScriptLinkParserPlugin >
|
||||
{
|
||||
QSharedPointer< ScriptLinkParserPlugin > createPlugin( const scriptobject_ptr&, ScriptAccount* ) override;
|
||||
void addPlugin( const QSharedPointer< ScriptLinkParserPlugin >& scriptPlugin ) const override;
|
||||
void removePlugin( const QSharedPointer< ScriptLinkParserPlugin >& scriptPlugin ) const override;
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_SCRIPTLINKPARSERPLUGINFACTORY_H
|
@@ -1,6 +1,7 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* 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
|
||||
@@ -16,33 +17,33 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTCOMMAND_LOOKUPURL_P_H
|
||||
#define SCRIPTCOMMAND_LOOKUPURL_P_H
|
||||
#ifndef TOMAHAWK_SCRIPTLINKGENERATORPLUGIN_P_H
|
||||
#define TOMAHAWK_SCRIPTLINKGENERATORPLUGIN_P_H
|
||||
|
||||
#include "ScriptCommand_LookupUrl.h"
|
||||
#include "ScriptLinkParserPlugin.h"
|
||||
|
||||
#include "ExternalResolver.h"
|
||||
|
||||
namespace Tomahawk
|
||||
namespace Tomahawk
|
||||
{
|
||||
|
||||
class ScriptCommand_LookupUrlPrivate
|
||||
class ScriptLinkParserPluginPrivate
|
||||
{
|
||||
public:
|
||||
ScriptCommand_LookupUrlPrivate( ScriptCommand_LookupUrl* q, Tomahawk::ExternalResolver* _resolver, const QString& _url )
|
||||
ScriptLinkParserPluginPrivate( ScriptLinkParserPlugin* q, const scriptobject_ptr& scriptObject, ScriptAccount* scriptAccount )
|
||||
: q_ptr ( q )
|
||||
, url( _url )
|
||||
, resolver( _resolver )
|
||||
, scriptObject( scriptObject )
|
||||
, scriptAccount( scriptAccount )
|
||||
{
|
||||
}
|
||||
ScriptCommand_LookupUrl* q_ptr;
|
||||
Q_DECLARE_PUBLIC ( ScriptCommand_LookupUrl )
|
||||
ScriptLinkParserPlugin* q_ptr;
|
||||
Q_DECLARE_PUBLIC ( ScriptLinkParserPlugin )
|
||||
|
||||
private:
|
||||
QString url;
|
||||
Tomahawk::ExternalResolver* resolver;
|
||||
scriptobject_ptr scriptObject;
|
||||
ScriptAccount* scriptAccount;
|
||||
QString pendingUrl;
|
||||
album_ptr pendingAlbum;
|
||||
};
|
||||
|
||||
} // ns: Tomahawk
|
||||
|
||||
#endif // SCRIPTCOMMAND_LOOKUPURL_P_H
|
||||
#endif // TOMAHAWK_SCRIPTLINKGENERATORPLUGIN_P_H
|
122
src/libtomahawk/utils/LinkParser.cpp
Normal file
122
src/libtomahawk/utils/LinkParser.cpp
Normal file
@@ -0,0 +1,122 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 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 2 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 "LinkParser.h"
|
||||
|
||||
#include "TomahawkUtils.h"
|
||||
#include "Logger.h"
|
||||
#include "../resolvers/SyncScriptJob.h"
|
||||
|
||||
using namespace Tomahawk;
|
||||
using namespace Tomahawk::Utils;
|
||||
|
||||
LinkParser* LinkParser::s_instance = 0;
|
||||
|
||||
|
||||
LinkParser*
|
||||
LinkParser::instance()
|
||||
{
|
||||
if ( !s_instance )
|
||||
s_instance = new LinkParser;
|
||||
|
||||
return s_instance;
|
||||
}
|
||||
|
||||
|
||||
LinkParser::LinkParser( QObject* parent )
|
||||
: QObject( parent )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
LinkParser::~LinkParser()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void LinkParser::addPlugin( const QSharedPointer< LinkParserPlugin >& plugin )
|
||||
{
|
||||
m_plugins.append( plugin );
|
||||
connect( plugin.data(), SIGNAL( informationFound( QString, QSharedPointer<QObject> ) ), SLOT( onInformationFound( QString, QSharedPointer<QObject> ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinkParser::removePlugin( const QSharedPointer< LinkParserPlugin >& plugin )
|
||||
{
|
||||
if ( !plugin.isNull() )
|
||||
{
|
||||
disconnect( plugin.data(), 0, this, 0);
|
||||
|
||||
}
|
||||
|
||||
QMutableListIterator< QSharedPointer< LinkParserPlugin > > iter( m_plugins );
|
||||
while ( iter.hasNext() )
|
||||
{
|
||||
QSharedPointer< LinkParserPlugin > ptr = iter.next();
|
||||
if ( ptr.data() == plugin.data() || ptr.isNull() )
|
||||
{
|
||||
iter.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
LinkParser::canParseUrl( const QString& url, UrlType type ) const
|
||||
{
|
||||
return !parserPluginsForUrl( url, type).isEmpty();
|
||||
}
|
||||
|
||||
|
||||
QList< QSharedPointer< LinkParserPlugin > >
|
||||
LinkParser::parserPluginsForUrl( const QString& url, Tomahawk::Utils::UrlType type ) const
|
||||
{
|
||||
QList< QSharedPointer< LinkParserPlugin > > plugins;
|
||||
|
||||
foreach ( const QSharedPointer< LinkParserPlugin >& plugin, m_plugins )
|
||||
{
|
||||
if ( plugin->canParseUrl( url, type ) )
|
||||
{
|
||||
plugins.append( plugin );
|
||||
}
|
||||
}
|
||||
|
||||
return plugins;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinkParser::lookupUrl( const QString& url, const QList< QSharedPointer < LinkParserPlugin > >& parserPlugins ) const
|
||||
{
|
||||
foreach ( const QSharedPointer< LinkParserPlugin >& plugin, parserPlugins )
|
||||
{
|
||||
if ( !plugin.isNull() )
|
||||
{
|
||||
plugin->lookupUrl( url );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
LinkParser::onInformationFound( const QString& url, const QSharedPointer<QObject>& information )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << url;
|
||||
emit informationFound( url, information );
|
||||
}
|
69
src/libtomahawk/utils/LinkParser.h
Normal file
69
src/libtomahawk/utils/LinkParser.h
Normal file
@@ -0,0 +1,69 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 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
|
||||
* (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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef TOMAHAWK_UTILS_LINKPARSER_H
|
||||
#define TOMAHAWK_UTILS_LINKPARSER_H
|
||||
|
||||
#include "../resolvers/ScriptJob.h"
|
||||
#include "LinkParserPlugin.h"
|
||||
#include "UrlType.h"
|
||||
|
||||
#include "../DllMacro.h"
|
||||
#include "../Typedefs.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Tomahawk {
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class LinkParserPlugin;
|
||||
|
||||
class DLLEXPORT LinkParser : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
static LinkParser* instance();
|
||||
virtual ~LinkParser();
|
||||
|
||||
void addPlugin( const QSharedPointer< LinkParserPlugin >& plugin );
|
||||
void removePlugin( const QSharedPointer< LinkParserPlugin >& plugin );
|
||||
|
||||
bool canParseUrl( const QString& url, UrlType type ) const;
|
||||
QList< QSharedPointer < LinkParserPlugin > > parserPluginsForUrl( const QString& url, UrlType type ) const;
|
||||
void lookupUrl( const QString& url, const QList< QSharedPointer < LinkParserPlugin > >& parserPlugins = QList< QSharedPointer < LinkParserPlugin > >() ) const;
|
||||
|
||||
signals:
|
||||
void informationFound( const QString& url, const QSharedPointer<QObject>& information );
|
||||
|
||||
private slots:
|
||||
void onInformationFound( const QString& url, const QSharedPointer<QObject>& information );
|
||||
|
||||
private:
|
||||
explicit LinkParser( QObject* parent = 0 );
|
||||
QList< QSharedPointer < LinkParserPlugin > > m_plugins;
|
||||
|
||||
|
||||
static LinkParser* s_instance;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_UTILS_LINKPARSER_H
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 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
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,23 +15,10 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#include "LinkParserPlugin.h"
|
||||
|
||||
#include "ScriptErrorStatusMessage.h"
|
||||
#include "../utils/Logger.h"
|
||||
#include "LinkParser.h"
|
||||
|
||||
ScriptErrorStatusMessage::ScriptErrorStatusMessage( const QString& message, Tomahawk::ScriptAccount* account )
|
||||
: ErrorStatusMessage( tr( "Script Error: %1" ).arg( message ) )
|
||||
, m_account( account )
|
||||
Tomahawk::Utils::LinkParserPlugin::~LinkParserPlugin()
|
||||
{
|
||||
}
|
||||
|
||||
void
|
||||
ScriptErrorStatusMessage::activated()
|
||||
{
|
||||
if ( m_account.isNull() )
|
||||
return;
|
||||
|
||||
tDebug() << "ScriptErrorStatusMessage clicked: " << mainText() << m_account->name();
|
||||
m_account->showDebugger();
|
||||
}
|
||||
|
50
src/libtomahawk/utils/LinkParserPlugin.h
Normal file
50
src/libtomahawk/utils/LinkParserPlugin.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 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 2 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/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#ifndef TOMAHAWK_UTILS_LINKPARSERPLUGIN_H
|
||||
#define TOMAHAWK_UTILS_LINKPARSERPLUGIN_H
|
||||
|
||||
#include "../DllMacro.h"
|
||||
#include "../Typedefs.h"
|
||||
#include "UrlType.h"
|
||||
|
||||
namespace Tomahawk {
|
||||
|
||||
class ScriptJob;
|
||||
|
||||
namespace Utils {
|
||||
|
||||
class DLLEXPORT LinkParserPlugin : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
virtual ~LinkParserPlugin();
|
||||
|
||||
virtual bool canParseUrl( const QString& url, Tomahawk::Utils::UrlType type ) const = 0;
|
||||
virtual void lookupUrl( const QString& url ) const = 0;
|
||||
|
||||
signals:
|
||||
void informationFound( const QString&, const QSharedPointer<QObject>& );
|
||||
};
|
||||
|
||||
} // namespace Utils
|
||||
} // namespace Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_UTILS_LINKPARSERPLUGIN_H
|
@@ -24,7 +24,6 @@
|
||||
#include "PluginLoader_p.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "TomahawkVersion.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
@@ -154,7 +153,7 @@ PluginLoader::pluginFilenames( const QString& name ) const
|
||||
QStringList fileNames;
|
||||
foreach( const QString& extension, extensions )
|
||||
{
|
||||
fileNames << QString("lib" TOMAHAWK_TARGET_NAME "_%1_%2.%3")
|
||||
fileNames << QString("libtomahawk_%1_%2.%3")
|
||||
.arg( d_ptr->type )
|
||||
.arg( name )
|
||||
.arg( extension );
|
||||
@@ -175,8 +174,12 @@ PluginLoader::pluginPaths( const QString& name ) const
|
||||
tDebug() << Q_FUNC_INFO << "Checking directory for" << type << "plugins:" << pluginDir.absolutePath();
|
||||
foreach ( QString fileName, pluginDir.entryList( pluginFilenames( name ), QDir::Files ) )
|
||||
{
|
||||
const QString path = pluginDir.absoluteFilePath( fileName );
|
||||
paths << path;
|
||||
//TODO: do we really need to check this?!
|
||||
if ( fileName.startsWith( QString( "libtomahawk_%1" ).arg( type ) ) )
|
||||
{
|
||||
const QString path = pluginDir.absoluteFilePath( fileName );
|
||||
paths << path;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -211,19 +211,11 @@ TomahawkStyle::styleScrollBar( QScrollBar* scrollBar )
|
||||
void
|
||||
TomahawkStyle::loadFonts()
|
||||
{
|
||||
#ifdef Q_OS_MAC
|
||||
QDir dir( QCoreApplication::applicationDirPath() + "/../Resources/Fonts" );
|
||||
#else
|
||||
QDir dir( ":/data/fonts" );
|
||||
#endif
|
||||
foreach ( const QString& fileName, dir.entryList() )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "Trying to add font resource:" << dir.absolutePath() << fileName;
|
||||
#ifdef Q_OS_MAC
|
||||
const int id = QFontDatabase::addApplicationFont( dir.absolutePath() + "/" + fileName );
|
||||
#else
|
||||
tDebug( LOGVERBOSE ) << "Trying to add font resource:" << fileName;
|
||||
const int id = QFontDatabase::addApplicationFont( ":/data/fonts/" + fileName );
|
||||
#endif
|
||||
if ( id >= 0 )
|
||||
{
|
||||
tDebug( LOGVERBOSE ) << "Added font:" << id << QFontDatabase::applicationFontFamilies( id ).first();
|
||||
|
@@ -102,7 +102,6 @@ namespace TomahawkStyle
|
||||
|
||||
static const QColor PLAYLIST_BUTTON_BACKGROUND = QColor( "#111111" );
|
||||
static const QColor PLAYLIST_BUTTON_FOREGROUND = QColor( "#ffffff" );
|
||||
static const QColor PLAYLIST_BUTTON_HOVER_BACKGROUND = QColor( "#111111" );
|
||||
|
||||
static const QColor PLAYLIST_PROGRESS_BACKGROUND = QColor( "#ffffff" );
|
||||
static const QColor PLAYLIST_PROGRESS_FOREGROUND = QColor( "#E61878" );
|
||||
|
@@ -320,11 +320,11 @@ filesizeToString( unsigned int size )
|
||||
|
||||
if ( mb )
|
||||
{
|
||||
return QString( "%1.%2 MB" ).arg( mb ).arg( int( ( kb % 1024 ) / 102.4 ) );
|
||||
return QString( "%1.%2 Mb" ).arg( mb ).arg( int( ( kb % 1024 ) / 102.4 ) );
|
||||
}
|
||||
else if ( kb )
|
||||
{
|
||||
return QString( "%1 KB" ).arg( kb );
|
||||
return QString( "%1 Kb" ).arg( kb );
|
||||
}
|
||||
else
|
||||
return QString::number( size );
|
||||
|
19
src/libtomahawk/utils/UrlType.cpp
Normal file
19
src/libtomahawk/utils/UrlType.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 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 2 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 "UrlType.h"
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 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
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -16,24 +16,25 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef SCRIPTERRORSTATUSMESSAGE_H
|
||||
#define SCRIPTERRORSTATUSMESSAGE_H
|
||||
#pragma once
|
||||
#ifndef TOMAHAWK_UTILS_URLTYPE_H
|
||||
#define TOMAHAWK_UTILS_URLTYPE_H
|
||||
|
||||
#include "ErrorStatusMessage.h"
|
||||
#include "../resolvers/ScriptAccount.h"
|
||||
namespace Tomahawk {
|
||||
|
||||
#include "DllMacro.h"
|
||||
namespace Utils {
|
||||
|
||||
class DLLEXPORT ScriptErrorStatusMessage : public ErrorStatusMessage
|
||||
enum UrlType
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ScriptErrorStatusMessage( const QString& scriptErrorMessage, Tomahawk::ScriptAccount* );
|
||||
|
||||
void activated() override;
|
||||
|
||||
private:
|
||||
QPointer< Tomahawk::ScriptAccount > m_account;
|
||||
UrlTypeAny = 0x00,
|
||||
UrlTypePlaylist = 0x01,
|
||||
UrlTypeTrack = 0x02,
|
||||
UrlTypeAlbum = 0x04,
|
||||
UrlTypeArtist = 0x08,
|
||||
UrlTypeXspf = 0x10
|
||||
};
|
||||
|
||||
#endif // SCRIPTERRORSTATUSMESSAGE_H
|
||||
} // namespace Utils
|
||||
} // namespace Tomahawk
|
||||
|
||||
#endif // TOMAHAWK_UTILS_URLTYPE_H
|
@@ -29,7 +29,6 @@
|
||||
#include "Source.h"
|
||||
#include "MetaPlaylistInterface.h"
|
||||
#include "playlist/TrackView.h"
|
||||
#include "playlist/TrackDetailView.h"
|
||||
#include "widgets/BasicHeader.h"
|
||||
|
||||
#include "database/DatabaseCommand_AllTracks.h"
|
||||
@@ -59,7 +58,6 @@ AlbumInfoWidget::AlbumInfoWidget( const Tomahawk::album_ptr& album, QWidget* par
|
||||
m_tracksModel->setMode( Mixed );
|
||||
|
||||
// We need to set the model on the view before loading the playlist, so spinners & co are connected
|
||||
ui->albumView->trackDetailView()->setBuyButtonVisible( true );
|
||||
ui->albumView->trackView()->setPlayableModel( m_tracksModel );
|
||||
ui->albumView->setCaption( tr( "Album Details" ) );
|
||||
|
||||
@@ -188,4 +186,4 @@ AlbumInfoWidget::pixmap() const
|
||||
return Tomahawk::ViewPage::pixmap();
|
||||
else
|
||||
return m_pixmap;
|
||||
}
|
||||
}
|
||||
|
@@ -107,7 +107,6 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
|
||||
ui->topHits->setItemWidth( scaledX( 140 ) );
|
||||
ui->topHits->proxyModel()->setHideDupeItems( true );
|
||||
ui->topHits->delegate()->setWordWrapping( true );
|
||||
ui->topHits->delegate()->setShowBuyButtons( true );
|
||||
ui->topHits->setFixedHeight( ui->topHits->itemSize().height() + ui->topHits->spacing() * 2 );
|
||||
|
||||
m_topHitsModel = new PlayableModel( ui->topHits );
|
||||
@@ -122,7 +121,7 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
|
||||
ui->biography->setObjectName( "biography" );
|
||||
ui->biography->setContentsMargins( 0, 0, 0, 0 );
|
||||
ui->biography->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
|
||||
ui->biography->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAsNeeded );
|
||||
ui->biography->page()->mainFrame()->setScrollBarPolicy( Qt::Vertical, Qt::ScrollBarAlwaysOff );
|
||||
ui->biography->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
|
||||
ui->biography->installEventFilter( this );
|
||||
|
||||
|
@@ -20,7 +20,6 @@
|
||||
#include "CollectionViewPage.h"
|
||||
|
||||
#include <QRadioButton>
|
||||
#include <QPushButton>
|
||||
#include <QStackedWidget>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
@@ -33,6 +32,7 @@
|
||||
#include "playlist/GridView.h"
|
||||
#include "playlist/PlayableProxyModelPlaylistInterface.h"
|
||||
#include "resolvers/ScriptCollection.h"
|
||||
#include "DownloadManager.h"
|
||||
#include "TomahawkSettings.h"
|
||||
#include "utils/ImageRegistry.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
@@ -58,13 +58,10 @@ CollectionViewPage::CollectionViewPage( const Tomahawk::collection_ptr& collecti
|
||||
qRegisterMetaType< CollectionViewPageMode >( "CollectionViewPageMode" );
|
||||
|
||||
m_header->setBackground( ImageRegistry::instance()->pixmap( RESPATH "images/collection_background.png", QSize( 0, 0 ) ), false );
|
||||
|
||||
setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultCollection, TomahawkUtils::Original, QSize( 256, 256 ) ) );
|
||||
|
||||
m_columnView->proxyModel()->setStyle( PlayableProxyModel::SingleColumn );
|
||||
|
||||
|
||||
PlayableProxyModel* trackViewProxyModel = m_trackView->proxyModel();
|
||||
if ( collection->backendType() == Collection::ScriptCollectionType )
|
||||
{
|
||||
m_trackView->proxyModel()->setStyle( PlayableProxyModel::Locker );
|
||||
@@ -73,15 +70,8 @@ CollectionViewPage::CollectionViewPage( const Tomahawk::collection_ptr& collecti
|
||||
{
|
||||
m_trackView->proxyModel()->setStyle( PlayableProxyModel::Collection );
|
||||
}
|
||||
// mapSourceColumnToColumn depends on the just set PlayableProxyModel::PlayableItemStyle
|
||||
m_trackView->setColumnHidden( trackViewProxyModel->mapSourceColumnToColumn( PlayableModel::Composer ), true );
|
||||
m_trackView->setColumnHidden( trackViewProxyModel->mapSourceColumnToColumn( PlayableModel::Origin ), true );
|
||||
m_trackView->setColumnHidden( trackViewProxyModel->mapSourceColumnToColumn( PlayableModel::Score ), true );
|
||||
m_trackView->setColumnHidden( trackViewProxyModel->mapSourceColumnToColumn( PlayableModel::Bitrate ), true );
|
||||
|
||||
m_trackView->setGuid( QString( "trackview/flat" ) );
|
||||
m_trackView->setSortingEnabled( true );
|
||||
m_trackView->sortByColumn( 0, Qt::AscendingOrder );
|
||||
|
||||
{
|
||||
m_albumView->setAutoResize( false );
|
||||
@@ -132,11 +122,8 @@ CollectionViewPage::CollectionViewPage( const Tomahawk::collection_ptr& collecti
|
||||
|
||||
if ( collection->backendType() == Collection::ScriptCollectionType )
|
||||
{
|
||||
m_downloadAllButton = m_header->addButton( tr( "Download All" ) );
|
||||
connect( m_downloadAllButton, SIGNAL( clicked() ), SLOT( onDownloadAll() ) );
|
||||
|
||||
connect( DownloadManager::instance(), SIGNAL( stateChanged( DownloadManager::DownloadManagerState, DownloadManager::DownloadManagerState ) ),
|
||||
SLOT( onDownloadManagerStateChanged( DownloadManager::DownloadManagerState, DownloadManager::DownloadManagerState ) ) );
|
||||
QAbstractButton* downloadButton = m_header->addButton( tr( "Download All" ) );
|
||||
connect( downloadButton, SIGNAL( clicked() ), SLOT( onDownloadAll() ) );
|
||||
|
||||
m_header->setRefreshVisible( true );
|
||||
connect( m_header, SIGNAL( refresh() ), SLOT( onCollectionChanged() ) );
|
||||
@@ -205,6 +192,8 @@ CollectionViewPage::setFlatModel( PlayableModel* model )
|
||||
|
||||
m_flatModel = model;
|
||||
m_trackView->setPlayableModel( model );
|
||||
m_trackView->setSortingEnabled( true );
|
||||
m_trackView->sortByColumn( 0, Qt::AscendingOrder );
|
||||
|
||||
if ( oldModel )
|
||||
{
|
||||
@@ -392,8 +381,6 @@ CollectionViewPage::restoreViewMode()
|
||||
} else {
|
||||
setCurrentMode( mode );
|
||||
}
|
||||
|
||||
onCollectionChanged();
|
||||
}
|
||||
|
||||
|
||||
@@ -450,40 +437,14 @@ CollectionViewPage::onCollectionChanged()
|
||||
void
|
||||
CollectionViewPage::onDownloadAll()
|
||||
{
|
||||
if ( DownloadManager::instance()->state() == DownloadManager::Running )
|
||||
for ( int i = 0; i < m_flatModel->rowCount( QModelIndex() ); i++ )
|
||||
{
|
||||
DownloadManager::instance()->cancelAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( int i = 0; i < m_trackView->proxyModel()->rowCount( QModelIndex() ); i++ )
|
||||
{
|
||||
PlayableItem* item = m_trackView->proxyModel()->itemFromIndex( m_trackView->proxyModel()->mapToSource( m_trackView->proxyModel()->index( i, 0, QModelIndex() ) ) );
|
||||
if ( !item )
|
||||
continue;
|
||||
PlayableItem* item = m_flatModel->itemFromIndex( m_flatModel->index( i, 0, QModelIndex() ) );
|
||||
if ( !item )
|
||||
continue;
|
||||
|
||||
QList< DownloadFormat > formats = item->query()->results().first()->downloadFormats();
|
||||
if ( formats.isEmpty() || !DownloadManager::instance()->localFileForDownload( formats.first().url.toString() ).isEmpty() )
|
||||
continue;
|
||||
|
||||
if ( !item->result()->downloadFormats().isEmpty() )
|
||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
CollectionViewPage::onDownloadManagerStateChanged( DownloadManager::DownloadManagerState newState, DownloadManager::DownloadManagerState oldState )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
if ( newState == DownloadManager::Running )
|
||||
{
|
||||
m_downloadAllButton->setText( tr( "Cancel Download" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_downloadAllButton->setText( tr( "Download All" ) );
|
||||
if ( !item->result()->downloadFormats().isEmpty() )
|
||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -498,14 +459,5 @@ CollectionViewPage::isTemporaryPage() const
|
||||
bool
|
||||
CollectionViewPage::isBeingPlayed() const
|
||||
{
|
||||
if ( !playlistInterface() )
|
||||
return false;
|
||||
|
||||
if ( playlistInterface() == AudioEngine::instance()->currentTrackPlaylist() )
|
||||
return true;
|
||||
|
||||
if ( playlistInterface()->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() ) )
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return m_playlistInterface->hasChildInterface( AudioEngine::instance()->currentTrackPlaylist() );
|
||||
}
|
||||
|
@@ -22,10 +22,8 @@
|
||||
|
||||
#include "ViewPage.h"
|
||||
#include "PlaylistInterface.h"
|
||||
#include "DownloadManager.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
class QPushButton;
|
||||
class QStackedWidget;
|
||||
|
||||
class GridView;
|
||||
@@ -85,12 +83,10 @@ private slots:
|
||||
void onCollectionChanged();
|
||||
|
||||
void onDownloadAll();
|
||||
void onDownloadManagerStateChanged( DownloadManager::DownloadManagerState newState, DownloadManager::DownloadManagerState oldState );
|
||||
|
||||
private:
|
||||
FilterHeader* m_header;
|
||||
QPixmap m_pixmap;
|
||||
QPushButton* m_downloadAllButton;
|
||||
|
||||
ColumnView* m_columnView;
|
||||
TrackView* m_trackView;
|
||||
|
@@ -100,7 +100,6 @@ SearchWidget::SearchWidget( const QString& search, QWidget* parent )
|
||||
ui->tracks->setItemWidth( TomahawkUtils::DpiScaler::scaledX( this, 140 ) );
|
||||
// ui->tracks->proxyModel()->setHideDupeItems( true );
|
||||
ui->tracks->delegate()->setWordWrapping( true );
|
||||
ui->tracks->delegate()->setShowBuyButtons( true );
|
||||
ui->tracks->setFixedHeight( ui->tracks->itemSize().height() + ui->tracks->spacing() * 2 );
|
||||
|
||||
m_resultsModel = new PlayableModel( ui->tracks );
|
||||
@@ -373,18 +372,13 @@ SearchWidget::onAlbumsFound( const QList<Tomahawk::album_ptr>& albums )
|
||||
|
||||
int distance = TomahawkUtils::levenshtein( m_search, album->name() );
|
||||
int maxlen = qMax( m_search.length(), album->name().length() );
|
||||
float scoreAlbum = (float)( maxlen - distance ) / maxlen;
|
||||
float score = (float)( maxlen - distance ) / maxlen;
|
||||
|
||||
distance = TomahawkUtils::levenshtein( m_search, album->artist()->name() );
|
||||
maxlen = qMax( m_search.length(), album->artist()->name().length() );
|
||||
float scoreArtist = (float)( maxlen - distance ) / maxlen;
|
||||
|
||||
float scoreMax = qMax( scoreAlbum, scoreArtist );
|
||||
if ( scoreMax <= 0.1 )
|
||||
if ( score <= 0.1 )
|
||||
continue;
|
||||
|
||||
m_albums.insert( album, scoreMax );
|
||||
// tDebug() << Q_FUNC_INFO << "found album:" << album->name() << "scoreMax:" << scoreMax;
|
||||
m_albums.insert( album, score );
|
||||
// tDebug() << Q_FUNC_INFO << "found album:" << album->name() << "score:" << score;
|
||||
}
|
||||
|
||||
// updateAlbums();
|
||||
|
@@ -132,16 +132,10 @@ BasicHeader::setPixmap( const QPixmap& pixmap, bool tinted )
|
||||
}
|
||||
|
||||
|
||||
QPushButton*
|
||||
QAbstractButton*
|
||||
BasicHeader::addButton( const QString& text )
|
||||
{
|
||||
QPushButton* button = new QPushButton( this );
|
||||
|
||||
button->setStyleSheet( "QPushButton:hover { font-size: 12px; color: #2b2b2b; background: #f8f8f8; border-style: solid; border-radius: 0px; border-width: 2px; border-color: #2b2b2b; }"
|
||||
"QPushButton { font-size: 12px; color: #ffffff; background-color: #000000; border-style: solid; border-radius: 0px; border-width: 0px; }" );
|
||||
button->setMinimumHeight( 30 );
|
||||
button->setMinimumWidth( 132 );
|
||||
|
||||
button->setText( text );
|
||||
|
||||
ui->horizontalLayout->addSpacing( 8 );
|
||||
|
@@ -26,7 +26,6 @@
|
||||
#include "widgets/BackgroundWidget.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
class QPushButton;
|
||||
class QLabel;
|
||||
class ElidedLabel;
|
||||
class QPaintEvent;
|
||||
@@ -41,7 +40,7 @@ public:
|
||||
|
||||
QScopedPointer<Ui::HeaderWidget> ui;
|
||||
|
||||
QPushButton* addButton( const QString& text );
|
||||
QAbstractButton* addButton( const QString& text );
|
||||
|
||||
public slots:
|
||||
virtual void setCaption( const QString& s );
|
||||
|
@@ -32,9 +32,7 @@ using namespace Tomahawk;
|
||||
|
||||
DropDownButton::DropDownButton( QWidget* parent )
|
||||
: QComboBox( parent )
|
||||
, m_hovering( false )
|
||||
{
|
||||
setAttribute( Qt::WA_Hover, true );
|
||||
}
|
||||
|
||||
|
||||
@@ -48,59 +46,44 @@ DropDownButton::paintEvent( QPaintEvent* event )
|
||||
{
|
||||
// QComboBox::paintEvent( event );
|
||||
QPainter p( this );
|
||||
|
||||
setupPainter( &p );
|
||||
|
||||
drawPrimitive( &p, contentsRect(), currentText(), m_hovering, true );
|
||||
drawPrimitive( &p, contentsRect(), currentText() );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropDownButton::drawPrimitive( QPainter* p, const QRect& rect, const QString& text, bool hovering, bool itemsAvailable )
|
||||
DropDownButton::drawPrimitive( QPainter* p, const QRect& rect, const QString& text )
|
||||
{
|
||||
p->save();
|
||||
|
||||
setupPainter( p );
|
||||
|
||||
p->setRenderHint( QPainter::TextAntialiasing );
|
||||
QRect r = rect.adjusted( 2, 2, -2, -2 );
|
||||
|
||||
QColor bgColor = hovering ? TomahawkStyle::PLAYLIST_BUTTON_HOVER_BACKGROUND : TomahawkStyle::PLAYLIST_BUTTON_BACKGROUND;
|
||||
|
||||
p->setOpacity( 1.0 );
|
||||
p->setPen( bgColor );
|
||||
p->setBrush( bgColor );
|
||||
p->setPen( TomahawkStyle::PLAYLIST_BUTTON_BACKGROUND.darker() );
|
||||
p->setBrush( TomahawkStyle::PLAYLIST_BUTTON_BACKGROUND );
|
||||
p->drawRect( r );
|
||||
|
||||
// paint divider
|
||||
p->setPen( TomahawkStyle::PLAYLIST_BUTTON_FOREGROUND );
|
||||
|
||||
int dropdownWidth = 0;
|
||||
p->drawLine( QPoint( r.right() - 24, r.top() + 3 ), QPoint( r.right() - 24, r.bottom() - 3 ) );
|
||||
|
||||
if ( itemsAvailable )
|
||||
{
|
||||
// paint divider
|
||||
p->drawLine( QPoint( r.right() - 24, r.top() + 3 ), QPoint( r.right() - 24, r.bottom() - 3 ) );
|
||||
|
||||
// paint drop-down arrow
|
||||
p->save();
|
||||
QPainterPath dropPath;
|
||||
dropPath.moveTo( QPointF( r.right() - 14, float(r.top()) + float(r.height()) * 0.5 - 1.5 ) );
|
||||
QPointF currentPosition = dropPath.currentPosition();
|
||||
dropPath.lineTo( currentPosition.x() + 6, currentPosition.y() );
|
||||
dropPath.lineTo( currentPosition.x() + 3, currentPosition.y() + 3 );
|
||||
dropPath.closeSubpath();
|
||||
p->setPen( TomahawkStyle::PLAYLIST_BUTTON_FOREGROUND );
|
||||
p->setBrush( TomahawkStyle::PLAYLIST_BUTTON_FOREGROUND );
|
||||
p->setRenderHint( QPainter::Antialiasing, false );
|
||||
p->drawPath( dropPath );
|
||||
p->restore();
|
||||
|
||||
dropdownWidth = 24;
|
||||
}
|
||||
// paint drop-down arrow
|
||||
p->save();
|
||||
QPainterPath dropPath;
|
||||
dropPath.moveTo( QPointF( r.right() - 14, float(r.top()) + float(r.height()) * 0.5 - 1.5 ) );
|
||||
QPointF currentPosition = dropPath.currentPosition();
|
||||
dropPath.lineTo( currentPosition.x() + 6, currentPosition.y() );
|
||||
dropPath.lineTo( currentPosition.x() + 3, currentPosition.y() + 3 );
|
||||
dropPath.closeSubpath();
|
||||
p->setPen( TomahawkStyle::PLAYLIST_BUTTON_FOREGROUND );
|
||||
p->setBrush( TomahawkStyle::PLAYLIST_BUTTON_FOREGROUND );
|
||||
p->setRenderHint( QPainter::Antialiasing, false );
|
||||
p->drawPath( dropPath );
|
||||
p->restore();
|
||||
|
||||
// paint label
|
||||
const QFontMetrics fm( p->font() );
|
||||
r.adjust( 0, 0, -dropdownWidth, 0 ); // center-align left of the divider
|
||||
p->drawText( r, Qt::AlignCenter, fm.elidedText( text.toUpper(), Qt::ElideRight, r.width() ) );
|
||||
r.adjust( 0, 0, -24, 0 ); // center-align left of the divider
|
||||
p->drawText( r, Qt::AlignCenter, fm.elidedText( text, Qt::ElideRight, r.width() ) );
|
||||
|
||||
p->restore();
|
||||
}
|
||||
@@ -118,29 +101,3 @@ DropDownButton::mousePressEvent( QMouseEvent* event )
|
||||
event->accept();
|
||||
emit clicked();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropDownButton::enterEvent( QEvent * event )
|
||||
{
|
||||
m_hovering = true;
|
||||
QWidget::enterEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropDownButton::leaveEvent( QEvent* event )
|
||||
{
|
||||
m_hovering = false;
|
||||
QWidget::leaveEvent(event);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DropDownButton::setupPainter( QPainter* p )
|
||||
{
|
||||
QFont f = p->font();
|
||||
f.setPointSize( TomahawkUtils::defaultFontSize() - 1 );
|
||||
f.setBold( true );
|
||||
p->setFont( f );
|
||||
}
|
||||
|
@@ -32,7 +32,7 @@ public:
|
||||
explicit DropDownButton( QWidget* parent = 0 );
|
||||
virtual ~DropDownButton();
|
||||
|
||||
static void drawPrimitive( QPainter* p, const QRect& rect, const QString& text, bool hovering, bool itemsAvailable );
|
||||
static void drawPrimitive( QPainter* p, const QRect& rect, const QString& text );
|
||||
|
||||
public slots:
|
||||
|
||||
@@ -42,15 +42,10 @@ signals:
|
||||
protected:
|
||||
void paintEvent( QPaintEvent* event );
|
||||
void mousePressEvent( QMouseEvent* event );
|
||||
void enterEvent( QEvent* event );
|
||||
void leaveEvent( QEvent* event );
|
||||
|
||||
private slots:
|
||||
|
||||
private:
|
||||
static void setupPainter( QPainter* p );
|
||||
|
||||
bool m_hovering;
|
||||
};
|
||||
|
||||
#endif // DROPDOWNBUTTON_H
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user