mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-26 21:59:09 +02:00
Compare commits
72 Commits
viewinfold
...
doubleVlc
Author | SHA1 | Date | |
---|---|---|---|
|
9a5750c6f4 | ||
|
3b6ba36e83 | ||
|
cf6a37ae45 | ||
|
690a87f1eb | ||
|
6842da7240 | ||
|
6910e5dd3b | ||
|
584aa76582 | ||
|
7e96285132 | ||
|
c996a8b90e | ||
|
c705013ee1 | ||
|
84360aed2f | ||
|
ada03e1a8d | ||
|
3a71da5705 | ||
|
214e310c91 | ||
|
ed9a027644 | ||
|
3e2d74128d | ||
|
84ed59f4be | ||
|
5dd36cbd4e | ||
|
7e38d94fe5 | ||
|
28ee9180c8 | ||
|
09e9a6e960 | ||
|
ffa098e52d | ||
|
a439427ca5 | ||
|
a9505f75c5 | ||
|
7e54e506df | ||
|
abc00b4758 | ||
|
77e9b69679 | ||
|
58b640d389 | ||
|
1a5f073437 | ||
|
c9ef7e74d8 | ||
|
34448b1b46 | ||
|
4408ba275c | ||
|
dfd71d7010 | ||
|
170e2e1c86 | ||
|
0047763188 | ||
|
525068a706 | ||
|
85657e40a6 | ||
|
af459afb0b | ||
|
5bbc39e6a5 | ||
|
c88640268a | ||
|
8749a04e23 | ||
|
d45917d14a | ||
|
c87b1390e5 | ||
|
bf28f6856e | ||
|
ceab0f9cf2 | ||
|
a562e75937 | ||
|
81eb226146 | ||
|
ec88cf27f3 | ||
|
931562fbe5 | ||
|
77593e32a7 | ||
|
bac38e4555 | ||
|
980ee97c97 | ||
|
26ad51f4b8 | ||
|
21bdb0bc89 | ||
|
0a560f2f27 | ||
|
9c9f5e4dae | ||
|
fb38735936 | ||
|
c62ae52bfe | ||
|
0341492069 | ||
|
879df894c3 | ||
|
0c9f1be2c8 | ||
|
f7a3d441a1 | ||
|
e9a1135525 | ||
|
bdce4f7636 | ||
|
de65e19cb7 | ||
|
ce3647a4a6 | ||
|
f498570a0e | ||
|
9a741cd2db | ||
|
102c9c6846 | ||
|
1b0517efc5 | ||
|
e6a8a41c31 | ||
|
193beda2bc |
@@ -179,7 +179,7 @@ if( NOT BUILD_WITH_QT4 )
|
|||||||
set(HAVE_X11 FALSE)
|
set(HAVE_X11 FALSE)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
message(STATUS "Found Qt5! Be aware that Qt5-support is still experimental and not officially supported!")
|
message(STATUS "Found Qt5!")
|
||||||
|
|
||||||
if( UNIX AND NOT APPLE )
|
if( UNIX AND NOT APPLE )
|
||||||
# We need this to find the paths to qdbusxml2cpp and co
|
# We need this to find the paths to qdbusxml2cpp and co
|
||||||
@@ -228,6 +228,10 @@ endif()
|
|||||||
if( NOT Qt5Core_DIR )
|
if( NOT Qt5Core_DIR )
|
||||||
message(STATUS "Could not find Qt5, searching for Qt4 instead...")
|
message(STATUS "Could not find Qt5, searching for Qt4 instead...")
|
||||||
|
|
||||||
|
if(NOT FORCE_QT4)
|
||||||
|
message(FATAL_ERROR "Qt4 support is broken, if you plan to fix it, add -DFORCE_QT4=ON to your cmake arguments otherwise you should compile Tomahawk with Qt5")
|
||||||
|
endif()
|
||||||
|
|
||||||
set(NEEDED_QT4_COMPONENTS "QtCore" "QtXml" "QtNetwork")
|
set(NEEDED_QT4_COMPONENTS "QtCore" "QtXml" "QtNetwork")
|
||||||
if( BUILD_GUI )
|
if( BUILD_GUI )
|
||||||
list(APPEND NEEDED_QT4_COMPONENTS "QtGui" "QtWebkit" "QtUiTools" "QtSvg")
|
list(APPEND NEEDED_QT4_COMPONENTS "QtGui" "QtWebkit" "QtUiTools" "QtSvg")
|
||||||
@@ -311,9 +315,6 @@ if(("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang" OR APPLE) AND LIBCPP_FOUND)
|
|||||||
tomahawk_add_cxx_flags( "-stdlib=libc++" )
|
tomahawk_add_cxx_flags( "-stdlib=libc++" )
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
macro_optional_find_package(Echonest 2.3.0)
|
|
||||||
macro_log_feature(ECHONEST_FOUND "Echonest" "Qt library for communicating with The Echo Nest" "http://projects.kde.org/libechonest" TRUE "" "libechonest 2.3.0 is needed for dynamic playlists and the infosystem")
|
|
||||||
|
|
||||||
find_package(Boost REQUIRED COMPONENTS filesystem system)
|
find_package(Boost REQUIRED COMPONENTS filesystem system)
|
||||||
macro_log_feature(Boost_FOUND "Boost" "Provides free peer-reviewed portable C++ source libraries" "http://www.boost.org" TRUE "" "") #FIXME: give useful explanation
|
macro_log_feature(Boost_FOUND "Boost" "Provides free peer-reviewed portable C++ source libraries" "http://www.boost.org" TRUE "" "") #FIXME: give useful explanation
|
||||||
|
|
||||||
|
@@ -1,42 +0,0 @@
|
|||||||
# - Find libechonest
|
|
||||||
# Find the libechonest includes and the libechonest libraries
|
|
||||||
# This module defines
|
|
||||||
# ECHONEST_INCLUDE_DIR, root echonest include dir. Include echonest includes with echonest/foo.h
|
|
||||||
# ECHONEST_LIBRARIES, the path to libechonest
|
|
||||||
# ECHONEST_FOUND, whether libechonest was found
|
|
||||||
|
|
||||||
FIND_PACKAGE(PkgConfig QUIET)
|
|
||||||
|
|
||||||
if( TOMAHAWK_QT5 )
|
|
||||||
set(LIBECHONEST_SUFFIX "5")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
PKG_CHECK_MODULES(PC_ECHONEST QUIET libechonest${LIBECHONEST_SUFFIX})
|
|
||||||
|
|
||||||
FIND_PATH(ECHONEST_INCLUDE_DIR NAMES echonest${LIBECHONEST_SUFFIX}/Track.h
|
|
||||||
HINTS
|
|
||||||
${PC_ECHONEST_INCLUDEDIR}
|
|
||||||
${PC_ECHONEST_INCLUDE_DIRS}
|
|
||||||
${CMAKE_INSTALL_INCLUDEDIR}
|
|
||||||
${KDE4_INCLUDE_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
FIND_LIBRARY(ECHONEST_LIBRARIES NAMES echonest${LIBECHONEST_SUFFIX}
|
|
||||||
HINTS
|
|
||||||
${PC_ECHONEST_LIBDIR}
|
|
||||||
${PC_ECHONEST_LIBRARY_DIRS}
|
|
||||||
${CMAKE_INSTALL_LIBDIR}
|
|
||||||
${KDE4_LIB_DIR}
|
|
||||||
)
|
|
||||||
|
|
||||||
IF(ECHONEST_LIBRARIES AND ECHONEST_INCLUDE_DIR AND NOT PC_ECHONEST_VERSION)
|
|
||||||
MESSAGE(WARNING "You don't have pkg-config and so the libechonest version check does not work!")
|
|
||||||
set(PC_ECHONEST_VERSION "999.9.9")
|
|
||||||
ENDIF()
|
|
||||||
|
|
||||||
INCLUDE(FindPackageHandleStandardArgs)
|
|
||||||
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Echonest
|
|
||||||
REQUIRED_VARS ECHONEST_LIBRARIES ECHONEST_INCLUDE_DIR
|
|
||||||
VERSION_VAR PC_ECHONEST_VERSION)
|
|
||||||
|
|
||||||
MARK_AS_ADVANCED(ECHONEST_INCLUDE_DIR ECHONEST_LIBRARIES)
|
|
@@ -79,7 +79,6 @@ Required dependencies:
|
|||||||
* [TagLib 1.8](https://taglib.github.io/)
|
* [TagLib 1.8](https://taglib.github.io/)
|
||||||
* [Boost 1.3](http://www.boost.org/)
|
* [Boost 1.3](http://www.boost.org/)
|
||||||
* [Lucene++ 3.0.6](https://github.com/luceneplusplus/LucenePlusPlus/)
|
* [Lucene++ 3.0.6](https://github.com/luceneplusplus/LucenePlusPlus/)
|
||||||
* [libechonest 2.3.1](http://projects.kde.org/projects/playground/libs/libechonest/)
|
|
||||||
* [Attica 5.6.0](http://ftp.kde.org/stable/attica/)
|
* [Attica 5.6.0](http://ftp.kde.org/stable/attica/)
|
||||||
* [QuaZip 0.4.3](http://quazip.sourceforge.net/)
|
* [QuaZip 0.4.3](http://quazip.sourceforge.net/)
|
||||||
* [liblastfm 1.0.9](https://github.com/lastfm/liblastfm/)
|
* [liblastfm 1.0.9](https://github.com/lastfm/liblastfm/)
|
||||||
|
@@ -3,8 +3,6 @@
|
|||||||
set( TOMAHAWK_QT5 @TOMAHAWK_QT5@ )
|
set( TOMAHAWK_QT5 @TOMAHAWK_QT5@ )
|
||||||
|
|
||||||
if(TOMAHAWK_QT5)
|
if(TOMAHAWK_QT5)
|
||||||
message(STATUS "Found Qt5! Be aware that Qt5-support is still experimental and not officially supported!")
|
|
||||||
|
|
||||||
# CMAKE 2.8.13+/3.0.0+ requires these for IMPORTed targets
|
# CMAKE 2.8.13+/3.0.0+ requires these for IMPORTed targets
|
||||||
find_package(Qt5Core REQUIRED)
|
find_package(Qt5Core REQUIRED)
|
||||||
find_package(Qt5Concurrent REQUIRED)
|
find_package(Qt5Concurrent REQUIRED)
|
||||||
|
@@ -42,6 +42,8 @@ Tomahawk.apiVersion = "0.2.2";
|
|||||||
//Statuses considered a success for HTTP request
|
//Statuses considered a success for HTTP request
|
||||||
var httpSuccessStatuses = [200, 201];
|
var httpSuccessStatuses = [200, 201];
|
||||||
|
|
||||||
|
Tomahawk.error = console.error;
|
||||||
|
|
||||||
// install RSVP error handler for uncaught(!) errors
|
// install RSVP error handler for uncaught(!) errors
|
||||||
RSVP.on('error', function (reason) {
|
RSVP.on('error', function (reason) {
|
||||||
var resolverName = "";
|
var resolverName = "";
|
||||||
@@ -49,9 +51,9 @@ RSVP.on('error', function (reason) {
|
|||||||
resolverName = Tomahawk.resolver.instance.settings.name + " - ";
|
resolverName = Tomahawk.resolver.instance.settings.name + " - ";
|
||||||
}
|
}
|
||||||
if (reason) {
|
if (reason) {
|
||||||
console.error(resolverName + 'Uncaught error:', reason);
|
Tomahawk.error(resolverName + 'Uncaught error:', reason);
|
||||||
} else {
|
} else {
|
||||||
console.error(resolverName + 'Uncaught error: error thrown from RSVP but it was empty');
|
Tomahawk.error(resolverName + 'Uncaught error: error thrown from RSVP but it was empty');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -273,6 +275,9 @@ Tomahawk.Resolver = {
|
|||||||
getStreamUrl: function (params) {
|
getStreamUrl: function (params) {
|
||||||
return params;
|
return params;
|
||||||
},
|
},
|
||||||
|
getDownloadUrl: function (params) {
|
||||||
|
return params;
|
||||||
|
},
|
||||||
resolve: function() {
|
resolve: function() {
|
||||||
},
|
},
|
||||||
_adapter_resolve: function (params) {
|
_adapter_resolve: function (params) {
|
||||||
@@ -300,13 +305,15 @@ Tomahawk.Resolver = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_adapter_testConfig: function (config) {
|
_adapter_testConfig: function (config) {
|
||||||
return RSVP.Promise.resolve(this.testConfig(config)).then(function () {
|
return RSVP.Promise.resolve(this.testConfig(config)).then(function (results) {
|
||||||
return {result: Tomahawk.ConfigTestResultType.Success};
|
results = results || Tomahawk.ConfigTestResultType.Success;
|
||||||
|
return results;
|
||||||
|
}, function (error) {
|
||||||
|
return error;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
// help functions
|
// help functions
|
||||||
|
|
||||||
Tomahawk.valueForSubNode = function (node, tag) {
|
Tomahawk.valueForSubNode = function (node, tag) {
|
||||||
@@ -377,48 +384,6 @@ Tomahawk.retrievedMetadata = function (metadataId, metadata, error) {
|
|||||||
delete Tomahawk.retrieveMetadataCallbacks[metadataId];
|
delete Tomahawk.retrieveMetadataCallbacks[metadataId];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Internal counter used to identify asyncRequest callback from native code.
|
|
||||||
*/
|
|
||||||
Tomahawk.asyncRequestIdCounter = 0;
|
|
||||||
/**
|
|
||||||
* Internal map used to map asyncRequestIds to the respective javascript
|
|
||||||
* callback functions.
|
|
||||||
*/
|
|
||||||
Tomahawk.asyncRequestCallbacks = {};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Pass the natively retrieved reply back to the javascript callback
|
|
||||||
* and augment the fake XMLHttpRequest object.
|
|
||||||
*
|
|
||||||
* Internal use only!
|
|
||||||
*/
|
|
||||||
Tomahawk.nativeAsyncRequestDone = function (reqId, xhr) {
|
|
||||||
// Check that we have a matching callback stored.
|
|
||||||
if (!Tomahawk.asyncRequestCallbacks.hasOwnProperty(reqId)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Call the real callback
|
|
||||||
if (xhr.readyState == 4 && httpSuccessStatuses.indexOf(xhr.status) != -1) {
|
|
||||||
// Call the real callback
|
|
||||||
if (Tomahawk.asyncRequestCallbacks[reqId].callback) {
|
|
||||||
Tomahawk.asyncRequestCallbacks[reqId].callback(xhr);
|
|
||||||
}
|
|
||||||
} else if (xhr.readyState === 4) {
|
|
||||||
Tomahawk.log("Failed to do nativeAsyncRequest");
|
|
||||||
Tomahawk.log("Status Code was: " + xhr.status);
|
|
||||||
if (Tomahawk.asyncRequestCallbacks[reqId].errorHandler) {
|
|
||||||
Tomahawk.asyncRequestCallbacks[reqId].errorHandler(xhr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Callbacks are only used once.
|
|
||||||
delete Tomahawk.asyncRequestCallbacks[reqId];
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method is externalized from Tomahawk.asyncRequest, so that other clients
|
* This method is externalized from Tomahawk.asyncRequest, so that other clients
|
||||||
* (like tomahawk-android) can inject their own logic that determines whether or not to do a request
|
* (like tomahawk-android) can inject their own logic that determines whether or not to do a request
|
||||||
@@ -433,9 +398,9 @@ var shouldDoNativeRequest = function (options) {
|
|||||||
|| extraHeaders.hasOwnProperty("User-Agent")));
|
|| extraHeaders.hasOwnProperty("User-Agent")));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Possible options:
|
* Possible options:
|
||||||
|
* - url: The URL to call
|
||||||
* - method: The HTTP request method (default: GET)
|
* - method: The HTTP request method (default: GET)
|
||||||
* - username: The username for HTTP Basic Auth
|
* - username: The username for HTTP Basic Auth
|
||||||
* - password: The password for HTTP Basic Auth
|
* - password: The password for HTTP Basic Auth
|
||||||
@@ -453,7 +418,12 @@ var doRequest = function(options) {
|
|||||||
return this.responseHeaders;
|
return this.responseHeaders;
|
||||||
};
|
};
|
||||||
xhr.getResponseHeader = function (header) {
|
xhr.getResponseHeader = function (header) {
|
||||||
return this.responseHeaders[header];
|
for(key in xhr.responseHeaders) {
|
||||||
|
if(key.toLowerCase() === header.toLowerCase()) {
|
||||||
|
return xhr.responseHeaders[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
};
|
};
|
||||||
|
|
||||||
return xhr;
|
return xhr;
|
||||||
@@ -745,7 +715,6 @@ Tomahawk.base64Encode = function (b) {
|
|||||||
return window.btoa(b);
|
return window.btoa(b);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
Tomahawk.PluginManager = {
|
Tomahawk.PluginManager = {
|
||||||
wrapperPrefix: '_adapter_',
|
wrapperPrefix: '_adapter_',
|
||||||
objects: {},
|
objects: {},
|
||||||
@@ -776,8 +745,6 @@ Tomahawk.PluginManager = {
|
|||||||
methodName = this.wrapperPrefix + methodName;
|
methodName = this.wrapperPrefix + methodName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
var pluginManager = this;
|
|
||||||
if (!this.objects[objectId]) {
|
if (!this.objects[objectId]) {
|
||||||
Tomahawk.log("Object not found! objectId: " + objectId + " methodName: " + methodName);
|
Tomahawk.log("Object not found! objectId: " + objectId + " methodName: " + methodName);
|
||||||
} else {
|
} else {
|
||||||
@@ -798,20 +765,21 @@ Tomahawk.PluginManager = {
|
|||||||
invoke: function (requestId, objectId, methodName, params) {
|
invoke: function (requestId, objectId, methodName, params) {
|
||||||
RSVP.Promise.resolve(this.invokeSync(requestId, objectId, methodName, params))
|
RSVP.Promise.resolve(this.invokeSync(requestId, objectId, methodName, params))
|
||||||
.then(function (result) {
|
.then(function (result) {
|
||||||
Tomahawk.reportScriptJobResults({
|
var params = {
|
||||||
requestId: requestId,
|
requestId: requestId,
|
||||||
data: result
|
data: result
|
||||||
});
|
};
|
||||||
|
Tomahawk.reportScriptJobResults(encodeParamsToNativeFunctions(params));
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
Tomahawk.reportScriptJobResults({
|
var params = {
|
||||||
requestId: requestId,
|
requestId: requestId,
|
||||||
error: error
|
error: error
|
||||||
});
|
};
|
||||||
|
Tomahawk.reportScriptJobResults(encodeParamsToNativeFunctions(params));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
var encodeParamsToNativeFunctions = function(param) {
|
var encodeParamsToNativeFunctions = function(param) {
|
||||||
return param;
|
return param;
|
||||||
};
|
};
|
||||||
@@ -825,7 +793,7 @@ Tomahawk.NativeScriptJobManager = {
|
|||||||
var requestId = this.idCounter++;
|
var requestId = this.idCounter++;
|
||||||
var deferred = RSVP.defer();
|
var deferred = RSVP.defer();
|
||||||
this.deferreds[requestId] = deferred;
|
this.deferreds[requestId] = deferred;
|
||||||
Tomahawk.invokeNativeScriptJob(requestId, methodName, encodeParamsToNativeFunctions(params));;
|
Tomahawk.invokeNativeScriptJob(requestId, methodName, encodeParamsToNativeFunctions(params));
|
||||||
return deferred.promise;
|
return deferred.promise;
|
||||||
},
|
},
|
||||||
reportNativeScriptJobResult: function(requestId, result) {
|
reportNativeScriptJobResult: function(requestId, result) {
|
||||||
@@ -1494,9 +1462,7 @@ Tomahawk.Collection = {
|
|||||||
return new RSVP.Promise(function (resolve, reject) {
|
return new RSVP.Promise(function (resolve, reject) {
|
||||||
that.cachedDbs[id].changeVersion(that.cachedDbs[id].version, "", null,
|
that.cachedDbs[id].changeVersion(that.cachedDbs[id].version, "", null,
|
||||||
function (err) {
|
function (err) {
|
||||||
if (console.error) {
|
Tomahawk.error("Error trying to change db version!", err);
|
||||||
console.error("Error!: %o", err);
|
|
||||||
}
|
|
||||||
reject();
|
reject();
|
||||||
}, function () {
|
}, function () {
|
||||||
delete that.cachedDbs[id];
|
delete that.cachedDbs[id];
|
||||||
@@ -1800,6 +1766,9 @@ Tomahawk.Collection = {
|
|||||||
this.settings.capabilities = [Tomahawk.Collection.BrowseCapability.Artists,
|
this.settings.capabilities = [Tomahawk.Collection.BrowseCapability.Artists,
|
||||||
Tomahawk.Collection.BrowseCapability.Albums,
|
Tomahawk.Collection.BrowseCapability.Albums,
|
||||||
Tomahawk.Collection.BrowseCapability.Tracks];
|
Tomahawk.Collection.BrowseCapability.Tracks];
|
||||||
|
if (!this.settings.weight && this.resolver && this.resolver.settings.weight) {
|
||||||
|
this.settings.weight = this.resolver.settings.weight;
|
||||||
|
}
|
||||||
return this.settings;
|
return this.settings;
|
||||||
},
|
},
|
||||||
|
|
||||||
@@ -1808,6 +1777,14 @@ Tomahawk.Collection = {
|
|||||||
return this.resolver.getStreamUrl(params);
|
return this.resolver.getStreamUrl(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return params;
|
||||||
|
},
|
||||||
|
|
||||||
|
getDownloadUrl: function(params) {
|
||||||
|
if(this.resolver) {
|
||||||
|
return this.resolver.getDownloadUrl(params);
|
||||||
|
}
|
||||||
|
|
||||||
return params;
|
return params;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@@ -44,12 +44,12 @@ namespace Tomahawk {
|
|||||||
void publishTune( QUrl url, Tomahawk::InfoSystem::InfoStringHash trackInfo );
|
void publishTune( QUrl url, Tomahawk::InfoSystem::InfoStringHash trackInfo );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData );
|
void notInCacheSlot( const Tomahawk::InfoSystem::InfoStringHash criteria, Tomahawk::InfoSystem::InfoRequestData requestData ) override;
|
||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void init();
|
void init() override;
|
||||||
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData );
|
void pushInfo( Tomahawk::InfoSystem::InfoPushData pushData ) override;
|
||||||
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData );
|
void getInfo( Tomahawk::InfoSystem::InfoRequestData requestData ) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void audioStarted( const Tomahawk::InfoSystem::PushInfoPair& pushInfoPair );
|
void audioStarted( const Tomahawk::InfoSystem::PushInfoPair& pushInfoPair );
|
||||||
|
@@ -54,14 +54,14 @@ public:
|
|||||||
Account::ConnectionState connectionState() const;
|
Account::ConnectionState connectionState() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void connectPlugin();
|
void connectPlugin() override;
|
||||||
void disconnectPlugin();
|
void disconnectPlugin() override;
|
||||||
|
|
||||||
void advertise();
|
void advertise();
|
||||||
|
|
||||||
virtual void sendSipInfos( const Tomahawk::peerinfo_ptr& /* receiver */, const QList<SipInfo>& /* info */ ) {}
|
virtual void sendSipInfos( const Tomahawk::peerinfo_ptr& /* receiver */, const QList<SipInfo>& /* info */ ) override {}
|
||||||
void broadcastMsg( const QString& ) {}
|
void broadcastMsg( const QString& ) {}
|
||||||
bool addContact( const QString&, AddContactOptions, const QString& ) { return false; }
|
bool addContact( const QString&, AddContactOptions, const QString& ) override { return false; }
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void lanHostFound( const QString& host, int port, const QString& name, const QString& nodeid );
|
void lanHostFound( const QString& host, int port, const QString& name, const QString& nodeid );
|
||||||
|
@@ -1,5 +1,4 @@
|
|||||||
include_directories(
|
include_directories(
|
||||||
${ECHONEST_INCLUDE_DIR}
|
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
)
|
)
|
||||||
if(WIN32 OR APPLE)
|
if(WIN32 OR APPLE)
|
||||||
@@ -15,14 +14,13 @@ endif()
|
|||||||
endif(WIN32 OR APPLE)
|
endif(WIN32 OR APPLE)
|
||||||
|
|
||||||
list(APPEND simple_plugins
|
list(APPEND simple_plugins
|
||||||
Echonest
|
|
||||||
Charts
|
Charts
|
||||||
NewReleases
|
NewReleases
|
||||||
Spotify
|
#Spotify
|
||||||
Hypem
|
Hypem
|
||||||
MusixMatch
|
MusixMatch
|
||||||
MusicBrainz
|
MusicBrainz
|
||||||
Rovi
|
#Rovi
|
||||||
Discogs
|
Discogs
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@@ -80,7 +80,7 @@ FdoNotifyPlugin::FdoNotifyPlugin()
|
|||||||
, m_wmSupportsBodyMarkup( false )
|
, m_wmSupportsBodyMarkup( false )
|
||||||
{
|
{
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
|
||||||
m_supportedPushTypes << InfoNotifyUser << InfoNowPlaying << InfoTrackUnresolved << InfoNowStopped << InfoInboxReceived;
|
m_supportedPushTypes << InfoNotifyUser << InfoNowPlaying << InfoNowResumed << InfoTrackUnresolved << InfoNowStopped << InfoInboxReceived;
|
||||||
|
|
||||||
// Query the window manager for its capabilties in styling notifications.
|
// Query the window manager for its capabilties in styling notifications.
|
||||||
notifications_interface = new org::freedesktop::Notifications( "org.freedesktop.Notifications", "/org/freedesktop/Notifications",
|
notifications_interface = new org::freedesktop::Notifications( "org.freedesktop.Notifications", "/org/freedesktop/Notifications",
|
||||||
@@ -139,6 +139,7 @@ FdoNotifyPlugin::pushInfo( Tomahawk::InfoSystem::InfoPushData pushData )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
case Tomahawk::InfoSystem::InfoNowPlaying:
|
case Tomahawk::InfoSystem::InfoNowPlaying:
|
||||||
|
case Tomahawk::InfoSystem::InfoNowResumed:
|
||||||
nowPlaying( pushData.infoPair.second );
|
nowPlaying( pushData.infoPair.second );
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -120,9 +120,12 @@ ActionCollection::initActions()
|
|||||||
m_actionCollection[ "createPlaylist" ] = new QAction( tr( "Create Playlist" ), this );
|
m_actionCollection[ "createPlaylist" ] = new QAction( tr( "Create Playlist" ), this );
|
||||||
m_actionCollection[ "createPlaylist" ]->setShortcut( QKeySequence( "Ctrl+N" ) );
|
m_actionCollection[ "createPlaylist" ]->setShortcut( QKeySequence( "Ctrl+N" ) );
|
||||||
m_actionCollection[ "createPlaylist" ]->setShortcutContext( Qt::ApplicationShortcut );
|
m_actionCollection[ "createPlaylist" ]->setShortcutContext( Qt::ApplicationShortcut );
|
||||||
|
// echonest is dead, disable stations
|
||||||
|
/*
|
||||||
m_actionCollection[ "createStation" ] = new QAction( tr( "Create Station" ), this );
|
m_actionCollection[ "createStation" ] = new QAction( tr( "Create Station" ), this );
|
||||||
m_actionCollection[ "createStation" ]->setShortcut( QKeySequence( "Ctrl+S" ) );
|
m_actionCollection[ "createStation" ]->setShortcut( QKeySequence( "Ctrl+S" ) );
|
||||||
m_actionCollection[ "createStation" ]->setShortcutContext( Qt::ApplicationShortcut );
|
m_actionCollection[ "createStation" ]->setShortcutContext( Qt::ApplicationShortcut );
|
||||||
|
*/
|
||||||
#ifdef Q_OS_MAC
|
#ifdef Q_OS_MAC
|
||||||
m_actionCollection[ "minimize" ] = new QAction( tr( "Minimize" ), this );
|
m_actionCollection[ "minimize" ] = new QAction( tr( "Minimize" ), this );
|
||||||
m_actionCollection[ "minimize" ]->setShortcut( QKeySequence( "Ctrl+M" ) );
|
m_actionCollection[ "minimize" ]->setShortcut( QKeySequence( "Ctrl+M" ) );
|
||||||
@@ -171,7 +174,8 @@ ActionCollection::createMenuBar( QWidget *parent )
|
|||||||
controlsMenu->addAction( m_actionCollection[ "showOfflineSources" ] );
|
controlsMenu->addAction( m_actionCollection[ "showOfflineSources" ] );
|
||||||
controlsMenu->addSeparator();
|
controlsMenu->addSeparator();
|
||||||
controlsMenu->addAction( m_actionCollection[ "createPlaylist" ] );
|
controlsMenu->addAction( m_actionCollection[ "createPlaylist" ] );
|
||||||
controlsMenu->addAction( m_actionCollection[ "createStation" ] );
|
// echonest is dead, disable stations
|
||||||
|
// controlsMenu->addAction( m_actionCollection[ "createStation" ] );
|
||||||
controlsMenu->addAction( m_actionCollection[ "importPlaylist" ] );
|
controlsMenu->addAction( m_actionCollection[ "importPlaylist" ] );
|
||||||
controlsMenu->addAction( m_actionCollection[ "updateCollection" ] );
|
controlsMenu->addAction( m_actionCollection[ "updateCollection" ] );
|
||||||
controlsMenu->addAction( m_actionCollection[ "rescanCollection" ] );
|
controlsMenu->addAction( m_actionCollection[ "rescanCollection" ] );
|
||||||
|
@@ -74,9 +74,6 @@ set( libGuiSources
|
|||||||
playlist/dynamic/DynamicPlaylist.cpp
|
playlist/dynamic/DynamicPlaylist.cpp
|
||||||
playlist/dynamic/DynamicView.cpp
|
playlist/dynamic/DynamicView.cpp
|
||||||
playlist/dynamic/DynamicModel.cpp
|
playlist/dynamic/DynamicModel.cpp
|
||||||
playlist/dynamic/echonest/EchonestGenerator.cpp
|
|
||||||
playlist/dynamic/echonest/EchonestControl.cpp
|
|
||||||
playlist/dynamic/echonest/EchonestSteerer.cpp
|
|
||||||
playlist/dynamic/widgets/DynamicWidget.cpp
|
playlist/dynamic/widgets/DynamicWidget.cpp
|
||||||
playlist/dynamic/widgets/DynamicControlWrapper.cpp
|
playlist/dynamic/widgets/DynamicControlWrapper.cpp
|
||||||
playlist/dynamic/widgets/DynamicControlList.cpp
|
playlist/dynamic/widgets/DynamicControlList.cpp
|
||||||
@@ -146,6 +143,7 @@ set( libGuiSources
|
|||||||
widgets/ClickableLabel.cpp
|
widgets/ClickableLabel.cpp
|
||||||
widgets/ComboBox.cpp
|
widgets/ComboBox.cpp
|
||||||
widgets/DropDownButton.cpp
|
widgets/DropDownButton.cpp
|
||||||
|
widgets/DownloadButton.cpp
|
||||||
widgets/ElidedLabel.cpp
|
widgets/ElidedLabel.cpp
|
||||||
widgets/FilterHeader.cpp
|
widgets/FilterHeader.cpp
|
||||||
widgets/CaptionLabel.cpp
|
widgets/CaptionLabel.cpp
|
||||||
@@ -207,7 +205,6 @@ list(APPEND libSources
|
|||||||
PlaylistInterface.cpp
|
PlaylistInterface.cpp
|
||||||
UrlHandler.cpp
|
UrlHandler.cpp
|
||||||
|
|
||||||
EchonestCatalogSynchronizer.cpp
|
|
||||||
|
|
||||||
accounts/AccountManager.cpp
|
accounts/AccountManager.cpp
|
||||||
accounts/Account.cpp
|
accounts/Account.cpp
|
||||||
@@ -412,7 +409,6 @@ include_directories(
|
|||||||
|
|
||||||
${QT_INCLUDE_DIR}
|
${QT_INCLUDE_DIR}
|
||||||
${QJSON_INCLUDE_DIR}
|
${QJSON_INCLUDE_DIR}
|
||||||
${ECHONEST_INCLUDE_DIR}
|
|
||||||
${LUCENEPP_INCLUDE_DIRS}
|
${LUCENEPP_INCLUDE_DIRS}
|
||||||
${LIBVLC_INCLUDE_DIR}
|
${LIBVLC_INCLUDE_DIR}
|
||||||
${Boost_INCLUDE_DIR}
|
${Boost_INCLUDE_DIR}
|
||||||
@@ -534,7 +530,6 @@ TARGET_LINK_LIBRARIES( ${TOMAHAWK_LIBRARY}
|
|||||||
# External deps
|
# External deps
|
||||||
${QJSON_LIBRARIES}
|
${QJSON_LIBRARIES}
|
||||||
${LUCENEPP_LIBRARIES}
|
${LUCENEPP_LIBRARIES}
|
||||||
${ECHONEST_LIBRARIES}
|
|
||||||
${QT_QTSQL_LIBRARY}
|
${QT_QTSQL_LIBRARY}
|
||||||
${QT_QTUITOOLS_LIBRARY}
|
${QT_QTUITOOLS_LIBRARY}
|
||||||
${QT_QTGUI_LIBRARY}
|
${QT_QTGUI_LIBRARY}
|
||||||
@@ -578,7 +573,7 @@ file( GLOB networkHeaders "network/*.h" )
|
|||||||
file( GLOB playlistHeaders "playlist/*.h" )
|
file( GLOB playlistHeaders "playlist/*.h" )
|
||||||
file( GLOB playlistDynamicHeaders "playlist/dynamic/*.h" )
|
file( GLOB playlistDynamicHeaders "playlist/dynamic/*.h" )
|
||||||
file( GLOB playlistDynamicDatabaseHeaders "playlist/dynamic/database/*.h" )
|
file( GLOB playlistDynamicDatabaseHeaders "playlist/dynamic/database/*.h" )
|
||||||
file( GLOB playlistDynamicEchonestHeaders "playlist/dynamic/echonest/*.h" )
|
# file( GLOB playlistDynamicEchonestHeaders "playlist/dynamic/echonest/*.h" )
|
||||||
file( GLOB playlistDynamicWidgetsHeaders "playlist/dynamic/widgets/*.h" )
|
file( GLOB playlistDynamicWidgetsHeaders "playlist/dynamic/widgets/*.h" )
|
||||||
file( GLOB resolversHeaders "resolvers/*.h" )
|
file( GLOB resolversHeaders "resolvers/*.h" )
|
||||||
file( GLOB sipHeaders "sip/*.h" )
|
file( GLOB sipHeaders "sip/*.h" )
|
||||||
@@ -607,7 +602,7 @@ install( FILES ${networkHeaders} DESTINATION include/libtomahawk/network )
|
|||||||
install( FILES ${playlistHeaders} DESTINATION include/libtomahawk/playlist )
|
install( FILES ${playlistHeaders} DESTINATION include/libtomahawk/playlist )
|
||||||
install( FILES ${playlistDynamicHeaders} DESTINATION include/libtomahawk/playlist/dynamic )
|
install( FILES ${playlistDynamicHeaders} DESTINATION include/libtomahawk/playlist/dynamic )
|
||||||
install( FILES ${playlistDynamicDatabaseHeaders} DESTINATION include/libtomahawk/playlist/dynamic/database )
|
install( FILES ${playlistDynamicDatabaseHeaders} DESTINATION include/libtomahawk/playlist/dynamic/database )
|
||||||
install( FILES ${playlistDynamicEchonestHeaders} DESTINATION include/libtomahawk/playlist/dynamic/echonest )
|
# install( FILES ${playlistDynamicEchonestHeaders} DESTINATION include/libtomahawk/playlist/dynamic/echonest )
|
||||||
install( FILES ${playlistDynamicWidgetsHeaders} DESTINATION include/libtomahawk/playlist/dynamic/widgets )
|
install( FILES ${playlistDynamicWidgetsHeaders} DESTINATION include/libtomahawk/playlist/dynamic/widgets )
|
||||||
install( FILES ${resolversHeaders} DESTINATION include/libtomahawk/resolvers )
|
install( FILES ${resolversHeaders} DESTINATION include/libtomahawk/resolvers )
|
||||||
install( FILES ${sipHeaders} DESTINATION include/libtomahawk/sip )
|
install( FILES ${sipHeaders} DESTINATION include/libtomahawk/sip )
|
||||||
|
@@ -226,8 +226,7 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
|||||||
if ( m_supportedActions & ActionOpenFileManager &&
|
if ( m_supportedActions & ActionOpenFileManager &&
|
||||||
queries.length() == 1 &&
|
queries.length() == 1 &&
|
||||||
queries.first()->numResults() &&
|
queries.first()->numResults() &&
|
||||||
queries.first()->results().first()->resolvedByCollection() &&
|
queries.first()->results().first()->isLocal() )
|
||||||
queries.first()->results().first()->resolvedByCollection()->isLocal() )
|
|
||||||
{
|
{
|
||||||
m_sigmap->setMapping( addAction( ImageRegistry::instance()->icon( RESPATH "images/folder.svg" ),
|
m_sigmap->setMapping( addAction( ImageRegistry::instance()->icon( RESPATH "images/folder.svg" ),
|
||||||
tr( "Open Folder in File Manager..." ) ), ActionOpenFileManager );
|
tr( "Open Folder in File Manager..." ) ), ActionOpenFileManager );
|
||||||
|
@@ -118,7 +118,7 @@ DownloadJob::localFile() const
|
|||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
DownloadJob::localPath() const
|
DownloadJob::localPath( const Tomahawk::album_ptr& album )
|
||||||
{
|
{
|
||||||
QDir dir = TomahawkSettings::instance()->downloadsPath();
|
QDir dir = TomahawkSettings::instance()->downloadsPath();
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ DownloadJob::localPath() const
|
|||||||
dir.mkpath( "." );
|
dir.mkpath( "." );
|
||||||
}
|
}
|
||||||
|
|
||||||
QString path = QString( "%1/%2" ).arg( safeEncode( m_track->artist(), true ) ).arg( safeEncode( m_track->album(), true ) );
|
QString path = QString( "%1/%2" ).arg( safeEncode( album->artist()->name(), true ) ).arg( safeEncode( album->name(), true ) );
|
||||||
dir.mkpath( path );
|
dir.mkpath( path );
|
||||||
|
|
||||||
return QString( dir.path() + "/" + path ).replace( "//", "/" );
|
return QString( dir.path() + "/" + path ).replace( "//", "/" );
|
||||||
@@ -138,7 +138,7 @@ QUrl
|
|||||||
DownloadJob::prepareFilename()
|
DownloadJob::prepareFilename()
|
||||||
{
|
{
|
||||||
QString filename = QString( "%1. %2.%3" ).arg( m_track->albumpos() ).arg( safeEncode( m_track->track() ) ).arg( m_format.extension );
|
QString filename = QString( "%1. %2.%3" ).arg( m_track->albumpos() ).arg( safeEncode( m_track->track() ) ).arg( m_format.extension );
|
||||||
QString path = localPath();
|
QString path = localPath( m_track->albumPtr() );
|
||||||
QString localFile = QString( path + "/" + filename );
|
QString localFile = QString( path + "/" + filename );
|
||||||
|
|
||||||
if ( !m_tryResuming )
|
if ( !m_tryResuming )
|
||||||
@@ -206,22 +206,17 @@ DownloadJob::download()
|
|||||||
{
|
{
|
||||||
if ( m_state == Running )
|
if ( m_state == Running )
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
setState( Running );
|
setState( Running );
|
||||||
|
|
||||||
if ( m_result->resolvedByCollection() )
|
if (m_result->resolvedBy() != nullptr) {
|
||||||
{
|
Tomahawk::ScriptJob *job = m_result->resolvedBy()->getDownloadUrl( m_result, m_format );
|
||||||
Tomahawk::ScriptCollection* collection = qobject_cast<Tomahawk::ScriptCollection*>( m_result->resolvedByCollection().data() );
|
connect( job, SIGNAL( done(QVariantMap) ), SLOT( onUrlRetrieved(QVariantMap) ) );
|
||||||
if ( collection )
|
job->start();
|
||||||
{
|
} else {
|
||||||
QVariantMap arguments;
|
onUrlRetrieved({{"url", m_format.url}});
|
||||||
arguments[ "url" ] = m_format.url;
|
|
||||||
|
|
||||||
// HACK: *shrug* WIP.
|
|
||||||
Tomahawk::ScriptJob* job = collection->scriptObject()->invoke( "getStreamUrl", arguments );
|
|
||||||
connect( job, SIGNAL( done(QVariantMap) ), SLOT( onUrlRetrieved(QVariantMap) ) );
|
|
||||||
job->start();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -444,7 +439,7 @@ DownloadJob::checkForResumedFile()
|
|||||||
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
DownloadJob::safeEncode( const QString& filename, bool removeTrailingDots ) const
|
DownloadJob::safeEncode( const QString& filename, bool removeTrailingDots )
|
||||||
{
|
{
|
||||||
//FIXME: make it a regexp
|
//FIXME: make it a regexp
|
||||||
QString res = QString( filename ).toLatin1().replace( "/", "_" ).replace( "\\", "_" )
|
QString res = QString( filename ).toLatin1().replace( "/", "_" ).replace( "\\", "_" )
|
||||||
|
@@ -58,7 +58,7 @@ public:
|
|||||||
long receivedSize() const { return m_rcvdSize; }
|
long receivedSize() const { return m_rcvdSize; }
|
||||||
long fileSize() const { return m_fileSize; }
|
long fileSize() const { return m_fileSize; }
|
||||||
|
|
||||||
QString localPath() const;
|
static QString localPath( const Tomahawk::album_ptr& album );
|
||||||
QString localFile() const;
|
QString localFile() const;
|
||||||
DownloadFormat format() const;
|
DownloadFormat format() const;
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ private slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void storeState();
|
void storeState();
|
||||||
QString safeEncode( const QString& filename, bool removeTrailingDots = false ) const;
|
static QString safeEncode( const QString& filename, bool removeTrailingDots = false );
|
||||||
bool checkForResumedFile();
|
bool checkForResumedFile();
|
||||||
QUrl prepareFilename();
|
QUrl prepareFilename();
|
||||||
|
|
||||||
|
@@ -24,6 +24,8 @@
|
|||||||
#include "TomahawkSettings.h"
|
#include "TomahawkSettings.h"
|
||||||
#include "infosystem/InfoSystem.h"
|
#include "infosystem/InfoSystem.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
#include "Result.h"
|
||||||
|
#include "Query.h"
|
||||||
|
|
||||||
DownloadManager* DownloadManager::s_instance = 0;
|
DownloadManager* DownloadManager::s_instance = 0;
|
||||||
|
|
||||||
@@ -85,6 +87,36 @@ DownloadManager::localFileForDownload( const QString& url ) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QUrl
|
||||||
|
DownloadManager::localUrlForDownload( const Tomahawk::query_ptr& query ) const
|
||||||
|
{
|
||||||
|
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||||
|
if ( result )
|
||||||
|
{
|
||||||
|
return localUrlForDownload( result );
|
||||||
|
}
|
||||||
|
|
||||||
|
return QUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
QUrl
|
||||||
|
DownloadManager::localUrlForDownload( const Tomahawk::result_ptr& result ) const
|
||||||
|
{
|
||||||
|
if ( result && !result->downloadFormats().isEmpty() &&
|
||||||
|
!localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() )
|
||||||
|
{
|
||||||
|
return QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ) ).absolutePath() );
|
||||||
|
}
|
||||||
|
else if ( result && result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished )
|
||||||
|
{
|
||||||
|
return QUrl::fromLocalFile( QFileInfo( result->downloadJob()->localFile() ).absolutePath() );
|
||||||
|
}
|
||||||
|
|
||||||
|
return QUrl();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DownloadManager::storeJobs( const QList<downloadjob_ptr>& jobs )
|
DownloadManager::storeJobs( const QList<downloadjob_ptr>& jobs )
|
||||||
{
|
{
|
||||||
|
@@ -45,6 +45,8 @@ public:
|
|||||||
|
|
||||||
void storeJobs( const QList<downloadjob_ptr>& jobs );
|
void storeJobs( const QList<downloadjob_ptr>& jobs );
|
||||||
QString localFileForDownload( const QString& url ) const;
|
QString localFileForDownload( const QString& url ) const;
|
||||||
|
QUrl localUrlForDownload( const Tomahawk::result_ptr& result ) const;
|
||||||
|
QUrl localUrlForDownload( const Tomahawk::query_ptr& query ) const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
bool addJob( const downloadjob_ptr& job );
|
bool addJob( const downloadjob_ptr& job );
|
||||||
|
@@ -980,7 +980,7 @@ DropJob::removeRemoteSources()
|
|||||||
|
|
||||||
foreach ( const Tomahawk::result_ptr& result, item->results() )
|
foreach ( const Tomahawk::result_ptr& result, item->results() )
|
||||||
{
|
{
|
||||||
if ( !result->resolvedByCollection().isNull() && !result->resolvedByCollection()->isLocal() )
|
if ( !result->isLocal() )
|
||||||
{
|
{
|
||||||
list.append( item );
|
list.append( item );
|
||||||
break;
|
break;
|
||||||
|
@@ -1,14 +1,14 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -20,7 +20,6 @@
|
|||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "GlobalActionManager.h"
|
#include "GlobalActionManager.h"
|
||||||
|
|
||||||
#include "accounts/AccountManager.h"
|
#include "accounts/AccountManager.h"
|
||||||
@@ -47,12 +46,6 @@
|
|||||||
#include "TomahawkSettings.h"
|
#include "TomahawkSettings.h"
|
||||||
#include "ViewManager.h"
|
#include "ViewManager.h"
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
|
||||||
#include <echonest5/Playlist.h>
|
|
||||||
#else
|
|
||||||
#include <echonest/Playlist.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QFileInfo>
|
#include <QFileInfo>
|
||||||
|
|
||||||
@@ -913,144 +906,144 @@ GlobalActionManager::loadDynamicPlaylist( const QUrl& url, bool station )
|
|||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistRadioType ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "artist_limitto" )
|
else if ( param.first == "artist_limitto" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistType ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "description" )
|
else if ( param.first == "description" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Description" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist Description" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistDescriptionType ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "variety" )
|
else if ( param.first == "variety" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Variety" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Variety" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Variety ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "tempo" ) )
|
else if ( param.first.startsWith( "tempo" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Tempo" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Tempo" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinTempo + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "duration" ) )
|
else if ( param.first.startsWith( "duration" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Duration" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Duration" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDuration + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "loudness" ) )
|
else if ( param.first.startsWith( "loudness" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Loudness" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Loudness" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinLoudness + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "danceability" ) )
|
else if ( param.first.startsWith( "danceability" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Danceability" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Danceability" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinDanceability + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "energy" ) )
|
else if ( param.first.startsWith( "energy" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Energy" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Energy" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::MinEnergy + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "artist_familiarity" ) )
|
else if ( param.first.startsWith( "artist_familiarity" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Familiarity" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist Familiarity" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinFamiliarity + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "artist_hotttnesss" ) )
|
else if ( param.first.startsWith( "artist_hotttnesss" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Artist Hotttnesss" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Artist Hotttnesss" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinHotttnesss + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinHotttnesss + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "song_hotttnesss" ) )
|
else if ( param.first.startsWith( "song_hotttnesss" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Song Hotttnesss" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Song Hotttnesss" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? -1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongMinHotttnesss + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "longitude" ) )
|
else if ( param.first.startsWith( "longitude" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Longitude" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Longitude" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLongitude + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first.startsWith( "latitude" ) )
|
else if ( param.first.startsWith( "latitude" ) )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Latitude" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Latitude" );
|
||||||
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
int extra = param.first.endsWith( "_max" ) ? 1 : 0;
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::ArtistMinLatitude + extra ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "key" )
|
else if ( param.first == "key" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Key" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Key" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Key ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "mode" )
|
else if ( param.first == "mode" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Mode" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Mode" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mode ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "mood" )
|
else if ( param.first == "mood" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Mood" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Mood" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mood ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Mood ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "style" )
|
else if ( param.first == "style" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Style" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Style" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Style ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::Style ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
else if ( param.first == "song" )
|
else if ( param.first == "song" )
|
||||||
{
|
{
|
||||||
dyncontrol_ptr c = pl->generator()->createControl( "Song" );
|
dyncontrol_ptr c = pl->generator()->createControl( "Song" );
|
||||||
c->setInput( param.second );
|
c->setInput( param.second );
|
||||||
c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongRadioType ) );
|
// c->setMatch( QString::number( (int)Echonest::DynamicPlaylist::SongRadioType ) );
|
||||||
controls << c;
|
// controls << c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,21 +1,21 @@
|
|||||||
/*
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
*
|
||||||
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
This program is free software; you can redistribute it and/or modify
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
it under the terms of the GNU General Public License as published by
|
*
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
(at your option) any later version.
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
This program is distributed in the hope that it will be useful,
|
* (at your option) any later version.
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
*
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
GNU General Public License for more details.
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
You should have received a copy of the GNU General Public License along
|
* GNU General Public License for more details.
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
*
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* You should have received a copy of the GNU General Public License
|
||||||
*/
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
#ifndef GLOBALACTIONMANAGER_H
|
#ifndef GLOBALACTIONMANAGER_H
|
||||||
#define GLOBALACTIONMANAGER_H
|
#define GLOBALACTIONMANAGER_H
|
||||||
|
@@ -36,7 +36,7 @@
|
|||||||
#define MAX_CONCURRENT_QUERIES 16
|
#define MAX_CONCURRENT_QUERIES 16
|
||||||
#define CLEANUP_TIMEOUT 5 * 60 * 1000
|
#define CLEANUP_TIMEOUT 5 * 60 * 1000
|
||||||
#define MINSCORE 0.5
|
#define MINSCORE 0.5
|
||||||
#define DEFAULT_RESOLVER_TIMEOUT 5000 //5 seconds
|
#define DEFAULT_RESOLVER_TIMEOUT 5000 // 5 seconds
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
@@ -542,12 +542,12 @@ Pipeline::shuntNext()
|
|||||||
q->setCurrentResolver( 0 );
|
q->setCurrentResolver( 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
//Zero-patient, a stub so that query is not resolved until we go through
|
// Zero-patient, a stub so that query is not resolved until we go through
|
||||||
//all resolvers
|
// all resolvers
|
||||||
//As query considered as 'finished trying to resolve' when there are no
|
// As query considered as 'finished trying to resolve' when there are no
|
||||||
//more qid entries in qidsState we'll put one as sort of 'keep this until
|
// more qid entries in qidsState we'll put one as sort of 'keep this until
|
||||||
//we kick off all our resolvers' entry
|
// we kick off all our resolvers' entry
|
||||||
//once we kick off all resolvers we'll remove this entry
|
// once we kick off all resolvers we'll remove this entry
|
||||||
incQIDState( q, nullptr );
|
incQIDState( q, nullptr );
|
||||||
checkQIDState( q );
|
checkQIDState( q );
|
||||||
}
|
}
|
||||||
@@ -673,7 +673,7 @@ Pipeline::decQIDState( const Tomahawk::query_ptr& query, Tomahawk::Resolver* r )
|
|||||||
{
|
{
|
||||||
{
|
{
|
||||||
QMutexLocker lock( &d->mut );
|
QMutexLocker lock( &d->mut );
|
||||||
d->qidsState.remove( query->id(), r );//Removes all matching pairs
|
d->qidsState.remove( query->id(), r ); // Removes all matching pairs
|
||||||
}
|
}
|
||||||
|
|
||||||
checkQIDState( query );
|
checkQIDState( query );
|
||||||
|
@@ -194,7 +194,7 @@ Query::addResults( const QList< Tomahawk::result_ptr >& newresults )
|
|||||||
}*/
|
}*/
|
||||||
|
|
||||||
d->results << newresults;
|
d->results << newresults;
|
||||||
qStableSort( d->results.begin(), d->results.end(), std::bind( &Query::resultSorter, this, std::placeholders::_1, std::placeholders::_2 ) );
|
sortResults();
|
||||||
|
|
||||||
// hook up signals, and check solved status
|
// hook up signals, and check solved status
|
||||||
foreach( const result_ptr& rp, newresults )
|
foreach( const result_ptr& rp, newresults )
|
||||||
@@ -258,7 +258,7 @@ Query::onResultStatusChanged()
|
|||||||
Q_D( Query );
|
Q_D( Query );
|
||||||
QMutexLocker lock( &d->mutex );
|
QMutexLocker lock( &d->mutex );
|
||||||
if ( !d->results.isEmpty() )
|
if ( !d->results.isEmpty() )
|
||||||
qStableSort( d->results.begin(), d->results.end(), std::bind( &Query::resultSorter, this, std::placeholders::_1, std::placeholders::_2 ) );
|
sortResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
checkResults();
|
checkResults();
|
||||||
@@ -273,6 +273,11 @@ Query::removeResult( const Tomahawk::result_ptr& result )
|
|||||||
Q_D( Query );
|
Q_D( Query );
|
||||||
QMutexLocker lock( &d->mutex );
|
QMutexLocker lock( &d->mutex );
|
||||||
d->results.removeAll( result );
|
d->results.removeAll( result );
|
||||||
|
if ( d->preferredResult == result )
|
||||||
|
{
|
||||||
|
d->preferredResult.clear();
|
||||||
|
}
|
||||||
|
sortResults();
|
||||||
}
|
}
|
||||||
|
|
||||||
emit resultsRemoved( result );
|
emit resultsRemoved( result );
|
||||||
@@ -396,12 +401,21 @@ Query::id() const
|
|||||||
bool
|
bool
|
||||||
Query::resultSorter( const result_ptr& left, const result_ptr& right )
|
Query::resultSorter( const result_ptr& left, const result_ptr& right )
|
||||||
{
|
{
|
||||||
|
Q_D( Query );
|
||||||
|
if ( !d->preferredResult.isNull() )
|
||||||
|
{
|
||||||
|
if ( d->preferredResult == left )
|
||||||
|
return true;
|
||||||
|
if ( d->preferredResult == right )
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
const float ls = left->isOnline() ? howSimilar( left ) : 0.0;
|
const float ls = left->isOnline() ? howSimilar( left ) : 0.0;
|
||||||
const float rs = right->isOnline() ? howSimilar( right ) : 0.0;
|
const float rs = right->isOnline() ? howSimilar( right ) : 0.0;
|
||||||
|
|
||||||
if ( ls == rs )
|
if ( ls == rs )
|
||||||
{
|
{
|
||||||
if ( right->resolvedByCollection() && right->resolvedByCollection()->isLocal() )
|
if ( right->isLocal() )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -427,6 +441,30 @@ Query::resultSorter( const result_ptr& left, const result_ptr& right )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
result_ptr
|
||||||
|
Query::preferredResult() const
|
||||||
|
{
|
||||||
|
Q_D( const Query );
|
||||||
|
return d->preferredResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Query::setPreferredResult( const result_ptr& result )
|
||||||
|
{
|
||||||
|
{
|
||||||
|
Q_D( Query );
|
||||||
|
QMutexLocker lock( &d->mutex );
|
||||||
|
|
||||||
|
Q_ASSERT( d->results.contains( result ) );
|
||||||
|
d->preferredResult = result;
|
||||||
|
sortResults();
|
||||||
|
}
|
||||||
|
|
||||||
|
emit resultsChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
Query::setCurrentResolver( Tomahawk::Resolver* resolver )
|
Query::setCurrentResolver( Tomahawk::Resolver* resolver )
|
||||||
{
|
{
|
||||||
@@ -622,6 +660,10 @@ float
|
|||||||
Query::howSimilar( const Tomahawk::result_ptr& r )
|
Query::howSimilar( const Tomahawk::result_ptr& r )
|
||||||
{
|
{
|
||||||
Q_D( Query );
|
Q_D( Query );
|
||||||
|
if (d->howSimilarCache.find(r->id()) != d->howSimilarCache.end())
|
||||||
|
{
|
||||||
|
return d->howSimilarCache[r->id()];
|
||||||
|
}
|
||||||
// result values
|
// result values
|
||||||
const QString& rArtistname = r->track()->artistSortname();
|
const QString& rArtistname = r->track()->artistSortname();
|
||||||
const QString& rAlbumname = r->track()->albumSortname();
|
const QString& rAlbumname = r->track()->albumSortname();
|
||||||
@@ -643,10 +685,12 @@ Query::howSimilar( const Tomahawk::result_ptr& r )
|
|||||||
qTrackname = queryTrack()->trackSortname();
|
qTrackname = queryTrack()->trackSortname();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const QRegExp filterOutChars = QRegExp(QString::fromUtf8("[-`´~!@#$%^&*\\(\\)_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]"));
|
||||||
|
|
||||||
//Cleanup symbols for minor naming differences
|
//Cleanup symbols for minor naming differences
|
||||||
qArtistname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
qArtistname.remove(filterOutChars);
|
||||||
qTrackname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
qTrackname.remove(filterOutChars);
|
||||||
qAlbumname.remove(QRegExp(QString::fromUtf8("[-`~!@#$%^&*()_—+=|:;<>«»,.?/{}\'\"\\[\\]\\\\]")));
|
qAlbumname.remove(filterOutChars);
|
||||||
|
|
||||||
// normal edit distance
|
// normal edit distance
|
||||||
const int artdist = TomahawkUtils::levenshtein( qArtistname, rArtistname );
|
const int artdist = TomahawkUtils::levenshtein( qArtistname, rArtistname );
|
||||||
@@ -678,12 +722,16 @@ Query::howSimilar( const Tomahawk::result_ptr& r )
|
|||||||
const int mlatr = qMax( artistTrackname.length(), rArtistTrackname.length() );
|
const int mlatr = qMax( artistTrackname.length(), rArtistTrackname.length() );
|
||||||
const float dcatr = (float)( mlatr - atrdist ) / mlatr;
|
const float dcatr = (float)( mlatr - atrdist ) / mlatr;
|
||||||
|
|
||||||
return qMax( dctrk, qMax( dcatr, qMax( dcart, dcalb ) ) );
|
float resultScore = qMax( dctrk, qMax( dcatr, qMax( dcart, dcalb ) ) );
|
||||||
|
d->howSimilarCache[r->id()] = resultScore;
|
||||||
|
return resultScore;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// weighted, so album match is worth less than track title
|
// weighted, so album match is worth less than track title
|
||||||
return ( dcart * 4 + dcalb + dctrk * 5 ) / 10;
|
float resultScore = ( dcart * 4 + dcalb + dctrk * 5 ) / 10;
|
||||||
|
d->howSimilarCache[r->id()] = resultScore;
|
||||||
|
return resultScore;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -734,3 +782,11 @@ Query::setWeakRef( QWeakPointer<Query> weakRef )
|
|||||||
Q_D( Query );
|
Q_D( Query );
|
||||||
d->ownRef = weakRef;
|
d->ownRef = weakRef;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
Query::sortResults()
|
||||||
|
{
|
||||||
|
Q_D( Query );
|
||||||
|
qStableSort( d->results.begin(), d->results.end(), std::bind( &Query::resultSorter, this, std::placeholders::_1, std::placeholders::_2 ) );
|
||||||
|
}
|
||||||
|
@@ -112,6 +112,8 @@ public:
|
|||||||
|
|
||||||
/// sorter for list of results
|
/// sorter for list of results
|
||||||
bool resultSorter( const result_ptr& left, const result_ptr& right );
|
bool resultSorter( const result_ptr& left, const result_ptr& right );
|
||||||
|
result_ptr preferredResult() const;
|
||||||
|
void setPreferredResult( const result_ptr& result );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void resultsAdded( const QList<Tomahawk::result_ptr>& );
|
void resultsAdded( const QList<Tomahawk::result_ptr>& );
|
||||||
@@ -158,6 +160,7 @@ private:
|
|||||||
void setCurrentResolver( Tomahawk::Resolver* resolver );
|
void setCurrentResolver( Tomahawk::Resolver* resolver );
|
||||||
void clearResults();
|
void clearResults();
|
||||||
void checkResults();
|
void checkResults();
|
||||||
|
void sortResults();
|
||||||
};
|
};
|
||||||
|
|
||||||
} //ns
|
} //ns
|
||||||
|
@@ -4,6 +4,7 @@
|
|||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
|
|
||||||
#include <QMutex>
|
#include <QMutex>
|
||||||
|
#include <map>
|
||||||
|
|
||||||
namespace Tomahawk
|
namespace Tomahawk
|
||||||
{
|
{
|
||||||
@@ -39,6 +40,7 @@ private:
|
|||||||
QList< Tomahawk::artist_ptr > artists;
|
QList< Tomahawk::artist_ptr > artists;
|
||||||
QList< Tomahawk::album_ptr > albums;
|
QList< Tomahawk::album_ptr > albums;
|
||||||
QList< Tomahawk::result_ptr > results;
|
QList< Tomahawk::result_ptr > results;
|
||||||
|
Tomahawk::result_ptr preferredResult;
|
||||||
|
|
||||||
float score;
|
float score;
|
||||||
bool solved;
|
bool solved;
|
||||||
@@ -58,6 +60,8 @@ private:
|
|||||||
|
|
||||||
mutable QMutex mutex;
|
mutable QMutex mutex;
|
||||||
QWeakPointer< Tomahawk::Query > ownRef;
|
QWeakPointer< Tomahawk::Query > ownRef;
|
||||||
|
|
||||||
|
std::map<QString, float> howSimilarCache;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // Tomahawk
|
} // Tomahawk
|
||||||
|
@@ -234,6 +234,13 @@ Result::playable() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
Result::isLocal() const
|
||||||
|
{
|
||||||
|
return resolvedByCollection().isNull() ? false : resolvedByCollection()->isLocal();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
QVariant
|
QVariant
|
||||||
Result::toVariant() const
|
Result::toVariant() const
|
||||||
{
|
{
|
||||||
|
@@ -94,6 +94,12 @@ public:
|
|||||||
bool isOnline() const;
|
bool isOnline() const;
|
||||||
bool playable() const;
|
bool playable() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief whether this result isLocal, i.e. resolved by a local collection
|
||||||
|
* @return isLocal
|
||||||
|
*/
|
||||||
|
bool isLocal() const;
|
||||||
|
|
||||||
QString url() const;
|
QString url() const;
|
||||||
/**
|
/**
|
||||||
* Has the given url been checked that it is accessible/valid.
|
* Has the given url been checked that it is accessible/valid.
|
||||||
|
@@ -1764,3 +1764,15 @@ TomahawkSettings::setPlaydarKey( const QByteArray& key )
|
|||||||
setValue( "playdar/key", key );
|
setValue( "playdar/key", key );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
TomahawkSettings::vlcArguments() const
|
||||||
|
{
|
||||||
|
return value( "vlc/cmdline_args" ).value< QString >();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
TomahawkSettings::setVlcArguments( const QString& args )
|
||||||
|
{
|
||||||
|
setValue( "vlc/cmdline_args", args);
|
||||||
|
}
|
||||||
|
|
||||||
|
@@ -253,6 +253,10 @@ public:
|
|||||||
QByteArray playdarKey() const;
|
QByteArray playdarKey() const;
|
||||||
void setPlaydarKey( const QByteArray& key );
|
void setPlaydarKey( const QByteArray& key );
|
||||||
|
|
||||||
|
// VLC Settings
|
||||||
|
QString vlcArguments() const;
|
||||||
|
void setVlcArguments( const QString& arguments );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void changed();
|
void changed();
|
||||||
void recentlyPlayedPlaylistAdded( const QString& playlistId, int sourceId );
|
void recentlyPlayedPlaylistAdded( const QString& playlistId, int sourceId );
|
||||||
|
@@ -167,7 +167,7 @@ signals:
|
|||||||
void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state );
|
void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state );
|
||||||
|
|
||||||
void configurationChanged();
|
void configurationChanged();
|
||||||
void configTestResult( Tomahawk::Accounts::ConfigTestResultType );
|
void configTestResult( int, const QString& = QString() );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void loadFromConfig( const QString &accountId );
|
virtual void loadFromConfig( const QString &accountId );
|
||||||
|
@@ -82,7 +82,7 @@ DelegateConfigWrapper::DelegateConfigWrapper( Tomahawk::Accounts::Account* accou
|
|||||||
if ( m_widget->metaObject()->indexOfSignal( "sizeHintChanged()" ) > -1 )
|
if ( m_widget->metaObject()->indexOfSignal( "sizeHintChanged()" ) > -1 )
|
||||||
connect( m_widget, SIGNAL( sizeHintChanged() ), this, SLOT( updateSizeHint() ) );
|
connect( m_widget, SIGNAL( sizeHintChanged() ), this, SLOT( updateSizeHint() ) );
|
||||||
|
|
||||||
connect( m_account, SIGNAL( configTestResult( Tomahawk::Accounts::ConfigTestResultType ) ), SLOT( onConfigTestResult( Tomahawk::Accounts::ConfigTestResultType ) ) );
|
connect( m_account, SIGNAL( configTestResult( int, const QString& ) ), SLOT( onConfigTestResult( int, const QString& ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -193,11 +193,11 @@ DelegateConfigWrapper::aboutClicked( bool )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
DelegateConfigWrapper::onConfigTestResult( Tomahawk::Accounts::ConfigTestResultType result )
|
DelegateConfigWrapper::onConfigTestResult( int code, const QString& message )
|
||||||
{
|
{
|
||||||
tLog() << Q_FUNC_INFO << result;
|
tLog() << Q_FUNC_INFO << code << ": " << message;
|
||||||
|
|
||||||
if( result == Tomahawk::Accounts::ConfigTestResultSuccess )
|
if( code == Tomahawk::Accounts::ConfigTestResultSuccess )
|
||||||
{
|
{
|
||||||
m_invalidData = QVariantMap();
|
m_invalidData = QVariantMap();
|
||||||
closeDialog( QDialog::Accepted );
|
closeDialog( QDialog::Accepted );
|
||||||
@@ -227,8 +227,25 @@ DelegateConfigWrapper::onConfigTestResult( Tomahawk::Accounts::ConfigTestResultT
|
|||||||
|
|
||||||
m_invalidData = m_widget->readData();
|
m_invalidData = m_widget->readData();
|
||||||
|
|
||||||
// TODO: generate message based on status code
|
QString msg = !message.isEmpty() ? message : getTestConfigMessage( code );
|
||||||
m_errorLabel->setText( QString( "<font color='red'>%1</font>" ).arg( tr( "Your config is invalid." ) ) );
|
m_errorLabel->setText( QString( "<font color='red'>%1</font>" ).arg( msg ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QString
|
||||||
|
DelegateConfigWrapper::getTestConfigMessage( int code )
|
||||||
|
{
|
||||||
|
switch(code) {
|
||||||
|
case Tomahawk::Accounts::ConfigTestResultCommunicationError:
|
||||||
|
return tr( "Unable to authenticate. Please check your connection." );
|
||||||
|
case Tomahawk::Accounts::ConfigTestResultInvalidCredentials:
|
||||||
|
return tr( "Username or password incorrect." );
|
||||||
|
case Tomahawk::Accounts::ConfigTestResultInvalidAccount:
|
||||||
|
return tr( "Account rejected by server." );
|
||||||
|
case Tomahawk::Accounts::ConfigTestResultPlayingElsewhere:
|
||||||
|
return tr( "Action not allowed, account is in use elsewhere." );
|
||||||
|
case Tomahawk::Accounts::ConfigTestResultAccountExpired:
|
||||||
|
return tr( "Your account has expired." );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -60,10 +60,11 @@ protected:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void aboutClicked( bool );
|
void aboutClicked( bool );
|
||||||
void onConfigTestResult( Tomahawk::Accounts::ConfigTestResultType );
|
void onConfigTestResult( int, const QString& );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void closeDialog( QDialog::DialogCode code );
|
void closeDialog( QDialog::DialogCode code );
|
||||||
|
QString getTestConfigMessage( int code );
|
||||||
|
|
||||||
Tomahawk::Accounts::Account* m_account;
|
Tomahawk::Accounts::Account* m_account;
|
||||||
AccountConfigWidget* m_widget;
|
AccountConfigWidget* m_widget;
|
||||||
|
@@ -542,7 +542,7 @@ ResolverAccount::testConfig()
|
|||||||
{
|
{
|
||||||
QVariantMap data = resolver->loadDataFromWidgets();
|
QVariantMap data = resolver->loadDataFromWidgets();
|
||||||
ScriptJob* job = resolver->scriptObject()->invoke( "testConfig", data );
|
ScriptJob* job = resolver->scriptObject()->invoke( "testConfig", data );
|
||||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( onTestConfig( QVariantMap ) ) );
|
connect( job, SIGNAL( done( QVariant ) ), SLOT( onTestConfig( QVariant ) ) );
|
||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -560,18 +560,17 @@ ResolverAccount::resolver() const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ResolverAccount::onTestConfig( const QVariantMap& result )
|
ResolverAccount::onTestConfig( const QVariant& result )
|
||||||
{
|
{
|
||||||
tLog() << Q_FUNC_INFO << result;
|
tLog() << Q_FUNC_INFO << result;
|
||||||
|
|
||||||
int resultCode = result[ "result" ].toInt();
|
if ( result.type() == QVariant::String )
|
||||||
if ( resultCode == 1 )
|
|
||||||
{
|
{
|
||||||
emit configTestResult( Accounts::ConfigTestResultSuccess );
|
emit configTestResult( Accounts::ConfigTestResultOther, result.toString() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
emit configTestResult( Accounts::ConfigTestResultOther );
|
emit configTestResult( result.toInt() );
|
||||||
}
|
}
|
||||||
|
|
||||||
sender()->deleteLater();
|
sender()->deleteLater();
|
||||||
@@ -590,6 +589,7 @@ AtticaResolverAccount::AtticaResolverAccount( const QString& accountId )
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId, const QVariantHash& initialConfiguration )
|
AtticaResolverAccount::AtticaResolverAccount( const QString& accountId, const QString& path, const QString& atticaId, const QVariantHash& initialConfiguration )
|
||||||
: ResolverAccount( accountId, path, initialConfiguration )
|
: ResolverAccount( accountId, path, initialConfiguration )
|
||||||
, m_atticaId( atticaId )
|
, m_atticaId( atticaId )
|
||||||
@@ -619,8 +619,6 @@ AtticaResolverAccount::init()
|
|||||||
loadIcon();
|
loadIcon();
|
||||||
else
|
else
|
||||||
connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( loadIcon() ) );
|
connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( loadIcon() ) );
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -110,7 +110,7 @@ public:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void resolverChanged();
|
void resolverChanged();
|
||||||
void onTestConfig( const QVariantMap& result );
|
void onTestConfig( const QVariant& result );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// Created by factory, when user installs a new resolver
|
// Created by factory, when user installs a new resolver
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2010-2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2010-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||||
*
|
*
|
||||||
@@ -572,10 +572,10 @@ AudioEngine::onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
AudioEngine::loadTrack( const Tomahawk::result_ptr& result, bool preload )
|
||||||
{
|
{
|
||||||
Q_D( AudioEngine );
|
Q_D( AudioEngine );
|
||||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() );
|
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ) << " preload:" << preload;
|
||||||
|
|
||||||
|
|
||||||
if ( !d->audioOutput->isInitialized() )
|
if ( !d->audioOutput->isInitialized() )
|
||||||
@@ -589,36 +589,82 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We do this to stop the audio as soon as a user activated another track
|
if (preload && d->preloadedTrack == result)
|
||||||
// If we don't block the audioOutput signals, the state change will trigger
|
return;
|
||||||
// loading yet another track
|
|
||||||
d->audioOutput->blockSignals( true );
|
|
||||||
d->audioOutput->stop();
|
|
||||||
d->audioOutput->blockSignals( false );
|
|
||||||
|
|
||||||
setCurrentTrack( result );
|
if (preload)
|
||||||
|
tDebug( LOGEXTRA ) << Q_FUNC_INFO << "not preloaded yet, preloading";
|
||||||
|
|
||||||
|
if (preload)
|
||||||
|
{
|
||||||
|
setPreloadTrack( result );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// We do this to stop the audio as soon as a user activated another track
|
||||||
|
// If we don't block the audioOutput signals, the state change will trigger
|
||||||
|
// loading yet another track
|
||||||
|
d->audioOutput->blockSignals( true );
|
||||||
|
d->audioOutput->stop();
|
||||||
|
d->audioOutput->blockSignals( false );
|
||||||
|
|
||||||
|
setCurrentTrack( result );
|
||||||
|
if ( result == d->preloadedTrack )
|
||||||
|
{
|
||||||
|
setPreloadTrack( Tomahawk::result_ptr(nullptr) );
|
||||||
|
d->state = Loading;
|
||||||
|
emit loading( d->currentTrack );
|
||||||
|
d->audioOutput->switchToPreloadedMedia();
|
||||||
|
if ( !d->input.isNull() )
|
||||||
|
{
|
||||||
|
d->input->close();
|
||||||
|
d->input.clear();
|
||||||
|
}
|
||||||
|
d->input = d->inputPreloaded;
|
||||||
|
|
||||||
|
d->audioOutput->play();
|
||||||
|
|
||||||
|
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
|
||||||
|
{
|
||||||
|
d->currentTrack->track()->startPlaying();
|
||||||
|
}
|
||||||
|
|
||||||
|
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
setPreloadTrack( Tomahawk::result_ptr(nullptr) );
|
||||||
|
}
|
||||||
|
|
||||||
ScriptJob* job = result->resolvedBy()->getStreamUrl( result );
|
ScriptJob* job = result->resolvedBy()->getStreamUrl( result );
|
||||||
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( gotStreamUrl( QVariantMap ) ) );
|
connect( job, SIGNAL( done( QVariantMap ) ), SLOT( gotStreamUrl( QVariantMap ) ) );
|
||||||
job->setProperty( "result", QVariant::fromValue( result ) );
|
job->setProperty( "result", QVariant::fromValue( result ) );
|
||||||
|
job->setProperty( "isPreload", QVariant::fromValue(preload) );
|
||||||
|
tDebug() << "preload:" << preload << ", for result:" << result;
|
||||||
job->start();
|
job->start();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::gotStreamUrl( const QVariantMap& data )
|
AudioEngine::gotStreamUrl( const QVariantMap& data )
|
||||||
{
|
{
|
||||||
QString streamUrl = data[ "url" ].toString();
|
QString streamUrl = data[ "url" ].toString();
|
||||||
QVariantMap headers = data[ "headers" ].toMap();
|
QVariantMap headers = data[ "headers" ].toMap();
|
||||||
Tomahawk::result_ptr result = sender()->property( "result" ).value<result_ptr>();
|
Tomahawk::result_ptr result = sender()->property( "result" ).value<result_ptr>();
|
||||||
|
bool isPreload = sender()->property( "isPreload" ).value<bool>();
|
||||||
|
|
||||||
if ( streamUrl.isEmpty() || !( TomahawkUtils::isHttpResult( streamUrl ) || TomahawkUtils::isHttpsResult( streamUrl ) || TomahawkUtils::isRtmpResult( streamUrl ) ) )
|
tDebug() << Q_FUNC_INFO << " is preload:" << isPreload << ", for result:" << result;
|
||||||
|
|
||||||
|
if ( streamUrl.isEmpty() || headers.isEmpty() ||
|
||||||
|
!( TomahawkUtils::isHttpResult( streamUrl ) || TomahawkUtils::isHttpsResult( streamUrl ) ) )
|
||||||
{
|
{
|
||||||
// Not an http(s) or RTMP URL, get IO device
|
// We can't supply custom headers to VLC - but prefer using its HTTP streaming due to improved seeking ability
|
||||||
|
// Not an RTMP or HTTP-with-headers URL, get IO device
|
||||||
QSharedPointer< QIODevice > sp;
|
QSharedPointer< QIODevice > sp;
|
||||||
performLoadIODevice( result, streamUrl );
|
performLoadIODevice( result, streamUrl, isPreload );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
// We need our own QIODevice for streaming
|
||||||
// TODO: just make this part of the http(s) IoDeviceFactory (?)
|
// TODO: just make this part of the http(s) IoDeviceFactory (?)
|
||||||
QUrl url = QUrl::fromEncoded( streamUrl.toUtf8() );
|
QUrl url = QUrl::fromEncoded( streamUrl.toUtf8() );
|
||||||
QNetworkRequest req( url );
|
QNetworkRequest req( url );
|
||||||
@@ -640,35 +686,42 @@ AudioEngine::gotStreamUrl( const QVariantMap& data )
|
|||||||
|
|
||||||
tDebug() << "Creating a QNetworkReply with url:" << req.url().toString();
|
tDebug() << "Creating a QNetworkReply with url:" << req.url().toString();
|
||||||
NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( req ) );
|
NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( req ) );
|
||||||
NewClosure( reply, SIGNAL( finalUrlReached() ), this, SLOT( gotRedirectedStreamUrl( Tomahawk::result_ptr, NetworkReply* )), result, reply );
|
NewClosure( reply, SIGNAL( finalUrlReached() ), this, SLOT( gotRedirectedStreamUrl( Tomahawk::result_ptr, NetworkReply* ) ), result, reply );
|
||||||
}
|
}
|
||||||
|
|
||||||
sender()->deleteLater();
|
sender()->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::gotRedirectedStreamUrl( const Tomahawk::result_ptr& result, NetworkReply* reply )
|
AudioEngine::gotRedirectedStreamUrl( const Tomahawk::result_ptr& result, NetworkReply* reply )
|
||||||
{
|
{
|
||||||
|
Q_D( AudioEngine );
|
||||||
// std::functions cannot accept temporaries as parameters
|
// std::functions cannot accept temporaries as parameters
|
||||||
QSharedPointer< QIODevice > sp ( reply->reply(), &QObject::deleteLater );
|
QSharedPointer< QIODevice > sp ( reply->reply(), &QObject::deleteLater );
|
||||||
QString url = reply->reply()->url().toString();
|
QString url = reply->reply()->url().toString();
|
||||||
reply->disconnectFromReply();
|
reply->disconnectFromReply();
|
||||||
reply->deleteLater();
|
reply->deleteLater();
|
||||||
|
|
||||||
performLoadTrack( result, url, sp );
|
bool isPreload = result == d->preloadedTrack;
|
||||||
|
tDebug() << Q_FUNC_INFO << " is preload:" << isPreload;
|
||||||
|
|
||||||
|
performLoadTrack( result, url, sp, isPreload );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::onPositionChanged( float new_position )
|
AudioEngine::onPositionChanged( float new_position )
|
||||||
{
|
{
|
||||||
|
if ( new_position >= 0.90 )
|
||||||
|
loadNextTrack(true);
|
||||||
// tDebug() << Q_FUNC_INFO << new_position << state();
|
// tDebug() << Q_FUNC_INFO << new_position << state();
|
||||||
emit trackPosition( new_position );
|
emit trackPosition( new_position );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url )
|
AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url, bool preload )
|
||||||
{
|
{
|
||||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : url );
|
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : url );
|
||||||
|
|
||||||
@@ -678,37 +731,39 @@ AudioEngine::performLoadIODevice( const result_ptr& result, const QString& url )
|
|||||||
std::function< void ( const QString, QSharedPointer< QIODevice > ) > callback =
|
std::function< void ( const QString, QSharedPointer< QIODevice > ) > callback =
|
||||||
std::bind( &AudioEngine::performLoadTrack, this, result,
|
std::bind( &AudioEngine::performLoadTrack, this, result,
|
||||||
std::placeholders::_1,
|
std::placeholders::_1,
|
||||||
std::placeholders::_2 );
|
std::placeholders::_2,
|
||||||
|
preload );
|
||||||
Tomahawk::UrlHandler::getIODeviceForUrl( result, url, callback );
|
Tomahawk::UrlHandler::getIODeviceForUrl( result, url, callback );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
QSharedPointer< QIODevice > io;
|
QSharedPointer< QIODevice > io;
|
||||||
performLoadTrack( result, url, io );
|
performLoadTrack( result, url, io, preload );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io )
|
AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io, bool preload )
|
||||||
{
|
{
|
||||||
if ( QThread::currentThread() != thread() )
|
if ( QThread::currentThread() != thread() )
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod( this, "performLoadTrack", Qt::QueuedConnection,
|
QMetaObject::invokeMethod( this, "performLoadTrack", Qt::QueuedConnection,
|
||||||
Q_ARG( const Tomahawk::result_ptr, result ),
|
Q_ARG( const Tomahawk::result_ptr, result ),
|
||||||
Q_ARG( const QString, url ),
|
Q_ARG( const QString, url ),
|
||||||
Q_ARG( QSharedPointer< QIODevice >, io )
|
Q_ARG( QSharedPointer< QIODevice >, io ),
|
||||||
|
Q_ARG( bool, preload )
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_D( AudioEngine );
|
Q_D( AudioEngine );
|
||||||
if ( currentTrack() != result )
|
if ( !preload && currentTrack() != result )
|
||||||
{
|
{
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Track loaded too late, skip.";
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Track loaded too late, skip.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() );
|
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() ) << preload;
|
||||||
QSharedPointer< QIODevice > ioToKeep = io;
|
QSharedPointer< QIODevice > ioToKeep = io;
|
||||||
|
|
||||||
bool err = false;
|
bool err = false;
|
||||||
@@ -722,9 +777,16 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
|||||||
|
|
||||||
if ( !err )
|
if ( !err )
|
||||||
{
|
{
|
||||||
tLog() << Q_FUNC_INFO << "Starting new song:" << url;
|
if (preload)
|
||||||
d->state = Loading;
|
{
|
||||||
emit loading( d->currentTrack );
|
tLog() << Q_FUNC_INFO << "Preloading new song:" << url;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tLog() << Q_FUNC_INFO << "Starting new song:" << url;
|
||||||
|
d->state = Loading;
|
||||||
|
emit loading( d->currentTrack );
|
||||||
|
}
|
||||||
|
|
||||||
if ( !TomahawkUtils::isLocalResult( url )
|
if ( !TomahawkUtils::isLocalResult( url )
|
||||||
&& !( TomahawkUtils::isHttpResult( url ) && io.isNull() )
|
&& !( TomahawkUtils::isHttpResult( url ) && io.isNull() )
|
||||||
@@ -733,18 +795,18 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
|||||||
QSharedPointer<QNetworkReply> qnr = io.objectCast<QNetworkReply>();
|
QSharedPointer<QNetworkReply> qnr = io.objectCast<QNetworkReply>();
|
||||||
if ( !qnr.isNull() )
|
if ( !qnr.isNull() )
|
||||||
{
|
{
|
||||||
d->audioOutput->setCurrentSource( new QNR_IODeviceStream( qnr, this ) );
|
d->audioOutput->setCurrentSource( new QNR_IODeviceStream( qnr, this ), preload );
|
||||||
// We keep track of the QNetworkReply in QNR_IODeviceStream
|
// We keep track of the QNetworkReply in QNR_IODeviceStream
|
||||||
// and AudioOutput handles the deletion of the
|
// and AudioOutput handles the deletion of the
|
||||||
// QNR_IODeviceStream object
|
// QNR_IODeviceStream object
|
||||||
ioToKeep.clear();
|
ioToKeep.clear();
|
||||||
d->audioOutput->setAutoDelete( true );
|
d->audioOutput->setAutoDelete( true, preload );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
d->audioOutput->setCurrentSource( io.data() );
|
d->audioOutput->setCurrentSource( io.data(), preload);
|
||||||
// We handle the deletion via tracking in d->input
|
// We handle the deletion via tracking in d->input
|
||||||
d->audioOutput->setAutoDelete( false );
|
d->audioOutput->setAutoDelete( false, preload);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -763,7 +825,7 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
|||||||
}
|
}
|
||||||
|
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Passing to VLC:" << furl;
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Passing to VLC:" << furl;
|
||||||
d->audioOutput->setCurrentSource( furl );
|
d->audioOutput->setCurrentSource( furl, preload );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -772,26 +834,37 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
|||||||
furl = furl.right( furl.length() - 7 );
|
furl = furl.right( furl.length() - 7 );
|
||||||
|
|
||||||
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Passing to VLC:" << QUrl::fromLocalFile( furl );
|
tLog( LOGVERBOSE ) << Q_FUNC_INFO << "Passing to VLC:" << QUrl::fromLocalFile( furl );
|
||||||
d->audioOutput->setCurrentSource( QUrl::fromLocalFile( furl ) );
|
d->audioOutput->setCurrentSource( QUrl::fromLocalFile( furl ), preload );
|
||||||
}
|
}
|
||||||
|
|
||||||
d->audioOutput->setAutoDelete( true );
|
d->audioOutput->setAutoDelete( true, preload );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !d->input.isNull() )
|
if ( preload ) {
|
||||||
|
if ( !d->inputPreloaded.isNull() )
|
||||||
|
{
|
||||||
|
d->inputPreloaded->close();
|
||||||
|
d->inputPreloaded.clear();
|
||||||
|
}
|
||||||
|
d->inputPreloaded = ioToKeep;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
d->input->close();
|
if ( !d->input.isNull() )
|
||||||
d->input.clear();
|
{
|
||||||
}
|
d->input->close();
|
||||||
d->input = ioToKeep;
|
d->input.clear();
|
||||||
d->audioOutput->play();
|
}
|
||||||
|
d->input = ioToKeep;
|
||||||
|
d->audioOutput->play();
|
||||||
|
|
||||||
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
|
if ( TomahawkSettings::instance()->privateListeningMode() != TomahawkSettings::FullyPrivate )
|
||||||
{
|
{
|
||||||
d->currentTrack->track()->startPlaying();
|
d->currentTrack->track()->startPlaying();
|
||||||
}
|
}
|
||||||
|
|
||||||
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
|
sendNowPlayingNotification( Tomahawk::InfoSystem::InfoNowPlaying );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,7 +874,10 @@ AudioEngine::performLoadTrack( const Tomahawk::result_ptr result, const QString&
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
d->waitingOnNewTrack = false;
|
if ( !preload )
|
||||||
|
{
|
||||||
|
d->waitingOnNewTrack = false;
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,18 +909,19 @@ AudioEngine::loadPreviousTrack()
|
|||||||
}
|
}
|
||||||
|
|
||||||
if ( result )
|
if ( result )
|
||||||
loadTrack( result );
|
loadTrack( result, false );
|
||||||
else
|
else
|
||||||
stop();
|
stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::loadNextTrack()
|
AudioEngine::loadNextTrack( bool preload )
|
||||||
{
|
{
|
||||||
if ( QThread::currentThread() != thread() )
|
if ( QThread::currentThread() != thread() )
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod( this, "loadNextTrack", Qt::QueuedConnection );
|
QMetaObject::invokeMethod( this, "loadNextTrack", Qt::QueuedConnection,
|
||||||
|
Q_ARG( bool, preload ));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -858,8 +935,11 @@ AudioEngine::loadNextTrack()
|
|||||||
{
|
{
|
||||||
if ( d->stopAfterTrack->track()->equals( d->currentTrack->track() ) )
|
if ( d->stopAfterTrack->track()->equals( d->currentTrack->track() ) )
|
||||||
{
|
{
|
||||||
d->stopAfterTrack.clear();
|
if ( !preload )
|
||||||
stop();
|
{
|
||||||
|
d->stopAfterTrack.clear();
|
||||||
|
stop();
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -877,17 +957,24 @@ AudioEngine::loadNextTrack()
|
|||||||
|
|
||||||
if ( d->playlist.data()->nextResult() )
|
if ( d->playlist.data()->nextResult() )
|
||||||
{
|
{
|
||||||
result = d->playlist.data()->setSiblingResult( 1 );
|
if ( preload )
|
||||||
setCurrentTrackPlaylist( d->playlist );
|
{
|
||||||
|
result = d->playlist.data()->nextResult();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = d->playlist.data()->setSiblingResult( 1 );
|
||||||
|
setCurrentTrackPlaylist( d->playlist );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( result )
|
if ( result )
|
||||||
{
|
{
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Got next item, loading track";
|
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "Got next item, loading track, preload:" << preload;
|
||||||
loadTrack( result );
|
loadTrack( result, preload );
|
||||||
}
|
}
|
||||||
else
|
else if ( !preload )
|
||||||
{
|
{
|
||||||
if ( !d->playlist.isNull() && d->playlist.data()->retryMode() == Tomahawk::PlaylistModes::Retry )
|
if ( !d->playlist.isNull() && d->playlist.data()->retryMode() == Tomahawk::PlaylistModes::Retry )
|
||||||
d->waitingOnNewTrack = true;
|
d->waitingOnNewTrack = true;
|
||||||
@@ -956,7 +1043,7 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
|
|||||||
|
|
||||||
if ( result )
|
if ( result )
|
||||||
{
|
{
|
||||||
loadTrack( result );
|
loadTrack( result, false );
|
||||||
}
|
}
|
||||||
else if ( !d->playlist.isNull() && d->playlist.data()->retryMode() == PlaylistModes::Retry )
|
else if ( !d->playlist.isNull() && d->playlist.data()->retryMode() == PlaylistModes::Retry )
|
||||||
{
|
{
|
||||||
@@ -1231,6 +1318,14 @@ AudioEngine::setStopAfterTrack( const query_ptr& query )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
AudioEngine::setPreloadTrack( const Tomahawk::result_ptr& result )
|
||||||
|
{
|
||||||
|
Q_D( AudioEngine );
|
||||||
|
|
||||||
|
d->preloadedTrack = result;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
||||||
{
|
{
|
||||||
@@ -1257,7 +1352,6 @@ AudioEngine::setCurrentTrack( const Tomahawk::result_ptr& result )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioEngine::setState( AudioState state )
|
AudioEngine::setState( AudioState state )
|
||||||
{
|
{
|
||||||
|
@@ -135,10 +135,10 @@ public slots:
|
|||||||
void toggleMute();
|
void toggleMute();
|
||||||
|
|
||||||
void play( const QUrl& url );
|
void play( const QUrl& url );
|
||||||
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery = Tomahawk::query_ptr() );
|
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery = Tomahawk::query_ptr());
|
||||||
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query );
|
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query);
|
||||||
void playItem( const Tomahawk::artist_ptr& artist );
|
void playItem( const Tomahawk::artist_ptr& artist);
|
||||||
void playItem( const Tomahawk::album_ptr& album );
|
void playItem( const Tomahawk::album_ptr& album);
|
||||||
void playPlaylistInterface( const Tomahawk::playlistinterface_ptr& playlist );
|
void playPlaylistInterface( const Tomahawk::playlistinterface_ptr& playlist );
|
||||||
void setPlaylist( Tomahawk::playlistinterface_ptr playlist );
|
void setPlaylist( Tomahawk::playlistinterface_ptr playlist );
|
||||||
void setQueue( const Tomahawk::playlistinterface_ptr& queue );
|
void setQueue( const Tomahawk::playlistinterface_ptr& queue );
|
||||||
@@ -182,21 +182,22 @@ signals:
|
|||||||
void error( AudioEngine::AudioErrorCode errorCode );
|
void error( AudioEngine::AudioErrorCode errorCode );
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void loadTrack( const Tomahawk::result_ptr& result ); //async!
|
void loadTrack( const Tomahawk::result_ptr& result, bool preload ); //async!
|
||||||
void gotStreamUrl( const QVariantMap& data );
|
void gotStreamUrl( const QVariantMap& data );
|
||||||
void gotRedirectedStreamUrl( const Tomahawk::result_ptr& result, NetworkReply* reply );
|
void gotRedirectedStreamUrl( const Tomahawk::result_ptr& result, NetworkReply* reply );
|
||||||
|
|
||||||
|
|
||||||
void performLoadIODevice( const Tomahawk::result_ptr& result, const QString& url ); //only call from loadTrack kthxbi
|
void performLoadIODevice( const Tomahawk::result_ptr& result, const QString& url, bool preload ); //only call from loadTrack kthxbi
|
||||||
void performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io ); //only call from loadTrack or performLoadIODevice kthxbi
|
void performLoadTrack( const Tomahawk::result_ptr result, const QString& url, QSharedPointer< QIODevice > io, bool preload ); //only call from loadTrack or performLoadIODevice kthxbi
|
||||||
void loadPreviousTrack();
|
void loadPreviousTrack();
|
||||||
void loadNextTrack();
|
void loadNextTrack(bool preload = false);
|
||||||
|
|
||||||
void onVolumeChanged( qreal volume );
|
void onVolumeChanged( qreal volume );
|
||||||
void timerTriggered( qint64 time );
|
void timerTriggered( qint64 time );
|
||||||
void onPositionChanged( float new_position );
|
void onPositionChanged( float new_position );
|
||||||
|
|
||||||
void setCurrentTrack( const Tomahawk::result_ptr& result );
|
void setCurrentTrack( const Tomahawk::result_ptr& result );
|
||||||
|
void setPreloadTrack( const Tomahawk::result_ptr& result );
|
||||||
void onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type );
|
void onNowPlayingInfoReady( const Tomahawk::InfoSystem::InfoType type );
|
||||||
void onPlaylistNextTrackAvailable();
|
void onPlaylistNextTrackAvailable();
|
||||||
|
|
||||||
|
@@ -28,9 +28,11 @@ public slots:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
QSharedPointer<QIODevice> input;
|
QSharedPointer<QIODevice> input;
|
||||||
|
QSharedPointer<QIODevice> inputPreloaded;
|
||||||
|
|
||||||
Tomahawk::query_ptr stopAfterTrack;
|
Tomahawk::query_ptr stopAfterTrack;
|
||||||
Tomahawk::result_ptr currentTrack;
|
Tomahawk::result_ptr currentTrack;
|
||||||
|
Tomahawk::result_ptr preloadedTrack;
|
||||||
Tomahawk::playlistinterface_ptr playlist;
|
Tomahawk::playlistinterface_ptr playlist;
|
||||||
Tomahawk::playlistinterface_ptr currentTrackPlaylist;
|
Tomahawk::playlistinterface_ptr currentTrackPlaylist;
|
||||||
Tomahawk::playlistinterface_ptr queue;
|
Tomahawk::playlistinterface_ptr queue;
|
||||||
|
@@ -22,6 +22,7 @@
|
|||||||
#include "AudioEngine.h"
|
#include "AudioEngine.h"
|
||||||
#include "AudioOutput.h"
|
#include "AudioOutput.h"
|
||||||
#include "TomahawkVersion.h"
|
#include "TomahawkVersion.h"
|
||||||
|
#include "TomahawkSettings.h"
|
||||||
|
|
||||||
#include "audio/MediaStream.h"
|
#include "audio/MediaStream.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
@@ -35,10 +36,12 @@
|
|||||||
|
|
||||||
#include <vlc/libvlc.h>
|
#include <vlc/libvlc.h>
|
||||||
#include <vlc/libvlc_media.h>
|
#include <vlc/libvlc_media.h>
|
||||||
#include <vlc/libvlc_media_player.h>
|
|
||||||
#include <vlc/libvlc_events.h>
|
#include <vlc/libvlc_events.h>
|
||||||
|
#include <vlc/libvlc_media_player.h>
|
||||||
#include <vlc/libvlc_version.h>
|
#include <vlc/libvlc_version.h>
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
AudioOutput* AudioOutput::s_instance = 0;
|
AudioOutput* AudioOutput::s_instance = 0;
|
||||||
|
|
||||||
|
|
||||||
@@ -53,9 +56,11 @@ AudioOutput::AudioOutput( QObject* parent )
|
|||||||
: QObject( parent )
|
: QObject( parent )
|
||||||
, m_currentState( Stopped )
|
, m_currentState( Stopped )
|
||||||
, m_currentStream( nullptr )
|
, m_currentStream( nullptr )
|
||||||
|
, m_preloadedStream( nullptr )
|
||||||
, m_seekable( true )
|
, m_seekable( true )
|
||||||
, m_muted( false )
|
, m_muted( false )
|
||||||
, m_autoDelete( true )
|
, m_autoDelete( true )
|
||||||
|
, m_preloadedAutoDelete( true )
|
||||||
, m_volume( 1.0 )
|
, m_volume( 1.0 )
|
||||||
, m_currentTime( 0 )
|
, m_currentTime( 0 )
|
||||||
, m_totalTime( 0 )
|
, m_totalTime( 0 )
|
||||||
@@ -65,6 +70,8 @@ AudioOutput::AudioOutput( QObject* parent )
|
|||||||
, m_vlcInstance( nullptr )
|
, m_vlcInstance( nullptr )
|
||||||
, m_vlcPlayer( nullptr )
|
, m_vlcPlayer( nullptr )
|
||||||
, m_vlcMedia( nullptr )
|
, m_vlcMedia( nullptr )
|
||||||
|
, m_vlcPreloadedPlayer( nullptr )
|
||||||
|
, m_vlcPreloadedMedia( nullptr )
|
||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO;
|
tDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
@@ -72,7 +79,7 @@ AudioOutput::AudioOutput( QObject* parent )
|
|||||||
|
|
||||||
qRegisterMetaType<AudioOutput::AudioState>("AudioOutput::AudioState");
|
qRegisterMetaType<AudioOutput::AudioState>("AudioOutput::AudioState");
|
||||||
|
|
||||||
const char* vlcArgs[] = {
|
QVector<const char*> vlcArgs = {
|
||||||
"--ignore-config",
|
"--ignore-config",
|
||||||
"--extraintf=logger",
|
"--extraintf=logger",
|
||||||
qApp->arguments().contains( "--verbose" ) ? "--verbose=3" : "",
|
qApp->arguments().contains( "--verbose" ) ? "--verbose=3" : "",
|
||||||
@@ -84,11 +91,28 @@ AudioOutput::AudioOutput( QObject* parent )
|
|||||||
// "--no-snapshot-preview",
|
// "--no-snapshot-preview",
|
||||||
// "--services-discovery=''",
|
// "--services-discovery=''",
|
||||||
"--no-video",
|
"--no-video",
|
||||||
|
//"--network-caching=10000",
|
||||||
|
//"--file-caching=10000",
|
||||||
|
//"--clock-synchro=0",
|
||||||
|
//"--cr-average=10000",
|
||||||
|
//"--clock-jitter=1",
|
||||||
"--no-xlib"
|
"--no-xlib"
|
||||||
};
|
};
|
||||||
|
TomahawkSettings* s = TomahawkSettings::instance();
|
||||||
|
//Save a list of Latin1 byte arrays for additional args
|
||||||
|
auto additionalVlcArgs = s->vlcArguments().split(",");
|
||||||
|
QVector<QByteArray> additionalArgsChar;
|
||||||
|
|
||||||
|
std::transform(additionalVlcArgs.begin(), additionalVlcArgs.end(),
|
||||||
|
std::back_inserter(additionalArgsChar), [](QString str) { return str.toLatin1(); });
|
||||||
|
|
||||||
|
for (auto&& str : additionalArgsChar)
|
||||||
|
{
|
||||||
|
vlcArgs.append(str.constData());
|
||||||
|
}
|
||||||
|
|
||||||
// Create and initialize a libvlc instance (it should be done only once)
|
// Create and initialize a libvlc instance (it should be done only once)
|
||||||
m_vlcInstance = libvlc_new( sizeof(vlcArgs) / sizeof(*vlcArgs), vlcArgs );
|
m_vlcInstance = libvlc_new( vlcArgs.size(), vlcArgs.constData() );
|
||||||
if ( !m_vlcInstance )
|
if ( !m_vlcInstance )
|
||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO << "libVLC: could not initialize";
|
tDebug() << Q_FUNC_INFO << "libVLC: could not initialize";
|
||||||
@@ -103,37 +127,46 @@ AudioOutput::AudioOutput( QObject* parent )
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_vlcPlayer = libvlc_media_player_new( m_vlcInstance );
|
m_vlcPlayer = libvlc_media_player_new( m_vlcInstance );
|
||||||
libvlc_event_manager_t* manager = libvlc_media_player_event_manager( m_vlcPlayer );
|
m_vlcPreloadedPlayer = libvlc_media_player_new( m_vlcInstance );
|
||||||
libvlc_event_type_t events[] = {
|
|
||||||
libvlc_MediaPlayerMediaChanged,
|
for( auto player : { m_vlcPlayer, m_vlcPreloadedPlayer } )
|
||||||
libvlc_MediaPlayerNothingSpecial,
|
|
||||||
libvlc_MediaPlayerOpening,
|
|
||||||
libvlc_MediaPlayerBuffering,
|
|
||||||
libvlc_MediaPlayerPlaying,
|
|
||||||
libvlc_MediaPlayerPaused,
|
|
||||||
libvlc_MediaPlayerStopped,
|
|
||||||
libvlc_MediaPlayerForward,
|
|
||||||
libvlc_MediaPlayerBackward,
|
|
||||||
libvlc_MediaPlayerEndReached,
|
|
||||||
libvlc_MediaPlayerEncounteredError,
|
|
||||||
libvlc_MediaPlayerTimeChanged,
|
|
||||||
libvlc_MediaPlayerPositionChanged,
|
|
||||||
libvlc_MediaPlayerSeekableChanged,
|
|
||||||
libvlc_MediaPlayerPausableChanged,
|
|
||||||
libvlc_MediaPlayerTitleChanged,
|
|
||||||
libvlc_MediaPlayerSnapshotTaken,
|
|
||||||
//libvlc_MediaPlayerLengthChanged,
|
|
||||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
|
||||||
libvlc_MediaPlayerAudioVolume,
|
|
||||||
libvlc_MediaPlayerMuted,
|
|
||||||
libvlc_MediaPlayerUnmuted,
|
|
||||||
#endif
|
|
||||||
libvlc_MediaPlayerVout
|
|
||||||
};
|
|
||||||
const int eventCount = sizeof(events) / sizeof( *events );
|
|
||||||
for ( int i = 0; i < eventCount; i++ )
|
|
||||||
{
|
{
|
||||||
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
libvlc_audio_set_mute( player, 0 );
|
||||||
|
{
|
||||||
|
libvlc_event_manager_t* current_manager = libvlc_media_player_event_manager( player );
|
||||||
|
libvlc_event_manager_t* new_manager = libvlc_media_player_event_manager( player );
|
||||||
|
static libvlc_event_type_t events[] = {
|
||||||
|
libvlc_MediaPlayerMediaChanged,
|
||||||
|
libvlc_MediaPlayerNothingSpecial,
|
||||||
|
libvlc_MediaPlayerOpening,
|
||||||
|
libvlc_MediaPlayerBuffering,
|
||||||
|
libvlc_MediaPlayerPlaying,
|
||||||
|
libvlc_MediaPlayerPaused,
|
||||||
|
libvlc_MediaPlayerStopped,
|
||||||
|
libvlc_MediaPlayerForward,
|
||||||
|
libvlc_MediaPlayerBackward,
|
||||||
|
libvlc_MediaPlayerEndReached,
|
||||||
|
libvlc_MediaPlayerEncounteredError,
|
||||||
|
libvlc_MediaPlayerTimeChanged,
|
||||||
|
libvlc_MediaPlayerPositionChanged,
|
||||||
|
libvlc_MediaPlayerSeekableChanged,
|
||||||
|
libvlc_MediaPlayerPausableChanged,
|
||||||
|
libvlc_MediaPlayerTitleChanged,
|
||||||
|
libvlc_MediaPlayerSnapshotTaken,
|
||||||
|
//libvlc_MediaPlayerLengthChanged,
|
||||||
|
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||||
|
libvlc_MediaPlayerAudioVolume,
|
||||||
|
libvlc_MediaPlayerMuted,
|
||||||
|
libvlc_MediaPlayerUnmuted,
|
||||||
|
#endif
|
||||||
|
libvlc_MediaPlayerVout
|
||||||
|
};
|
||||||
|
const int eventCount = sizeof(events) / sizeof( *events );
|
||||||
|
for ( int i = 0; i < eventCount; i++ )
|
||||||
|
{
|
||||||
|
libvlc_event_attach( new_manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// HACK: play silent ogg file and set volume on that to workaround vlc not allowing to set volume before a file is played
|
// HACK: play silent ogg file and set volume on that to workaround vlc not allowing to set volume before a file is played
|
||||||
@@ -141,7 +174,9 @@ AudioOutput::AudioOutput( QObject* parent )
|
|||||||
Q_ASSERT( m_silenceFile.exists() );
|
Q_ASSERT( m_silenceFile.exists() );
|
||||||
Q_ASSERT( m_silenceFile.open( QIODevice::ReadOnly ) );
|
Q_ASSERT( m_silenceFile.open( QIODevice::ReadOnly ) );
|
||||||
|
|
||||||
setCurrentSource( new MediaStream( &m_silenceFile, true ) );
|
setCurrentSource( new MediaStream( &m_silenceFile, true ), false );
|
||||||
|
setCurrentSource( new MediaStream( &m_silenceFile, true ), true );
|
||||||
|
|
||||||
libvlc_media_player_play( m_vlcPlayer );
|
libvlc_media_player_play( m_vlcPlayer );
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5,4,0)
|
#if QT_VERSION >= QT_VERSION_CHECK(5,4,0)
|
||||||
@@ -149,24 +184,71 @@ AudioOutput::AudioOutput( QObject* parent )
|
|||||||
QTimer::singleShot( 15000, [&]()
|
QTimer::singleShot( 15000, [&]()
|
||||||
{
|
{
|
||||||
if ( !m_initialized ) {
|
if ( !m_initialized ) {
|
||||||
m_initialized = true;
|
m_initialized = 2;
|
||||||
emit initialized();
|
emit initialized();
|
||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AudioOutput::switchToPreloadedMedia( void )
|
||||||
|
{
|
||||||
|
|
||||||
|
//Swap
|
||||||
|
auto tempPlayer = m_vlcPreloadedPlayer;
|
||||||
|
m_vlcPreloadedPlayer = m_vlcPlayer;
|
||||||
|
m_vlcPlayer = tempPlayer;
|
||||||
|
|
||||||
|
libvlc_media_player_stop( m_vlcPreloadedPlayer );
|
||||||
|
|
||||||
|
if ( m_vlcMedia != nullptr )
|
||||||
|
{
|
||||||
|
libvlc_media_release( m_vlcMedia );
|
||||||
|
}
|
||||||
|
//Now Media
|
||||||
|
{
|
||||||
|
if ( m_autoDelete && m_currentStream != nullptr )
|
||||||
|
{
|
||||||
|
delete m_currentStream;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vlcMedia = m_vlcPreloadedMedia;
|
||||||
|
m_vlcPreloadedMedia = nullptr;
|
||||||
|
m_currentStream = m_preloadedStream;
|
||||||
|
m_preloadedStream = nullptr;
|
||||||
|
m_autoDelete = m_preloadedAutoDelete;
|
||||||
|
|
||||||
|
m_totalTime = libvlc_media_get_duration( m_vlcMedia );
|
||||||
|
|
||||||
|
m_currentTime = 0;
|
||||||
|
m_justSeeked = false;
|
||||||
|
m_seekable = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
libvlc_media_player_set_position( m_vlcPlayer, 0.0 );
|
||||||
|
}
|
||||||
|
|
||||||
AudioOutput::~AudioOutput()
|
AudioOutput::~AudioOutput()
|
||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO;
|
tDebug() << Q_FUNC_INFO;
|
||||||
|
|
||||||
|
if ( m_vlcPreloadedPlayer != nullptr )
|
||||||
|
{
|
||||||
|
libvlc_media_player_stop( m_vlcPreloadedPlayer );
|
||||||
|
libvlc_media_player_release( m_vlcPreloadedPlayer );
|
||||||
|
m_vlcPreloadedPlayer = nullptr;
|
||||||
|
}
|
||||||
if ( m_vlcPlayer != nullptr )
|
if ( m_vlcPlayer != nullptr )
|
||||||
{
|
{
|
||||||
libvlc_media_player_stop( m_vlcPlayer );
|
libvlc_media_player_stop( m_vlcPlayer );
|
||||||
libvlc_media_player_release( m_vlcPlayer );
|
libvlc_media_player_release( m_vlcPlayer );
|
||||||
m_vlcPlayer = nullptr;
|
m_vlcPlayer = nullptr;
|
||||||
}
|
}
|
||||||
|
if ( m_vlcPreloadedMedia != nullptr )
|
||||||
|
{
|
||||||
|
libvlc_media_release( m_vlcPreloadedMedia );
|
||||||
|
m_vlcPreloadedMedia = nullptr;
|
||||||
|
}
|
||||||
if ( m_vlcMedia != nullptr )
|
if ( m_vlcMedia != nullptr )
|
||||||
{
|
{
|
||||||
libvlc_media_release( m_vlcMedia );
|
libvlc_media_release( m_vlcMedia );
|
||||||
@@ -188,11 +270,19 @@ AudioOutput::onInitVlcEvent( const libvlc_event_t* event )
|
|||||||
setVolume( volume() );
|
setVolume( volume() );
|
||||||
setMuted( isMuted() );
|
setMuted( isMuted() );
|
||||||
|
|
||||||
m_initialized = true;
|
m_initialized ++;
|
||||||
m_silenceFile.close();
|
|
||||||
|
|
||||||
tDebug() << Q_FUNC_INFO << "Init OK";
|
tDebug() << Q_FUNC_INFO << "Init OK";
|
||||||
emit initialized();
|
if (m_initialized >=2)
|
||||||
|
{
|
||||||
|
m_silenceFile.close();
|
||||||
|
emit initialized();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
switchToPreloadedMedia();
|
||||||
|
libvlc_media_player_play( m_vlcPlayer );
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -202,23 +292,26 @@ AudioOutput::onInitVlcEvent( const libvlc_event_t* event )
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutput::setAutoDelete( bool ad )
|
AudioOutput::setAutoDelete( bool ad, bool preload )
|
||||||
{
|
{
|
||||||
m_autoDelete = ad;
|
if (preload)
|
||||||
|
m_preloadedAutoDelete = ad;
|
||||||
|
else
|
||||||
|
m_autoDelete = ad;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutput::setCurrentSource( const QUrl& stream )
|
AudioOutput::setCurrentSource( const QUrl& stream, bool preload )
|
||||||
{
|
{
|
||||||
setCurrentSource( new MediaStream( stream ) );
|
setCurrentSource( new MediaStream( stream ), preload );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutput::setCurrentSource( QIODevice* stream )
|
AudioOutput::setCurrentSource( QIODevice* stream, bool preload )
|
||||||
{
|
{
|
||||||
setCurrentSource( new MediaStream( stream ) );
|
setCurrentSource( new MediaStream( stream ), preload );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -238,29 +331,24 @@ readDoneCallback( void* data, const char* cookie, size_t bufferSize, void* buffe
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
AudioOutput::setCurrentSource( MediaStream* stream )
|
AudioOutput::setCurrentSource( MediaStream* stream, bool preload )
|
||||||
{
|
{
|
||||||
tDebug() << Q_FUNC_INFO;
|
tDebug() << Q_FUNC_INFO << ", preload = " << preload;
|
||||||
|
|
||||||
setState( Loading );
|
if ( !preload )
|
||||||
|
setState( Loading );
|
||||||
|
|
||||||
if ( m_vlcMedia != nullptr )
|
if ( m_vlcPreloadedMedia ) {
|
||||||
{
|
libvlc_media_player_stop( m_vlcPreloadedPlayer );
|
||||||
// Ensure playback is stopped, then release media
|
libvlc_media_release( m_vlcPreloadedMedia );
|
||||||
libvlc_media_player_stop( m_vlcPlayer );
|
m_vlcPreloadedMedia = nullptr;
|
||||||
libvlc_media_release( m_vlcMedia );
|
|
||||||
m_vlcMedia = nullptr;
|
|
||||||
}
|
}
|
||||||
if ( m_autoDelete && m_currentStream != nullptr )
|
if ( m_preloadedAutoDelete && m_preloadedStream != nullptr )
|
||||||
{
|
{
|
||||||
delete m_currentStream;
|
delete m_preloadedStream;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_currentStream = stream;
|
m_preloadedStream = stream;
|
||||||
m_totalTime = 0;
|
|
||||||
m_currentTime = 0;
|
|
||||||
m_justSeeked = false;
|
|
||||||
m_seekable = true;
|
|
||||||
|
|
||||||
QByteArray url;
|
QByteArray url;
|
||||||
switch ( stream->type() )
|
switch ( stream->type() )
|
||||||
@@ -294,34 +382,19 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
|||||||
|
|
||||||
tDebug() << Q_FUNC_INFO << "MediaStream::Final Url:" << url;
|
tDebug() << Q_FUNC_INFO << "MediaStream::Final Url:" << url;
|
||||||
|
|
||||||
m_vlcMedia = libvlc_media_new_location( m_vlcInstance, url.constData() );
|
m_vlcPreloadedMedia = libvlc_media_new_location( m_vlcInstance, url.constData() );
|
||||||
libvlc_event_manager_t* manager = libvlc_media_event_manager( m_vlcMedia );
|
if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice )
|
||||||
libvlc_event_type_t events[] = {
|
|
||||||
libvlc_MediaDurationChanged,
|
|
||||||
};
|
|
||||||
const int eventCount = sizeof(events) / sizeof( *events );
|
|
||||||
for ( int i = 0; i < eventCount; i++ )
|
|
||||||
{
|
{
|
||||||
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
QString tempString;
|
||||||
}
|
libvlc_media_add_option_flag(m_vlcPreloadedMedia, "imem-cat=4", libvlc_media_option_trusted);
|
||||||
|
tempString = QString( "imem-data=%1" ).arg( (uintptr_t)stream );
|
||||||
libvlc_media_player_set_media( m_vlcPlayer, m_vlcMedia );
|
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||||
|
tempString = QString( "imem-get=%1" ).arg( (uintptr_t)&readCallback );
|
||||||
if ( stream->type() == MediaStream::Url )
|
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||||
{
|
tempString = QString( "imem-release=%1" ).arg( (uintptr_t)&readDoneCallback );
|
||||||
m_totalTime = libvlc_media_get_duration( m_vlcMedia );
|
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||||
}
|
tempString = QString( "imem-seek=%1" ).arg( (uintptr_t)&MediaStream::seekCallback );
|
||||||
else if ( stream->type() == MediaStream::Stream || stream->type() == MediaStream::IODevice )
|
libvlc_media_add_option_flag(m_vlcPreloadedMedia, tempString.toLatin1().constData(), libvlc_media_option_trusted);
|
||||||
{
|
|
||||||
libvlc_media_add_option_flag(m_vlcMedia, "imem-cat=4", libvlc_media_option_trusted);
|
|
||||||
const char* imemData = QString( "imem-data=%1" ).arg( (uintptr_t)stream ).toLatin1().constData();
|
|
||||||
libvlc_media_add_option_flag(m_vlcMedia, imemData, libvlc_media_option_trusted);
|
|
||||||
const char* imemGet = QString( "imem-get=%1" ).arg( (uintptr_t)&readCallback ).toLatin1().constData();
|
|
||||||
libvlc_media_add_option_flag(m_vlcMedia, imemGet, libvlc_media_option_trusted);
|
|
||||||
const char* imemRelease = QString( "imem-release=%1" ).arg( (uintptr_t)&readDoneCallback ).toLatin1().constData();
|
|
||||||
libvlc_media_add_option_flag(m_vlcMedia, imemRelease, libvlc_media_option_trusted);
|
|
||||||
const char* imemSeek = QString( "imem-seek=%1" ).arg( (uintptr_t)&MediaStream::seekCallback ).toLatin1().constData();
|
|
||||||
libvlc_media_add_option_flag(m_vlcMedia, imemSeek, libvlc_media_option_trusted);
|
|
||||||
}
|
}
|
||||||
if ( qApp->arguments().contains( "--chromecast-ip" ) )
|
if ( qApp->arguments().contains( "--chromecast-ip" ) )
|
||||||
{
|
{
|
||||||
@@ -337,7 +410,7 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
|||||||
{
|
{
|
||||||
QString castIP = qApp->arguments().at( qApp->arguments().indexOf( "--chromecast-ip" ) + 1 );
|
QString castIP = qApp->arguments().at( qApp->arguments().indexOf( "--chromecast-ip" ) + 1 );
|
||||||
QString sout( ":sout=#transcode{vcodec=none,acodec=vorb,ab=320,channels=2,samplerate=44100}:chromecast{ip=%1,mux=webm}" );
|
QString sout( ":sout=#transcode{vcodec=none,acodec=vorb,ab=320,channels=2,samplerate=44100}:chromecast{ip=%1,mux=webm}" );
|
||||||
libvlc_media_add_option( m_vlcMedia, sout.arg( castIP ).toLatin1().constData() );
|
libvlc_media_add_option( m_vlcPreloadedMedia, sout.arg( castIP ).toLatin1().constData() );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -345,6 +418,24 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
libvlc_event_manager_t* manager = libvlc_media_event_manager( m_vlcPreloadedMedia );
|
||||||
|
static libvlc_event_type_t events[] = {
|
||||||
|
libvlc_MediaDurationChanged,
|
||||||
|
};
|
||||||
|
const int eventCount = sizeof(events) / sizeof( *events );
|
||||||
|
for ( int i = 0; i < eventCount; i++ )
|
||||||
|
{
|
||||||
|
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
||||||
|
}
|
||||||
|
|
||||||
|
libvlc_media_player_set_media( m_vlcPreloadedPlayer, m_vlcPreloadedMedia );
|
||||||
|
|
||||||
|
libvlc_audio_set_volume( m_vlcPreloadedPlayer, 0.0 );
|
||||||
|
libvlc_media_player_play( m_vlcPreloadedPlayer );
|
||||||
|
|
||||||
|
if ( !preload )
|
||||||
|
switchToPreloadedMedia();
|
||||||
|
|
||||||
// setState( Stopped );
|
// setState( Stopped );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -352,7 +443,7 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
|||||||
bool
|
bool
|
||||||
AudioOutput::isInitialized() const
|
AudioOutput::isInitialized() const
|
||||||
{
|
{
|
||||||
return m_initialized;
|
return m_initialized > 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -481,16 +572,19 @@ AudioOutput::seek( qint64 milliseconds )
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qint64 duration = AudioEngine::instance()->currentTrackTotalTime();
|
||||||
|
// for some tracks, seeking to an end seems not to work correctly with libvlc
|
||||||
|
// (tracks enter a random and infinite loop) - this is a temporary fix for that
|
||||||
|
if (duration == milliseconds)
|
||||||
|
milliseconds -= 1;
|
||||||
|
|
||||||
if ( m_seekable )
|
if ( m_seekable )
|
||||||
{
|
{
|
||||||
|
|
||||||
// tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking" << milliseconds << "msec";
|
|
||||||
libvlc_media_player_set_time( m_vlcPlayer, milliseconds );
|
libvlc_media_player_set_time( m_vlcPlayer, milliseconds );
|
||||||
setCurrentTime( milliseconds );
|
setCurrentTime( milliseconds );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
qint64 duration = AudioEngine::instance()->currentTrackTotalTime();
|
|
||||||
float position = float(float(milliseconds) / duration);
|
float position = float(float(milliseconds) / duration);
|
||||||
libvlc_media_player_set_position(m_vlcPlayer, position);
|
libvlc_media_player_set_position(m_vlcPlayer, position);
|
||||||
tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking via position" << position << "pos";
|
tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking via position" << position << "pos";
|
||||||
@@ -502,7 +596,7 @@ AudioOutput::seek( qint64 milliseconds )
|
|||||||
bool
|
bool
|
||||||
AudioOutput::isSeekable() const
|
AudioOutput::isSeekable() const
|
||||||
{
|
{
|
||||||
// tDebug() << Q_FUNC_INFO << m_seekable << m_havePosition << m_totalTime << libvlc_media_player_is_seekable( m_vlcPlayer );
|
tDebug() << Q_FUNC_INFO << m_seekable << m_havePosition << m_totalTime << libvlc_media_player_is_seekable( m_vlcPlayer );
|
||||||
return m_havePosition || (libvlc_media_player_is_seekable( m_vlcPlayer ) && m_totalTime > 0 );
|
return m_havePosition || (libvlc_media_player_is_seekable( m_vlcPlayer ) && m_totalTime > 0 );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -552,64 +646,107 @@ AudioOutput::setVolume( qreal vol )
|
|||||||
void
|
void
|
||||||
AudioOutput::onVlcEvent( const libvlc_event_t* event )
|
AudioOutput::onVlcEvent( const libvlc_event_t* event )
|
||||||
{
|
{
|
||||||
switch ( event->type )
|
if ( event->p_obj == m_vlcPlayer || event->p_obj == m_vlcMedia )
|
||||||
{
|
{
|
||||||
case libvlc_MediaPlayerTimeChanged:
|
switch ( event->type )
|
||||||
setCurrentTime( event->u.media_player_time_changed.new_time );
|
{
|
||||||
break;
|
case libvlc_MediaPlayerTimeChanged:
|
||||||
case libvlc_MediaPlayerPositionChanged:
|
setCurrentTime( event->u.media_player_time_changed.new_time );
|
||||||
setCurrentPosition( event->u.media_player_position_changed.new_position );
|
break;
|
||||||
break;
|
case libvlc_MediaPlayerPositionChanged:
|
||||||
case libvlc_MediaPlayerSeekableChanged:
|
setCurrentPosition( event->u.media_player_position_changed.new_position );
|
||||||
// tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable;
|
break;
|
||||||
break;
|
case libvlc_MediaPlayerSeekableChanged:
|
||||||
case libvlc_MediaDurationChanged:
|
// tDebug() << Q_FUNC_INFO << " : seekable changed : " << event->u.media_player_seekable_changed.new_seekable;
|
||||||
setTotalTime( event->u.media_duration_changed.new_duration );
|
break;
|
||||||
break;
|
case libvlc_MediaDurationChanged:
|
||||||
case libvlc_MediaPlayerLengthChanged:
|
setTotalTime( event->u.media_duration_changed.new_duration );
|
||||||
// tDebug() << Q_FUNC_INFO << " : length changed : " << event->u.media_player_length_changed.new_length;
|
break;
|
||||||
break;
|
case libvlc_MediaPlayerLengthChanged:
|
||||||
case libvlc_MediaPlayerPlaying:
|
// tDebug() << Q_FUNC_INFO << " : length changed : " << event->u.media_player_length_changed.new_length;
|
||||||
setState( Playing );
|
break;
|
||||||
break;
|
case libvlc_MediaPlayerPlaying:
|
||||||
case libvlc_MediaPlayerPaused:
|
setState( Playing );
|
||||||
setState( Paused );
|
break;
|
||||||
break;
|
case libvlc_MediaPlayerPaused:
|
||||||
case libvlc_MediaPlayerEndReached:
|
setState( Paused );
|
||||||
setState( Stopped );
|
break;
|
||||||
break;
|
case libvlc_MediaPlayerEndReached:
|
||||||
case libvlc_MediaPlayerEncounteredError:
|
setState( Stopped );
|
||||||
tDebug() << Q_FUNC_INFO << "LibVLC error: MediaPlayerEncounteredError. Stopping";
|
break;
|
||||||
// Don't call stop() here - it will deadlock libvlc
|
case libvlc_MediaPlayerEncounteredError:
|
||||||
setState( Error );
|
tDebug() << Q_FUNC_INFO << "LibVLC error: MediaPlayerEncounteredError. Stopping";
|
||||||
break;
|
// Don't call stop() here - it will deadlock libvlc
|
||||||
|
setState( Error );
|
||||||
|
break;
|
||||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||||
case libvlc_MediaPlayerAudioVolume:
|
case libvlc_MediaPlayerAudioVolume:
|
||||||
m_volume = event->u.media_player_audio_volume.volume;
|
m_volume = event->u.media_player_audio_volume.volume;
|
||||||
emit volumeChanged( volume() );
|
tDebug() << Q_FUNC_INFO << "Got signal in current player that volume changed to:" << m_volume;
|
||||||
break;
|
emit volumeChanged( volume() );
|
||||||
case libvlc_MediaPlayerMuted:
|
break;
|
||||||
m_muted = true;
|
case libvlc_MediaPlayerMuted:
|
||||||
emit mutedChanged( true );
|
m_muted = true;
|
||||||
break;
|
emit mutedChanged( true );
|
||||||
case libvlc_MediaPlayerUnmuted:
|
break;
|
||||||
m_muted = false;
|
case libvlc_MediaPlayerUnmuted:
|
||||||
emit mutedChanged( false );
|
m_muted = false;
|
||||||
break;
|
emit mutedChanged( false );
|
||||||
|
break;
|
||||||
#endif
|
#endif
|
||||||
case libvlc_MediaPlayerNothingSpecial:
|
case libvlc_MediaPlayerNothingSpecial:
|
||||||
case libvlc_MediaPlayerOpening:
|
case libvlc_MediaPlayerOpening:
|
||||||
case libvlc_MediaPlayerBuffering:
|
case libvlc_MediaPlayerBuffering:
|
||||||
case libvlc_MediaPlayerStopped:
|
case libvlc_MediaPlayerStopped:
|
||||||
case libvlc_MediaPlayerVout:
|
case libvlc_MediaPlayerVout:
|
||||||
case libvlc_MediaPlayerMediaChanged:
|
case libvlc_MediaPlayerMediaChanged:
|
||||||
case libvlc_MediaPlayerForward:
|
case libvlc_MediaPlayerForward:
|
||||||
case libvlc_MediaPlayerBackward:
|
case libvlc_MediaPlayerBackward:
|
||||||
case libvlc_MediaPlayerPausableChanged:
|
case libvlc_MediaPlayerPausableChanged:
|
||||||
case libvlc_MediaPlayerTitleChanged:
|
case libvlc_MediaPlayerTitleChanged:
|
||||||
case libvlc_MediaPlayerSnapshotTaken:
|
case libvlc_MediaPlayerSnapshotTaken:
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tDebug() << "Event for preloaded: " << libvlc_event_type_name(event->type);
|
||||||
|
switch ( event->type )
|
||||||
|
{
|
||||||
|
case libvlc_MediaPlayerPausableChanged:
|
||||||
|
case libvlc_MediaPlayerPlaying:
|
||||||
|
case libvlc_MediaPlayerMediaChanged:
|
||||||
|
case libvlc_MediaPlayerTitleChanged:
|
||||||
|
case libvlc_MediaPlayerSeekableChanged:
|
||||||
|
case libvlc_MediaDurationChanged:
|
||||||
|
case libvlc_MediaPlayerPositionChanged:
|
||||||
|
case libvlc_MediaPlayerPaused:
|
||||||
|
case libvlc_MediaPlayerBuffering:
|
||||||
|
libvlc_media_player_set_pause( m_vlcPreloadedPlayer, 1 );
|
||||||
|
libvlc_audio_set_volume( m_vlcPreloadedPlayer, 0.0 );
|
||||||
|
libvlc_media_player_set_position( m_vlcPreloadedPlayer, 0.0 );
|
||||||
|
break;
|
||||||
|
case libvlc_MediaPlayerTimeChanged:
|
||||||
|
case libvlc_MediaPlayerLengthChanged:
|
||||||
|
case libvlc_MediaPlayerOpening:
|
||||||
|
case libvlc_MediaPlayerEndReached:
|
||||||
|
case libvlc_MediaPlayerEncounteredError:
|
||||||
|
//TODO
|
||||||
|
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||||
|
case libvlc_MediaPlayerAudioVolume:
|
||||||
|
case libvlc_MediaPlayerMuted:
|
||||||
|
case libvlc_MediaPlayerUnmuted:
|
||||||
|
#endif
|
||||||
|
case libvlc_MediaPlayerNothingSpecial:
|
||||||
|
case libvlc_MediaPlayerStopped:
|
||||||
|
case libvlc_MediaPlayerVout:
|
||||||
|
case libvlc_MediaPlayerForward:
|
||||||
|
case libvlc_MediaPlayerBackward:
|
||||||
|
case libvlc_MediaPlayerSnapshotTaken:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -49,9 +49,10 @@ public:
|
|||||||
bool isInitialized() const;
|
bool isInitialized() const;
|
||||||
AudioState state() const;
|
AudioState state() const;
|
||||||
|
|
||||||
void setCurrentSource( const QUrl& stream );
|
void setCurrentSource( const QUrl& stream, bool preload );
|
||||||
void setCurrentSource( QIODevice* stream );
|
void setCurrentSource( QIODevice* stream, bool preload );
|
||||||
void setCurrentSource( MediaStream* stream );
|
void setCurrentSource( MediaStream* stream, bool preload );
|
||||||
|
void setPreloadedSourceAsCurrent( void );
|
||||||
|
|
||||||
void play();
|
void play();
|
||||||
void pause();
|
void pause();
|
||||||
@@ -65,13 +66,15 @@ public:
|
|||||||
qreal volume() const;
|
qreal volume() const;
|
||||||
qint64 currentTime() const;
|
qint64 currentTime() const;
|
||||||
qint64 totalTime() const;
|
qint64 totalTime() const;
|
||||||
void setAutoDelete ( bool ad );
|
void setAutoDelete ( bool ad, bool preload );
|
||||||
|
|
||||||
void setDspCallback( std::function< void( int, int, float*, int, int ) > cb );
|
void setDspCallback( std::function< void( int, int, float*, int, int ) > cb );
|
||||||
|
|
||||||
static AudioOutput* instance();
|
static AudioOutput* instance();
|
||||||
libvlc_instance_t* vlcInstance() const;
|
libvlc_instance_t* vlcInstance() const;
|
||||||
|
|
||||||
|
void switchToPreloadedMedia( void );
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
@@ -90,6 +93,7 @@ private:
|
|||||||
void setCurrentPosition( float position );
|
void setCurrentPosition( float position );
|
||||||
void setTotalTime( qint64 time );
|
void setTotalTime( qint64 time );
|
||||||
|
|
||||||
|
|
||||||
void onVlcEvent( const libvlc_event_t* event );
|
void onVlcEvent( const libvlc_event_t* event );
|
||||||
static void vlcEventCallback( const libvlc_event_t* event, void* opaque );
|
static void vlcEventCallback( const libvlc_event_t* event, void* opaque );
|
||||||
static void s_dspCallback( int frameNumber, float* samples, int nb_channels, int nb_samples );
|
static void s_dspCallback( int frameNumber, float* samples, int nb_channels, int nb_samples );
|
||||||
@@ -97,9 +101,11 @@ private:
|
|||||||
static AudioOutput* s_instance;
|
static AudioOutput* s_instance;
|
||||||
AudioState m_currentState;
|
AudioState m_currentState;
|
||||||
MediaStream* m_currentStream;
|
MediaStream* m_currentStream;
|
||||||
|
MediaStream* m_preloadedStream;
|
||||||
bool m_seekable;
|
bool m_seekable;
|
||||||
bool m_muted;
|
bool m_muted;
|
||||||
bool m_autoDelete;
|
bool m_autoDelete;
|
||||||
|
bool m_preloadedAutoDelete;
|
||||||
bool m_havePosition;
|
bool m_havePosition;
|
||||||
bool m_haveTiming;
|
bool m_haveTiming;
|
||||||
qreal m_volume;
|
qreal m_volume;
|
||||||
@@ -107,7 +113,7 @@ private:
|
|||||||
qint64 m_totalTime;
|
qint64 m_totalTime;
|
||||||
bool m_justSeeked;
|
bool m_justSeeked;
|
||||||
|
|
||||||
bool m_initialized;
|
int m_initialized;
|
||||||
QFile m_silenceFile;
|
QFile m_silenceFile;
|
||||||
|
|
||||||
std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback;
|
std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback;
|
||||||
@@ -115,6 +121,9 @@ private:
|
|||||||
libvlc_instance_t* m_vlcInstance;
|
libvlc_instance_t* m_vlcInstance;
|
||||||
libvlc_media_player_t* m_vlcPlayer;
|
libvlc_media_player_t* m_vlcPlayer;
|
||||||
libvlc_media_t* m_vlcMedia;
|
libvlc_media_t* m_vlcMedia;
|
||||||
|
libvlc_media_player_t* m_vlcBackPlayer;
|
||||||
|
libvlc_media_player_t* m_vlcPreloadedPlayer;
|
||||||
|
libvlc_media_t* m_vlcPreloadedMedia;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // AUDIOOUTPUT_H
|
#endif // AUDIOOUTPUT_H
|
||||||
|
@@ -151,7 +151,6 @@ int
|
|||||||
MediaStream::readDoneCallback ( const char *cookie, size_t bufferSize, void *buffer )
|
MediaStream::readDoneCallback ( const char *cookie, size_t bufferSize, void *buffer )
|
||||||
{
|
{
|
||||||
Q_UNUSED(cookie);
|
Q_UNUSED(cookie);
|
||||||
Q_UNUSED(bufferSize);
|
|
||||||
|
|
||||||
if ( ( m_type == Stream ) && buffer != nullptr && bufferSize > 0 ) {
|
if ( ( m_type == Stream ) && buffer != nullptr && bufferSize > 0 ) {
|
||||||
delete[] reinterpret_cast< char* >( buffer );
|
delete[] reinterpret_cast< char* >( buffer );
|
||||||
|
@@ -128,10 +128,13 @@ DatabaseCollection::playlists()
|
|||||||
QList< dynplaylist_ptr >
|
QList< dynplaylist_ptr >
|
||||||
DatabaseCollection::autoPlaylists()
|
DatabaseCollection::autoPlaylists()
|
||||||
{
|
{
|
||||||
|
// echonest is dead, disable all echonest code
|
||||||
|
/*
|
||||||
if ( Collection::autoPlaylists().isEmpty() )
|
if ( Collection::autoPlaylists().isEmpty() )
|
||||||
{
|
{
|
||||||
loadAutoPlaylists();
|
loadAutoPlaylists();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return Collection::autoPlaylists();
|
return Collection::autoPlaylists();
|
||||||
}
|
}
|
||||||
@@ -140,10 +143,13 @@ DatabaseCollection::autoPlaylists()
|
|||||||
QList< dynplaylist_ptr >
|
QList< dynplaylist_ptr >
|
||||||
DatabaseCollection::stations()
|
DatabaseCollection::stations()
|
||||||
{
|
{
|
||||||
|
// echonest is dead, disable all echonest code
|
||||||
|
/*
|
||||||
if ( Collection::stations().isEmpty() )
|
if ( Collection::stations().isEmpty() )
|
||||||
{
|
{
|
||||||
loadStations();
|
loadStations();
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
return Collection::stations();
|
return Collection::stations();
|
||||||
}
|
}
|
||||||
|
@@ -59,10 +59,10 @@ public:
|
|||||||
void setLimit( unsigned int amount ) { m_amount = amount; }
|
void setLimit( unsigned int amount ) { m_amount = amount; }
|
||||||
void setSortOrder( DatabaseCommand_AllArtists::SortOrder order ) { m_sortOrder = order; }
|
void setSortOrder( DatabaseCommand_AllArtists::SortOrder order ) { m_sortOrder = order; }
|
||||||
void setSortDescending( bool descending ) { m_sortDescending = descending; }
|
void setSortDescending( bool descending ) { m_sortDescending = descending; }
|
||||||
void setFilter( const QString& filter ) { m_filter = filter; }
|
void setFilter( const QString& filter ) override { m_filter = filter; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void artists( const QList<Tomahawk::artist_ptr>& );
|
void artists( const QList<Tomahawk::artist_ptr>& ) override;
|
||||||
void done();
|
void done();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -74,7 +74,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void tracks( const QList<Tomahawk::query_ptr>&, const QVariant& data );
|
void tracks( const QList<Tomahawk::query_ptr>&, const QVariant& data );
|
||||||
void tracks( const QList<Tomahawk::query_ptr>& );
|
void tracks( const QList<Tomahawk::query_ptr>& ) override;
|
||||||
void done( const Tomahawk::collection_ptr& );
|
void done( const Tomahawk::collection_ptr& );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@@ -21,7 +21,6 @@
|
|||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
#include "network/Servent.h"
|
#include "network/Servent.h"
|
||||||
#include "SourceList.h"
|
#include "SourceList.h"
|
||||||
#include "EchonestCatalogSynchronizer.h"
|
|
||||||
|
|
||||||
namespace Tomahawk
|
namespace Tomahawk
|
||||||
{
|
{
|
||||||
@@ -76,9 +75,11 @@ DatabaseCommand_SetCollectionAttributes::exec( DatabaseImpl *lib )
|
|||||||
void
|
void
|
||||||
DatabaseCommand_SetCollectionAttributes::postCommitHook()
|
DatabaseCommand_SetCollectionAttributes::postCommitHook()
|
||||||
{
|
{
|
||||||
|
/*
|
||||||
if ( m_type == EchonestSongCatalog ||
|
if ( m_type == EchonestSongCatalog ||
|
||||||
m_type == EchonestArtistCatalog )
|
m_type == EchonestArtistCatalog )
|
||||||
Tomahawk::EchonestCatalogSynchronizer::instance()->knownCatalogsChanged();
|
Tomahawk::EchonestCatalogSynchronizer::instance()->knownCatalogsChanged();
|
||||||
|
*/
|
||||||
|
|
||||||
if ( source()->isLocal() )
|
if ( source()->isLocal() )
|
||||||
Servent::instance()->triggerDBSync();
|
Servent::instance()->triggerDBSync();
|
||||||
|
@@ -34,11 +34,11 @@ public:
|
|||||||
explicit DatabaseResolver( int weight );
|
explicit DatabaseResolver( int weight );
|
||||||
|
|
||||||
QString name() const override;
|
QString name() const override;
|
||||||
virtual unsigned int weight() const { return m_weight; }
|
virtual unsigned int weight() const override{ return m_weight; }
|
||||||
virtual unsigned int timeout() const { return 0; }
|
virtual unsigned int timeout() const override{ return 0; }
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
virtual void resolve( const Tomahawk::query_ptr& query );
|
virtual void resolve( const Tomahawk::query_ptr& query ) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void gotResults( const Tomahawk::QID qid, QList< Tomahawk::result_ptr> results );
|
void gotResults( const Tomahawk::QID qid, QList< Tomahawk::result_ptr> results );
|
||||||
|
@@ -1,21 +1,20 @@
|
|||||||
/*
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
*
|
||||||
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
This program is free software; you can redistribute it and/or modify
|
*
|
||||||
it under the terms of the GNU General Public License as published by
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
* it under the terms of the GNU General Public License as published by
|
||||||
(at your option) any later version.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
This program is distributed in the hope that it will be useful,
|
*
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
GNU General Public License for more details.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License along
|
*
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
* You should have received a copy of the GNU General Public License
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "LocalCollection.h"
|
#include "LocalCollection.h"
|
||||||
|
|
||||||
|
@@ -1,21 +1,20 @@
|
|||||||
/*
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
*
|
||||||
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
This program is free software; you can redistribute it and/or modify
|
*
|
||||||
it under the terms of the GNU General Public License as published by
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
* it under the terms of the GNU General Public License as published by
|
||||||
(at your option) any later version.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
This program is distributed in the hope that it will be useful,
|
*
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
GNU General Public License for more details.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License along
|
*
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
* You should have received a copy of the GNU General Public License
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef LOCALCOLLECTION_H
|
#ifndef LOCALCOLLECTION_H
|
||||||
#define LOCALCOLLECTION_H
|
#define LOCALCOLLECTION_H
|
||||||
|
@@ -240,7 +240,7 @@ MetadataEditor::loadResult( const Tomahawk::result_ptr& result )
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
m_result = result;
|
m_result = result;
|
||||||
setEditable( result->resolvedByCollection() && result->resolvedByCollection()->isLocal() );
|
setEditable( result->isLocal() );
|
||||||
|
|
||||||
setTitle( result->track()->track() );
|
setTitle( result->track()->track() );
|
||||||
setArtist( result->track()->artist() );
|
setArtist( result->track()->artist() );
|
||||||
@@ -250,7 +250,7 @@ MetadataEditor::loadResult( const Tomahawk::result_ptr& result )
|
|||||||
setYear( result->track()->year() );
|
setYear( result->track()->year() );
|
||||||
setBitrate( result->bitrate() );
|
setBitrate( result->bitrate() );
|
||||||
|
|
||||||
if ( result->resolvedByCollection() && result->resolvedByCollection()->isLocal() )
|
if ( result->isLocal() )
|
||||||
{
|
{
|
||||||
QString furl = m_result->url();
|
QString furl = m_result->url();
|
||||||
if ( furl.startsWith( "file://" ) )
|
if ( furl.startsWith( "file://" ) )
|
||||||
|
@@ -40,6 +40,11 @@ using namespace Tomahawk;
|
|||||||
void
|
void
|
||||||
DirLister::go()
|
DirLister::go()
|
||||||
{
|
{
|
||||||
|
if ( m_dirs.isEmpty() )
|
||||||
|
{
|
||||||
|
emit finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
foreach ( const QString& dir, m_dirs )
|
foreach ( const QString& dir, m_dirs )
|
||||||
{
|
{
|
||||||
m_opcount++;
|
m_opcount++;
|
||||||
|
@@ -42,8 +42,8 @@ public:
|
|||||||
explicit DBSyncConnection( Servent* s, const Tomahawk::source_ptr& src );
|
explicit DBSyncConnection( Servent* s, const Tomahawk::source_ptr& src );
|
||||||
virtual ~DBSyncConnection();
|
virtual ~DBSyncConnection();
|
||||||
|
|
||||||
void setup();
|
void setup() override;
|
||||||
Connection* clone();
|
Connection* clone() override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void stateChanged( Tomahawk::DBSyncConnectionState newstate, Tomahawk::DBSyncConnectionState oldstate, const QString& info );
|
void stateChanged( Tomahawk::DBSyncConnectionState newstate, Tomahawk::DBSyncConnectionState oldstate, const QString& info );
|
||||||
|
@@ -1371,8 +1371,7 @@ Servent::isIPWhitelisted( QHostAddress ip )
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
|
// Qt cannot cope correctly with IPv4 addresses mapped into the IPv6
|
||||||
// Qt4 cannot cope correctly with IPv4 addresses mapped into the IPv6
|
|
||||||
// address space
|
// address space
|
||||||
if ( ip.protocol() == QAbstractSocket::IPv6Protocol )
|
if ( ip.protocol() == QAbstractSocket::IPv6Protocol )
|
||||||
{
|
{
|
||||||
@@ -1397,7 +1396,6 @@ Servent::isIPWhitelisted( QHostAddress ip )
|
|||||||
return isIPWhitelisted( addr );
|
return isIPWhitelisted( addr );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "failure";
|
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "failure";
|
||||||
return false;
|
return false;
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "utils/TomahawkUtilsGui.h"
|
#include "utils/TomahawkUtilsGui.h"
|
||||||
#include "utils/DpiScaler.h"
|
#include "utils/DpiScaler.h"
|
||||||
#include "ViewManager.h"
|
#include "ViewManager.h"
|
||||||
|
#include "widgets/DownloadButton.h"
|
||||||
|
|
||||||
#include <QLabel>
|
#include <QLabel>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
@@ -164,6 +165,10 @@ ColumnViewPreviewWidget::ColumnViewPreviewWidget( ColumnView* parent )
|
|||||||
m_ageValue->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
|
m_ageValue->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
|
||||||
gridLayout->addWidget( m_ageValue, 4, 1 );
|
gridLayout->addWidget( m_ageValue, 4, 1 );
|
||||||
|
|
||||||
|
|
||||||
|
m_downloadButton = new DownloadButton( this );
|
||||||
|
mainLayout->addWidget( m_downloadButton );
|
||||||
|
|
||||||
mainLayout->addStretch();
|
mainLayout->addStretch();
|
||||||
|
|
||||||
TomahawkUtils::unmarginLayout( mainLayout );
|
TomahawkUtils::unmarginLayout( mainLayout );
|
||||||
@@ -217,6 +222,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
|||||||
m_bitrateValue->setText( tr( "%1 kbps" ).arg( query->results().first()->bitrate() ) );
|
m_bitrateValue->setText( tr( "%1 kbps" ).arg( query->results().first()->bitrate() ) );
|
||||||
m_durationValue->setText( TomahawkUtils::timeToString( query->track()->duration() ) );
|
m_durationValue->setText( TomahawkUtils::timeToString( query->track()->duration() ) );
|
||||||
m_ageValue->setText( TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) ) );
|
m_ageValue->setText( TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) ) );
|
||||||
|
m_downloadButton->setQuery( query );
|
||||||
|
|
||||||
m_yearValue->setVisible( query->track()->year() > 0 );
|
m_yearValue->setVisible( query->track()->year() > 0 );
|
||||||
m_yearLabel->setVisible( query->track()->year() > 0 );
|
m_yearLabel->setVisible( query->track()->year() > 0 );
|
||||||
@@ -226,6 +232,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
|||||||
m_durationValue->setVisible( query->track()->duration() > 0 );
|
m_durationValue->setVisible( query->track()->duration() > 0 );
|
||||||
m_ageLabel->setVisible( query->results().first()->modificationTime() > 0 );
|
m_ageLabel->setVisible( query->results().first()->modificationTime() > 0 );
|
||||||
m_ageValue->setVisible( query->results().first()->modificationTime() > 0 );
|
m_ageValue->setVisible( query->results().first()->modificationTime() > 0 );
|
||||||
|
m_downloadButton->setVisible( true );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -237,6 +244,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
|||||||
m_durationValue->setVisible( false );
|
m_durationValue->setVisible( false );
|
||||||
m_ageLabel->setVisible( false );
|
m_ageLabel->setVisible( false );
|
||||||
m_ageValue->setVisible( false );
|
m_ageValue->setVisible( false );
|
||||||
|
m_downloadButton->setVisible( false );
|
||||||
}
|
}
|
||||||
|
|
||||||
setMinimumHeight( sizeHint().height() );
|
setMinimumHeight( sizeHint().height() );
|
||||||
|
@@ -30,6 +30,7 @@ class QueryLabel;
|
|||||||
class PlayableCover;
|
class PlayableCover;
|
||||||
class QLabel;
|
class QLabel;
|
||||||
class ScrollingLabel;
|
class ScrollingLabel;
|
||||||
|
class DownloadButton;
|
||||||
|
|
||||||
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
|
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
|
||||||
{
|
{
|
||||||
@@ -71,6 +72,8 @@ private:
|
|||||||
ScrollingLabel* m_trackLabel;
|
ScrollingLabel* m_trackLabel;
|
||||||
|
|
||||||
QueryLabel* m_artistLabel;
|
QueryLabel* m_artistLabel;
|
||||||
|
|
||||||
|
DownloadButton* m_downloadButton;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // COLUMNVIEWPREVIEWWIDGET_H
|
#endif // COLUMNVIEWPREVIEWWIDGET_H
|
||||||
|
@@ -19,16 +19,6 @@
|
|||||||
|
|
||||||
#include "GridItemDelegate.h"
|
#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 "Artist.h"
|
||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
#include "Result.h"
|
#include "Result.h"
|
||||||
@@ -39,17 +29,22 @@
|
|||||||
#include "playlist/PlayableItem.h"
|
#include "playlist/PlayableItem.h"
|
||||||
#include "playlist/PlayableProxyModel.h"
|
#include "playlist/PlayableProxyModel.h"
|
||||||
#include "widgets/HoverControls.h"
|
#include "widgets/HoverControls.h"
|
||||||
#include "widgets/DropDownButton.h"
|
#include "widgets/DownloadButton.h"
|
||||||
#include "widgets/ImageButton.h"
|
#include "widgets/ImageButton.h"
|
||||||
#include "utils/TomahawkStyle.h"
|
#include "utils/TomahawkStyle.h"
|
||||||
#include "utils/TomahawkUtilsGui.h"
|
#include "utils/TomahawkUtilsGui.h"
|
||||||
#include "utils/PixmapDelegateFader.h"
|
#include "utils/PixmapDelegateFader.h"
|
||||||
#include "utils/Closure.h"
|
#include "utils/Closure.h"
|
||||||
#include "utils/AnimatedSpinner.h"
|
#include "utils/AnimatedSpinner.h"
|
||||||
#include "utils/WebPopup.h"
|
|
||||||
#include "utils/DpiScaler.h"
|
#include "utils/DpiScaler.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QAbstractItemView>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QTimeLine>
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
static const int FADE_DURATION = 400;
|
static const int FADE_DURATION = 400;
|
||||||
};
|
};
|
||||||
@@ -325,39 +320,10 @@ GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
|||||||
QRect r = textRect;
|
QRect r = textRect;
|
||||||
r.setY( textRect.y() + textRect.height() + 8 );
|
r.setY( textRect.y() + textRect.height() + 8 );
|
||||||
r.setHeight( 32 );
|
r.setHeight( 32 );
|
||||||
m_buyButtonRects[ index ] = r;
|
|
||||||
|
|
||||||
QString text;
|
if( DownloadButton::drawPrimitive(painter, r, item->query(), m_hoveringOverBuyButton == index ) )
|
||||||
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" );
|
m_buyButtonRects[ index ] = r;
|
||||||
}
|
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -619,23 +585,7 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
|
|||||||
|
|
||||||
if ( hoveringBuyButton )
|
if ( hoveringBuyButton )
|
||||||
{
|
{
|
||||||
if ( event->type() == QEvent::MouseButtonRelease )
|
return DownloadButton::handleEditorEvent( event, m_view, m_model, index );
|
||||||
{
|
|
||||||
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;
|
return false;
|
||||||
@@ -865,63 +815,7 @@ GridItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& opt
|
|||||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||||
Q_ASSERT( item );
|
Q_ASSERT( item );
|
||||||
|
|
||||||
if ( item->result() && !item->result()->downloadFormats().isEmpty() &&
|
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
|
||||||
!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();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -930,13 +824,13 @@ GridItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewI
|
|||||||
{
|
{
|
||||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||||
|
|
||||||
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
|
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
|
||||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||||
|
|
||||||
if ( m_downloadDropDownRects.contains( index ) )
|
if ( m_buyButtonRects.contains( index ) )
|
||||||
{
|
{
|
||||||
editor->setGeometry( m_downloadDropDownRects.value( index ) );
|
editor->setGeometry( m_buyButtonRects.value( index ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !comboBox->property( "shownPopup" ).toBool() )
|
if ( !comboBox->property( "shownPopup" ).toBool() )
|
||||||
|
@@ -87,9 +87,6 @@ private slots:
|
|||||||
void fadingFrameChanged( const QPersistentModelIndex& );
|
void fadingFrameChanged( const QPersistentModelIndex& );
|
||||||
void fadingFrameFinished( const QPersistentModelIndex& );
|
void fadingFrameFinished( const QPersistentModelIndex& );
|
||||||
|
|
||||||
void closeEditor( const QModelIndex& index, QWidget* editor );
|
|
||||||
void addDownloadJob( const QModelIndex& index, QWidget* editor );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QTimeLine* createTimeline( QTimeLine::Direction direction, int startFrame = 0 );
|
QTimeLine* createTimeline( QTimeLine::Direction direction, int startFrame = 0 );
|
||||||
void clearButtons();
|
void clearButtons();
|
||||||
@@ -104,7 +101,6 @@ private:
|
|||||||
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_albumNameRects;
|
mutable QHash< QPersistentModelIndex, QRect > m_albumNameRects;
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
|
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
|
|
||||||
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_covers;
|
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_covers;
|
||||||
|
|
||||||
QPersistentModelIndex m_hoverIndex;
|
QPersistentModelIndex m_hoverIndex;
|
||||||
|
@@ -59,7 +59,7 @@ public:
|
|||||||
|
|
||||||
PlayableModel* sourceModel() const { return m_model; }
|
PlayableModel* sourceModel() const { return m_model; }
|
||||||
virtual void setSourcePlayableModel( PlayableModel* sourceModel );
|
virtual void setSourcePlayableModel( PlayableModel* sourceModel );
|
||||||
virtual void setSourceModel( QAbstractItemModel* model );
|
virtual void setSourceModel( QAbstractItemModel* model ) override;
|
||||||
|
|
||||||
virtual bool isLoading() const;
|
virtual bool isLoading() const;
|
||||||
|
|
||||||
@@ -91,9 +91,9 @@ public:
|
|||||||
|
|
||||||
QList< double > columnWeights() const;
|
QList< double > columnWeights() const;
|
||||||
|
|
||||||
virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const;
|
virtual int columnCount( const QModelIndex& parent = QModelIndex() ) const override;
|
||||||
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const;
|
virtual QVariant data( const QModelIndex& index, int role = Qt::DisplayRole ) const override;
|
||||||
virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const;
|
virtual QVariant headerData( int section, Qt::Orientation orientation, int role ) const override;
|
||||||
|
|
||||||
virtual void setFilter( const QString& pattern );
|
virtual void setFilter( const QString& pattern );
|
||||||
virtual void updateDetailedInfo( const QModelIndex& index );
|
virtual void updateDetailedInfo( const QModelIndex& index );
|
||||||
@@ -120,7 +120,7 @@ signals:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const Q_DECL_OVERRIDE;
|
bool filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent ) const Q_DECL_OVERRIDE;
|
||||||
virtual bool lessThan( const QModelIndex& left, const QModelIndex& right ) const;
|
virtual bool lessThan( const QModelIndex& left, const QModelIndex& right ) const override;
|
||||||
|
|
||||||
Tomahawk::playlistinterface_ptr m_playlistInterface;
|
Tomahawk::playlistinterface_ptr m_playlistInterface;
|
||||||
|
|
||||||
|
@@ -20,15 +20,6 @@
|
|||||||
|
|
||||||
#include "PlaylistItemDelegate.h"
|
#include "PlaylistItemDelegate.h"
|
||||||
|
|
||||||
#include <QAbstractTextDocumentLayout>
|
|
||||||
#include <QApplication>
|
|
||||||
#include <QDateTime>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QMouseEvent>
|
|
||||||
#include <QPainter>
|
|
||||||
#include <QDesktopServices>
|
|
||||||
#include <QToolTip>
|
|
||||||
|
|
||||||
#include "Query.h"
|
#include "Query.h"
|
||||||
#include "Result.h"
|
#include "Result.h"
|
||||||
#include "Artist.h"
|
#include "Artist.h"
|
||||||
@@ -36,8 +27,6 @@
|
|||||||
#include "Source.h"
|
#include "Source.h"
|
||||||
#include "SourceList.h"
|
#include "SourceList.h"
|
||||||
|
|
||||||
#include "DownloadManager.h"
|
|
||||||
#include "DownloadJob.h"
|
|
||||||
#include "PlayableModel.h"
|
#include "PlayableModel.h"
|
||||||
#include "PlayableItem.h"
|
#include "PlayableItem.h"
|
||||||
#include "PlayableProxyModel.h"
|
#include "PlayableProxyModel.h"
|
||||||
@@ -45,16 +34,22 @@
|
|||||||
#include "ViewHeader.h"
|
#include "ViewHeader.h"
|
||||||
#include "ViewManager.h"
|
#include "ViewManager.h"
|
||||||
|
|
||||||
#include "widgets/DropDownButton.h"
|
#include "widgets/DownloadButton.h"
|
||||||
#include "audio/AudioEngine.h"
|
#include "audio/AudioEngine.h"
|
||||||
#include "utils/ImageRegistry.h"
|
#include "utils/ImageRegistry.h"
|
||||||
#include "utils/PixmapDelegateFader.h"
|
#include "utils/PixmapDelegateFader.h"
|
||||||
#include "utils/Closure.h"
|
#include "utils/Closure.h"
|
||||||
#include "utils/TomahawkStyle.h"
|
#include "utils/TomahawkStyle.h"
|
||||||
#include "utils/TomahawkUtilsGui.h"
|
#include "utils/TomahawkUtilsGui.h"
|
||||||
#include "utils/WebPopup.h"
|
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
#include <QAbstractTextDocumentLayout>
|
||||||
|
#include <QApplication>
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QMouseEvent>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QToolTip>
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
|
|
||||||
@@ -125,63 +120,7 @@ PlaylistItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem&
|
|||||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||||
Q_ASSERT( item );
|
Q_ASSERT( item );
|
||||||
|
|
||||||
if ( /*index.column() == PlayableModel::Download &&*/ item->result() && !item->result()->downloadFormats().isEmpty() &&
|
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
|
||||||
!DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ) ).absolutePath() ) );
|
|
||||||
}
|
|
||||||
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() && item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished )
|
|
||||||
{
|
|
||||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( item->result()->downloadJob()->localFile() ).absolutePath() ) );
|
|
||||||
}
|
|
||||||
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() &&
|
|
||||||
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
|
|
||||||
{
|
|
||||||
QStringList formats;
|
|
||||||
foreach ( const DownloadFormat& format, item->result()->downloadFormats() )
|
|
||||||
{
|
|
||||||
formats << tr( "Download %1" ).arg( format.extension );
|
|
||||||
}
|
|
||||||
|
|
||||||
DropDownButton* editor = new DropDownButton( parent );
|
|
||||||
editor->addItems( formats );
|
|
||||||
|
|
||||||
NewClosure( editor, SIGNAL( clicked() ),
|
|
||||||
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
|
||||||
|
|
||||||
NewClosure( editor, SIGNAL( activated( int ) ),
|
|
||||||
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
|
||||||
return editor;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistItemDelegate::addDownloadJob( const QModelIndex& index, QWidget* editor )
|
|
||||||
{
|
|
||||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
|
||||||
Q_ASSERT( item );
|
|
||||||
|
|
||||||
m_view->closePersistentEditor( index );
|
|
||||||
|
|
||||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
|
||||||
if ( !item->result()->downloadFormats().isEmpty() )
|
|
||||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().at( cb->currentIndex() ) ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
PlaylistItemDelegate::closeEditor( const QModelIndex& index, QWidget* editor )
|
|
||||||
{
|
|
||||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
|
||||||
Q_ASSERT( item );
|
|
||||||
|
|
||||||
m_view->closePersistentEditor( index );
|
|
||||||
|
|
||||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
|
||||||
editor->deleteLater();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -190,7 +129,7 @@ PlaylistItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionV
|
|||||||
{
|
{
|
||||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||||
|
|
||||||
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
|
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
|
||||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||||
|
|
||||||
@@ -277,69 +216,7 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
|
|||||||
else */
|
else */
|
||||||
if ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download )
|
if ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download )
|
||||||
{
|
{
|
||||||
if ( item->result() && !item->result()->downloadFormats().isEmpty() )
|
DownloadButton::drawPrimitive( painter, opt.rect.adjusted( 4, 0, -4, 0 ), item->query(), hoveringOver() == index );
|
||||||
{
|
|
||||||
QStyleOptionComboBox optc;
|
|
||||||
optc.rect = opt.rect.adjusted( 4, 0, -4, 0 );
|
|
||||||
optc.editable = false;
|
|
||||||
optc.currentText = tr( "Download %1" ).arg( item->result()->downloadFormats().first().extension );
|
|
||||||
optc.palette = m_view->palette();
|
|
||||||
|
|
||||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
|
||||||
optc.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
|
||||||
else
|
|
||||||
optc.state = QStyle::State_Active | QStyle::State_Enabled;
|
|
||||||
|
|
||||||
if ( !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
|
||||||
{
|
|
||||||
painter->setPen( opt.palette.text().color() );
|
|
||||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
|
|
||||||
painter->drawText( opt.rect, text, textOption );
|
|
||||||
}
|
|
||||||
else if ( !item->result()->downloadJob() )
|
|
||||||
{
|
|
||||||
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
|
|
||||||
|
|
||||||
/* QApplication::style()->drawComplexControl( QStyle::CC_ComboBox, &optc, painter, 0 );
|
|
||||||
optc.rect.adjust( 4, 0, 0, 0 );
|
|
||||||
QApplication::style()->drawControl( QStyle::CE_ComboBoxLabel, &optc, painter, 0 );*/
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if ( item->result()->downloadJob()->state() == DownloadJob::Finished )
|
|
||||||
{
|
|
||||||
painter->setPen( opt.palette.text().color() );
|
|
||||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
|
|
||||||
painter->drawText( opt.rect, text, textOption );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
|
||||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
|
||||||
painter->drawRect( optc.rect.adjusted( 2, 2, -2, -2 ) );
|
|
||||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
|
||||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
|
||||||
QRect fillp = optc.rect.adjusted( 3, 3, -3, -3 );
|
|
||||||
fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
|
|
||||||
painter->drawRect( fillp );
|
|
||||||
|
|
||||||
/* QStyleOptionProgressBarV2 optp;
|
|
||||||
optp.rect = optc.rect;
|
|
||||||
optp.minimum = 0;
|
|
||||||
optp.maximum = 100;
|
|
||||||
optp.progress = item->result()->downloadJob()->progressPercentage();
|
|
||||||
optp.palette = m_view->palette();
|
|
||||||
optp.palette.setColor( QPalette::Highlight, QColor( "#E61878" ) );
|
|
||||||
|
|
||||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
|
||||||
optp.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
|
||||||
else
|
|
||||||
optp.state = QStyle::State_Active | QStyle::State_Enabled;
|
|
||||||
|
|
||||||
QApplication::style()->drawControl( QStyle::CE_ProgressBar, &optp, painter, 0 );*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if ( item->isPlaying() )
|
else if ( item->isPlaying() )
|
||||||
{
|
{
|
||||||
@@ -657,67 +534,14 @@ PlaylistItemDelegate::drawTrack( QPainter* painter, const QStyleOptionViewItem&
|
|||||||
|
|
||||||
stateWidth += r.width() + 16;
|
stateWidth += r.width() + 16;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( hasOnlineResults && !item->query()->results().first()->purchaseUrl().isEmpty() )
|
|
||||||
{
|
|
||||||
QRect r = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
|
||||||
r.setWidth( 144 );
|
|
||||||
DropDownButton::drawPrimitive( painter, r, tr( "Buy" ), m_hoveringOverBuyButton == index, false );
|
|
||||||
|
|
||||||
m_buyButtonRects[ index ] = r;
|
|
||||||
|
|
||||||
stateWidth += r.width() + 16;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( hasOnlineResults && !item->query()->results().first()->downloadFormats().isEmpty() )
|
QRect downloadButtonRect = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
||||||
|
downloadButtonRect.setWidth( 144 );
|
||||||
|
stateWidth += downloadButtonRect.width() + 16;
|
||||||
|
if ( DownloadButton::drawPrimitive( painter, downloadButtonRect, item->query(), m_hoveringOverDownloadButton == index ) )
|
||||||
{
|
{
|
||||||
painter->save();
|
m_downloadDropDownRects[ index ] = downloadButtonRect;
|
||||||
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;
|
const int remWidth = r.width() - numberWidth - durationWidth;
|
||||||
@@ -835,7 +659,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
|||||||
bool hoveringArtist = false;
|
bool hoveringArtist = false;
|
||||||
bool hoveringInfo = false;
|
bool hoveringInfo = false;
|
||||||
bool hoveringLove = false;
|
bool hoveringLove = false;
|
||||||
bool hoveringBuy = false;
|
|
||||||
bool hoveringDownloadDropDown = false;
|
bool hoveringDownloadDropDown = false;
|
||||||
Tomahawk::source_ptr hoveredAvatar;
|
Tomahawk::source_ptr hoveredAvatar;
|
||||||
QRect hoveredAvatarRect;
|
QRect hoveredAvatarRect;
|
||||||
@@ -858,12 +681,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
|||||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||||
hoveringLove = loveRect.contains( ev->pos() );
|
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 ) )
|
if ( m_downloadDropDownRects.contains( index ) )
|
||||||
{
|
{
|
||||||
const QRect downloadDropDownRect = m_downloadDropDownRects[ index ];
|
const QRect downloadDropDownRect = m_downloadDropDownRects[ index ];
|
||||||
@@ -887,7 +704,7 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
|||||||
|
|
||||||
if ( event->type() == QEvent::MouseMove )
|
if ( event->type() == QEvent::MouseMove )
|
||||||
{
|
{
|
||||||
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringBuy )
|
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringDownloadDropDown )
|
||||||
m_view->setCursor( Qt::PointingHandCursor );
|
m_view->setCursor( Qt::PointingHandCursor );
|
||||||
else
|
else
|
||||||
m_view->setCursor( Qt::ArrowCursor );
|
m_view->setCursor( Qt::ArrowCursor );
|
||||||
@@ -911,19 +728,19 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
|||||||
emit updateIndex( m_hoveringOverArtist );
|
emit updateIndex( m_hoveringOverArtist );
|
||||||
m_hoveringOverArtist = QModelIndex();
|
m_hoveringOverArtist = QModelIndex();
|
||||||
}
|
}
|
||||||
if ( hoveringBuy && m_hoveringOverBuyButton != index )
|
if ( hoveringDownloadDropDown && m_hoveringOverDownloadButton != index )
|
||||||
{
|
{
|
||||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
|
||||||
m_hoveringOverBuyButton = index;
|
m_hoveringOverDownloadButton = index;
|
||||||
|
|
||||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||||
item->requestRepaint();
|
item->requestRepaint();
|
||||||
emit updateIndex( m_hoveringOverBuyButton );
|
emit updateIndex( m_hoveringOverDownloadButton );
|
||||||
}
|
}
|
||||||
if ( !hoveringBuy && m_hoveringOverBuyButton.isValid() )
|
if ( !hoveringDownloadDropDown && m_hoveringOverDownloadButton.isValid() )
|
||||||
{
|
{
|
||||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
|
||||||
m_hoveringOverBuyButton = QModelIndex();
|
m_hoveringOverDownloadButton = QModelIndex();
|
||||||
|
|
||||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||||
item->requestRepaint();
|
item->requestRepaint();
|
||||||
@@ -957,10 +774,10 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
|||||||
{
|
{
|
||||||
item->query()->queryTrack()->setLoved( !item->query()->queryTrack()->loved() );
|
item->query()->queryTrack()->setLoved( !item->query()->queryTrack()->loved() );
|
||||||
}
|
}
|
||||||
else if ( hoveringBuy )
|
else if ( hoveringDownloadDropDown || ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) )
|
||||||
{
|
{
|
||||||
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
|
if ( DownloadButton::handleEditorEvent( event , m_view, m_model, index ) )
|
||||||
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
return true;
|
||||||
}
|
}
|
||||||
else if ( hoveringInfo )
|
else if ( hoveringInfo )
|
||||||
{
|
{
|
||||||
@@ -996,13 +813,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if ( ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) || hoveringDownloadDropDown )
|
|
||||||
{
|
|
||||||
m_model->sourceModel()->setAllColumnsEditable( true );
|
|
||||||
m_view->edit( index );
|
|
||||||
m_model->sourceModel()->setAllColumnsEditable( false );
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
return true;
|
return true;
|
||||||
@@ -1022,10 +832,9 @@ PlaylistItemDelegate::resetHoverIndex()
|
|||||||
|
|
||||||
m_hoveringOver = QModelIndex();
|
m_hoveringOver = QModelIndex();
|
||||||
m_hoveringOverArtist = QModelIndex();
|
m_hoveringOverArtist = QModelIndex();
|
||||||
m_hoveringOverBuyButton = QModelIndex();
|
m_hoveringOverDownloadButton = QModelIndex();
|
||||||
m_infoButtonRects.clear();
|
m_infoButtonRects.clear();
|
||||||
m_loveButtonRects.clear();
|
m_loveButtonRects.clear();
|
||||||
m_buyButtonRects.clear();
|
|
||||||
m_artistNameRects.clear();
|
m_artistNameRects.clear();
|
||||||
|
|
||||||
QModelIndex itemIdx = m_model->mapToSource( idx );
|
QModelIndex itemIdx = m_model->mapToSource( idx );
|
||||||
|
@@ -57,8 +57,6 @@ signals:
|
|||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void doUpdateIndex( const QPersistentModelIndex& index );
|
void doUpdateIndex( const QPersistentModelIndex& index );
|
||||||
void closeEditor( const QModelIndex& index, QWidget* editor );
|
|
||||||
void addDownloadJob( const QModelIndex& index, QWidget* editor );
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, PlayableItem* item ) const;
|
void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, PlayableItem* item ) const;
|
||||||
@@ -116,13 +114,12 @@ private:
|
|||||||
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps;
|
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps;
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_infoButtonRects;
|
mutable QHash< QPersistentModelIndex, QRect > m_infoButtonRects;
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_loveButtonRects;
|
mutable QHash< QPersistentModelIndex, QRect > m_loveButtonRects;
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
|
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
|
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
|
||||||
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
||||||
mutable QHash< QPersistentModelIndex, QHash< Tomahawk::source_ptr, QRect > > m_avatarBoxRects;
|
mutable QHash< QPersistentModelIndex, QHash< Tomahawk::source_ptr, QRect > > m_avatarBoxRects;
|
||||||
QPersistentModelIndex m_hoveringOver;
|
QPersistentModelIndex m_hoveringOver;
|
||||||
QPersistentModelIndex m_hoveringOverArtist;
|
QPersistentModelIndex m_hoveringOverArtist;
|
||||||
QPersistentModelIndex m_hoveringOverBuyButton;
|
QPersistentModelIndex m_hoveringOverDownloadButton;
|
||||||
mutable QPersistentModelIndex m_nowPlaying;
|
mutable QPersistentModelIndex m_nowPlaying;
|
||||||
|
|
||||||
TrackView* m_view;
|
TrackView* m_view;
|
||||||
|
@@ -18,12 +18,6 @@
|
|||||||
|
|
||||||
#include "TrackDetailView.h"
|
#include "TrackDetailView.h"
|
||||||
|
|
||||||
#include <QLabel>
|
|
||||||
#include <QPushButton>
|
|
||||||
#include <QScrollArea>
|
|
||||||
#include <QSizePolicy>
|
|
||||||
#include <QVBoxLayout>
|
|
||||||
|
|
||||||
#include "Album.h"
|
#include "Album.h"
|
||||||
#include "Track.h"
|
#include "Track.h"
|
||||||
#include "audio/AudioEngine.h"
|
#include "audio/AudioEngine.h"
|
||||||
@@ -39,6 +33,13 @@
|
|||||||
#include "utils/WebPopup.h"
|
#include "utils/WebPopup.h"
|
||||||
#include "utils/Logger.h"
|
#include "utils/Logger.h"
|
||||||
|
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QScrollArea>
|
||||||
|
#include <QSizePolicy>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QDesktopServices>
|
||||||
|
|
||||||
using namespace Tomahawk;
|
using namespace Tomahawk;
|
||||||
|
|
||||||
TrackDetailView::TrackDetailView( QWidget* parent )
|
TrackDetailView::TrackDetailView( QWidget* parent )
|
||||||
@@ -197,7 +198,7 @@ TrackDetailView::setQuery( const Tomahawk::query_ptr& query )
|
|||||||
|
|
||||||
connect( m_query->track().data(), SIGNAL( updated() ), SLOT( onCoverUpdated() ) );
|
connect( m_query->track().data(), SIGNAL( updated() ), SLOT( onCoverUpdated() ) );
|
||||||
connect( m_query->track().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) );
|
connect( m_query->track().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) );
|
||||||
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( onResultsChanged() ) );
|
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( onResultsChanged() ), Qt::QueuedConnection );
|
||||||
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( onAlbumUpdated() ) );
|
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( onAlbumUpdated() ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,8 +220,44 @@ TrackDetailView::onAlbumUpdated()
|
|||||||
{
|
{
|
||||||
if ( m_query->track()->albumPtr()->purchased() )
|
if ( m_query->track()->albumPtr()->purchased() )
|
||||||
{
|
{
|
||||||
m_buyButton->setText( tr( "Download Album" ) );
|
m_allTracksAvailableLocally = true;
|
||||||
m_buyButton->setVisible( true );
|
foreach( const query_ptr& currentQuery, m_playlistInterface->tracks() )
|
||||||
|
{
|
||||||
|
if ( currentQuery->results().isEmpty() )
|
||||||
|
{
|
||||||
|
m_allTracksAvailableLocally = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_allTracksAvailableLocally = false;
|
||||||
|
foreach ( const result_ptr& currentResult, currentQuery->results() )
|
||||||
|
{
|
||||||
|
QList< DownloadFormat > formats = currentResult->downloadFormats();
|
||||||
|
bool isDownloaded = formats.isEmpty() ? false : !DownloadManager::instance()->localFileForDownload( currentResult->downloadFormats().first().url.toString() ).isEmpty();
|
||||||
|
if ( currentResult->isLocal() || isDownloaded )
|
||||||
|
{
|
||||||
|
m_allTracksAvailableLocally = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( !m_allTracksAvailableLocally )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( m_allTracksAvailableLocally )
|
||||||
|
{
|
||||||
|
m_buyButton->setText( tr( "View in Folder" ) );
|
||||||
|
m_buyButton->setVisible( true );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_buyButton->setText( tr( "Download Album" ) );
|
||||||
|
m_buyButton->setVisible( true );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -251,7 +288,14 @@ TrackDetailView::onBuyButtonClicked()
|
|||||||
{
|
{
|
||||||
if ( m_query->track()->albumPtr()->purchased() )
|
if ( m_query->track()->albumPtr()->purchased() )
|
||||||
{
|
{
|
||||||
emit downloadAll();
|
if ( m_allTracksAvailableLocally )
|
||||||
|
{
|
||||||
|
QDesktopServices::openUrl( QUrl::fromLocalFile( DownloadJob::localPath( m_query->track()->albumPtr() ) ) );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
emit downloadAll();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -344,7 +388,7 @@ TrackDetailView::onResultsChanged()
|
|||||||
resolverIcon->setFixedWidth( 12 );
|
resolverIcon->setFixedWidth( 12 );
|
||||||
resolverIcon->setPixmap( result->sourceIcon( TomahawkUtils::RoundedCorners, QSize( 12, 12 ) ) );
|
resolverIcon->setPixmap( result->sourceIcon( TomahawkUtils::RoundedCorners, QSize( 12, 12 ) ) );
|
||||||
|
|
||||||
QLabel* resolverLabel = new ClickableLabel( this );
|
ClickableLabel* resolverLabel = new ClickableLabel( this );
|
||||||
resolverLabel->setFont( f );
|
resolverLabel->setFont( f );
|
||||||
resolverLabel->setStyleSheet( "QLabel { color: rgba( 0, 0, 0, 50% ) }" );
|
resolverLabel->setStyleSheet( "QLabel { color: rgba( 0, 0, 0, 50% ) }" );
|
||||||
resolverLabel->setText( QString( "%1 - %2" ).arg( result->track()->track() ).arg( result->track()->artist() ) );
|
resolverLabel->setText( QString( "%1 - %2" ).arg( result->track()->track() ).arg( result->track()->artist() ) );
|
||||||
@@ -359,8 +403,8 @@ TrackDetailView::onResultsChanged()
|
|||||||
;
|
;
|
||||||
resolverLabel->setFixedWidth( width() - 32 - 4 );
|
resolverLabel->setFixedWidth( width() - 32 - 4 );
|
||||||
|
|
||||||
NewClosure( resolverLabel, SIGNAL( clicked() ), const_cast< AudioEngine* >( AudioEngine::instance() ),
|
NewClosure( resolverLabel, SIGNAL( clicked() ), const_cast< TrackDetailView* >( this ),
|
||||||
SLOT( playItem( Tomahawk::playlistinterface_ptr, Tomahawk::result_ptr, Tomahawk::query_ptr ) ),
|
SLOT( onResultClicked( Tomahawk::playlistinterface_ptr, Tomahawk::result_ptr, Tomahawk::query_ptr ) ),
|
||||||
m_playlistInterface, result, m_query )->setAutoDelete( false );
|
m_playlistInterface, result, m_query )->setAutoDelete( false );
|
||||||
|
|
||||||
QWidget* hbox = new QWidget;
|
QWidget* hbox = new QWidget;
|
||||||
@@ -397,3 +441,13 @@ TrackDetailView::setBuyButtonVisible( bool visible )
|
|||||||
{
|
{
|
||||||
m_buyButtonVisible = visible;
|
m_buyButtonVisible = visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TrackDetailView::onResultClicked( const Tomahawk::playlistinterface_ptr& playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery )
|
||||||
|
{
|
||||||
|
fromQuery->setPreferredResult( result );
|
||||||
|
if (AudioEngine::instance()->isPlaying() && fromQuery->results().contains( AudioEngine::instance()->currentTrack() )) {
|
||||||
|
AudioEngine::instance()->playItem( playlist, result, fromQuery );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -64,6 +64,8 @@ private slots:
|
|||||||
void onBuyButtonClicked();
|
void onBuyButtonClicked();
|
||||||
void onDownloadManagerStateChanged( DownloadManager::DownloadManagerState newState, DownloadManager::DownloadManagerState oldState );
|
void onDownloadManagerStateChanged( DownloadManager::DownloadManagerState newState, DownloadManager::DownloadManagerState oldState );
|
||||||
|
|
||||||
|
void onResultClicked( const Tomahawk::playlistinterface_ptr& playlist, const Tomahawk::result_ptr& result, const Tomahawk::query_ptr& fromQuery );
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void setSocialActions();
|
void setSocialActions();
|
||||||
|
|
||||||
@@ -77,6 +79,7 @@ private:
|
|||||||
CaptionLabel* m_resultsBoxLabel;
|
CaptionLabel* m_resultsBoxLabel;
|
||||||
QPushButton* m_buyButton;
|
QPushButton* m_buyButton;
|
||||||
bool m_buyButtonVisible;
|
bool m_buyButtonVisible;
|
||||||
|
bool m_allTracksAvailableLocally;
|
||||||
|
|
||||||
QWidget* m_infoBox;
|
QWidget* m_infoBox;
|
||||||
QWidget* m_resultsBox;
|
QWidget* m_resultsBox;
|
||||||
|
@@ -383,6 +383,8 @@ void
|
|||||||
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
|
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
|
||||||
{
|
{
|
||||||
QTreeView::currentChanged( current, previous );
|
QTreeView::currentChanged( current, previous );
|
||||||
|
if ( !m_model )
|
||||||
|
return;
|
||||||
|
|
||||||
PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
|
PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
|
||||||
if ( item && item->query() )
|
if ( item && item->query() )
|
||||||
|
@@ -247,8 +247,8 @@ TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent
|
|||||||
if ( !item->result()->isOnline() && ti->result()->isOnline() )
|
if ( !item->result()->isOnline() && ti->result()->isOnline() )
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if ( ( item->result()->resolvedByCollection().isNull() || !item->result()->resolvedByCollection()->isLocal() ) &&
|
if ( ( !item->result()->isLocal() ) &&
|
||||||
!ti->result()->resolvedByCollection().isNull() && ti->result()->resolvedByCollection()->isLocal() )
|
!ti->result()->isLocal() )
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@@ -190,7 +190,7 @@ JSAccount::reportNativeScriptJobResult( int resultId, const QVariantMap& result
|
|||||||
.arg( serializeQVariantMap( result ) );
|
.arg( serializeQVariantMap( result ) );
|
||||||
|
|
||||||
// Remove when new scripting api turned out to work reliably
|
// Remove when new scripting api turned out to work reliably
|
||||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << eval;
|
//tDebug( LOGVERBOSE ) << Q_FUNC_INFO << eval;
|
||||||
|
|
||||||
evaluateJavaScript( eval );
|
evaluateJavaScript( eval );
|
||||||
}
|
}
|
||||||
|
@@ -711,3 +711,14 @@ JSResolver::getStreamUrl( const result_ptr& result )
|
|||||||
|
|
||||||
return scriptObject()->invoke( "getStreamUrl", arguments );
|
return scriptObject()->invoke( "getStreamUrl", arguments );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScriptJob*
|
||||||
|
JSResolver::getDownloadUrl( const result_ptr& result, const DownloadFormat& format )
|
||||||
|
{
|
||||||
|
QVariantMap arguments;
|
||||||
|
arguments["url"] = format.url.toString();
|
||||||
|
arguments["extension"] = format.extension;
|
||||||
|
arguments["mimetype"] = format.mimetype;
|
||||||
|
|
||||||
|
return scriptObject()->invoke( "getDownloadUrl", arguments );
|
||||||
|
}
|
||||||
|
@@ -76,6 +76,8 @@ public:
|
|||||||
ScriptAccount* scriptAccount() const;
|
ScriptAccount* scriptAccount() const;
|
||||||
|
|
||||||
ScriptJob* getStreamUrl( const result_ptr& result ) override;
|
ScriptJob* getStreamUrl( const result_ptr& result ) override;
|
||||||
|
ScriptJob* getDownloadUrl( const result_ptr& result, const DownloadFormat &format ) override;
|
||||||
|
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void resolve( const Tomahawk::query_ptr& query ) override;
|
void resolve( const Tomahawk::query_ptr& query ) override;
|
||||||
|
@@ -45,3 +45,12 @@ Tomahawk::Resolver::getStreamUrl( const result_ptr& result )
|
|||||||
|
|
||||||
return new SyncScriptJob( data );
|
return new SyncScriptJob( data );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Tomahawk::ScriptJob*
|
||||||
|
Tomahawk::Resolver::getDownloadUrl( const result_ptr& result, const DownloadFormat& format )
|
||||||
|
{
|
||||||
|
QVariantMap data;
|
||||||
|
data[ "url" ] = format.url.toString();
|
||||||
|
|
||||||
|
return new SyncScriptJob( data );
|
||||||
|
}
|
||||||
|
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
#include "Typedefs.h"
|
#include "Typedefs.h"
|
||||||
#include "DllMacro.h"
|
#include "DllMacro.h"
|
||||||
|
#include "../DownloadJob.h"
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ public:
|
|||||||
|
|
||||||
virtual void resolve( const Tomahawk::query_ptr& query ) = 0;
|
virtual void resolve( const Tomahawk::query_ptr& query ) = 0;
|
||||||
virtual ScriptJob* getStreamUrl( const result_ptr& result );
|
virtual ScriptJob* getStreamUrl( const result_ptr& result );
|
||||||
|
virtual ScriptJob* getDownloadUrl( const result_ptr& result, const DownloadFormat& format );
|
||||||
};
|
};
|
||||||
|
|
||||||
} //ns
|
} //ns
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2015-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -17,6 +17,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ScriptAccount.h"
|
#include "ScriptAccount.h"
|
||||||
|
|
||||||
#include "ScriptObject.h"
|
#include "ScriptObject.h"
|
||||||
@@ -31,11 +32,11 @@
|
|||||||
#include "ScriptLinkGeneratorPlugin.h"
|
#include "ScriptLinkGeneratorPlugin.h"
|
||||||
#include "ScriptInfoPlugin.h"
|
#include "ScriptInfoPlugin.h"
|
||||||
|
|
||||||
// TODO:
|
|
||||||
#include "../Artist.h"
|
#include "../Artist.h"
|
||||||
#include "../Album.h"
|
#include "../Album.h"
|
||||||
#include "../Result.h"
|
#include "../Result.h"
|
||||||
#include "../Track.h"
|
#include "../Track.h"
|
||||||
|
|
||||||
#include <QTime>
|
#include <QTime>
|
||||||
|
|
||||||
|
|
||||||
@@ -155,11 +156,17 @@ ScriptAccount::reportScriptJobResult( const QVariantMap& result )
|
|||||||
Q_ASSERT( job );
|
Q_ASSERT( job );
|
||||||
|
|
||||||
// got a successful job result
|
// got a successful job result
|
||||||
if ( result[ "error"].isNull() )
|
if ( result[ "error" ].isNull() )
|
||||||
{
|
{
|
||||||
const QVariantMap data = result[ "data" ].toMap();
|
if ( result[ "data" ].type() == QVariant::Map )
|
||||||
|
{
|
||||||
job->reportResults( data );
|
const QVariantMap data = result[ "data" ].toMap();
|
||||||
|
job->reportResultsMap( data );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
job->reportResults( result[ "data" ] );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2015-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -53,6 +53,7 @@ ScriptCollection::ScriptCollection( const scriptobject_ptr& scriptObject,
|
|||||||
qDebug() << Q_FUNC_INFO << scriptAccount->name() << Collection::name();
|
qDebug() << Q_FUNC_INFO << scriptAccount->name() << Collection::name();
|
||||||
|
|
||||||
m_servicePrettyName = scriptAccount->name();
|
m_servicePrettyName = scriptAccount->name();
|
||||||
|
m_weight = readMetaData().value( "weight", 99 ).toUInt();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -235,6 +236,16 @@ ScriptCollection::getStreamUrl( const result_ptr& result )
|
|||||||
return scriptObject()->invoke( "getStreamUrl", arguments );
|
return scriptObject()->invoke( "getStreamUrl", arguments );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScriptJob*
|
||||||
|
ScriptCollection::getDownloadUrl( const result_ptr& result, const DownloadFormat& format )
|
||||||
|
{
|
||||||
|
QVariantMap arguments;
|
||||||
|
arguments["url"] = format.url.toString();
|
||||||
|
arguments["extension"] = format.extension;
|
||||||
|
arguments["mimetype"] = format.mimetype;
|
||||||
|
|
||||||
|
return scriptObject()->invoke( "getDownloadUrl", arguments );
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ScriptCollection::parseMetaData( const QVariantMap& metadata )
|
ScriptCollection::parseMetaData( const QVariantMap& metadata )
|
||||||
@@ -350,7 +361,7 @@ ScriptCollection::timeout() const
|
|||||||
unsigned int
|
unsigned int
|
||||||
ScriptCollection::weight() const
|
ScriptCollection::weight() const
|
||||||
{
|
{
|
||||||
return 0;
|
return m_weight;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -96,6 +96,7 @@ public:
|
|||||||
unsigned int timeout() const override;
|
unsigned int timeout() const override;
|
||||||
void resolve( const Tomahawk::query_ptr& query ) override;
|
void resolve( const Tomahawk::query_ptr& query ) override;
|
||||||
ScriptJob* getStreamUrl( const result_ptr& result ) override;
|
ScriptJob* getStreamUrl( const result_ptr& result ) override;
|
||||||
|
ScriptJob* getDownloadUrl( const result_ptr& result, const DownloadFormat &format ) override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onIconFetched();
|
void onIconFetched();
|
||||||
@@ -106,6 +107,7 @@ private:
|
|||||||
QString m_servicePrettyName;
|
QString m_servicePrettyName;
|
||||||
QString m_description;
|
QString m_description;
|
||||||
int m_trackCount;
|
int m_trackCount;
|
||||||
|
int m_weight;
|
||||||
QPixmap m_icon;
|
QPixmap m_icon;
|
||||||
bool m_isOnline;
|
bool m_isOnline;
|
||||||
};
|
};
|
||||||
|
@@ -41,12 +41,12 @@ public:
|
|||||||
void setFilter( const QString& filter ) override;
|
void setFilter( const QString& filter ) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void albums( const QList< Tomahawk::album_ptr >& );
|
void albums( const QList< Tomahawk::album_ptr >& ) override;
|
||||||
void done();
|
void done() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void exec();
|
virtual void exec() override;
|
||||||
virtual void reportFailure();
|
virtual void reportFailure() override;
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onAlbumsJobDone( const QVariantMap& result );
|
void onAlbumsJobDone( const QVariantMap& result );
|
||||||
|
@@ -42,8 +42,8 @@ public:
|
|||||||
void setFilter( const QString& filter ) override;
|
void setFilter( const QString& filter ) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void artists( const QList< Tomahawk::artist_ptr >& );
|
void artists( const QList< Tomahawk::artist_ptr >& ) override;
|
||||||
void done();
|
void done() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void exec() override;
|
void exec() override;
|
||||||
|
@@ -39,8 +39,8 @@ public:
|
|||||||
void enqueue() override;
|
void enqueue() override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void tracks( const QList< Tomahawk::query_ptr >& );
|
void tracks( const QList< Tomahawk::query_ptr >& ) override;
|
||||||
void done();
|
void done() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Q_INVOKABLE void exec() override;
|
Q_INVOKABLE void exec() override;
|
||||||
|
@@ -45,7 +45,7 @@ public:
|
|||||||
|
|
||||||
signals:
|
signals:
|
||||||
void information( const QString& url, const QSharedPointer<QObject>& variant );
|
void information( const QString& url, const QSharedPointer<QObject>& variant );
|
||||||
void done();
|
void done() override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void exec() override;
|
void exec() override;
|
||||||
|
@@ -82,7 +82,15 @@ ScriptJob::arguments() const
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
ScriptJob::reportResults( const QVariantMap& data )
|
ScriptJob::reportResultsMap( const QVariantMap& data )
|
||||||
|
{
|
||||||
|
m_data = data;
|
||||||
|
emit done( data );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
ScriptJob::reportResults( const QVariant& data )
|
||||||
{
|
{
|
||||||
m_data = data;
|
m_data = data;
|
||||||
emit done( data );
|
emit done( data );
|
||||||
@@ -94,5 +102,6 @@ ScriptJob::reportFailure( const QString& errorMessage )
|
|||||||
{
|
{
|
||||||
emit error( errorMessage );
|
emit error( errorMessage );
|
||||||
|
|
||||||
reportResults( QVariantMap() );
|
reportResults();
|
||||||
|
reportResultsMap();
|
||||||
}
|
}
|
||||||
|
@@ -49,11 +49,13 @@ public:
|
|||||||
QVariantMap arguments() const;
|
QVariantMap arguments() const;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void reportResults( const QVariantMap& data = QVariantMap() );
|
void reportResultsMap( const QVariantMap& data = QVariantMap() );
|
||||||
|
void reportResults( const QVariant& data = QVariant() );
|
||||||
void reportFailure( const QString& errorMessage );
|
void reportFailure( const QString& errorMessage );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void done( const QVariantMap& result );
|
void done( const QVariantMap& result );
|
||||||
|
void done( const QVariant& result );
|
||||||
void error( const QString& errorMessage );
|
void error( const QString& errorMessage );
|
||||||
|
|
||||||
void destroyed( const QString& id );
|
void destroyed( const QString& id );
|
||||||
@@ -63,7 +65,7 @@ protected:
|
|||||||
bool m_error;
|
bool m_error;
|
||||||
QString m_id;
|
QString m_id;
|
||||||
scriptobject_ptr m_scriptObject;
|
scriptobject_ptr m_scriptObject;
|
||||||
QVariantMap m_data;
|
QVariant m_data;
|
||||||
QString m_methodName;
|
QString m_methodName;
|
||||||
QVariantMap m_arguments;
|
QVariantMap m_arguments;
|
||||||
};
|
};
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ScriptPlugin.h"
|
#include "ScriptPlugin.h"
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -15,4 +15,5 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ScriptPluginFactory.h"
|
#include "ScriptPluginFactory.h"
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "SyncScriptJob.h"
|
#include "SyncScriptJob.h"
|
||||||
|
|
||||||
#include "../Typedefs.h"
|
#include "../Typedefs.h"
|
||||||
@@ -30,5 +31,5 @@ Tomahawk::SyncScriptJob::SyncScriptJob( const QVariantMap& resultData )
|
|||||||
void
|
void
|
||||||
Tomahawk::SyncScriptJob::start()
|
Tomahawk::SyncScriptJob::start()
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod( this, "reportResults", Qt::QueuedConnection, Q_ARG( QVariantMap, m_data ) );
|
QMetaObject::invokeMethod( this, "reportResultsMap", Qt::QueuedConnection, Q_ARG( QVariantMap, m_data.toMap() ) );
|
||||||
}
|
}
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ScriptCollectionFactory.h"
|
#include "ScriptCollectionFactory.h"
|
||||||
|
|
||||||
#include "SourceList.h"
|
#include "SourceList.h"
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "ScriptInfoPluginFactory.h"
|
#include "ScriptInfoPluginFactory.h"
|
||||||
|
|
||||||
#include "SourceList.h"
|
#include "SourceList.h"
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -53,11 +53,11 @@ public:
|
|||||||
static QMargins scaled( const QPaintDevice* pd, const QMargins& margins );
|
static QMargins scaled( const QPaintDevice* pd, const QMargins& margins );
|
||||||
static int scaledX( const QPaintDevice* pd, int x );
|
static int scaledX( const QPaintDevice* pd, int x );
|
||||||
static int scaledY( const QPaintDevice* pd, int y );
|
static int scaledY( const QPaintDevice* pd, int y );
|
||||||
|
static qreal ratioFromFontHeight();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
inline static qreal ratioX( const QPaintDevice* pd );
|
inline static qreal ratioX( const QPaintDevice* pd );
|
||||||
inline static qreal ratioY( const QPaintDevice* pd );
|
inline static qreal ratioY( const QPaintDevice* pd );
|
||||||
inline static qreal ratioFromFontHeight();
|
|
||||||
|
|
||||||
qreal m_ratioX;
|
qreal m_ratioX;
|
||||||
qreal m_ratioY;
|
qreal m_ratioY;
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright (C) 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,11 +1,12 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -15,6 +15,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "LinkGeneratorPlugin.h"
|
#include "LinkGeneratorPlugin.h"
|
||||||
|
|
||||||
#include "LinkGenerator.h"
|
#include "LinkGenerator.h"
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -96,7 +96,14 @@ NetworkReply::metaDataChanged()
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
load( redir.toUrl() );
|
QUrl url = redir.toUrl();
|
||||||
|
if (url.path().isEmpty())
|
||||||
|
{
|
||||||
|
//Default cookie jar gets confused if path is empty
|
||||||
|
url.setPath("/");
|
||||||
|
}
|
||||||
|
|
||||||
|
load( url );
|
||||||
}
|
}
|
||||||
emit redirected();
|
emit redirected();
|
||||||
}
|
}
|
||||||
@@ -148,10 +155,14 @@ NetworkReply::load( const QUrl& url )
|
|||||||
m_formerUrls << url.toString();
|
m_formerUrls << url.toString();
|
||||||
QNetworkRequest request( url );
|
QNetworkRequest request( url );
|
||||||
|
|
||||||
//Carryover User-Agent
|
//Carryover some headers if set
|
||||||
if ( m_reply->request().hasRawHeader( "User-Agent" ))
|
static QList<QByteArray> headersToCarryOver = { "User-Agent", "Accept-Language" };
|
||||||
|
for (auto&& header : headersToCarryOver)
|
||||||
{
|
{
|
||||||
request.setRawHeader( "User-Agent", m_reply->request().rawHeader( "User-Agent" ) );
|
if ( m_reply->request().hasRawHeader( header ))
|
||||||
|
{
|
||||||
|
request.setRawHeader( header, m_reply->request().rawHeader( header ) );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_ASSERT( Tomahawk::Utils::nam() != 0 );
|
Q_ASSERT( Tomahawk::Utils::nam() != 0 );
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,13 +1,13 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
|
@@ -1,15 +1,15 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -20,6 +20,7 @@
|
|||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "TomaHkLinkGeneratorPlugin.h"
|
#include "TomaHkLinkGeneratorPlugin.h"
|
||||||
|
|
||||||
#include "../playlist/dynamic/GeneratorInterface.h"
|
#include "../playlist/dynamic/GeneratorInterface.h"
|
||||||
@@ -30,12 +31,6 @@
|
|||||||
#include "../resolvers/SyncScriptJob.h"
|
#include "../resolvers/SyncScriptJob.h"
|
||||||
#include "../utils/Logger.h"
|
#include "../utils/Logger.h"
|
||||||
|
|
||||||
#if QT_VERSION >= QT_VERSION_CHECK(5,0,0)
|
|
||||||
#include <echonest5/Playlist.h>
|
|
||||||
#else
|
|
||||||
#include <echonest/Playlist.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
QString
|
QString
|
||||||
Tomahawk::Utils::TomaHkLinkGeneratorPlugin::hostname() const
|
Tomahawk::Utils::TomaHkLinkGeneratorPlugin::hostname() const
|
||||||
{
|
{
|
||||||
@@ -82,6 +77,7 @@ Tomahawk::Utils::TomaHkLinkGeneratorPlugin::openLink( const Tomahawk::album_ptr&
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
Tomahawk::ScriptJob*
|
Tomahawk::ScriptJob*
|
||||||
Tomahawk::Utils::TomaHkLinkGeneratorPlugin::openLink( const Tomahawk::dynplaylist_ptr& playlist ) const
|
Tomahawk::Utils::TomaHkLinkGeneratorPlugin::openLink( const Tomahawk::dynplaylist_ptr& playlist ) const
|
||||||
{
|
{
|
||||||
@@ -130,3 +126,4 @@ Tomahawk::Utils::TomaHkLinkGeneratorPlugin::openLink( const Tomahawk::dynplaylis
|
|||||||
|
|
||||||
return new SyncScriptJob( data );
|
return new SyncScriptJob( data );
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
* the Free Software Foundation, either version 2 of the License, or
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
* (at your option) any later version.
|
* (at your option) any later version.
|
||||||
*
|
*
|
||||||
* Tomahawk is distributed in the hope that it will be useful,
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
@@ -37,7 +37,8 @@ public:
|
|||||||
ScriptJob* openLink( const QString& title, const QString& artist, const QString& album ) const override;
|
ScriptJob* openLink( const QString& title, const QString& artist, const QString& album ) const override;
|
||||||
ScriptJob* openLink( const Tomahawk::artist_ptr& artist ) const override;
|
ScriptJob* openLink( const Tomahawk::artist_ptr& artist ) const override;
|
||||||
ScriptJob* openLink( const Tomahawk::album_ptr& album ) const override;
|
ScriptJob* openLink( const Tomahawk::album_ptr& album ) const override;
|
||||||
ScriptJob* openLink( const Tomahawk::dynplaylist_ptr& playlist ) const override;
|
// echonest is dead, disable all echonest code
|
||||||
|
// ScriptJob* openLink( const Tomahawk::dynplaylist_ptr& playlist ) const override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString hostname() const;
|
QString hostname() const;
|
||||||
|
@@ -1,21 +1,20 @@
|
|||||||
/*
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
*
|
||||||
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
This program is free software; you can redistribute it and/or modify
|
*
|
||||||
it under the terms of the GNU General Public License as published by
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
* it under the terms of the GNU General Public License as published by
|
||||||
(at your option) any later version.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
This program is distributed in the hope that it will be useful,
|
*
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
GNU General Public License for more details.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License along
|
*
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
* You should have received a copy of the GNU General Public License
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include "XspfGenerator.h"
|
#include "XspfGenerator.h"
|
||||||
|
|
||||||
|
@@ -1,21 +1,20 @@
|
|||||||
/*
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
*
|
||||||
|
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||||
This program is free software; you can redistribute it and/or modify
|
*
|
||||||
it under the terms of the GNU General Public License as published by
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
the Free Software Foundation; either version 2 of the License, or
|
* it under the terms of the GNU General Public License as published by
|
||||||
(at your option) any later version.
|
* the Free Software Foundation, either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
This program is distributed in the hope that it will be useful,
|
*
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* Tomahawk is distributed in the hope that it will be useful,
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
GNU General Public License for more details.
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
You should have received a copy of the GNU General Public License along
|
*
|
||||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
* You should have received a copy of the GNU General Public License
|
||||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#ifndef XSPFGENERATOR_H
|
#ifndef XSPFGENERATOR_H
|
||||||
#define XSPFGENERATOR_H
|
#define XSPFGENERATOR_H
|
||||||
|
@@ -124,6 +124,15 @@ ArtistInfoWidget::ArtistInfoWidget( const Tomahawk::artist_ptr& artist, QWidget*
|
|||||||
ui->biography->page()->mainFrame()->setScrollBarPolicy( Qt::Horizontal, Qt::ScrollBarAlwaysOff );
|
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::ScrollBarAsNeeded );
|
||||||
ui->biography->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
|
ui->biography->page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
|
||||||
|
ui->biography->setTextSizeMultiplier( DpiScaler::ratioFromFontHeight() );
|
||||||
|
ui->biography->settings()->setFontFamily( QWebSettings::StandardFont,
|
||||||
|
ui->biography->settings()->
|
||||||
|
fontFamily( QWebSettings::SansSerifFont ) );
|
||||||
|
ui->biography->setRenderHints( QPainter::Antialiasing |
|
||||||
|
QPainter::TextAntialiasing |
|
||||||
|
QPainter::HighQualityAntialiasing |
|
||||||
|
QPainter::SmoothPixmapTransform |
|
||||||
|
QPainter::NonCosmeticDefaultPen );
|
||||||
ui->biography->installEventFilter( this );
|
ui->biography->installEventFilter( this );
|
||||||
|
|
||||||
TomahawkStyle::stylePageWidget( ui->biography );
|
TomahawkStyle::stylePageWidget( ui->biography );
|
||||||
@@ -358,7 +367,7 @@ ArtistInfoWidget::onTracksFound( const QList<Tomahawk::query_ptr>& queries, Mode
|
|||||||
Q_UNUSED( mode );
|
Q_UNUSED( mode );
|
||||||
|
|
||||||
m_topHitsModel->finishLoading();
|
m_topHitsModel->finishLoading();
|
||||||
m_topHitsModel->appendQueries( queries.mid( 0, 20 ) );
|
m_topHitsModel->appendQueries( queries.mid( 0, 50 ) );
|
||||||
m_topHitsModel->ensureResolved();
|
m_topHitsModel->ensureResolved();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||||
*
|
*
|
||||||
* Copyright 2013-2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
* Copyright 2013-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||||
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
* Copyright 2014, Teo Mrnjavac <teo@kde.org>
|
||||||
*
|
*
|
||||||
* Tomahawk is free software: you can redistribute it and/or modify
|
* Tomahawk is free software: you can redistribute it and/or modify
|
||||||
@@ -382,17 +382,22 @@ CollectionViewPage::restoreViewMode()
|
|||||||
setCurrentMode( CollectionViewPage::Flat );
|
setCurrentMode( CollectionViewPage::Flat );
|
||||||
else
|
else
|
||||||
setCurrentMode( CollectionViewPage::Columns );
|
setCurrentMode( CollectionViewPage::Columns );
|
||||||
} else if ( mode == CollectionViewPage::Flat && !m_collection->browseCapabilities().contains( Collection::CapabilityBrowseTracks ) )
|
}
|
||||||
|
else if ( mode == CollectionViewPage::Flat && !m_collection->browseCapabilities().contains( Collection::CapabilityBrowseTracks ) )
|
||||||
{
|
{
|
||||||
if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseArtists ) )
|
if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseArtists ) )
|
||||||
setCurrentMode( CollectionViewPage::Columns );
|
setCurrentMode( CollectionViewPage::Columns );
|
||||||
else if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseAlbums ) )
|
else if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseAlbums ) )
|
||||||
setCurrentMode( CollectionViewPage::Albums );
|
setCurrentMode( CollectionViewPage::Albums );
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
setCurrentMode( mode );
|
setCurrentMode( mode );
|
||||||
}
|
}
|
||||||
|
|
||||||
onCollectionChanged();
|
// We should think about auto-refreshing only locker collections here. Disabled for now,
|
||||||
|
// as we don't want the local collection to reload every single time you show it.
|
||||||
|
// onCollectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user