mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-09-21 03:11:30 +02:00
Compare commits
86 Commits
things
...
unify-down
Author | SHA1 | Date | |
---|---|---|---|
|
34448b1b46 | ||
|
4408ba275c | ||
|
dfd71d7010 | ||
|
170e2e1c86 | ||
|
0047763188 | ||
|
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 | ||
|
1fa35ae827 | ||
|
26c0f35d21 | ||
|
9acbb48659 | ||
|
cc9f287b41 | ||
|
99abd7434b | ||
|
f38f3ca367 | ||
|
773ecea0da | ||
|
620d3fe3fc | ||
|
8679fd5055 | ||
|
d7eccea4c0 | ||
|
2ab9418a9e | ||
|
285333d43b | ||
|
3bcf854a4f | ||
|
61a15cafac | ||
|
2d141ccb5e | ||
|
4c023b7d2f | ||
|
ceb5dc6aa4 | ||
|
13fa9c7c53 | ||
|
4c946b304c | ||
|
5075c9ddbf | ||
|
8b3a916aa6 | ||
|
cd412add8f | ||
|
68851843f5 | ||
|
af8811af30 | ||
|
fa38ed5e91 | ||
|
b7ff630808 | ||
|
196256d77b | ||
|
79cd3a7f0a | ||
|
f0f45673b1 | ||
|
86cd7c1be0 | ||
|
f74c6ae429 | ||
|
015b24479c | ||
|
8b904cf806 | ||
|
175e498c43 | ||
|
65908f9dfa | ||
|
3c9deb6389 | ||
|
978c1e58de | ||
|
0722dd7812 | ||
|
ff34afb4e3 | ||
|
bd607b6c54 | ||
|
81f7e3f8f4 | ||
|
798ca62190 | ||
|
f2631cda74 | ||
|
4813698a9a | ||
|
dc80d19a08 | ||
|
1b0517efc5 | ||
|
e6a8a41c31 | ||
|
193beda2bc |
@@ -179,7 +179,7 @@ if( NOT BUILD_WITH_QT4 )
|
||||
set(HAVE_X11 FALSE)
|
||||
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 )
|
||||
# We need this to find the paths to qdbusxml2cpp and co
|
||||
@@ -228,6 +228,10 @@ endif()
|
||||
if( NOT Qt5Core_DIR )
|
||||
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")
|
||||
if( BUILD_GUI )
|
||||
list(APPEND NEEDED_QT4_COMPONENTS "QtGui" "QtWebkit" "QtUiTools" "QtSvg")
|
||||
|
@@ -1,6 +1,7 @@
|
||||
Version 0.9.0:
|
||||
* Resolved various playback issues by switching to a new audio engine.
|
||||
* Fixed collection sorting.
|
||||
* Fixed volume/mute state not being reset correctly on startup.
|
||||
|
||||
Version 0.8.4:
|
||||
* Fixed drag & drop issues on sidebar.
|
||||
|
@@ -3,8 +3,6 @@
|
||||
set( TOMAHAWK_QT5 @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
|
||||
find_package(Qt5Core REQUIRED)
|
||||
find_package(Qt5Concurrent REQUIRED)
|
||||
|
@@ -46,7 +46,7 @@ CERT_SIGNER=$2
|
||||
cd ..
|
||||
if [ -f ~/sign_step.sh ];
|
||||
then
|
||||
~/sign_step.sh "$CERT_SIGNER" "${TARGET_NAME}.app" || true
|
||||
~/sign_step.sh "$CERT_SIGNER" "${TARGET_NAME}.app"
|
||||
fi
|
||||
|
||||
header "Creating DMG"
|
||||
|
@@ -9,19 +9,20 @@ fi
|
||||
|
||||
rm -rvf vlc/
|
||||
|
||||
VLC_TARBALL="vlc.tar.bz2"
|
||||
|
||||
echo "Download phonon archive..."
|
||||
# wget -c "http://downloads.sourceforge.net/project/vlc/1.1.9/win32/vlc-1.1.9-win32.7z?r=http%3A%2F%2Fwww.videolan.org%2Fvlc%2Fdownload-windows.html&ts=1306272584&use_mirror=leaseweb"
|
||||
# wget -c "http://download.tomahawk-player.org/tomahawk-vlc-0.1.zip"
|
||||
# wget -c http://people.videolan.org/~jb/phonon/phonon-vlc-last.7z
|
||||
# wget -c http://people.videolan.org/~jb/phonon/phonon_phonon-vlc_20111128.7z
|
||||
wget -c http://download.tomahawk-player.org/test/vlc.tar.bz2
|
||||
wget -c "http://download.tomahawk-player.org/test/$VLC_TARBALL"
|
||||
|
||||
echo "Extract binary..."
|
||||
# 7z x phonon*.7z
|
||||
# mv -v vlc-*/ vlc/
|
||||
# unzip tomahawk-vlc-0.1.zip
|
||||
tar xvjf vlc.tar.bz2
|
||||
tar xvjf "$VLC_TARBALL"
|
||||
|
||||
# echo "Download phonon_vlc_no_video.dll..."
|
||||
# wget -c http://people.videolan.org/~jb/phonon/phonon_vlc_no_video.dll
|
||||
@@ -72,7 +73,9 @@ rm -rvf \
|
||||
**/libi420* \
|
||||
**/libi422* \
|
||||
mux/ \
|
||||
stream_filter/ \
|
||||
stream_filter/*dash* \
|
||||
stream_filter/*smooth* \
|
||||
stream_filter/*record* \
|
||||
**/libtheora_plugin* \
|
||||
**/liblibbluray_plugin* \
|
||||
**/libdtv_plugin* \
|
||||
|
13
data/images/folder.svg
Normal file
13
data/images/folder.svg
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg width="86px" height="86px" viewBox="0 0 86 86" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:sketch="http://www.bohemiancoding.com/sketch/ns">
|
||||
<title>folder</title>
|
||||
<description>Created with Sketch (http://www.bohemiancoding.com/sketch)</description>
|
||||
<defs></defs>
|
||||
<g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" sketch:type="MSPage">
|
||||
<g id="folder" sketch:type="MSLayerGroup" transform="translate(0.000000, 13.000000)" fill="#000000">
|
||||
<g id="Page-1" sketch:type="MSShapeGroup">
|
||||
<path d="M84.1450038,10.4833376 C82.8248024,9.1092149 80.9427764,8.3195294 78.9789985,8.3195294 L72.233622,8.3195294 L34.4730823,8.3195294 L34.4730823,7.0184614 C34.4730823,3.1483061 31.3247762,0 27.4563602,0 L10.1441555,0 C6.27226058,0 3.12569415,3.1500456 3.12569415,7.0184614 L3.12569415,9.4918821 C1.2088801,10.761641 0,12.9237099 0,15.3362515 L0,54.4987445 C0,54.5057021 0,54.5178779 0.0017394,54.5265748 L0,54.5439688 C0,58.3897726 3.14656684,61.5154666 7.0184614,61.5154666 L72.2336242,61.5154666 C72.4736608,61.5154666 72.7102186,61.5050302 72.9432977,61.4789393 C72.9850432,61.4771999 73.028528,61.4650241 73.0702735,61.4615453 C73.2616071,61.4389332 73.4529406,61.4145816 73.6390559,61.3745755 C73.6686257,61.3693573 73.6947166,61.3606604 73.7242863,61.3519634 C73.9225774,61.3119573 74.1208685,61.2597754 74.3139414,61.200636 C74.3243778,61.1954178 74.3348142,61.191939 74.3452506,61.1884602 C76.756053,60.4300837 78.5998126,58.4123847 79.1059765,55.9198305 C79.1077159,55.912873 79.1077159,55.9024366 79.1077159,55.895479 C79.1512008,55.6937091 79.18251,55.4919392 79.2051221,55.2797329 C79.2103403,55.2240723 79.2155585,55.1684116 79.2190373,55.1092721 C79.2277343,55.0136054 79.2433888,54.9266356 79.2451282,54.8309688 L85.9539776,15.7937099 L85.9939837,15.4127822 C86.0705187,13.5587047 85.4147685,11.8086925 84.1450038,10.4833376 C84.1450038,10.4833376 85.4147685,11.8086925 84.1450038,10.4833376 L84.1450038,10.4833376" id="Shape"></path>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 2.1 KiB |
@@ -42,6 +42,8 @@ Tomahawk.apiVersion = "0.2.2";
|
||||
//Statuses considered a success for HTTP request
|
||||
var httpSuccessStatuses = [200, 201];
|
||||
|
||||
Tomahawk.error = console.error;
|
||||
|
||||
// install RSVP error handler for uncaught(!) errors
|
||||
RSVP.on('error', function (reason) {
|
||||
var resolverName = "";
|
||||
@@ -49,9 +51,9 @@ RSVP.on('error', function (reason) {
|
||||
resolverName = Tomahawk.resolver.instance.settings.name + " - ";
|
||||
}
|
||||
if (reason) {
|
||||
console.error(resolverName + 'Uncaught error:', reason);
|
||||
Tomahawk.error(resolverName + 'Uncaught error:', reason);
|
||||
} 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');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -300,13 +302,15 @@ Tomahawk.Resolver = {
|
||||
},
|
||||
|
||||
_adapter_testConfig: function (config) {
|
||||
return RSVP.Promise.resolve(this.testConfig(config)).then(function () {
|
||||
return {result: Tomahawk.ConfigTestResultType.Success};
|
||||
return RSVP.Promise.resolve(this.testConfig(config)).then(function (results) {
|
||||
results = results || Tomahawk.ConfigTestResultType.Success;
|
||||
return results;
|
||||
}, function (error) {
|
||||
return error;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// help functions
|
||||
|
||||
Tomahawk.valueForSubNode = function (node, tag) {
|
||||
@@ -377,48 +381,6 @@ Tomahawk.retrievedMetadata = function (metadataId, metadata, error) {
|
||||
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
|
||||
* (like tomahawk-android) can inject their own logic that determines whether or not to do a request
|
||||
@@ -433,9 +395,9 @@ var shouldDoNativeRequest = function (options) {
|
||||
|| extraHeaders.hasOwnProperty("User-Agent")));
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Possible options:
|
||||
* - url: The URL to call
|
||||
* - method: The HTTP request method (default: GET)
|
||||
* - username: The username for HTTP Basic Auth
|
||||
* - password: The password for HTTP Basic Auth
|
||||
@@ -453,7 +415,12 @@ var doRequest = function(options) {
|
||||
return this.responseHeaders;
|
||||
};
|
||||
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;
|
||||
@@ -745,7 +712,6 @@ Tomahawk.base64Encode = function (b) {
|
||||
return window.btoa(b);
|
||||
};
|
||||
|
||||
|
||||
Tomahawk.PluginManager = {
|
||||
wrapperPrefix: '_adapter_',
|
||||
objects: {},
|
||||
@@ -776,8 +742,6 @@ Tomahawk.PluginManager = {
|
||||
methodName = this.wrapperPrefix + methodName;
|
||||
}
|
||||
|
||||
|
||||
var pluginManager = this;
|
||||
if (!this.objects[objectId]) {
|
||||
Tomahawk.log("Object not found! objectId: " + objectId + " methodName: " + methodName);
|
||||
} else {
|
||||
@@ -798,20 +762,21 @@ Tomahawk.PluginManager = {
|
||||
invoke: function (requestId, objectId, methodName, params) {
|
||||
RSVP.Promise.resolve(this.invokeSync(requestId, objectId, methodName, params))
|
||||
.then(function (result) {
|
||||
Tomahawk.reportScriptJobResults({
|
||||
var params = {
|
||||
requestId: requestId,
|
||||
data: result
|
||||
});
|
||||
};
|
||||
Tomahawk.reportScriptJobResults(encodeParamsToNativeFunctions(params));
|
||||
}, function (error) {
|
||||
Tomahawk.reportScriptJobResults({
|
||||
var params = {
|
||||
requestId: requestId,
|
||||
error: error
|
||||
});
|
||||
};
|
||||
Tomahawk.reportScriptJobResults(encodeParamsToNativeFunctions(params));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
var encodeParamsToNativeFunctions = function(param) {
|
||||
return param;
|
||||
};
|
||||
@@ -825,7 +790,7 @@ Tomahawk.NativeScriptJobManager = {
|
||||
var requestId = this.idCounter++;
|
||||
var deferred = RSVP.defer();
|
||||
this.deferreds[requestId] = deferred;
|
||||
Tomahawk.invokeNativeScriptJob(requestId, methodName, encodeParamsToNativeFunctions(params));;
|
||||
Tomahawk.invokeNativeScriptJob(requestId, methodName, encodeParamsToNativeFunctions(params));
|
||||
return deferred.promise;
|
||||
},
|
||||
reportNativeScriptJobResult: function(requestId, result) {
|
||||
@@ -1494,9 +1459,7 @@ Tomahawk.Collection = {
|
||||
return new RSVP.Promise(function (resolve, reject) {
|
||||
that.cachedDbs[id].changeVersion(that.cachedDbs[id].version, "", null,
|
||||
function (err) {
|
||||
if (console.error) {
|
||||
console.error("Error!: %o", err);
|
||||
}
|
||||
Tomahawk.error("Error trying to change db version!", err);
|
||||
reject();
|
||||
}, function () {
|
||||
delete that.cachedDbs[id];
|
||||
|
BIN
data/sounds/silence.ogg
Normal file
BIN
data/sounds/silence.ogg
Normal file
Binary file not shown.
@@ -3,6 +3,7 @@
|
||||
<file>data/images/collection_background.png</file>
|
||||
<file>data/images/playlist_background.png</file>
|
||||
<file>data/images/filter.svg</file>
|
||||
<file>data/images/folder.svg</file>
|
||||
<file>data/images/loved.svg</file>
|
||||
<file>data/images/love.svg</file>
|
||||
<file>data/images/not-loved.svg</file>
|
||||
@@ -169,5 +170,6 @@
|
||||
<file>data/images/downloadbutton.svg</file>
|
||||
<file>data/images/nav-back.svg</file>
|
||||
<file>data/images/nav-forward.svg</file>
|
||||
<file>data/sounds/silence.ogg</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
@@ -24,6 +24,7 @@ tomahawk_add_library(${TOMAHAWK_PLAYDARAPI_LIBRARY_TARGET}
|
||||
qtcertificateaddon
|
||||
${GNUTLS_LIBRARIES}
|
||||
EXPORT TomahawkLibraryDepends
|
||||
EXPORT_MACRO TOMAHAWK_WIDGETS_EXPORT_PRO
|
||||
VERSION ${TOMAHAWK_VERSION_SHORT}
|
||||
)
|
||||
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef TOMAHAWK_PLAYDARAPI_EXPORT
|
||||
# if defined (tomahawk_playdarapi_EXPORTS)
|
||||
# if defined (TOMAHAWK_WIDGETS_EXPORT_PRO)
|
||||
# define TOMAHAWK_PLAYDARAPI_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define TOMAHAWK_PLAYDARAPI_EXPORT Q_DECL_IMPORT
|
||||
|
@@ -13,5 +13,6 @@ tomahawk_add_library(${TOMAHAWK_WIDGETS_LIBRARY_TARGET}
|
||||
SOURCES ${${TOMAHAWK_WIDGETS_LIBRARY_TARGET}_SOURCES}
|
||||
UI ${${TOMAHAWK_WIDGETS_LIBRARY_TARGET}_UI}
|
||||
EXPORT TomahawkLibraryDepends
|
||||
EXPORT_MACRO TOMAHAWK_WIDGETS_EXPORT_PRO
|
||||
VERSION ${TOMAHAWK_VERSION_SHORT}
|
||||
)
|
||||
|
@@ -23,7 +23,7 @@
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
#ifndef TOMAHAWK_WIDGETS_EXPORT
|
||||
# if defined (tomahawk_widgets_EXPORTS)
|
||||
# if defined (TOMAHAWK_WIDGETS_EXPORT_PRO)
|
||||
# define TOMAHAWK_WIDGETS_EXPORT Q_DECL_EXPORT
|
||||
# else
|
||||
# define TOMAHAWK_WIDGETS_EXPORT Q_DECL_IMPORT
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <QReadWriteLock>
|
||||
#include <QPixmapCache>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -75,6 +76,7 @@ Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCr
|
||||
}
|
||||
|
||||
album_ptr album = album_ptr( new Album( name, artist ), &Album::deleteLater );
|
||||
album->moveToThread( QCoreApplication::instance()->thread() );
|
||||
album->setWeakRef( album.toWeakRef() );
|
||||
album->loadId( autoCreate );
|
||||
s_albumsByName.insert( key, album );
|
||||
|
@@ -36,6 +36,7 @@
|
||||
|
||||
#include <QReadWriteLock>
|
||||
#include <QPixmapCache>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -109,6 +110,7 @@ Artist::get( unsigned int id, const QString& name )
|
||||
}
|
||||
|
||||
artist_ptr a = artist_ptr( new Artist( id, name ), &Artist::deleteLater );
|
||||
a->moveToThread( QCoreApplication::instance()->thread() );
|
||||
a->setWeakRef( a.toWeakRef() );
|
||||
s_artistsByName.insert( key, a );
|
||||
|
||||
|
@@ -146,6 +146,7 @@ set( libGuiSources
|
||||
widgets/ClickableLabel.cpp
|
||||
widgets/ComboBox.cpp
|
||||
widgets/DropDownButton.cpp
|
||||
widgets/DownloadButton.cpp
|
||||
widgets/ElidedLabel.cpp
|
||||
widgets/FilterHeader.cpp
|
||||
widgets/CaptionLabel.cpp
|
||||
|
@@ -37,6 +37,9 @@
|
||||
#include "utils/ImageRegistry.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QDesktopServices>
|
||||
#include <QFileInfo>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
@@ -51,7 +54,7 @@ ContextMenu::ContextMenu( QWidget* parent )
|
||||
m_sigmap = new QSignalMapper( this );
|
||||
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) );
|
||||
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionPlaylist | ActionCopyLink | ActionLove | ActionStopAfter | ActionPage | ActionEditMetadata | ActionSend;
|
||||
clear();
|
||||
}
|
||||
|
||||
|
||||
@@ -69,7 +72,7 @@ ContextMenu::clear()
|
||||
m_albums.clear();
|
||||
m_artists.clear();
|
||||
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionPlaylist | ActionCopyLink | ActionLove | ActionStopAfter | ActionPage | ActionEditMetadata | ActionSend;
|
||||
m_supportedActions = ActionPlay | ActionQueue | ActionPlaylist | ActionCopyLink | ActionLove | ActionStopAfter | ActionPage | ActionEditMetadata | ActionSend | ActionOpenFileManager;
|
||||
}
|
||||
|
||||
|
||||
@@ -216,10 +219,23 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "&Copy Track Link" ) ), ActionCopyLink );
|
||||
}
|
||||
|
||||
if ( m_supportedActions & ActionOpenFileManager &&
|
||||
queries.length() == 1 &&
|
||||
queries.first()->numResults() &&
|
||||
queries.first()->results().first()->isLocal() )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( ImageRegistry::instance()->icon( RESPATH "images/folder.svg" ),
|
||||
tr( "Open Folder in File Manager..." ) ), ActionOpenFileManager );
|
||||
}
|
||||
|
||||
if ( m_supportedActions & ActionEditMetadata && itemCount() == 1 )
|
||||
{
|
||||
m_sigmap->setMapping( addAction( tr( "Properties..." ) ), ActionEditMetadata );
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
|
||||
@@ -239,6 +255,8 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
|
||||
m_sigmap->setMapping( addAction( tr( "Mark as &Listened" ) ), ActionMarkListened );
|
||||
}
|
||||
|
||||
addSeparator();
|
||||
|
||||
if ( m_supportedActions & ActionDelete )
|
||||
m_sigmap->setMapping( addAction( queries.count() > 1 ? tr( "&Remove Items" ) : tr( "&Remove Item" ) ), ActionDelete );
|
||||
|
||||
@@ -394,6 +412,15 @@ ContextMenu::onTriggered( int action )
|
||||
}
|
||||
break;
|
||||
|
||||
case ActionOpenFileManager:
|
||||
{
|
||||
result_ptr result = m_queries.first()->results().first();
|
||||
QString path = QFileInfo( result->url() ).path();
|
||||
tLog() << Q_FUNC_INFO << "open directory" << path;
|
||||
QDesktopServices::openUrl( path );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
emit triggered( action );
|
||||
}
|
||||
|
@@ -37,21 +37,22 @@ Q_OBJECT
|
||||
public:
|
||||
enum MenuActions
|
||||
{
|
||||
ActionPlay = 1,
|
||||
ActionQueue = 2,
|
||||
ActionDelete = 4,
|
||||
ActionCopyLink = 8,
|
||||
ActionLove = 16,
|
||||
ActionStopAfter = 32,
|
||||
ActionPage = 64,
|
||||
ActionTrackPage = 128,
|
||||
ActionArtistPage = 256,
|
||||
ActionAlbumPage = 512,
|
||||
ActionEditMetadata = 1024,
|
||||
ActionPlaylist = 2048,
|
||||
ActionSend = 4096,
|
||||
ActionMarkListened = 8192,
|
||||
ActionDownload = 16384
|
||||
ActionPlay = 1,
|
||||
ActionQueue = 2,
|
||||
ActionDelete = 4,
|
||||
ActionCopyLink = 8,
|
||||
ActionLove = 16,
|
||||
ActionStopAfter = 32,
|
||||
ActionPage = 64,
|
||||
ActionTrackPage = 128,
|
||||
ActionArtistPage = 256,
|
||||
ActionAlbumPage = 512,
|
||||
ActionEditMetadata = 1024,
|
||||
ActionPlaylist = 2048,
|
||||
ActionSend = 4096,
|
||||
ActionMarkListened = 8192,
|
||||
ActionDownload = 16384,
|
||||
ActionOpenFileManager = 32768
|
||||
};
|
||||
|
||||
explicit ContextMenu( QWidget* parent = 0 );
|
||||
|
@@ -118,7 +118,7 @@ DownloadJob::localFile() const
|
||||
|
||||
|
||||
QString
|
||||
DownloadJob::localPath() const
|
||||
DownloadJob::localPath( const Tomahawk::album_ptr& album )
|
||||
{
|
||||
QDir dir = TomahawkSettings::instance()->downloadsPath();
|
||||
|
||||
@@ -127,7 +127,7 @@ DownloadJob::localPath() const
|
||||
dir.mkpath( "." );
|
||||
}
|
||||
|
||||
QString path = QString( "%1/%2" ).arg( safeEncode( m_track->artist(), true ) ).arg( safeEncode( m_track->album(), true ) );
|
||||
QString path = QString( "%1/%2" ).arg( safeEncode( album->artist()->name(), true ) ).arg( safeEncode( album->name(), true ) );
|
||||
dir.mkpath( path );
|
||||
|
||||
return QString( dir.path() + "/" + path ).replace( "//", "/" );
|
||||
@@ -138,7 +138,7 @@ QUrl
|
||||
DownloadJob::prepareFilename()
|
||||
{
|
||||
QString filename = QString( "%1. %2.%3" ).arg( m_track->albumpos() ).arg( safeEncode( m_track->track() ) ).arg( m_format.extension );
|
||||
QString path = localPath();
|
||||
QString path = localPath( m_track->albumPtr() );
|
||||
QString localFile = QString( path + "/" + filename );
|
||||
|
||||
if ( !m_tryResuming )
|
||||
@@ -444,7 +444,7 @@ DownloadJob::checkForResumedFile()
|
||||
|
||||
|
||||
QString
|
||||
DownloadJob::safeEncode( const QString& filename, bool removeTrailingDots ) const
|
||||
DownloadJob::safeEncode( const QString& filename, bool removeTrailingDots )
|
||||
{
|
||||
//FIXME: make it a regexp
|
||||
QString res = QString( filename ).toLatin1().replace( "/", "_" ).replace( "\\", "_" )
|
||||
|
@@ -58,7 +58,7 @@ public:
|
||||
long receivedSize() const { return m_rcvdSize; }
|
||||
long fileSize() const { return m_fileSize; }
|
||||
|
||||
QString localPath() const;
|
||||
static QString localPath( const Tomahawk::album_ptr& album );
|
||||
QString localFile() const;
|
||||
DownloadFormat format() const;
|
||||
|
||||
@@ -90,7 +90,7 @@ private slots:
|
||||
|
||||
private:
|
||||
void storeState();
|
||||
QString safeEncode( const QString& filename, bool removeTrailingDots = false ) const;
|
||||
static QString safeEncode( const QString& filename, bool removeTrailingDots = false );
|
||||
bool checkForResumedFile();
|
||||
QUrl prepareFilename();
|
||||
|
||||
|
@@ -24,6 +24,8 @@
|
||||
#include "TomahawkSettings.h"
|
||||
#include "infosystem/InfoSystem.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "Result.h"
|
||||
#include "Query.h"
|
||||
|
||||
DownloadManager* DownloadManager::s_instance = 0;
|
||||
|
||||
@@ -85,6 +87,36 @@ DownloadManager::localFileForDownload( const QString& url ) const
|
||||
}
|
||||
|
||||
|
||||
QUrl
|
||||
DownloadManager::localUrlForDownload( const Tomahawk::query_ptr& query ) const
|
||||
{
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result )
|
||||
{
|
||||
return localUrlForDownload( result );
|
||||
}
|
||||
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
|
||||
QUrl
|
||||
DownloadManager::localUrlForDownload( const Tomahawk::result_ptr& result ) const
|
||||
{
|
||||
if ( result && !result->downloadFormats().isEmpty() &&
|
||||
!localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
return QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ) ).absolutePath() );
|
||||
}
|
||||
else if ( result && result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
return QUrl::fromLocalFile( QFileInfo( result->downloadJob()->localFile() ).absolutePath() );
|
||||
}
|
||||
|
||||
return QUrl();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadManager::storeJobs( const QList<downloadjob_ptr>& jobs )
|
||||
{
|
||||
|
@@ -45,6 +45,8 @@ public:
|
||||
|
||||
void storeJobs( const QList<downloadjob_ptr>& jobs );
|
||||
QString localFileForDownload( const QString& url ) const;
|
||||
QUrl localUrlForDownload( const Tomahawk::result_ptr& result ) const;
|
||||
QUrl localUrlForDownload( const Tomahawk::query_ptr& query ) const;
|
||||
|
||||
public slots:
|
||||
bool addJob( const downloadjob_ptr& job );
|
||||
|
@@ -980,7 +980,7 @@ DropJob::removeRemoteSources()
|
||||
|
||||
foreach ( const Tomahawk::result_ptr& result, item->results() )
|
||||
{
|
||||
if ( !result->resolvedByCollection().isNull() && !result->resolvedByCollection()->isLocal() )
|
||||
if ( !result->isLocal() )
|
||||
{
|
||||
list.append( item );
|
||||
break;
|
||||
|
@@ -1,14 +1,14 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -20,7 +20,6 @@
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include "GlobalActionManager.h"
|
||||
|
||||
#include "accounts/AccountManager.h"
|
||||
|
@@ -1,21 +1,21 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef GLOBALACTIONMANAGER_H
|
||||
#define GLOBALACTIONMANAGER_H
|
||||
|
@@ -36,7 +36,7 @@
|
||||
#define MAX_CONCURRENT_QUERIES 16
|
||||
#define CLEANUP_TIMEOUT 5 * 60 * 1000
|
||||
#define MINSCORE 0.5
|
||||
#define DEFAULT_RESOLVER_TIMEOUT 5000 //5 seconds
|
||||
#define DEFAULT_RESOLVER_TIMEOUT 5000 // 5 seconds
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -542,12 +542,12 @@ Pipeline::shuntNext()
|
||||
q->setCurrentResolver( 0 );
|
||||
}
|
||||
|
||||
//Zero-patient, a stub so that query is not resolved until we go through
|
||||
//all resolvers
|
||||
//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
|
||||
//we kick off all our resolvers' entry
|
||||
//once we kick off all resolvers we'll remove this entry
|
||||
// Zero-patient, a stub so that query is not resolved until we go through
|
||||
// all resolvers
|
||||
// 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
|
||||
// we kick off all our resolvers' entry
|
||||
// once we kick off all resolvers we'll remove this entry
|
||||
incQIDState( q, nullptr );
|
||||
checkQIDState( q );
|
||||
}
|
||||
@@ -673,7 +673,7 @@ Pipeline::decQIDState( const Tomahawk::query_ptr& query, Tomahawk::Resolver* r )
|
||||
{
|
||||
{
|
||||
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 );
|
||||
|
@@ -33,6 +33,7 @@
|
||||
|
||||
#include <QtAlgorithms>
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@@ -47,6 +48,7 @@ Query::get( const QString& artist, const QString& track, const QString& album, c
|
||||
autoResolve = false;
|
||||
|
||||
query_ptr q = query_ptr( new Query( Track::get( artist, track, album ), qid, autoResolve ), &QObject::deleteLater );
|
||||
q->moveToThread( QCoreApplication::instance()->thread() );
|
||||
q->setWeakRef( q.toWeakRef() );
|
||||
|
||||
if ( autoResolve )
|
||||
@@ -399,7 +401,7 @@ Query::resultSorter( const result_ptr& left, const result_ptr& right )
|
||||
|
||||
if ( ls == rs )
|
||||
{
|
||||
if ( right->resolvedByCollection() && right->resolvedByCollection()->isLocal() )
|
||||
if ( right->isLocal() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -35,6 +35,8 @@
|
||||
#include "Track.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
static QHash< QString, result_wptr > s_results;
|
||||
@@ -69,6 +71,7 @@ Result::get( const QString& url, const track_ptr& track )
|
||||
}
|
||||
|
||||
result_ptr r = result_ptr( new Result( url, track ), &Result::deleteLater );
|
||||
r->moveToThread( QCoreApplication::instance()->thread() );
|
||||
r->setWeakRef( r.toWeakRef() );
|
||||
s_results.insert( url, r );
|
||||
|
||||
@@ -132,21 +135,25 @@ Result::deleteLater()
|
||||
void
|
||||
Result::onResolverRemoved( Tomahawk::Resolver* resolver )
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
m_mutex.lock();
|
||||
|
||||
if ( m_resolver.data() == resolver )
|
||||
{
|
||||
m_resolver = 0;
|
||||
m_mutex.unlock();
|
||||
|
||||
emit statusChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
collection_ptr
|
||||
Result::resolvedByCollection() const
|
||||
{
|
||||
QMutexLocker lock( &m_mutex );
|
||||
|
||||
return m_collection;
|
||||
}
|
||||
|
||||
@@ -227,6 +234,13 @@ Result::playable() const
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
Result::isLocal() const
|
||||
{
|
||||
return resolvedByCollection().isNull() ? false : resolvedByCollection()->isLocal();
|
||||
}
|
||||
|
||||
|
||||
QVariant
|
||||
Result::toVariant() const
|
||||
{
|
||||
@@ -323,11 +337,9 @@ Result::onOffline()
|
||||
|
||||
|
||||
void
|
||||
Result::setResolvedByCollection( const Tomahawk::collection_ptr& collection , bool emitOnlineEvents )
|
||||
Result::setResolvedByCollection( const Tomahawk::collection_ptr& collection, bool emitOnlineEvents )
|
||||
{
|
||||
m_mutex.lock();
|
||||
m_collection = collection;
|
||||
m_mutex.unlock();
|
||||
|
||||
if ( emitOnlineEvents )
|
||||
{
|
||||
|
@@ -94,6 +94,12 @@ public:
|
||||
bool isOnline() const;
|
||||
bool playable() const;
|
||||
|
||||
/**
|
||||
* @brief whether this result isLocal, i.e. resolved by a local collection
|
||||
* @return isLocal
|
||||
*/
|
||||
bool isLocal() const;
|
||||
|
||||
QString url() const;
|
||||
/**
|
||||
* Has the given url been checked that it is accessible/valid.
|
||||
|
@@ -929,6 +929,20 @@ TomahawkSettings::setVolume( unsigned int volume )
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
TomahawkSettings::muted() const
|
||||
{
|
||||
return value( "audio/muted" ).toBool();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkSettings::setMuted( bool muted )
|
||||
{
|
||||
setValue( "audio/muted", muted );
|
||||
}
|
||||
|
||||
|
||||
QString
|
||||
TomahawkSettings::proxyHost() const
|
||||
{
|
||||
|
@@ -107,6 +107,9 @@ public:
|
||||
unsigned int volume() const;
|
||||
void setVolume( unsigned int volume );
|
||||
|
||||
bool muted() const;
|
||||
void setMuted( bool muted );
|
||||
|
||||
/// Playlist stuff
|
||||
QByteArray playlistColumnSizes( const QString& playlistid ) const;
|
||||
void setPlaylistColumnSizes( const QString& playlistid, const QByteArray& state );
|
||||
|
@@ -37,6 +37,7 @@
|
||||
#include <QtAlgorithms>
|
||||
#include <QDateTime>
|
||||
#include <QReadWriteLock>
|
||||
#include <QCoreApplication>
|
||||
|
||||
|
||||
using namespace Tomahawk;
|
||||
@@ -92,6 +93,7 @@ Track::get( const QString& artist, const QString& track, const QString& album, c
|
||||
}
|
||||
|
||||
track_ptr t = track_ptr( new Track( artist, track, album, albumArtist, duration, composer, albumpos, discnumber ), &Track::deleteLater );
|
||||
t->moveToThread( QCoreApplication::instance()->thread() );
|
||||
t->setWeakRef( t.toWeakRef() );
|
||||
s_tracksByName.insert( key, t );
|
||||
|
||||
|
@@ -19,8 +19,7 @@
|
||||
|
||||
#include "TrackData.h"
|
||||
|
||||
#include <QtAlgorithms>
|
||||
#include <QReadWriteLock>
|
||||
|
||||
|
||||
#include "audio/AudioEngine.h"
|
||||
#include "collection/Collection.h"
|
||||
@@ -41,6 +40,10 @@
|
||||
#include "PlaylistEntry.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
#include <QtAlgorithms>
|
||||
#include <QReadWriteLock>
|
||||
#include <QCoreApplication>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
QHash< QString, trackdata_wptr > TrackData::s_trackDatasByName = QHash< QString, trackdata_wptr >();
|
||||
@@ -84,6 +87,7 @@ TrackData::get( unsigned int id, const QString& artist, const QString& track )
|
||||
}
|
||||
|
||||
trackdata_ptr t = trackdata_ptr( new TrackData( id, artist, track ), &TrackData::deleteLater );
|
||||
t->moveToThread( QCoreApplication::instance()->thread() );
|
||||
t->setWeakRef( t.toWeakRef() );
|
||||
s_trackDatasByName.insert( key, t );
|
||||
|
||||
|
@@ -167,7 +167,7 @@ signals:
|
||||
void connectionStateChanged( Tomahawk::Accounts::Account::ConnectionState state );
|
||||
|
||||
void configurationChanged();
|
||||
void configTestResult( Tomahawk::Accounts::ConfigTestResultType );
|
||||
void configTestResult( int, const QString& = QString() );
|
||||
|
||||
protected:
|
||||
virtual void loadFromConfig( const QString &accountId );
|
||||
|
@@ -68,6 +68,7 @@ DelegateConfigWrapper::DelegateConfigWrapper( Tomahawk::Accounts::Account* accou
|
||||
h->setContentsMargins( m_widget->contentsMargins() );
|
||||
|
||||
m_errorLabel->setAlignment( Qt::AlignCenter );
|
||||
m_errorLabel->setWordWrap( true );
|
||||
v->addWidget( m_errorLabel );
|
||||
|
||||
v->addLayout( h );
|
||||
@@ -81,7 +82,7 @@ DelegateConfigWrapper::DelegateConfigWrapper( Tomahawk::Accounts::Account* accou
|
||||
if ( m_widget->metaObject()->indexOfSignal( "sizeHintChanged()" ) > -1 )
|
||||
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& ) ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -192,11 +193,11 @@ DelegateConfigWrapper::aboutClicked( bool )
|
||||
|
||||
|
||||
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();
|
||||
closeDialog( QDialog::Accepted );
|
||||
@@ -226,8 +227,25 @@ DelegateConfigWrapper::onConfigTestResult( Tomahawk::Accounts::ConfigTestResultT
|
||||
|
||||
m_invalidData = m_widget->readData();
|
||||
|
||||
// TODO: generate message based on status code
|
||||
m_errorLabel->setText( QString( "<font color='red'>%1</font>" ).arg( tr( "Your config is invalid." ) ) );
|
||||
QString msg = !message.isEmpty() ? message : getTestConfigMessage( code );
|
||||
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:
|
||||
void aboutClicked( bool );
|
||||
void onConfigTestResult( Tomahawk::Accounts::ConfigTestResultType );
|
||||
void onConfigTestResult( int, const QString& );
|
||||
|
||||
private:
|
||||
void closeDialog( QDialog::DialogCode code );
|
||||
QString getTestConfigMessage( int code );
|
||||
|
||||
Tomahawk::Accounts::Account* m_account;
|
||||
AccountConfigWidget* m_widget;
|
||||
|
@@ -542,7 +542,7 @@ ResolverAccount::testConfig()
|
||||
{
|
||||
QVariantMap data = resolver->loadDataFromWidgets();
|
||||
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();
|
||||
}
|
||||
else
|
||||
@@ -560,18 +560,17 @@ ResolverAccount::resolver() const
|
||||
|
||||
|
||||
void
|
||||
ResolverAccount::onTestConfig( const QVariantMap& result )
|
||||
ResolverAccount::onTestConfig( const QVariant& result )
|
||||
{
|
||||
tLog() << Q_FUNC_INFO << result;
|
||||
|
||||
int resultCode = result[ "result" ].toInt();
|
||||
if ( resultCode == 1 )
|
||||
if ( result.type() == QVariant::String )
|
||||
{
|
||||
emit configTestResult( Accounts::ConfigTestResultSuccess );
|
||||
emit configTestResult( Accounts::ConfigTestResultOther, result.toString() );
|
||||
}
|
||||
else
|
||||
{
|
||||
emit configTestResult( Accounts::ConfigTestResultOther );
|
||||
emit configTestResult( result.toInt() );
|
||||
}
|
||||
|
||||
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 )
|
||||
: ResolverAccount( accountId, path, initialConfiguration )
|
||||
, m_atticaId( atticaId )
|
||||
@@ -619,8 +619,6 @@ AtticaResolverAccount::init()
|
||||
loadIcon();
|
||||
else
|
||||
connect( AtticaManager::instance(), SIGNAL( resolversLoaded( Attica::Content::List ) ), this, SLOT( loadIcon() ) );
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@@ -110,7 +110,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void resolverChanged();
|
||||
void onTestConfig( const QVariantMap& result );
|
||||
void onTestConfig( const QVariant& result );
|
||||
|
||||
protected:
|
||||
// Created by factory, when user installs a new resolver
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
*
|
||||
@@ -165,12 +165,19 @@ AudioEngine::AudioEngine()
|
||||
d->s_instance = this;
|
||||
tDebug() << "Init AudioEngine";
|
||||
|
||||
d->audioOutput = new AudioOutput(this);
|
||||
d->audioOutput = new AudioOutput( this );
|
||||
|
||||
connect( d->audioOutput, SIGNAL( initialized() ), this, SIGNAL( initialized() ) );
|
||||
connect( d->audioOutput, SIGNAL( stateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ), d_func(), SLOT( onStateChanged( AudioOutput::AudioState, AudioOutput::AudioState ) ) );
|
||||
connect( d->audioOutput, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) );
|
||||
connect( d->audioOutput, SIGNAL( positionChanged( float ) ), SLOT( onPositionChanged( float ) ) );
|
||||
connect( d->audioOutput, SIGNAL( volumeChanged( qreal ) ), SLOT( onVolumeChanged( qreal ) ) );
|
||||
connect( d->audioOutput, SIGNAL( mutedChanged( bool ) ), SIGNAL( mutedChanged( bool ) ) );
|
||||
|
||||
if ( TomahawkSettings::instance()->muted() )
|
||||
{
|
||||
mute();
|
||||
}
|
||||
setVolume( TomahawkSettings::instance()->volume() );
|
||||
|
||||
qRegisterMetaType< AudioErrorCode >("AudioErrorCode");
|
||||
@@ -183,6 +190,7 @@ AudioEngine::~AudioEngine()
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
TomahawkSettings::instance()->setVolume( volume() );
|
||||
TomahawkSettings::instance()->setMuted( isMuted() );
|
||||
|
||||
delete d_ptr;
|
||||
}
|
||||
@@ -289,8 +297,11 @@ AudioEngine::stop( AudioErrorCode errorCode )
|
||||
if ( d->waitingOnNewTrack )
|
||||
sendWaitingNotification();
|
||||
|
||||
Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
|
||||
if ( d->audioOutput->isInitialized() )
|
||||
{
|
||||
Tomahawk::InfoSystem::InfoPushData pushData( s_aeInfoIdentifier, Tomahawk::InfoSystem::InfoNowStopped, QVariant(), Tomahawk::InfoSystem::PushNoFlag );
|
||||
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo( pushData );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -455,6 +466,8 @@ AudioEngine::mute()
|
||||
{
|
||||
Q_D( AudioEngine );
|
||||
d->audioOutput->setMuted( true );
|
||||
|
||||
emit volumeChanged( volume() );
|
||||
}
|
||||
|
||||
|
||||
@@ -463,6 +476,8 @@ AudioEngine::toggleMute()
|
||||
{
|
||||
Q_D( AudioEngine );
|
||||
d->audioOutput->setMuted( !d->audioOutput->isMuted() );
|
||||
|
||||
emit volumeChanged( volume() );
|
||||
}
|
||||
|
||||
|
||||
@@ -562,6 +577,12 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
Q_D( AudioEngine );
|
||||
tDebug( LOGEXTRA ) << Q_FUNC_INFO << ( result.isNull() ? QString() : result->url() );
|
||||
|
||||
|
||||
if ( !d->audioOutput->isInitialized() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if ( !result )
|
||||
{
|
||||
stop();
|
||||
@@ -583,6 +604,7 @@ AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
|
||||
job->start();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::gotStreamUrl( const QVariantMap& data )
|
||||
{
|
||||
@@ -590,14 +612,17 @@ AudioEngine::gotStreamUrl( const QVariantMap& data )
|
||||
QVariantMap headers = data[ "headers" ].toMap();
|
||||
Tomahawk::result_ptr result = sender()->property( "result" ).value<result_ptr>();
|
||||
|
||||
if ( streamUrl.isEmpty() || !( TomahawkUtils::isHttpResult( streamUrl ) || TomahawkUtils::isHttpsResult( streamUrl ) || TomahawkUtils::isRtmpResult( streamUrl ) ) )
|
||||
if ( streamUrl.isEmpty() || headers.isEmpty() ||
|
||||
!( TomahawkUtils::isHttpResult( streamUrl ) || TomahawkUtils::isHttpsResult( streamUrl ) ) )
|
||||
{
|
||||
// Not an http(s) or RTMP URL, get IO device
|
||||
// We can't supply custom headers to VLC - but prefer using its HTTP streaming due to improved seeking ability
|
||||
// Not an RTMP or HTTP-with-headers URL, get IO device
|
||||
QSharedPointer< QIODevice > sp;
|
||||
performLoadIODevice( result, streamUrl );
|
||||
}
|
||||
else
|
||||
{
|
||||
// We need our own QIODevice for streaming
|
||||
// TODO: just make this part of the http(s) IoDeviceFactory (?)
|
||||
QUrl url = QUrl::fromEncoded( streamUrl.toUtf8() );
|
||||
QNetworkRequest req( url );
|
||||
@@ -619,12 +644,13 @@ AudioEngine::gotStreamUrl( const QVariantMap& data )
|
||||
|
||||
tDebug() << "Creating a QNetworkReply with url:" << req.url().toString();
|
||||
NetworkReply* reply = new NetworkReply( Tomahawk::Utils::nam()->get( req ) );
|
||||
NewClosure( reply, SIGNAL( finalUrlReached() ), this, SLOT( gotRedirectedStreamUrl( Tomahawk::result_ptr, NetworkReply* )), result, reply );
|
||||
NewClosure( reply, SIGNAL( finalUrlReached() ), this, SLOT( gotRedirectedStreamUrl( Tomahawk::result_ptr, NetworkReply* ) ), result, reply );
|
||||
}
|
||||
|
||||
sender()->deleteLater();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioEngine::gotRedirectedStreamUrl( const Tomahawk::result_ptr& result, NetworkReply* reply )
|
||||
{
|
||||
@@ -951,9 +977,9 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
|
||||
void
|
||||
AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::query_ptr& query )
|
||||
{
|
||||
if ( query->resolvingFinished() )
|
||||
if ( query->resolvingFinished() || query->numResults( true ) )
|
||||
{
|
||||
if ( query->numResults() && query->results().first()->isOnline() )
|
||||
if ( query->numResults( true ) )
|
||||
{
|
||||
playItem( playlist, query->results().first(), query );
|
||||
return;
|
||||
@@ -969,7 +995,7 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
|
||||
{
|
||||
Pipeline::instance()->resolve( query );
|
||||
|
||||
NewClosure( query.data(), SIGNAL( resolvingFinished( bool ) ),
|
||||
NewClosure( query.data(), SIGNAL( resultsChanged() ),
|
||||
const_cast<AudioEngine*>(this), SLOT( playItem( Tomahawk::playlistinterface_ptr, Tomahawk::query_ptr ) ), playlist, query );
|
||||
}
|
||||
}
|
||||
|
@@ -149,6 +149,8 @@ public slots:
|
||||
void setShuffled( bool enabled );
|
||||
|
||||
signals:
|
||||
void initialized();
|
||||
|
||||
void loading( const Tomahawk::result_ptr track );
|
||||
void started( const Tomahawk::result_ptr track );
|
||||
void finished( const Tomahawk::result_ptr track );
|
||||
|
@@ -25,11 +25,13 @@
|
||||
|
||||
#include "audio/MediaStream.h"
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/TomahawkUtils.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QVarLengthArray>
|
||||
#include <QFile>
|
||||
#include <QDir>
|
||||
#include <QTimer>
|
||||
|
||||
#include <vlc/libvlc.h>
|
||||
#include <vlc/libvlc_media.h>
|
||||
@@ -58,6 +60,7 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
, m_currentTime( 0 )
|
||||
, m_totalTime( 0 )
|
||||
, m_justSeeked( false )
|
||||
, m_initialized( false )
|
||||
, dspPluginCallback( nullptr )
|
||||
, m_vlcInstance( nullptr )
|
||||
, m_vlcPlayer( nullptr )
|
||||
@@ -95,8 +98,8 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
TOMAHAWK_APPLICATION_NAME "/" TOMAHAWK_VERSION );
|
||||
// FIXME: icon is named tomahawk, so we need the lowercase application name
|
||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 1, 0, 0))
|
||||
libvlc_set_app_id( m_vlcInstance, "org.tomahawk-player.desktop",
|
||||
TOMAHAWK_VERSION, "tomahawk" );
|
||||
libvlc_set_app_id( m_vlcInstance, TOMAHAWK_APPLICATION_PACKAGE_NAME,
|
||||
TOMAHAWK_VERSION, TOMAHAWK_TARGET_NAME );
|
||||
#endif
|
||||
|
||||
m_vlcPlayer = libvlc_media_player_new( m_vlcInstance );
|
||||
@@ -120,6 +123,11 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
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 );
|
||||
@@ -128,7 +136,24 @@ AudioOutput::AudioOutput( QObject* parent )
|
||||
libvlc_event_attach( manager, events[ i ], &AudioOutput::vlcEventCallback, this );
|
||||
}
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "Init OK";
|
||||
// HACK: play silent ogg file and set volume on that to workaround vlc not allowing to set volume before a file is played
|
||||
m_silenceFile.setFileName( RESPATH "sounds/silence.ogg" );
|
||||
Q_ASSERT( m_silenceFile.exists() );
|
||||
Q_ASSERT( m_silenceFile.open( QIODevice::ReadOnly ) );
|
||||
|
||||
setCurrentSource( new MediaStream( &m_silenceFile, true ) );
|
||||
libvlc_media_player_play( m_vlcPlayer );
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(5,4,0)
|
||||
// if the silence file did not play for 15 secs, we pretend the AudioOutput is initialized, to allow proper error reporting
|
||||
QTimer::singleShot( 15000, [&]()
|
||||
{
|
||||
if ( !m_initialized ) {
|
||||
m_initialized = true;
|
||||
emit initialized();
|
||||
}
|
||||
} );
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -154,6 +179,28 @@ AudioOutput::~AudioOutput()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::onInitVlcEvent( const libvlc_event_t* event )
|
||||
{
|
||||
switch ( event->type )
|
||||
{
|
||||
case libvlc_MediaPlayerTimeChanged:
|
||||
setVolume( volume() );
|
||||
setMuted( isMuted() );
|
||||
|
||||
m_initialized = true;
|
||||
m_silenceFile.close();
|
||||
|
||||
tDebug() << Q_FUNC_INFO << "Init OK";
|
||||
emit initialized();
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AudioOutput::setAutoDelete( bool ad )
|
||||
{
|
||||
@@ -302,6 +349,13 @@ AudioOutput::setCurrentSource( MediaStream* stream )
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
AudioOutput::isInitialized() const
|
||||
{
|
||||
return m_initialized;
|
||||
}
|
||||
|
||||
|
||||
AudioOutput::AudioState
|
||||
AudioOutput::state() const
|
||||
{
|
||||
@@ -427,16 +481,19 @@ AudioOutput::seek( qint64 milliseconds )
|
||||
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 )
|
||||
{
|
||||
|
||||
// tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking" << milliseconds << "msec";
|
||||
libvlc_media_player_set_time( m_vlcPlayer, milliseconds );
|
||||
setCurrentTime( milliseconds );
|
||||
}
|
||||
else
|
||||
{
|
||||
qint64 duration = AudioEngine::instance()->currentTrackTotalTime();
|
||||
float position = float(float(milliseconds) / duration);
|
||||
libvlc_media_player_set_position(m_vlcPlayer, position);
|
||||
tDebug() << Q_FUNC_INFO << "AudioOutput:: seeking via position" << position << "pos";
|
||||
@@ -466,11 +523,9 @@ AudioOutput::setMuted( bool m )
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
|
||||
m_muted = m;
|
||||
if ( m_muted )
|
||||
{
|
||||
libvlc_audio_set_volume( m_vlcPlayer, 0 );
|
||||
}
|
||||
else
|
||||
libvlc_audio_set_mute( m_vlcPlayer, m );
|
||||
|
||||
if ( !m_muted )
|
||||
{
|
||||
libvlc_audio_set_volume( m_vlcPlayer, m_volume * 100.0 );
|
||||
}
|
||||
@@ -487,7 +542,7 @@ AudioOutput::volume() const
|
||||
void
|
||||
AudioOutput::setVolume( qreal vol )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO;
|
||||
tDebug() << Q_FUNC_INFO << vol << m_muted;
|
||||
|
||||
m_volume = vol;
|
||||
if ( !m_muted )
|
||||
@@ -531,6 +586,20 @@ AudioOutput::onVlcEvent( const libvlc_event_t* event )
|
||||
// Don't call stop() here - it will deadlock libvlc
|
||||
setState( Error );
|
||||
break;
|
||||
#if (LIBVLC_VERSION_INT >= LIBVLC_VERSION(2, 2, 2, 0))
|
||||
case libvlc_MediaPlayerAudioVolume:
|
||||
m_volume = event->u.media_player_audio_volume.volume;
|
||||
emit volumeChanged( volume() );
|
||||
break;
|
||||
case libvlc_MediaPlayerMuted:
|
||||
m_muted = true;
|
||||
emit mutedChanged( true );
|
||||
break;
|
||||
case libvlc_MediaPlayerUnmuted:
|
||||
m_muted = false;
|
||||
emit mutedChanged( false );
|
||||
break;
|
||||
#endif
|
||||
case libvlc_MediaPlayerNothingSpecial:
|
||||
case libvlc_MediaPlayerOpening:
|
||||
case libvlc_MediaPlayerBuffering:
|
||||
@@ -556,7 +625,14 @@ AudioOutput::vlcEventCallback( const libvlc_event_t* event, void* opaque )
|
||||
AudioOutput* that = reinterpret_cast < AudioOutput * > ( opaque );
|
||||
Q_ASSERT( that );
|
||||
|
||||
that->onVlcEvent( event );
|
||||
if ( !that->isInitialized() )
|
||||
{
|
||||
that->onInitVlcEvent( event );
|
||||
}
|
||||
else
|
||||
{
|
||||
that->onVlcEvent( event );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -25,6 +25,8 @@
|
||||
#include "DllMacro.h"
|
||||
#include "Typedefs.h"
|
||||
|
||||
#include <QFile>
|
||||
|
||||
#include <functional>
|
||||
|
||||
struct libvlc_instance_t;
|
||||
@@ -44,6 +46,7 @@ public:
|
||||
explicit AudioOutput( QObject* parent = nullptr );
|
||||
~AudioOutput();
|
||||
|
||||
bool isInitialized() const;
|
||||
AudioState state() const;
|
||||
|
||||
void setCurrentSource( const QUrl& stream );
|
||||
@@ -72,11 +75,16 @@ public:
|
||||
public slots:
|
||||
|
||||
signals:
|
||||
void initialized();
|
||||
void stateChanged( AudioOutput::AudioState, AudioOutput::AudioState );
|
||||
void tick( qint64 );
|
||||
void positionChanged( float );
|
||||
void volumeChanged( qreal volume );
|
||||
void mutedChanged( bool );
|
||||
|
||||
private:
|
||||
void onInitVlcEvent( const libvlc_event_t* event );
|
||||
|
||||
void setState( AudioState state );
|
||||
void setCurrentTime( qint64 time );
|
||||
void setCurrentPosition( float position );
|
||||
@@ -99,6 +107,9 @@ private:
|
||||
qint64 m_totalTime;
|
||||
bool m_justSeeked;
|
||||
|
||||
bool m_initialized;
|
||||
QFile m_silenceFile;
|
||||
|
||||
std::function< void( int state, int frameNumber, float* samples, int nb_channels, int nb_samples ) > dspPluginCallback;
|
||||
|
||||
libvlc_instance_t* m_vlcInstance;
|
||||
|
@@ -41,12 +41,16 @@ MediaStream::MediaStream( const QUrl &url )
|
||||
}
|
||||
|
||||
|
||||
MediaStream::MediaStream( QIODevice* device )
|
||||
MediaStream::MediaStream( QIODevice* device, bool bufferingFinished )
|
||||
: QObject( nullptr )
|
||||
, m_type( IODevice )
|
||||
, m_ioDevice ( device )
|
||||
, m_bufferingFinished( bufferingFinished )
|
||||
{
|
||||
QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) );
|
||||
if ( !bufferingFinished )
|
||||
{
|
||||
QObject::connect( m_ioDevice, SIGNAL( readChannelFinished() ), this, SLOT( bufferingFinished() ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@@ -42,7 +42,7 @@ public:
|
||||
|
||||
MediaStream( QObject* parent = nullptr );
|
||||
explicit MediaStream( const QUrl &url );
|
||||
explicit MediaStream( QIODevice* device );
|
||||
explicit MediaStream( QIODevice* device, bool bufferingFinished = false );
|
||||
virtual ~MediaStream();
|
||||
|
||||
MediaType type() const;
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LocalCollection.h"
|
||||
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef LOCALCOLLECTION_H
|
||||
#define LOCALCOLLECTION_H
|
||||
|
@@ -240,7 +240,7 @@ MetadataEditor::loadResult( const Tomahawk::result_ptr& result )
|
||||
return;
|
||||
|
||||
m_result = result;
|
||||
setEditable( result->resolvedByCollection() && result->resolvedByCollection()->isLocal() );
|
||||
setEditable( result->isLocal() );
|
||||
|
||||
setTitle( result->track()->track() );
|
||||
setArtist( result->track()->artist() );
|
||||
@@ -250,7 +250,7 @@ MetadataEditor::loadResult( const Tomahawk::result_ptr& result )
|
||||
setYear( result->track()->year() );
|
||||
setBitrate( result->bitrate() );
|
||||
|
||||
if ( result->resolvedByCollection() && result->resolvedByCollection()->isLocal() )
|
||||
if ( result->isLocal() )
|
||||
{
|
||||
QString furl = m_result->url();
|
||||
if ( furl.startsWith( "file://" ) )
|
||||
|
@@ -1371,8 +1371,7 @@ Servent::isIPWhitelisted( QHostAddress ip )
|
||||
}
|
||||
}
|
||||
|
||||
#if QT_VERSION < QT_VERSION_CHECK( 5, 0, 0 )
|
||||
// Qt4 cannot cope correctly with IPv4 addresses mapped into the IPv6
|
||||
// Qt cannot cope correctly with IPv4 addresses mapped into the IPv6
|
||||
// address space
|
||||
if ( ip.protocol() == QAbstractSocket::IPv6Protocol )
|
||||
{
|
||||
@@ -1397,7 +1396,6 @@ Servent::isIPWhitelisted( QHostAddress ip )
|
||||
return isIPWhitelisted( addr );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "failure";
|
||||
return false;
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/DpiScaler.h"
|
||||
#include "ViewManager.h"
|
||||
#include "widgets/DownloadButton.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QVBoxLayout>
|
||||
@@ -164,6 +165,10 @@ ColumnViewPreviewWidget::ColumnViewPreviewWidget( ColumnView* parent )
|
||||
m_ageValue->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
|
||||
gridLayout->addWidget( m_ageValue, 4, 1 );
|
||||
|
||||
|
||||
m_downloadButton = new DownloadButton( this );
|
||||
mainLayout->addWidget( m_downloadButton );
|
||||
|
||||
mainLayout->addStretch();
|
||||
|
||||
TomahawkUtils::unmarginLayout( mainLayout );
|
||||
@@ -217,6 +222,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
||||
m_bitrateValue->setText( tr( "%1 kbps" ).arg( query->results().first()->bitrate() ) );
|
||||
m_durationValue->setText( TomahawkUtils::timeToString( query->track()->duration() ) );
|
||||
m_ageValue->setText( TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) ) );
|
||||
m_downloadButton->setQuery( query );
|
||||
|
||||
m_yearValue->setVisible( query->track()->year() > 0 );
|
||||
m_yearLabel->setVisible( query->track()->year() > 0 );
|
||||
@@ -226,6 +232,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
||||
m_durationValue->setVisible( query->track()->duration() > 0 );
|
||||
m_ageLabel->setVisible( query->results().first()->modificationTime() > 0 );
|
||||
m_ageValue->setVisible( query->results().first()->modificationTime() > 0 );
|
||||
m_downloadButton->setVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -237,6 +244,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
|
||||
m_durationValue->setVisible( false );
|
||||
m_ageLabel->setVisible( false );
|
||||
m_ageValue->setVisible( false );
|
||||
m_downloadButton->setVisible( false );
|
||||
}
|
||||
|
||||
setMinimumHeight( sizeHint().height() );
|
||||
|
@@ -30,6 +30,7 @@ class QueryLabel;
|
||||
class PlayableCover;
|
||||
class QLabel;
|
||||
class ScrollingLabel;
|
||||
class DownloadButton;
|
||||
|
||||
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
|
||||
{
|
||||
@@ -71,6 +72,8 @@ private:
|
||||
ScrollingLabel* m_trackLabel;
|
||||
|
||||
QueryLabel* m_artistLabel;
|
||||
|
||||
DownloadButton* m_downloadButton;
|
||||
};
|
||||
|
||||
#endif // COLUMNVIEWPREVIEWWIDGET_H
|
||||
|
@@ -19,16 +19,6 @@
|
||||
|
||||
#include "GridItemDelegate.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDesktopServices>
|
||||
#include <QPainter>
|
||||
#include <QAbstractItemView>
|
||||
#include <QMouseEvent>
|
||||
#include <QTimeLine>
|
||||
|
||||
#include "DownloadManager.h"
|
||||
#include "DownloadJob.h"
|
||||
|
||||
#include "Artist.h"
|
||||
#include "Query.h"
|
||||
#include "Result.h"
|
||||
@@ -39,17 +29,22 @@
|
||||
#include "playlist/PlayableItem.h"
|
||||
#include "playlist/PlayableProxyModel.h"
|
||||
#include "widgets/HoverControls.h"
|
||||
#include "widgets/DropDownButton.h"
|
||||
#include "widgets/DownloadButton.h"
|
||||
#include "widgets/ImageButton.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/PixmapDelegateFader.h"
|
||||
#include "utils/Closure.h"
|
||||
#include "utils/AnimatedSpinner.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/DpiScaler.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QPainter>
|
||||
#include <QAbstractItemView>
|
||||
#include <QMouseEvent>
|
||||
#include <QTimeLine>
|
||||
|
||||
namespace {
|
||||
static const int FADE_DURATION = 400;
|
||||
};
|
||||
@@ -325,39 +320,10 @@ GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
|
||||
QRect r = textRect;
|
||||
r.setY( textRect.y() + textRect.height() + 8 );
|
||||
r.setHeight( 32 );
|
||||
m_buyButtonRects[ index ] = r;
|
||||
|
||||
QString text;
|
||||
if ( item->result() &&
|
||||
( ( !item->result()->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() ) ||
|
||||
( item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished ) ) )
|
||||
if( DownloadButton::drawPrimitive(painter, r, item->query(), m_hoveringOverBuyButton == index ) )
|
||||
{
|
||||
text = tr( "View in Finder" );
|
||||
}
|
||||
else if ( item->query() && item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
{
|
||||
text = tr( "Download %1" ).arg( item->query()->results().first()->downloadFormats().first().extension.toUpper() );
|
||||
}
|
||||
else if ( item->query()->numResults( true ) && !item->query()->results().first()->purchaseUrl().isEmpty() )
|
||||
{
|
||||
text = tr( "Buy" );
|
||||
}
|
||||
|
||||
if ( !item->result() || !item->result()->downloadJob() )
|
||||
{
|
||||
if ( !text.isEmpty() )
|
||||
DropDownButton::drawPrimitive( painter, r, text, m_hoveringOverBuyButton == index, false );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( r.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = r.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
m_buyButtonRects[ index ] = r;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -619,23 +585,7 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
|
||||
|
||||
if ( hoveringBuyButton )
|
||||
{
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
|
||||
if ( !item )
|
||||
return false;
|
||||
|
||||
if ( item->query() && item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
{
|
||||
m_view->edit( index );
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
}
|
||||
}
|
||||
return DownloadButton::handleEditorEvent( event, m_view, m_model, index );
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -865,63 +815,7 @@ GridItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& opt
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
if ( item->result() && !item->result()->downloadFormats().isEmpty() &&
|
||||
!DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ) ).absolutePath() ) );
|
||||
}
|
||||
else if ( item->result() && item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( item->result()->downloadJob()->localFile() ).absolutePath() ) );
|
||||
}
|
||||
else if ( item->result() &&
|
||||
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
|
||||
{
|
||||
QStringList formats;
|
||||
foreach ( const DownloadFormat& format, item->result()->downloadFormats() )
|
||||
{
|
||||
formats << tr( "Download %1" ).arg( format.extension.toUpper() );
|
||||
}
|
||||
|
||||
DropDownButton* editor = new DropDownButton( parent );
|
||||
editor->addItems( formats );
|
||||
|
||||
NewClosure( editor, SIGNAL( clicked() ),
|
||||
const_cast<GridItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
|
||||
NewClosure( editor, SIGNAL( activated( int ) ),
|
||||
const_cast<GridItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
return editor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GridItemDelegate::addDownloadJob( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
if ( !item->result()->downloadFormats().isEmpty() )
|
||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().at( cb->currentIndex() ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
GridItemDelegate::closeEditor( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
editor->deleteLater();
|
||||
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
|
||||
}
|
||||
|
||||
|
||||
@@ -930,13 +824,13 @@ GridItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewI
|
||||
{
|
||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||
|
||||
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
|
||||
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
|
||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||
|
||||
if ( m_downloadDropDownRects.contains( index ) )
|
||||
if ( m_buyButtonRects.contains( index ) )
|
||||
{
|
||||
editor->setGeometry( m_downloadDropDownRects.value( index ) );
|
||||
editor->setGeometry( m_buyButtonRects.value( index ) );
|
||||
}
|
||||
|
||||
if ( !comboBox->property( "shownPopup" ).toBool() )
|
||||
|
@@ -87,9 +87,6 @@ private slots:
|
||||
void fadingFrameChanged( const QPersistentModelIndex& );
|
||||
void fadingFrameFinished( const QPersistentModelIndex& );
|
||||
|
||||
void closeEditor( const QModelIndex& index, QWidget* editor );
|
||||
void addDownloadJob( const QModelIndex& index, QWidget* editor );
|
||||
|
||||
private:
|
||||
QTimeLine* createTimeline( QTimeLine::Direction direction, int startFrame = 0 );
|
||||
void clearButtons();
|
||||
@@ -104,7 +101,6 @@ private:
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_albumNameRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
|
||||
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_covers;
|
||||
|
||||
QPersistentModelIndex m_hoverIndex;
|
||||
|
@@ -20,15 +20,6 @@
|
||||
|
||||
#include "PlaylistItemDelegate.h"
|
||||
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QDesktopServices>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QDesktopServices>
|
||||
#include <QToolTip>
|
||||
|
||||
#include "Query.h"
|
||||
#include "Result.h"
|
||||
#include "Artist.h"
|
||||
@@ -36,8 +27,6 @@
|
||||
#include "Source.h"
|
||||
#include "SourceList.h"
|
||||
|
||||
#include "DownloadManager.h"
|
||||
#include "DownloadJob.h"
|
||||
#include "PlayableModel.h"
|
||||
#include "PlayableItem.h"
|
||||
#include "PlayableProxyModel.h"
|
||||
@@ -45,16 +34,22 @@
|
||||
#include "ViewHeader.h"
|
||||
#include "ViewManager.h"
|
||||
|
||||
#include "widgets/DropDownButton.h"
|
||||
#include "widgets/DownloadButton.h"
|
||||
#include "audio/AudioEngine.h"
|
||||
#include "utils/ImageRegistry.h"
|
||||
#include "utils/PixmapDelegateFader.h"
|
||||
#include "utils/Closure.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
#include "utils/TomahawkUtilsGui.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QAbstractTextDocumentLayout>
|
||||
#include <QApplication>
|
||||
#include <QDateTime>
|
||||
#include <QMouseEvent>
|
||||
#include <QPainter>
|
||||
#include <QToolTip>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
@@ -125,63 +120,7 @@ PlaylistItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem&
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
if ( /*index.column() == PlayableModel::Download &&*/ item->result() && !item->result()->downloadFormats().isEmpty() &&
|
||||
!DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ) ).absolutePath() ) );
|
||||
}
|
||||
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() && item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( item->result()->downloadJob()->localFile() ).absolutePath() ) );
|
||||
}
|
||||
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() &&
|
||||
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
|
||||
{
|
||||
QStringList formats;
|
||||
foreach ( const DownloadFormat& format, item->result()->downloadFormats() )
|
||||
{
|
||||
formats << tr( "Download %1" ).arg( format.extension );
|
||||
}
|
||||
|
||||
DropDownButton* editor = new DropDownButton( parent );
|
||||
editor->addItems( formats );
|
||||
|
||||
NewClosure( editor, SIGNAL( clicked() ),
|
||||
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
|
||||
NewClosure( editor, SIGNAL( activated( int ) ),
|
||||
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
|
||||
return editor;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItemDelegate::addDownloadJob( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
if ( !item->result()->downloadFormats().isEmpty() )
|
||||
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().at( cb->currentIndex() ) ) );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistItemDelegate::closeEditor( const QModelIndex& index, QWidget* editor )
|
||||
{
|
||||
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
|
||||
Q_ASSERT( item );
|
||||
|
||||
m_view->closePersistentEditor( index );
|
||||
|
||||
DropDownButton* cb = static_cast< DropDownButton* >(editor);
|
||||
editor->deleteLater();
|
||||
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
|
||||
}
|
||||
|
||||
|
||||
@@ -190,7 +129,7 @@ PlaylistItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionV
|
||||
{
|
||||
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
|
||||
|
||||
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
|
||||
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
|
||||
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
|
||||
comboBox->move( option.rect.x() + 4, option.rect.y() );
|
||||
|
||||
@@ -277,69 +216,7 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
|
||||
else */
|
||||
if ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download )
|
||||
{
|
||||
if ( item->result() && !item->result()->downloadFormats().isEmpty() )
|
||||
{
|
||||
QStyleOptionComboBox optc;
|
||||
optc.rect = opt.rect.adjusted( 4, 0, -4, 0 );
|
||||
optc.editable = false;
|
||||
optc.currentText = tr( "Download %1" ).arg( item->result()->downloadFormats().first().extension );
|
||||
optc.palette = m_view->palette();
|
||||
|
||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
||||
optc.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
||||
else
|
||||
optc.state = QStyle::State_Active | QStyle::State_Enabled;
|
||||
|
||||
if ( !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
painter->setPen( opt.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
|
||||
painter->drawText( opt.rect, text, textOption );
|
||||
}
|
||||
else if ( !item->result()->downloadJob() )
|
||||
{
|
||||
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
|
||||
|
||||
/* QApplication::style()->drawComplexControl( QStyle::CC_ComboBox, &optc, painter, 0 );
|
||||
optc.rect.adjust( 4, 0, 0, 0 );
|
||||
QApplication::style()->drawControl( QStyle::CE_ComboBoxLabel, &optc, painter, 0 );*/
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( item->result()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
painter->setPen( opt.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
|
||||
painter->drawText( opt.rect, text, textOption );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( optc.rect.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = optc.rect.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
|
||||
/* QStyleOptionProgressBarV2 optp;
|
||||
optp.rect = optc.rect;
|
||||
optp.minimum = 0;
|
||||
optp.maximum = 100;
|
||||
optp.progress = item->result()->downloadJob()->progressPercentage();
|
||||
optp.palette = m_view->palette();
|
||||
optp.palette.setColor( QPalette::Highlight, QColor( "#E61878" ) );
|
||||
|
||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
||||
optp.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
||||
else
|
||||
optp.state = QStyle::State_Active | QStyle::State_Enabled;
|
||||
|
||||
QApplication::style()->drawControl( QStyle::CE_ProgressBar, &optp, painter, 0 );*/
|
||||
}
|
||||
}
|
||||
}
|
||||
DownloadButton::drawPrimitive( painter, opt.rect.adjusted( 4, 0, -4, 0 ), item->query(), hoveringOver() == index );
|
||||
}
|
||||
else if ( item->isPlaying() )
|
||||
{
|
||||
@@ -657,67 +534,14 @@ PlaylistItemDelegate::drawTrack( QPainter* painter, const QStyleOptionViewItem&
|
||||
|
||||
stateWidth += r.width() + 16;
|
||||
}
|
||||
|
||||
if ( hasOnlineResults && !item->query()->results().first()->purchaseUrl().isEmpty() )
|
||||
{
|
||||
QRect r = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
||||
r.setWidth( 144 );
|
||||
DropDownButton::drawPrimitive( painter, r, tr( "Buy" ), m_hoveringOverBuyButton == index, false );
|
||||
|
||||
m_buyButtonRects[ index ] = r;
|
||||
|
||||
stateWidth += r.width() + 16;
|
||||
}
|
||||
}
|
||||
|
||||
if ( hasOnlineResults && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
QRect downloadButtonRect = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
||||
downloadButtonRect.setWidth( 144 );
|
||||
stateWidth += downloadButtonRect.width() + 16;
|
||||
if ( DownloadButton::drawPrimitive( painter, downloadButtonRect, item->query(), m_hoveringOverDownloadButton == index ) )
|
||||
{
|
||||
painter->save();
|
||||
QStyleOptionComboBox optc;
|
||||
optc.rect = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
|
||||
optc.rect.setWidth( 144 );
|
||||
m_downloadDropDownRects[ index ] = optc.rect;
|
||||
stateWidth += optc.rect.width() + 16;
|
||||
optc.editable = false;
|
||||
optc.currentText = tr( "Download %1" ).arg( item->query()->results().first()->downloadFormats().first().extension.toUpper() );
|
||||
optc.palette = m_view->palette();
|
||||
|
||||
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
|
||||
optc.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
|
||||
else
|
||||
optc.state = QStyle::State_Active | QStyle::State_Enabled;
|
||||
|
||||
if ( !DownloadManager::instance()->localFileForDownload( item->query()->results().first()->downloadFormats().first().url.toString() ).isEmpty() )
|
||||
{
|
||||
painter->setPen( optc.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, optc.rect.width() - 3 );
|
||||
painter->drawText( optc.rect, text, QTextOption( Qt::AlignCenter ) );
|
||||
}
|
||||
else if ( !item->query()->results().first()->downloadJob() )
|
||||
{
|
||||
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
|
||||
}
|
||||
else
|
||||
{
|
||||
if ( item->query()->results().first()->downloadJob()->state() == DownloadJob::Finished )
|
||||
{
|
||||
painter->setPen( optc.palette.text().color() );
|
||||
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, optc.rect.width() - 3 );
|
||||
painter->drawText( optc.rect, text, QTextOption( Qt::AlignCenter ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( optc.rect.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = optc.rect.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float(item->query()->results().first()->downloadJob()->progressPercentage()) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
}
|
||||
}
|
||||
painter->restore();
|
||||
m_downloadDropDownRects[ index ] = downloadButtonRect;
|
||||
}
|
||||
|
||||
const int remWidth = r.width() - numberWidth - durationWidth;
|
||||
@@ -835,7 +659,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
bool hoveringArtist = false;
|
||||
bool hoveringInfo = false;
|
||||
bool hoveringLove = false;
|
||||
bool hoveringBuy = false;
|
||||
bool hoveringDownloadDropDown = false;
|
||||
Tomahawk::source_ptr hoveredAvatar;
|
||||
QRect hoveredAvatarRect;
|
||||
@@ -858,12 +681,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||
hoveringLove = loveRect.contains( ev->pos() );
|
||||
}
|
||||
if ( m_buyButtonRects.contains( index ) )
|
||||
{
|
||||
const QRect buyRect = m_buyButtonRects[ index ];
|
||||
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
|
||||
hoveringBuy = buyRect.contains( ev->pos() );
|
||||
}
|
||||
if ( m_downloadDropDownRects.contains( index ) )
|
||||
{
|
||||
const QRect downloadDropDownRect = m_downloadDropDownRects[ index ];
|
||||
@@ -887,7 +704,7 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
|
||||
if ( event->type() == QEvent::MouseMove )
|
||||
{
|
||||
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringBuy )
|
||||
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringDownloadDropDown )
|
||||
m_view->setCursor( Qt::PointingHandCursor );
|
||||
else
|
||||
m_view->setCursor( Qt::ArrowCursor );
|
||||
@@ -911,19 +728,19 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
emit updateIndex( m_hoveringOverArtist );
|
||||
m_hoveringOverArtist = QModelIndex();
|
||||
}
|
||||
if ( hoveringBuy && m_hoveringOverBuyButton != index )
|
||||
if ( hoveringDownloadDropDown && m_hoveringOverDownloadButton != index )
|
||||
{
|
||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
||||
m_hoveringOverBuyButton = index;
|
||||
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
|
||||
m_hoveringOverDownloadButton = index;
|
||||
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||
item->requestRepaint();
|
||||
emit updateIndex( m_hoveringOverBuyButton );
|
||||
emit updateIndex( m_hoveringOverDownloadButton );
|
||||
}
|
||||
if ( !hoveringBuy && m_hoveringOverBuyButton.isValid() )
|
||||
if ( !hoveringDownloadDropDown && m_hoveringOverDownloadButton.isValid() )
|
||||
{
|
||||
QPersistentModelIndex ti = m_hoveringOverBuyButton;
|
||||
m_hoveringOverBuyButton = QModelIndex();
|
||||
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
|
||||
m_hoveringOverDownloadButton = QModelIndex();
|
||||
|
||||
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
|
||||
item->requestRepaint();
|
||||
@@ -957,10 +774,10 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
{
|
||||
item->query()->queryTrack()->setLoved( !item->query()->queryTrack()->loved() );
|
||||
}
|
||||
else if ( hoveringBuy )
|
||||
else if ( hoveringDownloadDropDown || ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) )
|
||||
{
|
||||
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
if ( DownloadButton::handleEditorEvent( event , m_view, m_model, index ) )
|
||||
return true;
|
||||
}
|
||||
else if ( hoveringInfo )
|
||||
{
|
||||
@@ -996,13 +813,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) || hoveringDownloadDropDown )
|
||||
{
|
||||
m_model->sourceModel()->setAllColumnsEditable( true );
|
||||
m_view->edit( index );
|
||||
m_model->sourceModel()->setAllColumnsEditable( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
event->accept();
|
||||
return true;
|
||||
@@ -1022,10 +832,9 @@ PlaylistItemDelegate::resetHoverIndex()
|
||||
|
||||
m_hoveringOver = QModelIndex();
|
||||
m_hoveringOverArtist = QModelIndex();
|
||||
m_hoveringOverBuyButton = QModelIndex();
|
||||
m_hoveringOverDownloadButton = QModelIndex();
|
||||
m_infoButtonRects.clear();
|
||||
m_loveButtonRects.clear();
|
||||
m_buyButtonRects.clear();
|
||||
m_artistNameRects.clear();
|
||||
|
||||
QModelIndex itemIdx = m_model->mapToSource( idx );
|
||||
|
@@ -57,8 +57,6 @@ signals:
|
||||
|
||||
private slots:
|
||||
void doUpdateIndex( const QPersistentModelIndex& index );
|
||||
void closeEditor( const QModelIndex& index, QWidget* editor );
|
||||
void addDownloadJob( const QModelIndex& index, QWidget* editor );
|
||||
|
||||
protected:
|
||||
void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, PlayableItem* item ) const;
|
||||
@@ -116,13 +114,12 @@ private:
|
||||
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_infoButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_loveButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
|
||||
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
|
||||
mutable QHash< QPersistentModelIndex, QHash< Tomahawk::source_ptr, QRect > > m_avatarBoxRects;
|
||||
QPersistentModelIndex m_hoveringOver;
|
||||
QPersistentModelIndex m_hoveringOverArtist;
|
||||
QPersistentModelIndex m_hoveringOverBuyButton;
|
||||
QPersistentModelIndex m_hoveringOverDownloadButton;
|
||||
mutable QPersistentModelIndex m_nowPlaying;
|
||||
|
||||
TrackView* m_view;
|
||||
|
@@ -18,12 +18,6 @@
|
||||
|
||||
#include "TrackDetailView.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
#include <QSizePolicy>
|
||||
#include <QVBoxLayout>
|
||||
|
||||
#include "Album.h"
|
||||
#include "Track.h"
|
||||
#include "audio/AudioEngine.h"
|
||||
@@ -39,6 +33,13 @@
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QLabel>
|
||||
#include <QPushButton>
|
||||
#include <QScrollArea>
|
||||
#include <QSizePolicy>
|
||||
#include <QVBoxLayout>
|
||||
#include <QDesktopServices>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
TrackDetailView::TrackDetailView( QWidget* parent )
|
||||
@@ -219,8 +220,44 @@ TrackDetailView::onAlbumUpdated()
|
||||
{
|
||||
if ( m_query->track()->albumPtr()->purchased() )
|
||||
{
|
||||
m_buyButton->setText( tr( "Download Album" ) );
|
||||
m_buyButton->setVisible( true );
|
||||
m_allTracksAvailableLocally = true;
|
||||
foreach( const query_ptr& currentQuery, m_playlistInterface->tracks() )
|
||||
{
|
||||
if ( currentQuery->results().isEmpty() )
|
||||
{
|
||||
m_allTracksAvailableLocally = false;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
m_allTracksAvailableLocally = false;
|
||||
foreach ( const result_ptr& currentResult, currentQuery->results() )
|
||||
{
|
||||
QList< DownloadFormat > formats = currentResult->downloadFormats();
|
||||
bool isDownloaded = formats.isEmpty() ? false : !DownloadManager::instance()->localFileForDownload( currentResult->downloadFormats().first().url.toString() ).isEmpty();
|
||||
if ( currentResult->isLocal() || isDownloaded )
|
||||
{
|
||||
m_allTracksAvailableLocally = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( !m_allTracksAvailableLocally )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_allTracksAvailableLocally )
|
||||
{
|
||||
m_buyButton->setText( tr( "View in Folder" ) );
|
||||
m_buyButton->setVisible( true );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_buyButton->setText( tr( "Download Album" ) );
|
||||
m_buyButton->setVisible( true );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -251,7 +288,14 @@ TrackDetailView::onBuyButtonClicked()
|
||||
{
|
||||
if ( m_query->track()->albumPtr()->purchased() )
|
||||
{
|
||||
emit downloadAll();
|
||||
if ( m_allTracksAvailableLocally )
|
||||
{
|
||||
QDesktopServices::openUrl( QUrl::fromLocalFile( DownloadJob::localPath( m_query->track()->albumPtr() ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
emit downloadAll();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -77,6 +77,7 @@ private:
|
||||
CaptionLabel* m_resultsBoxLabel;
|
||||
QPushButton* m_buyButton;
|
||||
bool m_buyButtonVisible;
|
||||
bool m_allTracksAvailableLocally;
|
||||
|
||||
QWidget* m_infoBox;
|
||||
QWidget* m_resultsBox;
|
||||
|
@@ -247,8 +247,8 @@ TreeProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParent
|
||||
if ( !item->result()->isOnline() && ti->result()->isOnline() )
|
||||
return false;
|
||||
|
||||
if ( ( item->result()->resolvedByCollection().isNull() || !item->result()->resolvedByCollection()->isLocal() ) &&
|
||||
!ti->result()->resolvedByCollection().isNull() && ti->result()->resolvedByCollection()->isLocal() )
|
||||
if ( ( !item->result()->isLocal() ) &&
|
||||
!ti->result()->isLocal() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
@@ -156,6 +156,7 @@ XspfUpdater::setAutoUpdate( bool autoUpdate )
|
||||
emit changed();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
XspfUpdater::setInterval( int intervalMsecs )
|
||||
{
|
||||
|
@@ -1,12 +1,12 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -17,6 +17,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptAccount.h"
|
||||
|
||||
#include "ScriptObject.h"
|
||||
@@ -31,11 +32,11 @@
|
||||
#include "ScriptLinkGeneratorPlugin.h"
|
||||
#include "ScriptInfoPlugin.h"
|
||||
|
||||
// TODO:
|
||||
#include "../Artist.h"
|
||||
#include "../Album.h"
|
||||
#include "../Result.h"
|
||||
#include "../Track.h"
|
||||
|
||||
#include <QTime>
|
||||
|
||||
|
||||
@@ -155,11 +156,17 @@ ScriptAccount::reportScriptJobResult( const QVariantMap& result )
|
||||
Q_ASSERT( job );
|
||||
|
||||
// got a successful job result
|
||||
if ( result[ "error"].isNull() )
|
||||
if ( result[ "error" ].isNull() )
|
||||
{
|
||||
const QVariantMap data = result[ "data" ].toMap();
|
||||
|
||||
job->reportResults( data );
|
||||
if ( result[ "data" ].type() == QVariant::Map )
|
||||
{
|
||||
const QVariantMap data = result[ "data" ].toMap();
|
||||
job->reportResultsMap( data );
|
||||
}
|
||||
else
|
||||
{
|
||||
job->reportResults( result[ "data" ] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@@ -1,12 +1,12 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright (C) 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -82,7 +82,15 @@ ScriptJob::arguments() const
|
||||
|
||||
|
||||
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;
|
||||
emit done( data );
|
||||
@@ -94,5 +102,6 @@ ScriptJob::reportFailure( const QString& errorMessage )
|
||||
{
|
||||
emit error( errorMessage );
|
||||
|
||||
reportResults( QVariantMap() );
|
||||
reportResults();
|
||||
reportResultsMap();
|
||||
}
|
||||
|
@@ -49,11 +49,13 @@ public:
|
||||
QVariantMap arguments() const;
|
||||
|
||||
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 );
|
||||
|
||||
signals:
|
||||
void done( const QVariantMap& result );
|
||||
void done( const QVariant& result );
|
||||
void error( const QString& errorMessage );
|
||||
|
||||
void destroyed( const QString& id );
|
||||
@@ -63,7 +65,7 @@ protected:
|
||||
bool m_error;
|
||||
QString m_id;
|
||||
scriptobject_ptr m_scriptObject;
|
||||
QVariantMap m_data;
|
||||
QVariant m_data;
|
||||
QString m_methodName;
|
||||
QVariantMap m_arguments;
|
||||
};
|
||||
|
@@ -42,7 +42,7 @@ ScriptJob*
|
||||
ScriptLinkGeneratorPlugin::openLink( const QString& title, const QString& artist, const QString& album ) const
|
||||
{
|
||||
QVariantMap arguments;
|
||||
arguments[ "title" ] = QVariant( title );
|
||||
arguments[ "track" ] = QVariant( title );
|
||||
arguments[ "artist" ] = QVariant( artist );
|
||||
arguments[ "album" ] = QVariant( album );
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptPlugin.h"
|
||||
|
||||
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,4 +15,5 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptPluginFactory.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "SyncScriptJob.h"
|
||||
|
||||
#include "../Typedefs.h"
|
||||
@@ -30,5 +31,5 @@ Tomahawk::SyncScriptJob::SyncScriptJob( const QVariantMap& resultData )
|
||||
void
|
||||
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> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptCollectionFactory.h"
|
||||
|
||||
#include "SourceList.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "ScriptInfoPluginFactory.h"
|
||||
|
||||
#include "SourceList.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2015 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2015, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -53,11 +53,11 @@ public:
|
||||
static QMargins scaled( const QPaintDevice* pd, const QMargins& margins );
|
||||
static int scaledX( const QPaintDevice* pd, int x );
|
||||
static int scaledY( const QPaintDevice* pd, int y );
|
||||
static qreal ratioFromFontHeight();
|
||||
|
||||
private:
|
||||
inline static qreal ratioX( const QPaintDevice* pd );
|
||||
inline static qreal ratioY( const QPaintDevice* pd );
|
||||
inline static qreal ratioFromFontHeight();
|
||||
|
||||
qreal m_ratioX;
|
||||
qreal m_ratioY;
|
||||
|
@@ -1,15 +1,15 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright (C) 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,11 +1,12 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -15,6 +15,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "LinkGeneratorPlugin.h"
|
||||
|
||||
#include "LinkGenerator.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,13 +1,13 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2012, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,15 +1,15 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright (C) 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright (C) 2011-2014, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright (C) 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright (C) 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2011-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2013, Uwe L. Korn <uwelk@xhochy.com>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
@@ -20,6 +20,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "TomaHkLinkGeneratorPlugin.h"
|
||||
|
||||
#include "../playlist/dynamic/GeneratorInterface.h"
|
||||
|
@@ -1,10 +1,10 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright (C) 2014 Dominik Schmidt <domme@tomahawk-player.org>
|
||||
* Copyright 2014, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 2 of the License, or
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "XspfGenerator.h"
|
||||
|
||||
|
@@ -1,21 +1,20 @@
|
||||
/*
|
||||
Copyright (C) 2011 Leo Franchi <lfranchi@kde.org>
|
||||
|
||||
This program is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 2 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License along
|
||||
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef XSPFGENERATOR_H
|
||||
#define XSPFGENERATOR_H
|
||||
|
@@ -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::Vertical, Qt::ScrollBarAsNeeded );
|
||||
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 );
|
||||
|
||||
TomahawkStyle::stylePageWidget( ui->biography );
|
||||
@@ -358,7 +367,7 @@ ArtistInfoWidget::onTracksFound( const QList<Tomahawk::query_ptr>& queries, Mode
|
||||
Q_UNUSED( mode );
|
||||
|
||||
m_topHitsModel->finishLoading();
|
||||
m_topHitsModel->appendQueries( queries.mid( 0, 20 ) );
|
||||
m_topHitsModel->appendQueries( queries.mid( 0, 50 ) );
|
||||
m_topHitsModel->ensureResolved();
|
||||
}
|
||||
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* === 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>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
@@ -57,13 +57,12 @@ CollectionViewPage::CollectionViewPage( const Tomahawk::collection_ptr& collecti
|
||||
{
|
||||
qRegisterMetaType< CollectionViewPageMode >( "CollectionViewPageMode" );
|
||||
|
||||
m_header->setBackground( ImageRegistry::instance()->pixmap( RESPATH "images/collection_background.png", QSize( 0, 0 ) ), false );
|
||||
m_header->setBackground( ImageRegistry::instance()->pixmap( RESPATH "images/collection_background.png", QSize( 0, 0 ) ), true );
|
||||
|
||||
setPixmap( TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultCollection, TomahawkUtils::Original, QSize( 256, 256 ) ) );
|
||||
|
||||
m_columnView->proxyModel()->setStyle( PlayableProxyModel::SingleColumn );
|
||||
|
||||
|
||||
PlayableProxyModel* trackViewProxyModel = m_trackView->proxyModel();
|
||||
if ( collection->backendType() == Collection::ScriptCollectionType )
|
||||
{
|
||||
@@ -383,17 +382,22 @@ CollectionViewPage::restoreViewMode()
|
||||
setCurrentMode( CollectionViewPage::Flat );
|
||||
else
|
||||
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 ) )
|
||||
setCurrentMode( CollectionViewPage::Columns );
|
||||
else if ( m_collection->browseCapabilities().contains( Collection::CapabilityBrowseAlbums ) )
|
||||
setCurrentMode( CollectionViewPage::Albums );
|
||||
} else {
|
||||
}
|
||||
else
|
||||
{
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
|
282
src/libtomahawk/widgets/DownloadButton.cpp
Normal file
282
src/libtomahawk/widgets/DownloadButton.cpp
Normal file
@@ -0,0 +1,282 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "DownloadButton.h"
|
||||
|
||||
#include "Artist.h"
|
||||
#include "Album.h"
|
||||
#include "Result.h"
|
||||
#include "DownloadManager.h"
|
||||
#include "utils/TomahawkStyle.h"
|
||||
#include "utils/WebPopup.h"
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QPainter>
|
||||
#include <QEvent>
|
||||
#include <QAbstractItemView>
|
||||
#include <QDesktopServices>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
|
||||
DownloadButton::DownloadButton( const Tomahawk::query_ptr& query, QWidget* parent, QAbstractItemView* view, const QModelIndex& index )
|
||||
: DropDownButton( parent )
|
||||
, m_view( view )
|
||||
, m_index( index )
|
||||
{
|
||||
init();
|
||||
|
||||
setQuery( query );
|
||||
}
|
||||
|
||||
|
||||
DownloadButton::DownloadButton( QWidget* parent )
|
||||
: DropDownButton( parent )
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadButton::init()
|
||||
{
|
||||
connect( this, SIGNAL( clicked() ), this, SLOT( addDownloadJob() ) );
|
||||
connect( this, SIGNAL( activated( int ) ), this, SLOT( addDownloadJob() ) );
|
||||
}
|
||||
|
||||
|
||||
DownloadButton::~DownloadButton()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadButton::setQuery( const query_ptr& query )
|
||||
{
|
||||
if ( !m_query.isNull() )
|
||||
{
|
||||
m_query->disconnect( this );
|
||||
}
|
||||
if ( !m_result.isNull() )
|
||||
{
|
||||
m_result->disconnect( this );
|
||||
}
|
||||
|
||||
clear();
|
||||
m_result.clear();
|
||||
|
||||
m_query = query;
|
||||
|
||||
if ( query.isNull() )
|
||||
return;
|
||||
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result.isNull() )
|
||||
return;
|
||||
|
||||
QStringList formats;
|
||||
foreach ( const DownloadFormat& format, result->downloadFormats() )
|
||||
{
|
||||
formats << QObject::tr( "Download %1" ).arg( format.extension.toUpper() );
|
||||
}
|
||||
|
||||
addItems( formats );
|
||||
}
|
||||
|
||||
void
|
||||
DownloadButton::addDownloadJob()
|
||||
{
|
||||
if ( m_query.isNull() )
|
||||
return;
|
||||
|
||||
Tomahawk::result_ptr result = m_query->numResults( true ) ? m_query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result.isNull() )
|
||||
return;
|
||||
|
||||
if ( handleClickPreDownload( m_query ) )
|
||||
return;
|
||||
|
||||
if ( !result->downloadFormats().isEmpty() )
|
||||
{
|
||||
if ( m_view && m_index.isValid() )
|
||||
{
|
||||
m_view->closePersistentEditor( m_index );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_result = result;
|
||||
connect( result.data(), SIGNAL( updated() ), SLOT( update() ) );
|
||||
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( update() ) );
|
||||
}
|
||||
|
||||
DownloadManager::instance()->addJob( result->toDownloadJob( result->downloadFormats().at( currentIndex() ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
handleClickPostDownload( m_query );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DownloadButton::paintEvent( QPaintEvent* event )
|
||||
{
|
||||
QPainter p( this );
|
||||
setupPainter( &p );
|
||||
|
||||
if ( DownloadButton::drawPrimitive( &p, contentsRect(), m_query, m_hovering ) )
|
||||
setCursor( Qt::PointingHandCursor );
|
||||
else
|
||||
setCursor( Qt::ArrowCursor );
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DownloadButton::drawPrimitive( QPainter* painter, const QRect& rect, const Tomahawk::query_ptr& query, bool hovering )
|
||||
{
|
||||
if ( query.isNull() )
|
||||
return false;
|
||||
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result.isNull() )
|
||||
return false;
|
||||
|
||||
if ( result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
|
||||
{
|
||||
// if downloadJob exists and is not finished, paint a progress bar
|
||||
painter->save();
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
|
||||
painter->drawRect( rect.adjusted( 2, 2, -2, -2 ) );
|
||||
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
|
||||
QRect fillp = rect.adjusted( 3, 3, -3, -3 );
|
||||
fillp.setWidth( float(fillp.width()) * ( float( result->downloadJob()->progressPercentage() ) / 100.0 ) );
|
||||
painter->drawRect( fillp );
|
||||
painter->restore();
|
||||
}
|
||||
else
|
||||
{
|
||||
QString text;
|
||||
bool itemsAvailable = false;
|
||||
if ( result &&
|
||||
( ( !result->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() ) ||
|
||||
( result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished ) ) )
|
||||
{
|
||||
text = QObject::tr( "View in Finder" );
|
||||
}
|
||||
else if ( !result->downloadFormats().isEmpty() )
|
||||
{
|
||||
text = tr( "Download %1" ).arg( query->results().first()->downloadFormats().first().extension.toUpper() );
|
||||
itemsAvailable = true;
|
||||
}
|
||||
else if ( !result->purchaseUrl().isEmpty() )
|
||||
{
|
||||
text = tr( "Buy" );
|
||||
}
|
||||
|
||||
if ( !text.isEmpty() )
|
||||
DropDownButton::drawPrimitive( painter, rect, text, hovering, itemsAvailable );
|
||||
else
|
||||
{
|
||||
// this result can neither be bought nor downloaded
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
DownloadButton::handleEditorEvent(QEvent* event , QAbstractItemView* view, PlayableProxyModel* model, const QModelIndex& index)
|
||||
{
|
||||
if ( event->type() == QEvent::MouseButtonRelease )
|
||||
{
|
||||
PlayableItem* item = model->sourceModel()->itemFromIndex( model->mapToSource( index ) );
|
||||
if ( !item && ! item->query() )
|
||||
return false;
|
||||
|
||||
if ( handleClickPreDownload( item->query() ) )
|
||||
return true;
|
||||
|
||||
if( item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
|
||||
{
|
||||
model->sourceModel()->setAllColumnsEditable( true );
|
||||
view->edit( index );
|
||||
model->sourceModel()->setAllColumnsEditable( false );
|
||||
return true;
|
||||
}
|
||||
|
||||
return handleClickPostDownload( item->query() );
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DownloadButton::handleClickPreDownload( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
// view in folder
|
||||
if ( !DownloadManager::instance()->localUrlForDownload( query ).isEmpty() )
|
||||
{
|
||||
QDesktopServices::openUrl( DownloadManager::instance()->localUrlForDownload( query ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
// download in progress
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result && result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
|
||||
{
|
||||
// do nothing, handled
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
DownloadButton::handleClickPostDownload( const Tomahawk::query_ptr& query )
|
||||
{
|
||||
// handle buy click
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result && !result->purchaseUrl().isEmpty() )
|
||||
{
|
||||
WebPopup* popup = new WebPopup( result->purchaseUrl(), QSize( 400, 800 ) );
|
||||
connect( result.data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
QWidget*
|
||||
DownloadButton::handleCreateEditor( QWidget* parent, const query_ptr& query, QAbstractItemView* view, const QModelIndex& index )
|
||||
{
|
||||
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
|
||||
if ( result && !result->downloadFormats().isEmpty() && !result->downloadJob() )
|
||||
{
|
||||
return new DownloadButton( query, parent, view, index );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
61
src/libtomahawk/widgets/DownloadButton.h
Normal file
61
src/libtomahawk/widgets/DownloadButton.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
|
||||
*
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef DOWNLOADBUTTON_H
|
||||
#define DOWNLOADBUTTON_H
|
||||
|
||||
#include "DropDownButton.h"
|
||||
#include "playlist/PlayableProxyModel.h"
|
||||
|
||||
#include "Typedefs.h"
|
||||
#include "DllMacro.h"
|
||||
|
||||
class DLLEXPORT DownloadButton : public DropDownButton
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit DownloadButton( const Tomahawk::query_ptr& query, QWidget* parent = nullptr, QAbstractItemView* view = nullptr, const QModelIndex& index = QModelIndex() );
|
||||
explicit DownloadButton( QWidget* parent = nullptr );
|
||||
virtual ~DownloadButton();
|
||||
|
||||
void setQuery( const Tomahawk::query_ptr& query );
|
||||
|
||||
static bool drawPrimitive( QPainter* p, const QRect& rect, const Tomahawk::query_ptr& query, bool hovering );
|
||||
static bool handleEditorEvent( QEvent* event, QAbstractItemView* view, PlayableProxyModel* model, const QModelIndex& index );
|
||||
static QWidget* handleCreateEditor( QWidget* parent, const Tomahawk::query_ptr& query , QAbstractItemView* view, const QModelIndex& index );
|
||||
|
||||
protected:
|
||||
void paintEvent( QPaintEvent* event );
|
||||
|
||||
private slots:
|
||||
void addDownloadJob();
|
||||
|
||||
private:
|
||||
static bool handleClickPreDownload( const Tomahawk::query_ptr& query );
|
||||
static bool handleClickPostDownload( const Tomahawk::query_ptr& query );
|
||||
void init();
|
||||
|
||||
Tomahawk::query_ptr m_query;
|
||||
Tomahawk::result_ptr m_result;
|
||||
QAbstractItemView* m_view;
|
||||
QModelIndex m_index;
|
||||
};
|
||||
|
||||
#endif // DOWNLOADBUTTON_H
|
@@ -47,7 +47,7 @@ protected:
|
||||
|
||||
private slots:
|
||||
|
||||
private:
|
||||
protected:
|
||||
static void setupPainter( QPainter* p );
|
||||
|
||||
bool m_hovering;
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2013, Teo Mrnjavac <teo@kde.org>
|
||||
*
|
||||
@@ -33,6 +33,7 @@ SeekSlider::SeekSlider( QWidget* parent )
|
||||
, TomahawkUtils::DpiScaler( this )
|
||||
, m_timeLine( 0 )
|
||||
, m_acceptWheelEvents( true )
|
||||
, m_isScrubbing( false )
|
||||
{
|
||||
setStyleSheet( QString(
|
||||
"QSlider::groove:horizontal {"
|
||||
@@ -72,6 +73,8 @@ SeekSlider::mousePressEvent( QMouseEvent* event )
|
||||
{
|
||||
if ( event->button() == Qt::LeftButton )
|
||||
{
|
||||
m_isScrubbing = true;
|
||||
|
||||
QMouseEvent eventSwap( QEvent::MouseButtonRelease, event->pos(), event->globalPos(), Qt::MidButton, Qt::MidButton, event->modifiers() );
|
||||
QSlider::mousePressEvent( &eventSwap );
|
||||
}
|
||||
@@ -102,8 +105,25 @@ SeekSlider::wheelEvent( QWheelEvent* event )
|
||||
{
|
||||
if ( m_acceptWheelEvents )
|
||||
{
|
||||
QAbstractSlider::wheelEvent(event);
|
||||
QAbstractSlider::wheelEvent( event );
|
||||
return;
|
||||
}
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SeekSlider::mouseMoveEvent( QMouseEvent* event )
|
||||
{
|
||||
if ( !m_isScrubbing )
|
||||
return;
|
||||
|
||||
// disable further scrubbing when we're past the slider's right margin
|
||||
if ( event->pos().x() > width() )
|
||||
{
|
||||
m_isScrubbing = false;
|
||||
return;
|
||||
}
|
||||
|
||||
QSlider::mouseMoveEvent( event );
|
||||
}
|
||||
|
@@ -44,11 +44,13 @@ public slots:
|
||||
|
||||
protected:
|
||||
void mousePressEvent( QMouseEvent* event );
|
||||
void mouseMoveEvent( QMouseEvent* event );
|
||||
void wheelEvent( QWheelEvent* event );
|
||||
|
||||
private:
|
||||
QTimeLine* m_timeLine;
|
||||
bool m_acceptWheelEvents;
|
||||
bool m_isScrubbing;
|
||||
};
|
||||
|
||||
#endif // SEEKSLIDER_H
|
||||
|
@@ -1,8 +1,8 @@
|
||||
FILE( GLOB _icons "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-*.png" )
|
||||
FILE( GLOB _icons "${CMAKE_SOURCE_DIR}/data/icons/*-tomahawk-icon.png" )
|
||||
FOREACH( _file ${_icons} )
|
||||
STRING( REPLACE "${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon-" "" _res ${_file} )
|
||||
STRING( REPLACE ".png" "" _res ${_res} )
|
||||
INSTALL( FILES ${_file} RENAME tomahawk.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/${_res}/apps )
|
||||
STRING( REPLACE "${CMAKE_SOURCE_DIR}/data/icons/" "" _res ${_file} )
|
||||
STRING( REPLACE "-tomahawk-icon.png" "" _res ${_res} )
|
||||
INSTALL( FILES ${_file} RENAME ${TOMAHAWK_TARGET_NAME}.png DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/${_res}/apps )
|
||||
ENDFOREACH( _file )
|
||||
|
||||
IF( WITH_UPOWER )
|
||||
@@ -15,6 +15,7 @@ IF( WITH_GNOMESHORTCUTHANDLER )
|
||||
SET( tomahawkSources ${tomahawkSources} linux/GnomeShortcutHandler.cpp )
|
||||
ENDIF( WITH_GNOMESHORTCUTHANDLER )
|
||||
|
||||
INSTALL( FILES ${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon.svg RENAME tomahawk.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps )
|
||||
INSTALL( FILES ${CMAKE_SOURCE_DIR}/data/icons/tomahawk-icon.svg RENAME ${TOMAHAWK_TARGET_NAME}.svg DESTINATION ${CMAKE_INSTALL_DATADIR}/icons/hicolor/scalable/apps )
|
||||
|
||||
INSTALL( FILES ${CMAKE_SOURCE_DIR}/admin/unix/tomahawk.desktop RENAME ${TOMAHAWK_TARGET_NAME}.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications )
|
||||
|
||||
INSTALL( FILES ${CMAKE_SOURCE_DIR}/admin/unix/tomahawk.desktop DESTINATION ${CMAKE_INSTALL_DATADIR}/applications )
|
||||
|
@@ -1,6 +1,6 @@
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* Copyright 2010-2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2016, Christian Muehlhaeuser <muesli@tomahawk-player.org>
|
||||
* Copyright 2010-2012, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2012, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
* Copyright 2012, Teo Mrnjavac <teo@kde.org>
|
||||
@@ -722,11 +722,13 @@ TomahawkWindow::eventFilter( QObject* obj, QEvent* event )
|
||||
{
|
||||
case Qt::XButton1:
|
||||
m_backAction->trigger();
|
||||
break;
|
||||
event->accept();
|
||||
return true;
|
||||
|
||||
case Qt::XButton2:
|
||||
m_forwardAction->trigger();
|
||||
break;
|
||||
event->accept();
|
||||
return true;
|
||||
|
||||
default:
|
||||
break;
|
||||
@@ -890,6 +892,7 @@ TomahawkWindow::audioStateChanged( AudioState newState, AudioState oldState )
|
||||
#endif//Q_OS_WIN
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
TomahawkWindow::onHistoryBackAvailable( bool avail )
|
||||
{
|
||||
@@ -1283,7 +1286,7 @@ TomahawkWindow::showAboutTomahawk()
|
||||
const QString thanksto( tr( "Thanks to:" ) );
|
||||
|
||||
desc = QString( "https://tomahawk-player.org<br/><br/>%1<br/><br/>Christian Muehlhaeuser <muesli@tomahawk-player.org><br/><br/>"
|
||||
"%2 Leo Franchi, Jeff Mitchell, Dominik Schmidt, Jason Herskowitz, Alejandro Wainzinger, Hugo Lindström, Michael Zanetti, Teo Mrnjavac, Christopher Reichert, Uwe L. Korn, Patrick von Reth, Harald Sitter, Syd Lawrence, Jordi Verdú Orts" )
|
||||
"%2 Leo Franchi, Jeff Mitchell, Dominik Schmidt, Jason Herskowitz, Alejandro Wainzinger, Hugo Lindström, Michael Zanetti, Teo Mrnjavac, Christopher Reichert, Uwe L. Korn, Patrick von Reth, Harald Sitter, Syd Lawrence, Jordi Verdú Orts, Anton Romanov, Stefan Ahlers" )
|
||||
.arg( copyright )
|
||||
.arg( thanksto );
|
||||
|
||||
|
@@ -412,7 +412,7 @@ SettingsDialog::onCustomContextMenu( const QPoint& point )
|
||||
void
|
||||
SettingsDialog::onShowDebuggerForSelectedAccount()
|
||||
{
|
||||
ResolverAccount* account = m_accountProxy->data( m_accountsWidgetUi->accountsView->currentIndex(), AccountModel::AccountData ).value< ResolverAccount* >();
|
||||
ResolverAccount* account = qobject_cast< ResolverAccount* >( m_accountProxy->data( m_accountsWidgetUi->accountsView->currentIndex(), AccountModel::AccountData ).value< Tomahawk::Accounts::Account* >() );
|
||||
Tomahawk::JSResolver* jsResolver = qobject_cast< Tomahawk::JSResolver* >( account->resolver() );
|
||||
jsResolver->scriptAccount()->showDebugger();
|
||||
}
|
||||
|
@@ -167,7 +167,7 @@ main( int argc, char *argv[] )
|
||||
QCA::Initializer init;
|
||||
Q_UNUSED( init )
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#ifdef Q_OS_MAC
|
||||
// Do Mac specific startup to get media keys working.
|
||||
// This must go before QApplication initialisation.
|
||||
Tomahawk::macMain();
|
||||
@@ -253,11 +253,11 @@ main( int argc, char *argv[] )
|
||||
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#ifdef Q_OS_MAC64
|
||||
#ifdef Q_OS_MAC64
|
||||
static pascal OSErr appleEventHandler( const AppleEvent* e, AppleEvent*, void* )
|
||||
#elif defined Q_OS_MAC32
|
||||
#elif defined Q_OS_MAC32
|
||||
static pascal OSErr appleEventHandler( const AppleEvent* e, AppleEvent*, long )
|
||||
#endif //Q_OS_MAC64/32
|
||||
#endif //Q_OS_MAC64/32
|
||||
{
|
||||
OSType id = typeWildCard;
|
||||
AEGetAttributePtr( e, keyEventIDAttr, typeType, 0, &id, sizeof( id ), 0 );
|
||||
|
@@ -447,7 +447,6 @@ SourceTreeView::deletePlaylist( const QModelIndex& idxIn )
|
||||
|
||||
m_popupDialog.data()->move( rightCenter.x() - m_popupDialog.data()->offset(), rightCenter.y() - m_popupDialog.data()->sizeHint().height() / 2. );
|
||||
m_popupDialog.data()->show();
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -571,7 +570,7 @@ SourceTreeView::addToLocal()
|
||||
// copy to a link and then generate a new playlist from that
|
||||
// this way we cheaply regenerate the needed controls
|
||||
ScriptJob* job = Utils::LinkGenerator::instance()->openLink( playlist );
|
||||
if( !job )
|
||||
if ( !job )
|
||||
{
|
||||
// No supported generator
|
||||
return;
|
||||
@@ -586,7 +585,7 @@ SourceTreeView::addToLocal()
|
||||
|
||||
// just create the new playlist with the same values
|
||||
QList< query_ptr > queries;
|
||||
foreach( const plentry_ptr& e, playlist->entries() )
|
||||
foreach ( const plentry_ptr& e, playlist->entries() )
|
||||
queries << e->query();
|
||||
|
||||
playlist_ptr newpl = Playlist::create( SourceList::instance()->getLocal(), uuid(), playlist->title(), playlist->info(), playlist->creator(), playlist->shared(), queries );
|
||||
@@ -659,7 +658,6 @@ SourceTreeView::latchOff( const Tomahawk::source_ptr& source )
|
||||
void
|
||||
SourceTreeView::latchModeToggled( bool checked )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << checked;
|
||||
disconnect( this, SLOT( latchOff() ) );
|
||||
if ( !m_contextMenuIndex.isValid() )
|
||||
return;
|
||||
@@ -756,7 +754,7 @@ SourceTreeView::onCustomContextMenu( const QPoint& pos )
|
||||
customMenu.addActions( customActions );
|
||||
customMenu.exec( mapToGlobal( pos ) );
|
||||
}
|
||||
m_contextMenuIndex = QModelIndex(); //we invalidate it because there's no active context menu
|
||||
m_contextMenuIndex = QModelIndex(); // we invalidate it because there's no active context menu
|
||||
}
|
||||
|
||||
|
||||
@@ -797,20 +795,21 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
|
||||
{
|
||||
QTreeView::dragMoveEvent( event );
|
||||
|
||||
bool accept = false;
|
||||
if ( DropJob::isDropType( DropJob::Playlist, event->mimeData() ) )
|
||||
{
|
||||
// Don't highlight the drop for a playlist, as it won't get added to the playlist but created generally
|
||||
event->setDropAction( Qt::CopyAction );
|
||||
event->accept();
|
||||
accept = true;
|
||||
}
|
||||
else if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Track, DropJob::Append ) )
|
||||
{
|
||||
bool accept = false;
|
||||
setDirtyRegion( m_dropRect );
|
||||
const QPoint pos = event->pos();
|
||||
const QModelIndex index = indexAt( pos );
|
||||
dataChanged( m_dropIndex, m_dropIndex );
|
||||
m_dropIndex = QPersistentModelIndex( index );
|
||||
|
||||
if ( index != m_dropIndex )
|
||||
dataChanged( m_dropIndex, m_dropIndex );
|
||||
|
||||
if ( index.isValid() )
|
||||
{
|
||||
@@ -827,9 +826,10 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
|
||||
{
|
||||
case SourcesModel::StaticPlaylist:
|
||||
case SourcesModel::CategoryAdd:
|
||||
case SourcesModel::Source: //drop to send tracks to peers
|
||||
case SourcesModel::Source: // drop to send tracks to peers
|
||||
m_delegate->hovered( index, event->mimeData() );
|
||||
dataChanged( index, index );
|
||||
if ( index != m_dropIndex )
|
||||
dataChanged( index, index );
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -845,24 +845,30 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
|
||||
m_dropRect = QRect();
|
||||
}
|
||||
|
||||
if ( accept || DropJob::isDropType( DropJob::Playlist, event->mimeData() ) )
|
||||
if ( accept )
|
||||
{
|
||||
// Playlists are accepted always since they can be dropped anywhere
|
||||
//tDebug() << Q_FUNC_INFO << "Accepting";
|
||||
event->setDropAction( Qt::CopyAction );
|
||||
event->accept();
|
||||
m_dropIndex = QPersistentModelIndex( index );
|
||||
}
|
||||
else
|
||||
{
|
||||
// tDebug() << Q_FUNC_INFO << "Ignoring";
|
||||
event->ignore();
|
||||
}
|
||||
m_dropIndex = QPersistentModelIndex();
|
||||
}
|
||||
else if ( DropJob::acceptsMimeData( event->mimeData(), DropJob::Playlist | DropJob::Artist | DropJob::Album, DropJob::Create ) )
|
||||
{
|
||||
event->setDropAction( Qt::CopyAction );
|
||||
accept = true;
|
||||
}
|
||||
|
||||
if ( accept )
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
{
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
setDirtyRegion( m_dropRect );
|
||||
}
|
||||
@@ -886,26 +892,25 @@ SourceTreeView::dropEvent( QDropEvent* event )
|
||||
}*/
|
||||
|
||||
QTreeView::dropEvent( event );
|
||||
if ( event->isAccepted() )
|
||||
if ( !event->isAccepted() )
|
||||
{
|
||||
tDebug() << Q_FUNC_INFO << "Ignoring accepted event!";
|
||||
}
|
||||
// if it's a playlist drop, accept it anywhere in the sourcetree by manually parsing it.
|
||||
else if ( DropJob::isDropType( DropJob::Playlist, event->mimeData() ) )
|
||||
{
|
||||
DropJob* dropThis = new DropJob;
|
||||
dropThis->setDropTypes( DropJob::Playlist );
|
||||
dropThis->setDropAction( DropJob::Create );
|
||||
dropThis->parseMimeData( event->mimeData() );
|
||||
// if it's a playlist drop, accept it anywhere in the sourcetree by manually parsing it.
|
||||
if ( DropJob::isDropType( DropJob::Playlist, event->mimeData() ) )
|
||||
{
|
||||
DropJob* dropThis = new DropJob;
|
||||
dropThis->setDropTypes( DropJob::Playlist );
|
||||
dropThis->setDropAction( DropJob::Create );
|
||||
dropThis->parseMimeData( event->mimeData() );
|
||||
|
||||
// Don't add it to the playlist under drop, it's a new playlist now
|
||||
event->acceptProposedAction();
|
||||
event->accept();
|
||||
}
|
||||
else if ( model()->dropMimeData( event->mimeData(), event->proposedAction(), index.row(), 0, index.parent() ) )
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
event->accept();
|
||||
// Don't add it to the playlist under drop, it's a new playlist now
|
||||
event->acceptProposedAction();
|
||||
event->accept();
|
||||
}
|
||||
else if ( model()->dropMimeData( event->mimeData(), event->proposedAction(), index.row(), 0, index.parent() ) )
|
||||
{
|
||||
event->acceptProposedAction();
|
||||
event->accept();
|
||||
}
|
||||
}
|
||||
|
||||
m_dragging = false;
|
||||
@@ -944,7 +949,8 @@ SourceTreeView::keyPressEvent( QKeyEvent* event )
|
||||
void
|
||||
SourceTreeView::paintEvent( QPaintEvent* event )
|
||||
{
|
||||
if ( m_dragging && !m_dropRect.isEmpty() )
|
||||
/* Draw drag & drop hover background */
|
||||
if ( m_dragging && !m_dropRect.isEmpty() && m_dropIndex.isValid() )
|
||||
{
|
||||
QPainter painter( viewport() );
|
||||
const QRect itemRect = visualRect( m_dropIndex );
|
||||
@@ -961,13 +967,6 @@ SourceTreeView::paintEvent( QPaintEvent* event )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
|
||||
{
|
||||
QTreeView::drawRow( painter, option, index );
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::drawBranches( QPainter* /* painter */, const QRect& /* rect */, const QModelIndex& /* index */ ) const
|
||||
{
|
||||
|
@@ -92,7 +92,6 @@ private slots:
|
||||
void onPlaylistLinkReady( const QVariantMap& data );
|
||||
|
||||
protected:
|
||||
void drawRow( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const;
|
||||
void drawBranches( QPainter *painter, const QRect &rect, const QModelIndex &index ) const;
|
||||
|
||||
virtual void paintEvent( QPaintEvent* event );
|
||||
|
@@ -1,20 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
* Copyright 2010-2011, Jeff Mitchell <jeff@tomahawk-player.org>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "CategoryItems.h"
|
||||
|
@@ -1,19 +1,19 @@
|
||||
/*
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
* Copyright 2010-2011, Leo Franchi <lfranchi@kde.org>
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
* Tomahawk is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
* Tomahawk is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef CATEGORY_ITEM_H
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user