1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-09-22 20:01:31 +02:00

Compare commits

..

47 Commits

Author SHA1 Message Date
Dominik Schmidt
5d6da03dd6 Show View In Folder button if album is already completely downloaded 2016-03-10 01:32:50 +01:00
Dominik Schmidt
6a44002404 Add Result::isLocal helper method 2016-03-10 00:05:42 +01:00
Dominik Schmidt
1fa35ae827 Go back to former VLC build as the new build is crashy 2016-02-25 23:10:07 +01:00
Dominik Schmidt
26c0f35d21 Wrap error message in account config 2016-02-25 03:46:44 +01:00
Dominik Schmidt
9acbb48659 If sign_step.sh exists, require it to succeed 2016-02-25 02:52:25 +01:00
Dominik Schmidt
cc9f287b41 Don't rely on target names for export macros 2016-02-23 17:20:31 +01:00
Dominik Schmidt
99abd7434b Don't hardcode app id for vlc 2016-02-23 16:14:10 +01:00
Dominik Schmidt
f38f3ca367 Linux: Fix icon installation 2016-02-23 16:14:10 +01:00
Christian Muehlhaeuser
773ecea0da Be less verbose in SourceTreeView. 2016-02-23 02:24:10 +01:00
Christian Muehlhaeuser
620d3fe3fc Style fixes in SourceTreeView. 2016-02-23 02:23:47 +01:00
Christian Muehlhaeuser
8679fd5055 Style fix in CollectionViewPage. 2016-02-23 02:23:19 +01:00
Christian Muehlhaeuser
d7eccea4c0 Remove obsolete method in SourceTreeView. 2016-02-23 02:22:53 +01:00
Christian Muehlhaeuser
2ab9418a9e Don't paint a hover background during drag & drop, when you can't drop something on a sidebar item, e.g. groups, labels etc. 2016-02-23 02:15:45 +01:00
Christian Muehlhaeuser
285333d43b Blur the collection header background, so the labels stand out a bit more. 2016-02-23 01:20:35 +01:00
Christian Muehlhaeuser
3bcf854a4f Updated ChangeLog. 2016-02-22 22:32:54 +01:00
Christian Muehlhaeuser
61a15cafac Speed up drag & drop moves over sidebar. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
2d141ccb5e Style fix in SoureTreeView. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
4c023b7d2f Style fix in XspfUpdater. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
ceb5dc6aa4 Style fix in main.cpp. 2016-02-22 22:31:34 +01:00
Christian Muehlhaeuser
13fa9c7c53 Merge pull request #448 from tomahawk-player/vlc-volume-fix
Fix #441: Handle VLC volume and muted state properly
2016-02-22 22:31:04 +01:00
Dominik Schmidt
4c946b304c Fix #451: Can't select crash ID in the crash report UI 2016-02-22 22:02:54 +01:00
Dominik Schmidt
5075c9ddbf Fix compilation with libvlc < 2.2.2 2016-02-22 16:10:47 +01:00
Dominik Schmidt
8b3a916aa6 Update VLC for Windows 2016-02-22 16:10:47 +01:00
Dominik Schmidt
cd412add8f Persist muted state accross restarts 2016-02-22 16:10:47 +01:00
Dominik Schmidt
68851843f5 Unmute AudioOutput on start up 2016-02-22 16:10:47 +01:00
Dominik Schmidt
af8811af30 Fix volume on external (un)muting 2016-02-22 16:10:47 +01:00
Dominik Schmidt
fa38ed5e91 Sync muted state as well 2016-02-22 16:10:47 +01:00
Dominik Schmidt
b7ff630808 Sync audio volume if it's changed externally in vlc 2016-02-22 16:10:47 +01:00
Dominik Schmidt
196256d77b Fix startup volume for good 2016-02-22 16:10:47 +01:00
Dominik Schmidt
79cd3a7f0a Revert "Fix startup volume for good"
This reverts commit 86cd7c1be0.
2016-02-22 16:10:20 +01:00
Dominik Schmidt
f0f45673b1 Fix #419: Fix HLS streams on Windows (e.g. Amazon Prime Music) 2016-02-22 16:09:11 +01:00
Dominik Schmidt
86cd7c1be0 Fix startup volume for good 2016-02-22 00:10:17 +01:00
Dominik Schmidt
f74c6ae429 Fix #446: Fix compilation with Qt4 2016-02-21 18:06:14 +01:00
Dominik Schmidt
015b24479c Fix crash in context menu 2016-02-21 11:12:17 +01:00
Jason Herskowitz
8b904cf806 Make folder icon match other context menu icons 2016-02-19 10:04:32 -05:00
Christian Muehlhaeuser
175e498c43 Use folder icon for file manager in context menu. 2016-02-19 04:48:42 +01:00
Jason Herskowitz
65908f9dfa Add folder icon 2016-02-18 22:35:42 -05:00
Christian Muehlhaeuser
3c9deb6389 A few improvements regarding VLC's weird mute state on startup. 2016-02-19 04:11:11 +01:00
Christian Muehlhaeuser
978c1e58de Fixed crash in ContextMenu and moved 'open file manager' action up. 2016-02-19 03:50:17 +01:00
Christian Muehlhaeuser
0722dd7812 Merge pull request #442 from tomahawk-player/open-in-file-manager
Add "Open File in File Manager..." context menu
2016-02-19 03:37:50 +01:00
Dominik Schmidt
ff34afb4e3 Fix #425: add "Open in Folder in File Manager..." context menu to local results 2016-02-18 16:02:16 +01:00
Dominik Schmidt
bd607b6c54 DRY in ContextMenu 2016-02-18 15:40:08 +01:00
Dominik Schmidt
81f7e3f8f4 consistency++: Pass track to linkGenerator instead of title 2016-02-18 14:14:21 +01:00
Christian Muehlhaeuser
798ca62190 When waiting for a query to resolve for playback, accept the earliest online result, preventing further playback delay. 2016-02-18 07:03:17 +01:00
Christian Muehlhaeuser
f2631cda74 Don't wait for resolving to finish if we want to play a track and already got some results. 2016-02-18 06:40:16 +01:00
Dominik Schmidt
4813698a9a Allow creating basic data types from QtConcurrent::run
When QObjects are created from QtConcurrent::run they live in a pooled thread that doesn't handle events/signals/slots properly
2016-02-18 00:52:48 +01:00
Christian Muehlhaeuser
dc80d19a08 Merge pull request #399 from tomahawk-player/things
Various download and branding improvements
2016-02-17 20:32:06 +01:00
42 changed files with 394 additions and 124 deletions

View File

@@ -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.

View File

@@ -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"

View File

@@ -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
View 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

BIN
data/sounds/silence.ogg Normal file

Binary file not shown.

View File

@@ -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>

View File

@@ -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}
)

View File

@@ -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

View File

@@ -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}
)

View File

@@ -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

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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 );
}

View File

@@ -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 );

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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 )
{

View File

@@ -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.

View File

@@ -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
{

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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 );

View File

@@ -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();
@@ -951,9 +972,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 +990,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 );
}
}

View File

@@ -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 );

View File

@@ -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
{
@@ -466,11 +520,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 +539,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 +583,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 +622,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 );
}
}

View File

@@ -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;

View File

@@ -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() ) );
}
}

View File

@@ -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;

View File

@@ -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://" ) )

View File

@@ -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,32 @@ TrackDetailView::onBuyButtonClicked()
{
if ( m_query->track()->albumPtr()->purchased() )
{
emit downloadAll();
if ( m_allTracksAvailableLocally )
{
QString path;
foreach( const result_ptr& currentResult, m_query->results() ) {
if ( !currentResult->downloadFormats().isEmpty() )
{
path = DownloadManager::instance()->localFileForDownload( currentResult->downloadFormats().first().url.toString() );
}
if ( path.isEmpty() && currentResult->isLocal() )
{
path = currentResult->url();
}
if ( !path.isEmpty() )
{
QDesktopServices::openUrl( QFileInfo( path ).dir().path() );
break;
}
}
}
else
{
emit downloadAll();
}
}
else
{

View File

@@ -77,6 +77,7 @@ private:
CaptionLabel* m_resultsBoxLabel;
QPushButton* m_buyButton;
bool m_buyButtonVisible;
bool m_allTracksAvailableLocally;
QWidget* m_infoBox;
QWidget* m_resultsBox;

View File

@@ -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;
}

View File

@@ -156,6 +156,7 @@ XspfUpdater::setAutoUpdate( bool autoUpdate )
emit changed();
}
void
XspfUpdater::setInterval( int intervalMsecs )
{

View File

@@ -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 );

View File

@@ -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 )
{

View File

@@ -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 )

View File

@@ -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();
}

View File

@@ -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 );

View File

@@ -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
{

View File

@@ -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 );