1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-19 23:39:42 +01:00

Merge remote-tracking branch 'origin/master' into accounts

Conflicts:
	src/accounts/xmpp/sip/xmppsip.cpp
	src/libtomahawk/CMakeLists.txt
This commit is contained in:
Leo Franchi 2012-01-29 10:27:31 -05:00
commit e5414c8ff6
157 changed files with 2148 additions and 1118 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@ -1,4 +1,4 @@
-- Script to migate from db version 6 to 27
-- Script to migate from db version 26 to 27
-- Nothing to do
CREATE TABLE IF NOT EXISTS collection_attributes (

View File

@ -0,0 +1,7 @@
-- Script to migate from db version 27 to 28.
-- Added albumartist and discnumber to file_join
ALTER TABLE file_join ADD COLUMN composer INTEGER REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED;
ALTER TABLE file_join ADD COLUMN discnumber INTEGER;
UPDATE settings SET v = '28' WHERE k == 'schema_version';

View File

@ -128,8 +128,11 @@
<file>data/images/headphones.png</file>
<file>data/images/headphones-off.png</file>
<file>data/images/headphones-sidebar.png</file>
<file>data/images/closed-padlock.png</file>
<file>data/images/open-padlock.png</file>
<file>data/images/headphones-bigger.png</file>
<file>data/images/no-album-no-case.png</file>
<file>data/images/rdio.png</file>
<file>data/sql/dbmigrate-27_to_28.sql</file>
</qresource>
</RCC>

View File

@ -276,8 +276,14 @@ void XmlConsole::stackProcess(const QByteArray &data, bool incoming)
break;
case QXmlStreamReader::Characters:
token = d->tokens.isEmpty() ? 0 : d->tokens.last();
if (token && token->type == QXmlStreamReader::StartElement && !token->startTag.empty)
d->tokens << new StackToken(d->reader);
if (token && token->type == QXmlStreamReader::StartElement && !token->startTag.empty) {
if (*token->startTag.name == QLatin1String("auth")
&& *token->startTag.xmlns == QLatin1String("urn:ietf:params:xml:ns:xmpp-sasl")) {
d->tokens << new StackToken(QLatin1String("<<Private data>>"));
} else {
d->tokens << new StackToken(d->reader);
}
}
break;
default:
break;

View File

@ -110,6 +110,14 @@ private:
endTag.name = new QStringRef(endTag.namePointer, tmp.position(), tmp.length());
}
}
StackToken(const QString &name)
{
type = QXmlStreamReader::Characters;
charachters.textPointer = new QString(name);
charachters.text = new QStringRef(charachters.textPointer);
}
~StackToken()
{
if (type == QXmlStreamReader::StartElement) {

View File

@ -52,7 +52,6 @@
#include <QMessageBox>
#endif
#include <utils/tomahawkutilsgui.h>
#include "utils/logger.h"
@ -146,6 +145,7 @@ XmppSipPlugin::~XmppSipPlugin()
delete m_client;
}
#ifndef ENABLE_HEADLESS
QMenu*
XmppSipPlugin::menu()
@ -178,6 +178,7 @@ XmppSipPlugin::connectPlugin()
return;
}
void
XmppSipPlugin::disconnectPlugin()
{
@ -203,6 +204,7 @@ XmppSipPlugin::disconnectPlugin()
emit stateChanged( m_state );
}
void
XmppSipPlugin::onConnect()
{
@ -245,6 +247,7 @@ XmppSipPlugin::onConnect()
addMenuHelper();
}
void
XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
{
@ -286,12 +289,14 @@ XmppSipPlugin::onDisconnect( Jreen::Client::DisconnectReason reason )
}
}
void
XmppSipPlugin::onError( const Jreen::Connection::SocketError& e )
{
tLog() << "JABBER error:" << e;
tDebug() << "JABBER error:" << e;
}
QString
XmppSipPlugin::errorMessage( Jreen::Client::DisconnectReason reason )
{
@ -341,6 +346,7 @@ XmppSipPlugin::errorMessage( Jreen::Client::DisconnectReason reason )
return QString();
}
void
XmppSipPlugin::sendMsg(const QString& to, const QString& msg)
{
@ -386,6 +392,7 @@ XmppSipPlugin::sendMsg(const QString& to, const QString& msg)
connect(reply, SIGNAL(received(Jreen::IQ)), SLOT(onNewIq(Jreen::IQ)));
}
void
XmppSipPlugin::broadcastMsg(const QString& msg)
{
@ -400,6 +407,7 @@ XmppSipPlugin::broadcastMsg(const QString& msg)
}
}
void
XmppSipPlugin::addContact(const QString& jid, const QString& msg)
{
@ -414,6 +422,7 @@ XmppSipPlugin::addContact(const QString& jid, const QString& msg)
return;
}
void
XmppSipPlugin::showAddFriendDialog()
{
@ -430,6 +439,7 @@ XmppSipPlugin::showAddFriendDialog()
#endif
}
QString
XmppSipPlugin::defaultSuffix() const
{
@ -577,7 +587,7 @@ void XmppSipPlugin::onNewMessage(const Jreen::Message& message)
if( message.subtype() == Jreen::Message::Error )
{
qDebug() << Q_FUNC_INFO << "Received error message from " << from << ", not answering... (Condition: "
tDebug() << Q_FUNC_INFO << "Received error message from " << from << ", not answering... (Condition: "
<< ( message.error().isNull() ? -1 : message.error()->condition() ) << ")";
return;
}
@ -612,7 +622,7 @@ void XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, cons
Jreen::JID jid = presence.from();
QString fulljid( jid.full() );
// qDebug() << Q_FUNC_INFO << "* New presence:" << fulljid << presence.subtype();
qDebug() << Q_FUNC_INFO << "* New presence:" << fulljid << presence.subtype();
if( jid == m_client->jid() )
return;
@ -626,7 +636,7 @@ void XmppSipPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, cons
Jreen::Capabilities::Ptr caps = presence.payload<Jreen::Capabilities>();
if( caps )
{
// qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node() << "requesting disco...";
qDebug() << Q_FUNC_INFO << fulljid << "Running tomahawk: maybe" << "caps " << caps->node() << "requesting disco...";
// request disco features
QString node = caps->node() + '#' + caps->ver();
@ -698,6 +708,7 @@ void XmppSipPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, c
#endif
}
void
XmppSipPlugin::onSubscriptionRequestConfirmed( int result )
{
@ -923,7 +934,6 @@ XmppSipPlugin::readUsername()
return credentials.contains( "username" ) ? credentials[ "username" ].toString() : QString();
}
QString
XmppSipPlugin::readPassword()
{

View File

@ -26,7 +26,6 @@
#include "audio/audioengine.h"
#include "playlist/playlistview.h"
#include "database/database.h"
#include "database/databasecommand_socialaction.h"
#include "widgets/imagebutton.h"
#include "utils/tomahawkutils.h"
#include "utils/logger.h"
@ -37,8 +36,6 @@
using namespace Tomahawk;
static QString s_acInfoIdentifier = QString( "AUDIOCONTROLS" );
AudioControls::AudioControls( QWidget* parent )
: QWidget( parent )
@ -99,10 +96,12 @@ AudioControls::AudioControls( QWidget* parent )
ui->volumeSlider->setValue( AudioEngine::instance()->volume() );
m_phononTickCheckTimer.setSingleShot( true );
m_sliderTimeLine.setCurveShape( QTimeLine::LinearCurve );
ui->seekSlider->setTimeLine( &m_sliderTimeLine );
m_defaultCover = QPixmap( RESPATH "images/no-album-no-case.png" ).scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
connect( &m_phononTickCheckTimer, SIGNAL( timeout() ), SLOT( phononTickCheckTimeout() ) );
connect( &m_sliderTimeLine, SIGNAL( frameChanged( int ) ), ui->seekSlider, SLOT( setValue( int ) ) );
@ -136,15 +135,6 @@ AudioControls::AudioControls( QWidget* parent )
connect( AudioEngine::instance(), SIGNAL( timerMilliSeconds( qint64 ) ), SLOT( onPlaybackTimer( qint64 ) ) );
connect( AudioEngine::instance(), SIGNAL( volumeChanged( int ) ), SLOT( onVolumeChanged( int ) ) );
m_defaultCover = QPixmap( RESPATH "images/no-album-no-case.png" )
.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
ui->buttonAreaLayout->setSpacing( 0 );
ui->stackedLayout->setSpacing( 0 );
ui->stackedLayout->setContentsMargins( 0, 0, 0, 0 );
@ -198,8 +188,6 @@ AudioControls::onVolumeChanged( int volume )
void
AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
{
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
if ( result.isNull() )
return;
@ -215,7 +203,7 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
ui->seekSlider->setValue( 0 );
m_phononTickCheckTimer.stop();
m_sliderTimeLine.stop();
m_sliderTimeLine.setDuration( duration );
m_sliderTimeLine.setFrameRange( 0, duration );
@ -226,107 +214,90 @@ AudioControls::onPlaybackStarted( const Tomahawk::result_ptr& result )
m_noTimeChange = false;
m_lastSliderCheck = 0;
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["artist"] = result->artist()->name();
trackInfo["album"] = result->album()->name();
Tomahawk::InfoSystem::InfoRequestData requestData;
requestData.caller = s_acInfoIdentifier;
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
void
AudioControls::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
{
if ( requestData.caller != s_acInfoIdentifier || requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
{
return;
}
if ( m_currentTrack.isNull() )
{
tLog() << "Current track is null when trying to apply fetched cover art";
return;
}
if ( !output.canConvert< QVariantMap >() )
{
tDebug( LOGINFO ) << "Cannot convert fetched art from a QByteArray";
return;
}
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
QPixmap pm;
pm.loadFromData( ba );
if ( pm.isNull() )
ui->coverImage->setPixmap( m_defaultCover );
else
ui->coverImage->setPixmap( pm.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
}
}
void
AudioControls::infoSystemFinished( QString target )
{
Q_UNUSED( target );
}
void
AudioControls::onPlaybackLoading( const Tomahawk::result_ptr& result )
{
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
if ( !m_currentTrack.isNull() )
{
disconnect( m_currentTrack->album().data(), SIGNAL( updated() ), this, SLOT( onAlbumCoverUpdated() ) );
disconnect( m_currentTrack->toQuery().data(), SIGNAL( socialActionsLoaded() ), this, SLOT( onSocialActionsLoaded() ) );
}
m_currentTrack = result;
connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onAlbumCoverUpdated() ) );
connect( m_currentTrack->toQuery().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) );
ui->artistTrackLabel->setResult( result );
ui->albumLabel->setResult( result );
ui->ownerLabel->setText( result->friendlySource() );
ui->coverImage->setPixmap( m_defaultCover );
const QString duration = TomahawkUtils::timeToString( result.data()->duration() );
ui->timeLabel->setFixedWidth( ui->timeLabel->fontMetrics().width( QString( duration.length(), QChar( '0' ) ) ) );
ui->timeLabel->setText( TomahawkUtils::timeToString( 0 ) );
ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( result.data()->duration() ) );
ui->timeLeftLabel->setFixedWidth( ui->timeLeftLabel->fontMetrics().width( QString( duration.length() + 1, QChar( '0' ) ) ) );
ui->timeLeftLabel->setText( "-" + duration );
ui->stackedLayout->setCurrentWidget( ui->pauseButton );
ui->loveButton->setEnabled( true );
ui->loveButton->setVisible( true );
result->loadSocialActions();
connect( result.data(), SIGNAL( socialActionsLoaded() ), SLOT( socialActionsLoaded() ) );
setAlbumCover();
setSocialActions();
}
void
AudioControls::socialActionsLoaded()
AudioControls::onAlbumCoverUpdated()
{
Result* r = qobject_cast< Result* >( sender() );
Q_ASSERT( r );
Album* album = qobject_cast< Album* >( sender() );
if ( !album || album != m_currentTrack->album().data() )
return;
if ( m_currentTrack.data() == r )
setAlbumCover();
}
void
AudioControls::setAlbumCover()
{
if ( !m_currentTrack->album()->cover().isNull() )
{
if ( m_currentTrack->loved() )
{
ui->loveButton->setPixmap( RESPATH "images/loved.png" );
ui->loveButton->setChecked( true );
}
else
{
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
ui->loveButton->setChecked( false );
}
QPixmap cover;
cover.loadFromData( m_currentTrack->album()->cover() );
ui->coverImage->setPixmap( cover.scaled( ui->coverImage->size(), Qt::IgnoreAspectRatio, Qt::SmoothTransformation ) );
}
else
ui->coverImage->setPixmap( m_defaultCover );
}
void
AudioControls::onSocialActionsLoaded()
{
Query* query = qobject_cast< Query* >( sender() );
if ( !query || query != m_currentTrack->toQuery().data() )
return;
setSocialActions();
}
void
AudioControls::setSocialActions()
{
if ( m_currentTrack->toQuery()->loved() )
{
ui->loveButton->setPixmap( RESPATH "images/loved.png" );
ui->loveButton->setChecked( true );
}
else
{
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
ui->loveButton->setChecked( false );
}
}
@ -396,12 +367,12 @@ AudioControls::onPlaybackTimer( qint64 msElapsed )
m_sliderTimeLine.stop();
return;
}
ui->seekSlider->blockSignals( true );
if ( sender() != &m_phononTickCheckTimer )
m_phononTickCheckTimer.start( 1000 );
const int seconds = msElapsed / 1000;
ui->timeLabel->setText( TomahawkUtils::timeToString( seconds ) );
ui->timeLeftLabel->setText( "-" + TomahawkUtils::timeToString( m_currentTrack->duration() - seconds ) );
@ -616,30 +587,17 @@ AudioControls::droppedTracks( QList< query_ptr > tracks )
void
AudioControls::onLoveButtonClicked( bool checked )
{
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["title"] = m_currentTrack->track();
trackInfo["artist"] = m_currentTrack->artist()->name();
trackInfo["album"] = m_currentTrack->album()->name();
if ( checked )
{
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoLove,
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) );
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "true") );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
ui->loveButton->setPixmap( RESPATH "images/loved.png" );
m_currentTrack->toQuery()->setLoved( true );
}
else
{
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
s_acInfoIdentifier, Tomahawk::InfoSystem::InfoUnLove,
QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo ) );
DatabaseCommand_SocialAction* cmd = new DatabaseCommand_SocialAction( m_currentTrack, QString( "Love" ), QString( "false" ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>(cmd) );
ui->loveButton->setPixmap( RESPATH "images/not-loved.png" );
m_currentTrack->toQuery()->setLoved( false );
}
}

View File

@ -25,7 +25,6 @@
#include "result.h"
#include "playlistinterface.h"
#include "infosystem/infosystem.h"
#include "query.h"
class QDropEvent;
@ -80,14 +79,16 @@ private slots:
void onTrackClicked();
void onLoveButtonClicked( bool );
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void infoSystemFinished( QString target );
void onAlbumCoverUpdated();
void droppedTracks( QList<Tomahawk::query_ptr> );
void socialActionsLoaded();
void onSocialActionsLoaded();
private:
void setAlbumCover();
void setSocialActions();
Ui::AudioControls *ui;
QPixmap m_defaultCover;

View File

@ -345,6 +345,9 @@
<property name="text">
<string>Time</string>
</property>
<property name="alignment">
<set>Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item>
@ -371,6 +374,9 @@
<property name="text">
<string>Time Left</string>
</property>
<property name="alignment">
<set>Qt::AlignRight|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout>

View File

@ -150,7 +150,6 @@ set( libGuiHeaders
contextmenu.h
dropjob.h
viewpage.h
viewmanager.h
globalactionmanager.h
LatchManager.h
@ -235,7 +234,6 @@ set( libGuiHeaders
utils/rdioparser.h
utils/shortenedlinkparser.h
utils/dropjobnotifier.h
utils/tomahawkutilsgui.h
widgets/checkdirtree.h
widgets/querylabel.h
@ -402,6 +400,14 @@ set( libSources
playlist/dynamic/database/DatabaseControl.cpp
playlist/dynamic/DynamicControl.cpp
taghandlers/tag.cpp
taghandlers/apetag.cpp
taghandlers/asftag.cpp
taghandlers/id3v1tag.cpp
taghandlers/id3v2tag.cpp
taghandlers/mp4tag.cpp
taghandlers/oggtag.cpp
utils/tomahawkutils.cpp
utils/logger.cpp
utils/qnr_iodevicestream.cpp
@ -436,6 +442,7 @@ set( libHeaders
albumplaylistinterface.h
playlist.h
playlistplaylistinterface.h
viewpage.h
accounts/Account.h
accounts/AccountManager.h
@ -536,6 +543,7 @@ set( libHeaders
thirdparty/kdsingleapplicationguard/kdsingleapplicationguard.h
utils/tomahawkutilsgui.h
utils/xspfloader.h
utils/qnr_iodevicestream.h
)
@ -547,6 +555,14 @@ set( libHeaders_NoMOC
infosystem/infoplugins/unix/imageconverter.h
taghandlers/tag.h
taghandlers/apetag.h
taghandlers/asftag.h
taghandlers/id3v1tag.h
taghandlers/id3v2tag.h
taghandlers/mp4tag.h
taghandlers/oggtag.h
utils/tomahawkutils.h
)

View File

@ -22,8 +22,7 @@
#include "audio/audioengine.h"
#include "database/database.h"
#include <QtCore/QStateMachine>
#include <QtCore/QState>
#include <QtGui/QAction>
#include "sourcelist.h"
#include "database/databasecommand_socialaction.h"
#include "sourceplaylistinterface.h"
@ -58,7 +57,7 @@ LatchManager::latchRequest( const source_ptr& source )
m_state = Latching;
m_waitingForLatch = source;
AudioEngine::instance()->playItem( source->getPlaylistInterface(), source->getPlaylistInterface()->nextItem() );
AudioEngine::instance()->playItem( source->playlistInterface(), source->playlistInterface()->nextItem() );
}
void
@ -71,7 +70,7 @@ LatchManager::playlistChanged( Tomahawk::playlistinterface_ptr )
return; // Neither latched on nor waiting to be latched on, no-op
m_latchedOnTo = m_waitingForLatch;
m_latchedInterface = m_waitingForLatch->getPlaylistInterface();
m_latchedInterface = m_waitingForLatch->playlistInterface();
m_waitingForLatch.clear();
m_state = Latched;
@ -82,7 +81,9 @@ LatchManager::playlistChanged( Tomahawk::playlistinterface_ptr )
cmd->setTimestamp( QDateTime::currentDateTime().toTime_t() );
Database::instance()->enqueue( QSharedPointer< DatabaseCommand >( cmd ) );
ActionCollection::instance()->getAction( "latchOn" )->setText( tr( "&Catch Up" ) );
QAction *latchOnAction = ActionCollection::instance()->getAction( "latchOn" );
latchOnAction->setText( tr( "&Catch Up" ) );
latchOnAction->setIcon( QIcon() );
// If not, then keep waiting
return;
@ -117,7 +118,9 @@ LatchManager::playlistChanged( Tomahawk::playlistinterface_ptr )
m_state = NotLatched;
ActionCollection::instance()->getAction( "latchOn" )->setText( tr( "&Listen Along" ) );
QAction *latchOnAction = ActionCollection::instance()->getAction( "latchOn" );
latchOnAction->setText( tr( "&Listen Along" ) );
latchOnAction->setIcon( QIcon( RESPATH "images/headphones-sidebar.png" ) );
}
@ -128,6 +131,7 @@ LatchManager::catchUpRequest()
AudioEngine::instance()->next();
}
void
LatchManager::unlatchRequest( const source_ptr& source )
{
@ -135,5 +139,19 @@ LatchManager::unlatchRequest( const source_ptr& source )
AudioEngine::instance()->stop();
AudioEngine::instance()->setPlaylist( Tomahawk::playlistinterface_ptr() );
ActionCollection::instance()->getAction( "latchOn" )->setText( tr( "&Listen Along" ) );
QAction *latchOnAction = ActionCollection::instance()->getAction( "latchOn" );
latchOnAction->setText( tr( "&Listen Along" ) );
latchOnAction->setIcon( QIcon( RESPATH "images/headphones-sidebar.png" ) );
}
void
LatchManager::latchModeChangeRequest( const Tomahawk::source_ptr& source, bool realtime )
{
if ( !isLatched( source ) )
return;
source->playlistInterface()->setLatchMode( realtime ? Tomahawk::PlaylistInterface::RealTime : Tomahawk::PlaylistInterface::StayOnSong );
if ( realtime )
catchUpRequest();
}

View File

@ -43,6 +43,7 @@ public slots:
void latchRequest( const Tomahawk::source_ptr& source );
void unlatchRequest( const Tomahawk::source_ptr& source );
void catchUpRequest();
void latchModeChangeRequest( const Tomahawk::source_ptr& source, bool realtime );
private slots:
void playlistChanged( Tomahawk::playlistinterface_ptr );

View File

@ -46,6 +46,10 @@ ActionCollection::initActions()
latchOff->setIcon( QIcon( RESPATH "images/headphones-off.png" ) );
m_actionCollection[ "latchOff" ] = latchOff;
QAction *realtimeFollowingAlong = new QAction( tr( "&Follow in real-time" ), this );
realtimeFollowingAlong->setCheckable( true );
m_actionCollection[ "realtimeFollowingAlong" ] = realtimeFollowingAlong;
bool isPublic = TomahawkSettings::instance()->privateListeningMode() == TomahawkSettings::PublicListening;
QAction *privacyToggle = new QAction( ( isPublic ? tr( "&Listen Privately" ) : tr( "&Listen Publicly" ) ), this );
privacyToggle->setIcon( QIcon( RESPATH "images/private-listening.png" ) );

View File

@ -21,7 +21,7 @@
#include "dllmacro.h"
#include <QAction>
#include <QtGui/QAction>
class DLLEXPORT ActionCollection : public QObject
{

View File

@ -29,8 +29,11 @@
using namespace Tomahawk;
Album::Album() {}
Album::~Album() {}
Album::~Album()
{
}
album_ptr
Album::get( const Tomahawk::artist_ptr& artist, const QString& name, bool autoCreate )
@ -68,19 +71,21 @@ Album::Album( unsigned int id, const QString& name, const Tomahawk::artist_ptr&
, m_id( id )
, m_name( name )
, m_artist( artist )
, m_infoLoaded( false )
{
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
}
void
Album::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
{
qDebug() << Q_FUNC_INFO;
Tomahawk::AlbumPlaylistInterface* api = dynamic_cast< Tomahawk::AlbumPlaylistInterface* >( getPlaylistInterface().data() );
Tomahawk::AlbumPlaylistInterface* api = dynamic_cast< Tomahawk::AlbumPlaylistInterface* >( playlistInterface().data() );
if ( api )
api->addQueries( tracks );
emit tracksAdded( tracks );
}
@ -92,13 +97,61 @@ Album::artist() const
}
QByteArray
Album::cover() const
{
if ( !m_infoLoaded )
{
m_uuid = uuid();
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["artist"] = artist()->name();
trackInfo["album"] = name();
Tomahawk::InfoSystem::InfoRequestData requestData;
requestData.caller = m_uuid;
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
return m_cover;
}
void
Album::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
{
if ( requestData.caller != m_uuid ||
requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
{
return;
}
m_infoLoaded = true;
if ( !output.isNull() && output.isValid() )
{
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
m_cover = ba;
}
}
emit updated();
}
Tomahawk::playlistinterface_ptr
Album::getPlaylistInterface()
Album::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{
m_playlistInterface = Tomahawk::playlistinterface_ptr( new Tomahawk::AlbumPlaylistInterface( this ) );
}
return m_playlistInterface;
}
}

View File

@ -25,6 +25,7 @@
#include "typedefs.h"
#include "playlistinterface.h"
#include "dllmacro.h"
#include "infosystem/infosystem.h"
namespace Tomahawk
{
@ -43,23 +44,29 @@ public:
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
artist_ptr artist() const;
QByteArray cover() const;
bool infoLoaded() const { return m_infoLoaded; }
Tomahawk::playlistinterface_ptr getPlaylistInterface();
Tomahawk::playlistinterface_ptr playlistInterface();
signals:
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void updated();
private slots:
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
private:
Q_DISABLE_COPY( Album )
explicit Album();
unsigned int m_id;
QString m_name;
artist_ptr m_artist;
QByteArray m_cover;
bool m_infoLoaded;
mutable QString m_uuid;
Tomahawk::playlistinterface_ptr m_playlistInterface;
};

View File

@ -88,11 +88,12 @@ AlbumPlaylistInterface::tracks()
if ( m_queries.isEmpty() && m_album )
{
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks();
cmd->setAlbum( m_album.data() );
cmd->setAlbum( m_album );
cmd->setSortOrder( DatabaseCommand_AllTracks::AlbumPosition );
//this takes discnumber into account as well
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
m_album.data(), SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}

View File

@ -59,7 +59,7 @@ public:
virtual void addQueries( const QList<Tomahawk::query_ptr>& tracks );
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void repeatModeChanged( Tomahawk::PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void trackCountChanged( unsigned int tracks );

View File

@ -29,11 +29,6 @@
using namespace Tomahawk;
Artist::Artist()
{
}
Artist::~Artist()
{
}
@ -74,24 +69,75 @@ Artist::Artist( unsigned int id, const QString& name )
: QObject()
, m_id( id )
, m_name( name )
, m_infoLoaded( false )
{
m_sortname = DatabaseImpl::sortname( name, true );
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
}
void
Artist::onTracksAdded( const QList<Tomahawk::query_ptr>& tracks )
{
qDebug() << Q_FUNC_INFO;
Tomahawk::ArtistPlaylistInterface* api = dynamic_cast< Tomahawk::ArtistPlaylistInterface* >( getPlaylistInterface().data() );
Tomahawk::ArtistPlaylistInterface* api = dynamic_cast< Tomahawk::ArtistPlaylistInterface* >( playlistInterface().data() );
if ( api )
api->addQueries( tracks );
emit tracksAdded( tracks );
}
QByteArray
Artist::cover() const
{
if ( !m_infoLoaded )
{
m_uuid = uuid();
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["artist"] = name();
Tomahawk::InfoSystem::InfoRequestData requestData;
requestData.caller = m_uuid;
requestData.type = Tomahawk::InfoSystem::InfoArtistImages;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
return m_cover;
}
void
Artist::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
{
if ( requestData.caller != m_uuid ||
requestData.type != Tomahawk::InfoSystem::InfoArtistImages )
{
return;
}
m_infoLoaded = true;
if ( !output.isNull() && output.isValid() )
{
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
m_cover = ba;
}
}
emit updated();
}
Tomahawk::playlistinterface_ptr
Artist::getPlaylistInterface()
Artist::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -24,6 +24,7 @@
#include "typedefs.h"
#include "dllmacro.h"
#include "infosystem/infosystem.h"
namespace Tomahawk
{
@ -35,29 +36,36 @@ Q_OBJECT
public:
static artist_ptr get( const QString& name, bool autoCreate = false );
static artist_ptr get( unsigned int id, const QString& name );
explicit Artist( unsigned int id, const QString& name );
explicit Artist();
explicit Artist( unsigned int id, const QString& name );
virtual ~Artist();
unsigned int id() const { return m_id; }
QString name() const { return m_name; }
QString sortname() const { return m_sortname; }
QByteArray cover() const;
bool infoLoaded() const { return m_infoLoaded; }
Tomahawk::playlistinterface_ptr getPlaylistInterface();
Tomahawk::playlistinterface_ptr playlistInterface();
signals:
void tracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void updated();
private slots:
void onTracksAdded( const QList<Tomahawk::query_ptr>& tracks );
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
private:
Q_DISABLE_COPY( Artist )
unsigned int m_id;
QString m_name;
QString m_sortname;
QByteArray m_cover;
bool m_infoLoaded;
mutable QString m_uuid;
Tomahawk::playlistinterface_ptr m_playlistInterface;
};

View File

@ -86,7 +86,7 @@ ArtistPlaylistInterface::tracks()
if ( m_queries.isEmpty() && m_artist )
{
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks();
cmd->setArtist( m_artist.data() );
cmd->setArtist( m_artist );
cmd->setSortOrder( DatabaseCommand_AllTracks::Album );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),

View File

@ -58,15 +58,6 @@ public:
virtual void addQueries( const QList<Tomahawk::query_ptr>& tracks );
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void trackCountChanged( unsigned int tracks );
void sourceTrackCountChanged( unsigned int tracks );
void nextTrackReady();
private:
Q_DISABLE_COPY( ArtistPlaylistInterface )

View File

@ -18,8 +18,8 @@
#include "audioengine.h"
#include <QUrl>
#include <QNetworkReply>
#include <QtCore/QUrl>
#include <QtNetwork/QNetworkReply>
#include "playlistinterface.h"
#include "sourceplaylistinterface.h"
@ -29,7 +29,7 @@
#include "network/servent.h"
#include "utils/qnr_iodevicestream.h"
#include "headlesscheck.h"
#include "infosystem/infosystem.h"
#include "album.h"
#include "utils/logger.h"
@ -55,7 +55,6 @@ AudioEngine::AudioEngine()
, m_timeElapsed( 0 )
, m_expectStop( false )
, m_waitingOnNewTrack( false )
, m_infoSystemConnected( false )
, m_state( Stopped )
{
s_instance = this;
@ -73,8 +72,10 @@ AudioEngine::AudioEngine()
connect( m_mediaObject, SIGNAL( tick( qint64 ) ), SLOT( timerTriggered( qint64 ) ) );
connect( m_mediaObject, SIGNAL( aboutToFinish() ), SLOT( onAboutToFinish() ) );
connect( m_audioOutput, SIGNAL( volumeChanged( qreal ) ), this, SLOT( onVolumeChanged( qreal ) ) );
connect( m_audioOutput, SIGNAL( volumeChanged( qreal ) ), SLOT( onVolumeChanged( qreal ) ) );
connect( this, SIGNAL( sendWaitingNotification() ), SLOT( sendWaitingNotificationSlot() ), Qt::QueuedConnection );
onVolumeChanged( m_audioOutput->volume() );
#ifndef Q_WS_X11
@ -179,9 +180,7 @@ AudioEngine::stop()
map[ Tomahawk::InfoSystem::InfoNowStopped ] = QVariant();
if ( m_waitingOnNewTrack )
{
sendWaitingNotification();
}
emit sendWaitingNotification();
else if ( TomahawkSettings::instance()->verboseNotifications() )
{
QVariantMap stopInfo;
@ -228,12 +227,12 @@ AudioEngine::canGoNext()
m_playlist.data()->skipRestrictions() == PlaylistInterface::NoSkipForwards )
return false;
if ( !m_currentTrack.isNull() && !m_playlist.data()->hasNextItem() &&
( m_playlist.data()->currentItem().isNull() || ( m_currentTrack->id() == m_playlist.data()->currentItem()->id() ) ) )
if ( !m_currentTrack.isNull() && !m_playlist->hasNextItem() &&
( m_playlist->currentItem().isNull() || ( m_currentTrack->id() == m_playlist->currentItem()->id() ) ) )
{
//For instance, when doing a catch-up while listening along, but the person
//you're following hasn't started a new track yet...don't do anything
tDebug( LOGEXTRA ) << Q_FUNC_INFO << "catch up";
tDebug( LOGEXTRA ) << Q_FUNC_INFO << "catch up, but same track or can't move on because don't have next track or it wasn't resolved";
return false;
}
@ -311,8 +310,13 @@ AudioEngine::mute()
void
AudioEngine::sendWaitingNotification() const
AudioEngine::sendWaitingNotificationSlot() const
{
tDebug( LOGVERBOSE ) << Q_FUNC_INFO;
//since it's async, after this is triggered our result could come in, so don't show the popup in that case
if ( !m_playlist.isNull() && m_playlist->hasNextItem() )
return;
QVariantMap retryInfo;
retryInfo["message"] = QString( "The current track could not be resolved. Tomahawk will pick back up with the next resolvable track from this source." );
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
@ -324,62 +328,38 @@ AudioEngine::sendWaitingNotification() const
void
AudioEngine::sendNowPlayingNotification()
{
tDebug( LOGEXTRA ) << Q_FUNC_INFO;
if ( ! m_infoSystemConnected )
if ( m_currentTrack->album().isNull() || m_currentTrack->album()->infoLoaded() )
onNowPlayingInfoReady();
else
{
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
m_infoSystemConnected = true;
connect( m_currentTrack->album().data(), SIGNAL( updated() ), SLOT( onNowPlayingInfoReady() ), Qt::UniqueConnection );
m_currentTrack->album()->cover();
}
Tomahawk::InfoSystem::InfoStringHash trackInfo;
trackInfo["artist"] = m_currentTrack->album()->artist()->name();
trackInfo["album"] = m_currentTrack->album()->name();
Tomahawk::InfoSystem::InfoRequestData requestData;
requestData.caller = s_aeInfoIdentifier;
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
void
AudioEngine::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
AudioEngine::onNowPlayingInfoReady()
{
if ( requestData.caller != s_aeInfoIdentifier ||
requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt )
{
return;
}
if ( m_currentTrack.isNull() ||
m_currentTrack->track().isNull() ||
m_currentTrack->artist().isNull() )
return;
if ( !m_currentTrack->album().isNull() && sender() && m_currentTrack->album().data() != sender() )
return;
QVariantMap playInfo;
playInfo["message"] = tr( "Tomahawk is playing \"%1\" by %2%3." )
.arg( m_currentTrack->track() )
.arg( m_currentTrack->artist()->name() )
.arg( m_currentTrack->album().isNull() ? QString() : tr( " on album %1" ).arg( m_currentTrack->album()->name() ) );
if ( !output.isNull() && output.isValid() )
.arg( m_currentTrack->album().isNull() ? QString() : QString( " %1" ).arg( tr( "on album %1" ).arg( m_currentTrack->album()->name() ) ) );
if ( !m_currentTrack->album().isNull() )
{
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
QPixmap pm;
pm.loadFromData( ba );
playInfo["image"] = QVariant( pm.toImage() );
}
QImage cover;
cover.loadFromData( m_currentTrack->album()->cover() );
playInfo["image"] = QVariant( cover );
}
Tomahawk::InfoSystem::InfoSystem::instance()->pushInfo(
@ -388,13 +368,6 @@ AudioEngine::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData,
}
void
AudioEngine::infoSystemFinished( QString caller )
{
Q_UNUSED( caller );
}
bool
AudioEngine::loadTrack( const Tomahawk::result_ptr& result )
{
@ -570,7 +543,7 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
{
m_waitingOnNewTrack = true;
if ( isStopped() )
sendWaitingNotification();
emit sendWaitingNotification();
else
stop();
}
@ -578,8 +551,16 @@ AudioEngine::playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk:
void
AudioEngine::playlistNextTrackReady()
AudioEngine::onPlaylistNextTrackReady()
{
// If in real-time and you have a few seconds left, you're probably lagging -- finish it up
if ( m_playlist && m_playlist->latchMode() == PlaylistInterface::RealTime && ( m_waitingOnNewTrack || m_currentTrack.isNull() || m_currentTrack->id() == 0 || ( currentTrackTotalTime() - currentTime() > 6000 ) ) )
{
m_waitingOnNewTrack = false;
loadNextTrack();
return;
}
if ( !m_waitingOnNewTrack )
return;
@ -697,7 +678,7 @@ AudioEngine::setPlaylist( Tomahawk::playlistinterface_ptr playlist )
m_playlist = playlist;
if ( !m_playlist.isNull() && m_playlist.data() && m_playlist.data()->retryMode() == PlaylistInterface::Retry )
connect( m_playlist.data(), SIGNAL( nextTrackReady() ), SLOT( playlistNextTrackReady() ) );
connect( m_playlist.data(), SIGNAL( nextTrackReady() ), SLOT( onPlaylistNextTrackReady() ) );
emit playlistChanged( playlist );
}

View File

@ -26,8 +26,6 @@
#include <phonon/AudioOutput>
#include <phonon/BackendCapabilities>
#include "infosystem/infosystem.h"
#include "result.h"
#include "typedefs.h"
#include "playlistinterface.h"
@ -87,18 +85,12 @@ public slots:
void setVolume( int percentage );
void lowerVolume() { setVolume( volume() - AUDIO_VOLUME_STEP ); }
void raiseVolume() { setVolume( volume() + AUDIO_VOLUME_STEP ); }
void onVolumeChanged( qreal volume ) { emit volumeChanged( volume * 100 ); }
void mute();
void playItem( Tomahawk::playlistinterface_ptr playlist, const Tomahawk::result_ptr& result );
void setPlaylist( Tomahawk::playlistinterface_ptr playlist );
void setQueue( Tomahawk::playlistinterface_ptr queue ) { m_queue = queue; }
void playlistNextTrackReady();
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void infoSystemFinished( QString caller );
signals:
void loading( const Tomahawk::result_ptr& track );
void started( const Tomahawk::result_ptr& track );
@ -120,6 +112,8 @@ signals:
void error( AudioEngine::AudioErrorCode errorCode );
void sendWaitingNotification();
private slots:
bool loadTrack( const Tomahawk::result_ptr& result );
void loadPreviousTrack();
@ -127,9 +121,14 @@ private slots:
void onAboutToFinish();
void onStateChanged( Phonon::State newState, Phonon::State oldState );
void onVolumeChanged( qreal volume ) { emit volumeChanged( volume * 100 ); }
void timerTriggered( qint64 time );
void setCurrentTrack( const Tomahawk::result_ptr& result );
void onNowPlayingInfoReady();
void onPlaylistNextTrackReady();
void sendWaitingNotificationSlot() const;
private:
void setState( AudioState state );
@ -137,7 +136,6 @@ private:
bool isHttpResult( const QString& ) const;
bool isLocalResult( const QString& ) const;
void sendWaitingNotification() const;
void sendNowPlayingNotification();
QSharedPointer<QIODevice> m_input;
@ -154,7 +152,6 @@ private:
unsigned int m_timeElapsed;
bool m_expectStop;
bool m_waitingOnNewTrack;
bool m_infoSystemConnected;
mutable QStringList m_supportedMimeTypes;
AudioState m_state;

View File

@ -32,11 +32,12 @@ using namespace Tomahawk;
ContextMenu::ContextMenu( QWidget* parent )
: QMenu( parent )
, m_loveAction( 0 )
{
m_sigmap = new QSignalMapper( this );
connect( m_sigmap, SIGNAL( mapped( int ) ), SLOT( onTriggered( int ) ) );
m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink;
m_supportedActions = ActionPlay | ActionQueue | ActionCopyLink | ActionLove;
}
@ -59,7 +60,7 @@ ContextMenu::clear()
unsigned int
ContextMenu::itemCount() const
{
return m_queries.count() + m_artists.count() + m_albums.count();
return m_queries.count() + m_artists.count() + m_albums.count();
}
@ -81,8 +82,17 @@ ContextMenu::setQueries( const QList<Tomahawk::query_ptr>& queries )
addSeparator();
if ( m_supportedActions & ActionLove && itemCount() == 1 )
{
m_loveAction = addAction( tr( "&Love" ) );
m_sigmap->setMapping( m_loveAction, ActionLove );
connect( queries.first().data(), SIGNAL( socialActionsLoaded() ), SLOT( onSocialActionsLoaded() ) );
onSocialActionsLoaded();
}
if ( m_supportedActions & ActionCopyLink && itemCount() == 1 )
m_sigmap->setMapping( addAction( tr( "Copy Track &Link" ) ), ActionCopyLink );
m_sigmap->setMapping( addAction( tr( "&Copy Track Link" ) ), ActionCopyLink );
addSeparator();
@ -117,7 +127,7 @@ ContextMenu::setAlbums( const QList<Tomahawk::album_ptr>& albums )
m_albums << albums;
if ( m_supportedActions & ActionPlay && itemCount() == 1 )
m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay );
m_sigmap->setMapping( addAction( tr( "Show &Album page" ) ), ActionPlay );
if ( m_supportedActions & ActionQueue )
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
@ -156,7 +166,7 @@ ContextMenu::setArtists( const QList<Tomahawk::artist_ptr>& artists )
m_artists << artists;
if ( m_supportedActions & ActionPlay && itemCount() == 1 )
m_sigmap->setMapping( addAction( tr( "&Play" ) ), ActionPlay );
m_sigmap->setMapping( addAction( tr( "Show &Artist page" ) ), ActionPlay );
if ( m_supportedActions & ActionQueue )
m_sigmap->setMapping( addAction( tr( "Add to &Queue" ) ), ActionQueue );
@ -197,6 +207,10 @@ ContextMenu::onTriggered( int action )
copyLink();
break;
case ActionLove:
m_queries.first()->setLoved( !m_queries.first()->loved() );
break;
default:
emit triggered( action );
}
@ -232,3 +246,19 @@ ContextMenu::copyLink()
GlobalActionManager::instance()->copyToClipboard( m_queries.first() );
}
}
void
ContextMenu::onSocialActionsLoaded()
{
if ( m_queries.first()->loved() )
{
m_loveAction->setText( tr( "Un-&Love" ) );
m_loveAction->setIcon( QIcon( RESPATH "images/not-loved.png" ) );
}
else
{
m_loveAction->setText( tr( "&Love" ) );
m_loveAction->setIcon( QIcon( RESPATH "images/loved.png" ) );
}
}

View File

@ -38,7 +38,8 @@ public:
ActionPlay = 1,
ActionQueue = 2,
ActionDelete = 4,
ActionCopyLink = 8
ActionCopyLink = 8,
ActionLove = 16
};
explicit ContextMenu( QWidget* parent = 0 );
@ -68,10 +69,14 @@ private slots:
void copyLink();
void addToQueue();
void onSocialActionsLoaded();
private:
QSignalMapper* m_sigmap;
int m_supportedActions;
QAction* m_loveAction;
QList<Tomahawk::query_ptr> m_queries;
QList<Tomahawk::artist_ptr> m_artists;
QList<Tomahawk::album_ptr> m_albums;

View File

@ -80,7 +80,7 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
TomahawkSqlQuery query_trackattr = dbi->newquery();
query_file.prepare( "INSERT INTO file(source, url, size, mtime, md5, mimetype, duration, bitrate) VALUES (?, ?, ?, ?, ?, ?, ?, ?)" );
query_filejoin.prepare( "INSERT INTO file_join(file, artist, album, track, albumpos) VALUES (?, ?, ?, ?, ?)" );
query_filejoin.prepare( "INSERT INTO file_join(file, artist, album, track, albumpos, composer, discnumber) VALUES (?, ?, ?, ?, ?, ?, ?)" );
query_trackattr.prepare( "INSERT INTO track_attributes(id, k, v) VALUES (?, ?, ?)" );
int added = 0;
@ -92,7 +92,8 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
{
QVariant& v = *it;
QVariantMap m = v.toMap();
int fileid = 0, artistid = 0, albumid = 0, trackid = 0;
int fileid = 0, artistid = 0, albumid = 0, trackid = 0, composerid = 0;
QString url = m.value( "url" ).toString();
int mtime = m.value( "mtime" ).toInt();
@ -105,6 +106,8 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
QString album = m.value( "album" ).toString();
QString track = m.value( "track" ).toString();
uint albumpos = m.value( "albumpos" ).toUInt();
QString composer = m.value( "composer" ).toString();
uint discnumber = m.value( "discnumber" ).toUInt();
int year = m.value( "year" ).toInt();
query_file.bindValue( 0, srcid );
@ -134,13 +137,22 @@ DatabaseCommand_AddFiles::exec( DatabaseImpl* dbi )
continue;
albumid = dbi->albumId( artistid, album, true );
if( !composer.trimmed().isEmpty() )
composerid = dbi->artistId( composer, true );
// Now add the association
query_filejoin.bindValue( 0, fileid );
query_filejoin.bindValue( 1, artistid );
query_filejoin.bindValue( 2, albumid > 0 ? albumid : QVariant( QVariant::Int ) );
query_filejoin.bindValue( 3, trackid );
query_filejoin.bindValue( 4, albumpos );
query_filejoin.exec();
query_filejoin.bindValue( 5, composerid > 0 ? composerid : QVariant( QVariant::Int ) );
query_filejoin.bindValue( 6, discnumber );
if ( !query_filejoin.exec() )
{
qDebug() << "Error inserting into file_join table";
continue;
}
query_trackattr.bindValue( 0, trackid );
query_trackattr.bindValue( 1, "releaseyear" );

View File

@ -40,7 +40,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
break;
case Album:
m_orderToken = "album.name, file_join.albumpos";
m_orderToken = "album.name, file_join.discnumber, file_join.albumpos";
break;
case ModificationTime:
@ -48,7 +48,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
break;
case AlbumPosition:
m_orderToken = "file_join.albumpos";
m_orderToken = "file_join.discnumber, file_join.albumpos";
break;
}
@ -60,7 +60,7 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
{
if ( m_album->id() == 0 )
{
m_artist = m_album->artist().data();
m_artist = m_album->artist();
albumToken = QString( "AND album.id IS NULL" );
}
else
@ -68,11 +68,15 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
}
QString sql = QString(
"SELECT file.id, artist.name, album.name, track.name, file.size, "
"file.duration, file.bitrate, file.url, file.source, file.mtime, file.mimetype, file_join.albumpos, artist.id, album.id, track.id "
"SELECT file.id, artist.name, album.name, track.name, composer.name, file.size, " //0
"file.duration, file.bitrate, file.url, file.source, file.mtime, " //6
"file.mimetype, file_join.discnumber, file_join.albumpos, artist.id, " //11
"album.id, track.id, composer.id " //15
"FROM file, artist, track, file_join "
"LEFT OUTER JOIN album "
"ON file_join.album = album.id "
"LEFT OUTER JOIN artist AS composer "
"ON file_join.composer = composer.id "
"WHERE file.id = file_join.file "
"AND file_join.artist = artist.id "
"AND file_join.track = track.id "
@ -92,15 +96,15 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
while( query.next() )
{
Tomahawk::source_ptr s;
QString url = query.value( 7 ).toString();
QString url = query.value( 8 ).toString();
if ( query.value( 8 ).toUInt() == 0 )
if ( query.value( 9 ).toUInt() == 0 )
{
s = SourceList::instance()->getLocal();
}
else
{
s = SourceList::instance()->get( query.value( 8 ).toUInt() );
s = SourceList::instance()->get( query.value( 9 ).toUInt() );
if ( s.isNull() )
{
Q_ASSERT( false );
@ -110,26 +114,30 @@ DatabaseCommand_AllTracks::exec( DatabaseImpl* dbi )
url = QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url );
}
QString artist, track, album;
QString artist, track, album, composer;
artist = query.value( 1 ).toString();
album = query.value( 2 ).toString();
track = query.value( 3 ).toString();
composer = query.value( 4 ).toString();
Tomahawk::result_ptr result = Tomahawk::Result::get( url );
Tomahawk::query_ptr qry = Tomahawk::Query::get( artist, track, album );
Tomahawk::artist_ptr artistptr = Tomahawk::Artist::get( query.value( 12 ).toUInt(), artist );
Tomahawk::album_ptr albumptr = Tomahawk::Album::get( query.value( 13 ).toUInt(), album, artistptr );
Tomahawk::artist_ptr artistptr = Tomahawk::Artist::get( query.value( 14 ).toUInt(), artist );
Tomahawk::artist_ptr composerptr = Tomahawk::Artist::get( query.value( 17 ).toUInt(), composer );
Tomahawk::album_ptr albumptr = Tomahawk::Album::get( query.value( 15 ).toUInt(), album, artistptr );
result->setTrackId( query.value( 14 ).toUInt() );
result->setTrackId( query.value( 16 ).toUInt() );
result->setArtist( artistptr );
result->setAlbum( albumptr );
result->setTrack( query.value( 3 ).toString() );
result->setSize( query.value( 4 ).toUInt() );
result->setDuration( query.value( 5 ).toUInt() );
result->setBitrate( query.value( 6 ).toUInt() );
result->setModificationTime( query.value( 9 ).toUInt() );
result->setMimetype( query.value( 10 ).toString() );
result->setAlbumPos( query.value( 11 ).toUInt() );
result->setComposer( composerptr );
result->setSize( query.value( 5 ).toUInt() );
result->setDuration( query.value( 6 ).toUInt() );
result->setBitrate( query.value( 7 ).toUInt() );
result->setModificationTime( query.value( 10 ).toUInt() );
result->setMimetype( query.value( 11 ).toString() );
result->setDiscNumber( query.value( 12 ).toUInt() );
result->setAlbumPos( query.value( 13 ).toUInt() );
result->setScore( 1.0 );
result->setCollection( s->collection() );

View File

@ -26,6 +26,8 @@
#include "collection.h"
#include "typedefs.h"
#include "query.h"
#include "artist.h"
#include "album.h"
#include "dllmacro.h"
@ -55,8 +57,8 @@ public:
virtual bool doesMutates() const { return false; }
virtual QString commandname() const { return "alltracks"; }
void setArtist( Tomahawk::Artist* artist ) { m_artist = artist; }
void setAlbum( Tomahawk::Album* album ) { m_album = album; }
void setArtist( const Tomahawk::artist_ptr& artist ) { m_artist = artist; }
void setAlbum( const Tomahawk::album_ptr& album ) { m_album = album; }
void setLimit( unsigned int amount ) { m_amount = amount; }
void setSortOrder( DatabaseCommand_AllTracks::SortOrder order ) { m_sortOrder = order; }
@ -69,8 +71,8 @@ signals:
private:
Tomahawk::collection_ptr m_collection;
Tomahawk::Artist* m_artist;
Tomahawk::Album* m_album;
Tomahawk::artist_ptr m_artist;
Tomahawk::album_ptr m_album;
unsigned int m_amount;
DatabaseCommand_AllTracks::SortOrder m_sortOrder;

View File

@ -18,14 +18,14 @@
#include "databasecommand_deletefiles.h"
#include <QSqlQuery>
#include <QtSql/QSqlQuery>
#include "artist.h"
#include "album.h"
#include "collection.h"
#include "source.h"
#include "database/database.h"
#include "databaseimpl.h"
#include "database/databaseimpl.h"
#include "network/servent.h"
#include "utils/logger.h"
#include "utils/tomahawkutils.h"
@ -60,7 +60,7 @@ DatabaseCommand_DeleteFiles::exec( DatabaseImpl* dbi )
{
Q_ASSERT( !source().isNull() );
QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id();
int srcid = source()->isLocal() ? 0 : source()->id();
TomahawkSqlQuery delquery = dbi->newquery();
if ( m_deleteAll )
@ -68,8 +68,8 @@ DatabaseCommand_DeleteFiles::exec( DatabaseImpl* dbi )
TomahawkSqlQuery dirquery = dbi->newquery();
dirquery.prepare( QString( "SELECT id FROM file WHERE source %1" )
.arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) ) );
dirquery.exec();
while ( dirquery.next() )
m_idList << dirquery.value( 0 ).toUInt();
}
@ -115,7 +115,8 @@ DatabaseCommand_DeleteFiles::exec( DatabaseImpl* dbi )
delquery.prepare( QString( "SELECT id FROM file WHERE source = %1 AND url IN ( %2 )" )
.arg( source()->id() )
.arg( idstring ) );
delquery.exec();
idstring = QString();
while ( delquery.next() )
{
@ -128,7 +129,6 @@ DatabaseCommand_DeleteFiles::exec( DatabaseImpl* dbi )
delquery.prepare( QString( "DELETE FROM file WHERE source %1 AND id IN ( %2 )" )
.arg( source()->isLocal() ? "IS NULL" : QString( "= %1" ).arg( source()->id() ) )
.arg( idstring ) );
delquery.exec();
}

View File

@ -19,9 +19,9 @@
#ifndef DATABASECOMMAND_DELETEFILES_H
#define DATABASECOMMAND_DELETEFILES_H
#include <QObject>
#include <QDir>
#include <QVariantMap>
#include <QtCore/QObject>
#include <QtCore/QDir>
#include <QtCore/QVariantMap>
#include "database/databasecommandloggable.h"
#include "typedefs.h"

View File

@ -39,13 +39,11 @@ DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi )
QVariant srcid = source()->isLocal() ? QVariant( QVariant::Int ) : source()->id();
bool autoCreate = false;
int artid = dbi->artistId( m_artist, autoCreate );
int artid = dbi->artistId( m_artist, false );
if( artid < 1 )
return;
autoCreate = false; // artistId overwrites autoCreate (reference)
int trkid = dbi->trackId( artid, m_track, autoCreate );
int trkid = dbi->trackId( artid, m_track, false );
if( trkid < 1 )
return;
@ -72,6 +70,6 @@ DatabaseCommand_LoadSocialActions::exec( DatabaseImpl* dbi )
allSocialActions.append( action );
}
m_result->setAllSocialActions( allSocialActions );
m_query->setAllSocialActions( allSocialActions );
}

View File

@ -56,17 +56,17 @@ public:
/**
* \brief Overloaded constructor for DatabaseCommand_LoadSocialAction.
* \param result Pointer to a Tomahawk::Result.
* \param result A Tomahawk Query object.
* \param parent Parent class.
*
* Constructor which creates a new database command for loading all social actions.
*/
explicit DatabaseCommand_LoadSocialActions( Tomahawk::Result* result, QObject* parent = 0 )
: DatabaseCommand( parent ), m_result( result )
explicit DatabaseCommand_LoadSocialActions( const Tomahawk::query_ptr& query, QObject* parent = 0 )
: DatabaseCommand( parent ), m_query( query )
{
setSource( SourceList::instance()->getLocal() );
setArtist( result->artist()->name() );
setTrack( result->track() );
setArtist( query->artist() );
setTrack( query->track() );
}
/**
@ -125,7 +125,7 @@ signals:
void done( QList< Tomahawk::SocialAction >& allSocialActions );
private:
Tomahawk::Result* m_result;
Tomahawk::query_ptr m_query;
QString m_artist;
QString m_track;

View File

@ -100,16 +100,21 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib )
QString trksToken = QString( "file_join.track IN (%1)" ).arg( trksl.join( "," ) );
QString sql = QString( "SELECT "
"url, mtime, size, md5, mimetype, duration, bitrate, file_join.artist, file_join.album, file_join.track, "
"artist.name as artname, "
"album.name as albname, "
"track.name as trkname, "
"file.source, "
"file_join.albumpos, "
"artist.id as artid, "
"album.id as albid "
"url, mtime, size, md5, mimetype, duration, bitrate, " //0
"file_join.artist, file_join.album, file_join.track, " //7
"file_join.composer, file_join.discnumber, " //10
"artist.name as artname, " //12
"album.name as albname, " //13
"track.name as trkname, " //14
"composer.name as cmpname, " //15
"file.source, " //16
"file_join.albumpos, " //17
"artist.id as artid, " //18
"album.id as albid, " //19
"composer.id as cmpid " //20
"FROM file, file_join, artist, track "
"LEFT JOIN album ON album.id = file_join.album "
"LEFT JOIN artist AS composer ON composer.id = file_join.composer "
"WHERE "
"artist.id = file_join.artist AND "
"track.id = file_join.track AND "
@ -126,16 +131,16 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib )
source_ptr s;
QString url = files_query.value( 0 ).toString();
if ( files_query.value( 13 ).toUInt() == 0 )
if ( files_query.value( 16 ).toUInt() == 0 )
{
s = SourceList::instance()->getLocal();
}
else
{
s = SourceList::instance()->get( files_query.value( 13 ).toUInt() );
s = SourceList::instance()->get( files_query.value( 16 ).toUInt() );
if( s.isNull() )
{
qDebug() << "Could not find source" << files_query.value( 13 ).toUInt();
qDebug() << "Could not find source" << files_query.value( 16 ).toUInt();
continue;
}
@ -143,8 +148,12 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib )
}
Tomahawk::result_ptr result = Tomahawk::Result::get( url );
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( files_query.value( 15 ).toUInt(), files_query.value( 10 ).toString() );
Tomahawk::album_ptr album = Tomahawk::Album::get( files_query.value( 16 ).toUInt(), files_query.value( 11 ).toString(), artist );
Tomahawk::artist_ptr artist =
Tomahawk::Artist::get( files_query.value( 18 ).toUInt(), files_query.value( 12 ).toString() );
Tomahawk::album_ptr album =
Tomahawk::Album::get( files_query.value( 19 ).toUInt(), files_query.value( 13 ).toString(), artist );
Tomahawk::artist_ptr composer =
Tomahawk::Artist::get( files_query.value( 20 ).toUInt(), files_query.value( 15 ).toString() );
result->setModificationTime( files_query.value( 1 ).toUInt() );
result->setSize( files_query.value( 2 ).toUInt() );
@ -152,10 +161,12 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib )
result->setDuration( files_query.value( 5 ).toUInt() );
result->setBitrate( files_query.value( 6 ).toUInt() );
result->setArtist( artist );
result->setComposer( composer );
result->setAlbum( album );
result->setTrack( files_query.value( 12 ).toString() );
result->setDiscNumber( files_query.value( 11 ).toUInt() );
result->setTrack( files_query.value( 14 ).toString() );
result->setRID( uuid() );
result->setAlbumPos( files_query.value( 14 ).toUInt() );
result->setAlbumPos( files_query.value( 17 ).toUInt() );
result->setTrackId( files_query.value( 9 ).toUInt() );
TomahawkSqlQuery attrQuery = lib->newquery();
@ -248,16 +259,21 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib )
QString albsToken = QString( "file_join.album IN (%1)" ).arg( albsl.join( "," ) );
QString sql = QString( "SELECT "
"url, mtime, size, md5, mimetype, duration, bitrate, file_join.artist, file_join.album, file_join.track, "
"artist.name as artname, "
"album.name as albname, "
"track.name as trkname, "
"file.source, "
"file_join.albumpos, "
"artist.id as artid, "
"album.id as albid "
"url, mtime, size, md5, mimetype, duration, bitrate, " //0
"file_join.artist, file_join.album, file_join.track, " //7
"file_join.composer, file_join.discnumber, " //10
"artist.name as artname, " //12
"album.name as albname, " //13
"track.name as trkname, " //14
"composer.name as cmpname, " //15
"file.source, " //16
"file_join.albumpos, " //17
"artist.id as artid, " //18
"album.id as albid, " //19
"composer.id as cmpid " //20
"FROM file, file_join, artist, track "
"LEFT JOIN album ON album.id = file_join.album "
"LEFT JOIN artist AS composer ON composer.id = file_join.composer "
"WHERE "
"artist.id = file_join.artist AND "
"track.id = file_join.track AND "
@ -273,16 +289,16 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib )
source_ptr s;
QString url = files_query.value( 0 ).toString();
if ( files_query.value( 13 ).toUInt() == 0 )
if ( files_query.value( 16 ).toUInt() == 0 )
{
s = SourceList::instance()->getLocal();
}
else
{
s = SourceList::instance()->get( files_query.value( 13 ).toUInt() );
s = SourceList::instance()->get( files_query.value( 16 ).toUInt() );
if( s.isNull() )
{
qDebug() << "Could not find source" << files_query.value( 13 ).toUInt();
qDebug() << "Could not find source" << files_query.value( 16 ).toUInt();
continue;
}
@ -290,8 +306,12 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib )
}
Tomahawk::result_ptr result = Tomahawk::Result::get( url );
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( files_query.value( 15 ).toUInt(), files_query.value( 10 ).toString() );
Tomahawk::album_ptr album = Tomahawk::Album::get( files_query.value( 16 ).toUInt(), files_query.value( 11 ).toString(), artist );
Tomahawk::artist_ptr artist =
Tomahawk::Artist::get( files_query.value( 18 ).toUInt(), files_query.value( 12 ).toString() );
Tomahawk::album_ptr album =
Tomahawk::Album::get( files_query.value( 19 ).toUInt(), files_query.value( 13 ).toString(), artist );
Tomahawk::artist_ptr composer =
Tomahawk::Artist::get( files_query.value( 20 ).toUInt(), files_query.value( 15 ).toString() );
result->setModificationTime( files_query.value( 1 ).toUInt() );
result->setSize( files_query.value( 2 ).toUInt() );
@ -299,12 +319,13 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib )
result->setDuration( files_query.value( 5 ).toUInt() );
result->setBitrate( files_query.value( 6 ).toUInt() );
result->setArtist( artist );
result->setComposer( composer );
result->setAlbum( album );
result->setTrack( files_query.value( 12 ).toString() );
result->setDiscNumber( files_query.value( 11 ).toUInt() );
result->setTrack( files_query.value( 14 ).toString() );
result->setRID( uuid() );
result->setAlbumPos( files_query.value( 14 ).toUInt() );
result->setAlbumPos( files_query.value( 17 ).toUInt() );
result->setTrackId( files_query.value( 9 ).toUInt() );
result->setYear( files_query.value( 17 ).toUInt() );
for ( int k = 0; k < trackPairs.count(); k++ )
{

View File

@ -22,6 +22,8 @@
#include "databasecommand.h"
#include "databaseimpl.h"
#include "result.h"
#include "artist.h"
#include "album.h"
#include <QVariant>

View File

@ -61,20 +61,20 @@ public:
/**
* \brief Overloaded constructor for DatabaseCommand_SocialAction.
* \param result Pointer to a Tomahawk::Result.
* \param query A Tomahawk Query object.
* \param action Name of the social action to be written to the database.
* \param comment Comment associated with this social action.
* \param parent Parent class.
*
* Constructor which creates a new database command for the specified social action.
*/
explicit DatabaseCommand_SocialAction( const Tomahawk::result_ptr& result, QString action, QString comment="", QObject* parent = 0 )
: DatabaseCommandLoggable( parent ), m_result( result ), m_action( action )
explicit DatabaseCommand_SocialAction( const Tomahawk::query_ptr& query, QString action, QString comment = "", QObject* parent = 0 )
: DatabaseCommandLoggable( parent ), m_query( query ), m_action( action )
{
setSource( SourceList::instance()->getLocal() );
setArtist( result->artist()->name() );
setTrack( result->track() );
setArtist( query->artist() );
setTrack( query->track() );
setComment( comment );
setTimestamp( QDateTime::currentDateTime().toTime_t() );
}
@ -173,7 +173,7 @@ public:
virtual bool groupable() const { return true; }
private:
Tomahawk::result_ptr m_result;
Tomahawk::query_ptr m_query;
QString m_artist;
QString m_track;

View File

@ -40,7 +40,7 @@
*/
#include "schema.sql.h"
#define CURRENT_SCHEMA_VERSION 27
#define CURRENT_SCHEMA_VERSION 28
DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
@ -80,6 +80,12 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent )
m_fuzzyIndex = new FuzzyIndex( *this, schemaUpdated );
tDebug( LOGVERBOSE ) << "Loaded index:" << t.elapsed();
if ( qApp->arguments().contains( "--dumpdb" ) )
{
dumpDatabase();
::exit( 0 );
}
}
@ -89,6 +95,34 @@ DatabaseImpl::~DatabaseImpl()
}
void
DatabaseImpl::dumpDatabase()
{
QFile dump( "dbdump.txt" );
if ( !dump.open( QIODevice::WriteOnly | QIODevice::Text ) )
{
tDebug() << "Couldn't open dbdump.txt for writing!";
Q_ASSERT( false );
}
else
{
QTextStream dumpout( &dump );
TomahawkSqlQuery query = newquery();
query.exec( "SELECT * FROM oplog" );
while ( query.next() )
{
dumpout << "ID: " << query.value( 0 ).toInt() << endl
<< "GUID: " << query.value( 2 ).toString() << endl
<< "Command: " << query.value( 3 ).toString() << endl
<< "Singleton: " << query.value( 4 ).toBool() << endl
<< "JSON: " << ( query.value( 5 ).toBool() ? qUncompress( query.value( 6 ).toByteArray() ) : query.value( 6 ).toByteArray() )
<< endl << endl << endl;
}
}
}
void
DatabaseImpl::loadIndex()
{
@ -174,10 +208,11 @@ DatabaseImpl::file( int fid )
Tomahawk::result_ptr r;
TomahawkSqlQuery query = newquery();
query.exec( QString( "SELECT url, mtime, size, md5, mimetype, duration, bitrate, "
"file_join.artist, file_join.album, file_join.track, "
"file_join.artist, file_join.album, file_join.track, file_join.composer, "
"(select name from artist where id = file_join.artist) as artname, "
"(select name from album where id = file_join.album) as albname, "
"(select name from track where id = file_join.track) as trkname, "
"(select name from artist where id = file_join.composer) as cmpname, "
"source "
"FROM file, file_join "
"WHERE file.id = file_join.file AND file.id = %1" )
@ -188,13 +223,13 @@ DatabaseImpl::file( int fid )
Tomahawk::source_ptr s;
QString url = query.value( 0 ).toString();
if ( query.value( 13 ).toUInt() == 0 )
if ( query.value( 15 ).toUInt() == 0 )
{
s = SourceList::instance()->getLocal();
}
else
{
s = SourceList::instance()->get( query.value( 13 ).toUInt() );
s = SourceList::instance()->get( query.value( 15 ).toUInt() );
if ( s.isNull() )
{
return r;
@ -204,8 +239,9 @@ DatabaseImpl::file( int fid )
}
r = Tomahawk::Result::get( url );
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( query.value( 7 ).toUInt(), query.value( 10 ).toString() );
Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 8 ).toUInt(), query.value( 11 ).toString(), artist );
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( query.value( 7 ).toUInt(), query.value( 11 ).toString() );
Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 8 ).toUInt(), query.value( 12 ).toString(), artist );
Tomahawk::artist_ptr composer = Tomahawk::Artist::get( query.value( 10 ).toUInt(), query.value( 14 ).toString() );
r->setModificationTime( query.value( 1 ).toUInt() );
r->setSize( query.value( 2 ).toUInt() );
@ -214,7 +250,8 @@ DatabaseImpl::file( int fid )
r->setBitrate( query.value( 6 ).toUInt() );
r->setArtist( artist );
r->setAlbum( album );
r->setTrack( query.value( 12 ).toString() );
r->setComposer( composer );
r->setTrack( query.value( 13 ).toString() );
r->setTrackId( query.value( 9 ).toUInt() );
r->setCollection( s->collection() );
r->setScore( 1.0 );
@ -523,17 +560,23 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery )
bool searchlocal = s->isLocal();
QString sql = QString( "SELECT "
"url, mtime, size, md5, mimetype, duration, bitrate, file_join.artist, file_join.album, file_join.track, "
"artist.name as artname, "
"album.name as albname, "
"track.name as trkname, "
"file.source, "
"file_join.albumpos, "
"artist.id as artid, "
"album.id as albid, "
"track_attributes.v as year "
"url, mtime, size, md5, mimetype, duration, bitrate, " //0
"file_join.artist, file_join.album, file_join.track, " //7
"file_join.composer, " //10
"artist.name as artname, " //11
"album.name as albname, " //12
"track.name as trkname, " //13
"composer.name as cmpname, " //14
"file.source, " //15
"file_join.albumpos, " //16
"file_join.discnumber, " //17
"artist.id as artid, " //18
"album.id as albid, " //19
"composer.id as cmpid, " //20
"track_attributes.v as year " //21
"FROM file, file_join, artist, track, track_attributes "
"LEFT JOIN album ON album.id = file_join.album "
"LEFT JOIN artist AS composer on composer.id = file_join.composer "
"WHERE "
"artist.id = file_join.artist AND "
"track.id = file_join.track AND "
@ -552,13 +595,13 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery )
Tomahawk::source_ptr s;
QString url = query.value( 0 ).toString();
if ( query.value( 13 ).toUInt() == 0 )
if ( query.value( 15 ).toUInt() == 0 )
{
s = SourceList::instance()->getLocal();
}
else
{
s = SourceList::instance()->get( query.value( 13 ).toUInt() );
s = SourceList::instance()->get( query.value( 15 ).toUInt() );
if ( s.isNull() )
{
return res;
@ -568,8 +611,9 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery )
}
res = Tomahawk::Result::get( url );
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( query.value( 15 ).toUInt(), query.value( 10 ).toString() );
Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 16 ).toUInt(), query.value( 11 ).toString(), artist );
Tomahawk::artist_ptr artist = Tomahawk::Artist::get( query.value( 18 ).toUInt(), query.value( 11 ).toString() );
Tomahawk::album_ptr album = Tomahawk::Album::get( query.value( 19 ).toUInt(), query.value( 12 ).toString(), artist );
Tomahawk::artist_ptr composer = Tomahawk::Artist::get( query.value( 20 ).toUInt(), query.value( 14 ).toString() );
res->setModificationTime( query.value( 1 ).toUInt() );
res->setSize( query.value( 2 ).toUInt() );
@ -578,13 +622,15 @@ DatabaseImpl::resultFromHint( const Tomahawk::query_ptr& origquery )
res->setBitrate( query.value( 6 ).toInt() );
res->setArtist( artist );
res->setAlbum( album );
res->setComposer( composer );
res->setScore( 1.0 );
res->setTrack( query.value( 12 ).toString() );
res->setAlbumPos( query.value( 14 ).toUInt() );
res->setTrack( query.value( 13 ).toString() );
res->setAlbumPos( query.value( 16 ).toUInt() );
res->setDiscNumber( query.value( 17 ).toUInt() );
res->setRID( uuid() );
res->setTrackId( query.value( 9 ).toUInt() );
res->setCollection( s->collection() );
res->setYear( query.value( 17 ).toUInt() );
res->setYear( query.value( 21 ).toUInt() );
}
return res;

View File

@ -52,7 +52,7 @@ public:
TomahawkSqlQuery newquery() { return TomahawkSqlQuery( m_db ); }
QSqlDatabase& database() { return m_db; }
int artistId( const QString& name_orig, bool autoCreate );
int artistId( const QString& name_orig, bool autoCreate ); //also for composers!
int trackId( int artistid, const QString& name_orig, bool autoCreate );
int albumId( int artistid, const QString& name_orig, bool autoCreate );
@ -84,6 +84,7 @@ public slots:
private:
QString cleanSql( const QString& sql );
bool updateSchema( int oldVersion );
void dumpDatabase();
bool m_ready;
QSqlDatabase m_db;

View File

@ -21,6 +21,8 @@
#include "resolver.h"
#include "result.h"
#include "artist.h"
#include "album.h"
#include "dllmacro.h"

View File

@ -206,7 +206,7 @@ FuzzyIndex::search( const QString& table, const QString& name )
}
catch( CLuceneError& error )
{
qDebug() << "Caught CLucene error:" << error.what();
tDebug() << "Caught CLucene error:" << error.what();
Q_ASSERT( false );
}

View File

@ -175,7 +175,9 @@ CREATE TABLE IF NOT EXISTS file_join (
artist INTEGER NOT NULL REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
track INTEGER NOT NULL REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
album INTEGER REFERENCES album(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
albumpos INTEGER
albumpos INTEGER,
composer INTEGER REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,
discnumber INTEGER
);
CREATE INDEX file_join_track ON file_join(track);
CREATE INDEX file_join_artist ON file_join(artist);
@ -292,4 +294,4 @@ CREATE TABLE IF NOT EXISTS settings (
v TEXT NOT NULL DEFAULT ''
);
INSERT INTO settings(k,v) VALUES('schema_version', '27');
INSERT INTO settings(k,v) VALUES('schema_version', '28');

View File

@ -1,5 +1,5 @@
/*
This file was automatically generated from schema.sql on Wed Nov 16 22:47:16 EST 2011.
This file was automatically generated from ./schema.sql on Fri Nov 18 14:00:37 CET 2011.
*/
static const char * tomahawk_schema_sql =
@ -116,7 +116,9 @@ static const char * tomahawk_schema_sql =
" artist INTEGER NOT NULL REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
" track INTEGER NOT NULL REFERENCES track(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
" album INTEGER REFERENCES album(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
" albumpos INTEGER"
" albumpos INTEGER,"
" composer INTEGER REFERENCES artist(id) ON DELETE CASCADE ON UPDATE CASCADE DEFERRABLE INITIALLY DEFERRED,"
" discnumber INTEGER"
");"
"CREATE INDEX file_join_track ON file_join(track);"
"CREATE INDEX file_join_artist ON file_join(artist);"
@ -189,7 +191,7 @@ static const char * tomahawk_schema_sql =
" k TEXT NOT NULL PRIMARY KEY,"
" v TEXT NOT NULL DEFAULT ''"
");"
"INSERT INTO settings(k,v) VALUES('schema_version', '27');"
"INSERT INTO settings(k,v) VALUES('schema_version', '28');"
;
const char * get_tomahawk_sql()

View File

@ -764,7 +764,7 @@ QList< query_ptr >
DropJob::getArtist( const QString &artist )
{
artist_ptr artistPtr = Artist::get( artist );
if ( artistPtr->getPlaylistInterface()->tracks().isEmpty() )
if ( artistPtr->playlistInterface()->tracks().isEmpty() )
{
connect( artistPtr.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
@ -772,7 +772,7 @@ DropJob::getArtist( const QString &artist )
return QList< query_ptr >();
}
else
return artistPtr->getPlaylistInterface()->tracks();
return artistPtr->playlistInterface()->tracks();
}
@ -785,7 +785,7 @@ DropJob::getAlbum(const QString &artist, const QString &album)
if ( albumPtr.isNull() )
return QList< query_ptr >();
if ( albumPtr->getPlaylistInterface()->tracks().isEmpty() )
if ( albumPtr->playlistInterface()->tracks().isEmpty() )
{
m_dropJob = new DropJobNotifier( QPixmap( RESPATH "images/album-icon.png" ), Album );
connect( albumPtr.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
@ -796,7 +796,7 @@ DropJob::getAlbum(const QString &artist, const QString &album)
return QList< query_ptr >();
}
else
return albumPtr->getPlaylistInterface()->tracks();
return albumPtr->playlistInterface()->tracks();
}

View File

@ -45,7 +45,9 @@ ChartsPlugin::ChartsPlugin()
, m_chartsFetchJobs( 0 )
{
/// Add resources here
m_chartResources << "billboard" << "itunes" << "rdio" << "wearehunted" << "ex.fm";
m_chartResources << "billboard" << "itunes" << "rdio" << "wearehunted" << "ex.fm" << "soundcloudwall.com";
/// If you add resource, update version aswell
m_chartVersion = "1.0";
m_supportedGetTypes << InfoChart << InfoChartCapabilities;
}
@ -153,7 +155,8 @@ ChartsPlugin::fetchChartCapabilities( Tomahawk::InfoSystem::InfoRequestData requ
Tomahawk::InfoSystem::InfoStringHash criteria;
criteria[ "InfoChartCapabilities" ] = "chartsplugin";
emit getCachedInfo( criteria, 604800000, requestData );
criteria[ "InfoChartVersion" ] = m_chartVersion;
emit getCachedInfo( criteria, 864000000, requestData );
}
void
@ -182,8 +185,8 @@ ChartsPlugin::notInCacheSlot( QHash<QString, QString> criteria, Tomahawk::InfoSy
tDebug( LOGVERBOSE ) << Q_FUNC_INFO << "InfoChartCapabilities not in cache! Fetching...";
// we never need to re-fetch
if ( !m_allChartsMap.isEmpty() )
return;
//if ( !m_allChartsMap.isEmpty() )
// return;
/// Then get each chart from resource
@ -333,6 +336,7 @@ ChartsPlugin::chartTypes()
if( source == "wearehunted" ){
chartName = "WeAreHunted";
}
}
}
@ -422,7 +426,8 @@ ChartsPlugin::chartTypes()
// update cache
Tomahawk::InfoSystem::InfoStringHash criteria;
criteria[ "InfoChartCapabilities" ] = "chartsplugin";
emit updateCache( criteria, 604800000, request.type, m_allChartsMap );
criteria[ "InfoChartVersion" ] = m_chartVersion;
emit updateCache( criteria, 864000000, request.type, m_allChartsMap );
}
m_cachedRequests.clear();
}

View File

@ -72,16 +72,13 @@ private:
void dataError( Tomahawk::InfoSystem::InfoRequestData requestData );
QStringList m_chartResources;
QString m_chartVersion;
QList< InfoStringHash > m_charts;
ChartType m_chartType;
QVariantMap m_allChartsMap;
uint m_chartsFetchJobs;
QList< InfoRequestData > m_cachedRequests;
QHash< QString, QString > m_cachedCountries;
QWeakPointer< QNetworkAccessManager > m_nam;
};

View File

@ -489,15 +489,26 @@ LastFmPlugin::similarArtistsReturned()
QNetworkReply* reply = qobject_cast<QNetworkReply*>( sender() );
QMap< int, QString > similarArtists = lastfm::Artist::getSimilar( reply );
QStringList sortedArtists;
QStringList sortedScores;
QStringList al;
QStringList sl;
foreach ( const QString& a, similarArtists.values() )
al << a;
foreach ( const QString& artist, similarArtists.values() )
al << artist;
foreach ( int score, similarArtists.keys() )
sl << QString::number( score );
for ( int i = al.count() - 1; i >= 0; i-- )
{
sortedArtists << al.at( i );
sortedScores << sl.at( i );
}
QVariantMap returnedData;
returnedData["artists"] = al;
returnedData["score"] = sl;
returnedData["artists"] = sortedArtists;
returnedData["score"] = sortedScores;
Tomahawk::InfoSystem::InfoRequestData requestData = reply->property( "requestData" ).value< Tomahawk::InfoSystem::InfoRequestData >();
@ -682,25 +693,25 @@ LastFmPlugin::artistImagesReturned()
void
LastFmPlugin::settingsChanged()
{
if( !m_scrobbler && TomahawkSettings::instance()->scrobblingEnabled() )
if ( !m_scrobbler && TomahawkSettings::instance()->scrobblingEnabled() )
{ // can simply create the scrobbler
lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername();
m_pw = TomahawkSettings::instance()->lastFmPassword();
createScrobbler();
}
else if( m_scrobbler && !TomahawkSettings::instance()->scrobblingEnabled() )
else if ( m_scrobbler && !TomahawkSettings::instance()->scrobblingEnabled() )
{
delete m_scrobbler;
m_scrobbler = 0;
}
else if( TomahawkSettings::instance()->lastFmUsername() != lastfm::ws::Username ||
else if ( TomahawkSettings::instance()->lastFmUsername() != lastfm::ws::Username ||
TomahawkSettings::instance()->lastFmPassword() != m_pw )
{
lastfm::ws::Username = TomahawkSettings::instance()->lastFmUsername();
m_pw = TomahawkSettings::instance()->lastFmPassword();
// credentials have changed, have to re-create scrobbler for them to take effect
if( m_scrobbler )
if ( m_scrobbler )
{
delete m_scrobbler;
m_scrobbler = 0;
@ -715,17 +726,17 @@ void
LastFmPlugin::onAuthenticated()
{
QNetworkReply* authJob = dynamic_cast<QNetworkReply*>( sender() );
if( !authJob )
if ( !authJob )
{
tLog() << Q_FUNC_INFO << "Help! No longer got a last.fm auth job!";
return;
}
if( authJob->error() == QNetworkReply::NoError )
if ( authJob->error() == QNetworkReply::NoError )
{
lastfm::XmlQuery lfm = lastfm::XmlQuery( authJob->readAll() );
if( lfm.children( "error" ).size() > 0 )
if ( lfm.children( "error" ).size() > 0 )
{
tLog() << "Error from authenticating with Last.fm service:" << lfm.text();
TomahawkSettings::instance()->setLastFmSessionKey( QByteArray() );
@ -737,7 +748,7 @@ LastFmPlugin::onAuthenticated()
TomahawkSettings::instance()->setLastFmSessionKey( lastfm::ws::SessionKey.toLatin1() );
// qDebug() << "Got session key from last.fm";
if( TomahawkSettings::instance()->scrobblingEnabled() )
if ( TomahawkSettings::instance()->scrobblingEnabled() )
m_scrobbler = new lastfm::Audioscrobbler( "thk" );
}
}
@ -753,7 +764,7 @@ LastFmPlugin::onAuthenticated()
void
LastFmPlugin::createScrobbler()
{
if( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one
if ( TomahawkSettings::instance()->lastFmSessionKey().isEmpty() ) // no session key, so get one
{
qDebug() << "LastFmPlugin::createScrobbler Session key is empty";
QString authToken = TomahawkUtils::md5( ( lastfm::ws::Username.toLower() + TomahawkUtils::md5( m_pw.toUtf8() ) ).toUtf8() );
@ -780,14 +791,15 @@ QList<lastfm::Track>
LastFmPlugin::parseTrackList( QNetworkReply* reply )
{
QList<lastfm::Track> tracks;
try {
try
{
lastfm::XmlQuery lfm = reply->readAll();
foreach ( lastfm::XmlQuery xq, lfm.children( "track" ) )
{
tracks.append( lastfm::Track( xq ) );
}
}
catch( lastfm::ws::ParseError& e )
catch ( lastfm::ws::ParseError& e )
{
qWarning() << e.what();
}

View File

@ -42,7 +42,7 @@
#include <QtDBus/QDBusConnection>
#include <QtDBus/QDBusMessage>
#include <QImage>
#include <QtGui/QImage>
#include "utils/logger.h"
@ -84,18 +84,14 @@ FdoNotifyPlugin::pushInfo( QString caller, Tomahawk::InfoSystem::InfoType type,
arguments << quint32( 0 ); //notification_id
arguments << QString(); //app_icon
arguments << QString( "Tomahawk" ); //summary
arguments << hash["message"].toString(); //body
arguments << hash[ "message" ].toString(); //body
arguments << QStringList(); //actions
QVariantMap dict;
dict["desktop-entry"] = QString( "tomahawk" );
if ( hash.contains( "image" ) )
{
QVariant tempVariant = hash["image"];
QImage tempImage = tempVariant.value< QImage >();
dict["image_data"] = ImageConverter::variantForImage( tempImage );
}
if ( hash.contains( "image" ) && hash[ "image" ].canConvert< QImage >() )
dict[ "image_data" ] = ImageConverter::variantForImage( hash[ "image" ].value< QImage >() );
else
dict["image_data"] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) );
dict[ "image_data" ] = ImageConverter::variantForImage( QImage( RESPATH "icons/tomahawk-icon-128x128.png" ) );
arguments << dict; //hints
arguments << qint32( -1 ); //expire_timeout
message.setArguments( arguments );

View File

@ -20,7 +20,7 @@
#include <QtDBus/QDBusArgument>
#include <QtDBus/QDBusMetaType>
#include <QImage>
#include <QtGui/QImage>
#include "utils/logger.h"

View File

@ -595,7 +595,7 @@ Playlist::checkRevisionQueue()
Tomahawk::playlistinterface_ptr
Playlist::getPlaylistInterface()
Playlist::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -185,7 +185,7 @@ public:
void setUpdater( PlaylistUpdaterInterface* interface ) { m_updater = interface; }
PlaylistUpdaterInterface* updater() const { return m_updater; }
Tomahawk::playlistinterface_ptr getPlaylistInterface();
Tomahawk::playlistinterface_ptr playlistInterface();
signals:
/// emitted when the playlist revision changes (whenever the playlist changes)

View File

@ -74,6 +74,8 @@ AlbumItem::AlbumItem( const Tomahawk::album_ptr& album, AlbumItem* parent, int r
}
toberemoved = false;
connect( album.data(), SIGNAL( updated() ), SIGNAL( dataChanged() ) );
}
@ -98,4 +100,6 @@ AlbumItem::AlbumItem( const Tomahawk::artist_ptr& artist, AlbumItem* parent, int
}
toberemoved = false;
connect( artist.data(), SIGNAL( updated() ), SIGNAL( dataChanged() ) );
}

View File

@ -24,6 +24,7 @@
#include <QPersistentModelIndex>
#include <QPixmap>
#include "artist.h"
#include "album.h"
#include "dllmacro.h"
@ -41,7 +42,6 @@ public:
const Tomahawk::artist_ptr& artist() const { return m_artist; }
const Tomahawk::album_ptr& album() const { return m_album; }
void setCover( const QPixmap& cover ) { this->cover = cover; emit dataChanged(); }
AlbumItem* parent;
QList<AlbumItem*> children;
@ -49,7 +49,6 @@ public:
int childCount;
QPersistentModelIndex index;
QAbstractItemModel* model;
QPixmap cover;
bool toberemoved;
signals:

View File

@ -89,7 +89,19 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
painter->drawLine( shadowRect.bottomLeft() + QPoint( 0, 4 ), shadowRect.bottomRight() + QPoint( 0, 4 ) );
}
QPixmap cover = item->cover.isNull() ? m_defaultCover : item->cover;
QPixmap cover;
if ( !item->album().isNull() )
{
cover.loadFromData( item->album()->cover() );
}
else if ( !item->artist().isNull() )
{
cover.loadFromData( item->artist()->cover() );
}
if ( cover.isNull() )
cover = m_defaultCover;
QRect r = option.rect.adjusted( 6, 5, -6, -41 );
if ( option.state & QStyle::State_Selected )
@ -167,23 +179,24 @@ AlbumItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
r.adjust( 4, 0, -4, -1 );
if ( m_hoveringOver == index )
{
TomahawkUtils::drawQueryBackground( painter, opt.palette, r, 1.5 );
TomahawkUtils::drawQueryBackground( painter, opt.palette, r, 1.1 );
painter->setPen( opt.palette.color( QPalette::HighlightedText ) );
}
else
{
if ( !( option.state & QStyle::State_Selected ) )
#ifdef Q_WS_MAC
painter->setPen( opt.palette.color( QPalette::Dark ).darker( 200 ) );
painter->setPen( opt.palette.color( QPalette::Dark ).darker( 200 ) );
#else
painter->setPen( opt.palette.color( QPalette::Dark ) );
painter->setPen( opt.palette.color( QPalette::Dark ) );
#endif
}
to.setAlignment( Qt::AlignHCenter | Qt::AlignBottom );
text = painter->fontMetrics().elidedText( item->album()->artist()->name(), Qt::ElideRight, textRect.width() - 3 );
painter->drawText( textRect, text, to );
// Calculate rect of artist on-hover button click area
text = painter->fontMetrics().elidedText( item->album()->artist()->name(), Qt::ElideRight, textRect.width() - 10 );
painter->drawText( textRect.adjusted( 5, -1, -5, -1 ), text, to );
// Calculate rect of artist on-hover button click area
m_artistNameRects[ index ] = r;
}

View File

@ -30,8 +30,6 @@
#include "utils/tomahawkutils.h"
#include "utils/logger.h"
static QString s_tmInfoIdentifier = QString( "ALBUMMODEL" );
using namespace Tomahawk;
@ -40,11 +38,6 @@ AlbumModel::AlbumModel( QObject* parent )
, m_rootItem( new AlbumItem( 0, this ) )
, m_overwriteOnAdd( false )
{
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
}
@ -123,11 +116,6 @@ AlbumModel::data( const QModelIndex& index, int role ) const
if ( !entry )
return QVariant();
if ( role == Qt::DecorationRole )
{
return entry->cover;
}
if ( role != Qt::DisplayRole ) // && role != Qt::ToolTipRole )
return QVariant();
@ -187,8 +175,6 @@ AlbumModel::mimeTypes() const
QMimeData*
AlbumModel::mimeData( const QModelIndexList &indexes ) const
{
qDebug() << Q_FUNC_INFO;
QByteArray queryData;
QDataStream queryStream( &queryData, QIODevice::WriteOnly );
@ -404,89 +390,6 @@ AlbumModel::clear()
}
bool
AlbumModel::getCover( const QModelIndex& index )
{
AlbumItem* item = itemFromIndex( index );
if ( !item || !item->cover.isNull() )
return false;
Tomahawk::InfoSystem::InfoStringHash trackInfo;
Tomahawk::InfoSystem::InfoRequestData requestData;
if ( !item->artist().isNull() )
{
requestData.type = Tomahawk::InfoSystem::InfoArtistImages;
trackInfo["artist"] = item->artist()->name();
}
else if ( !item->album().isNull() && !item->album()->artist().isNull() )
{
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
trackInfo["artist"] = item->album()->artist()->name();
trackInfo["album"] = item->album()->name();
}
m_coverHash.insert( (qlonglong)item, index );
trackInfo["pptr"] = QString::number( (qlonglong)item );
requestData.caller = s_tmInfoIdentifier;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
return true;
}
void
AlbumModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output )
{
// qDebug() << Q_FUNC_INFO << " with caller " << requestData.caller;
if ( requestData.caller != s_tmInfoIdentifier ||
( requestData.type != Tomahawk::InfoSystem::InfoAlbumCoverArt && requestData.type != Tomahawk::InfoSystem::InfoArtistImages ) )
{
return;
}
if ( !output.canConvert< QVariantMap >() )
{
qDebug() << "Cannot convert fetched art from a QByteArray";
return;
}
Tomahawk::InfoSystem::InfoStringHash pptr = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
QPixmap pm;
pm.loadFromData( ba );
bool ok;
qlonglong p = pptr["pptr"].toLongLong( &ok );
AlbumItem* ai = itemFromIndex( m_coverHash.take( p ) );
if ( !ai )
return;
if ( !pm.isNull() )
ai->cover = pm;
if ( ai->index.isValid() )
emit dataChanged( ai->index, ai->index.sibling( ai->index.row(), columnCount( QModelIndex() ) - 1 ) );
}
}
void
AlbumModel::infoSystemFinished( QString target )
{
Q_UNUSED( target );
}
void
AlbumModel::onDataChanged()
{

View File

@ -25,7 +25,6 @@
#include "album.h"
#include "playlistinterface.h"
#include "database/databasecommand_allalbums.h"
#include "infosystem/infosystem.h"
#include "dllmacro.h"
@ -67,8 +66,6 @@ public:
void addCollection( const Tomahawk::collection_ptr& collection, bool overwrite = false );
void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllAlbums::SortOrder order, bool overwrite = false );
bool getCover( const QModelIndex& index );
virtual QString title() const { return m_title; }
virtual QString description() const { return m_description; }
virtual void setTitle( const QString& title ) { m_title = title; }
@ -106,9 +103,6 @@ private slots:
void onSourceAdded( const Tomahawk::source_ptr& source );
void onCollectionChanged();
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void infoSystemFinished( QString target );
private:
QPersistentModelIndex m_currentIndex;
AlbumItem* m_rootItem;
@ -118,8 +112,6 @@ private:
bool m_overwriteOnAdd;
Tomahawk::collection_ptr m_collection;
QHash<qlonglong, QPersistentModelIndex> m_coverHash;
};
#endif // ALBUMMODEL_H

View File

@ -141,7 +141,7 @@ AlbumProxyModel::removeIndexes( const QList<QModelIndex>& indexes )
Tomahawk::playlistinterface_ptr
AlbumProxyModel::getPlaylistInterface()
AlbumProxyModel::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -45,7 +45,7 @@ public:
virtual void emitFilterChanged( const QString &pattern ) { emit filterChanged( pattern ); }
virtual Tomahawk::playlistinterface_ptr getPlaylistInterface();
virtual Tomahawk::playlistinterface_ptr playlistInterface();
signals:
void filterChanged( const QString& filter );

View File

@ -63,7 +63,7 @@ signals:
void nextTrackReady();
public slots:
virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setRepeatMode( Tomahawk::PlaylistInterface::RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); }
private:

View File

@ -63,12 +63,6 @@ AlbumView::AlbumView( QWidget* parent )
setAutoFitItems( true );
setProxyModel( new AlbumProxyModel( this ) );
m_timer.setInterval( SCROLL_TIMEOUT );
connect( verticalScrollBar(), SIGNAL( rangeChanged( int, int ) ), SLOT( onViewChanged() ) );
connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), SLOT( onViewChanged() ) );
connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
}
@ -112,13 +106,10 @@ AlbumView::setAlbumModel( AlbumModel* model )
}
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
connect( m_proxyModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), SLOT( onViewChanged() ) );
connect( m_model, SIGNAL( itemCountChanged( unsigned int ) ), SLOT( onItemCountChanged( unsigned int ) ) );
connect( m_model, SIGNAL( loadingStarted() ), m_loadingSpinner, SLOT( fadeIn() ) );
connect( m_model, SIGNAL( loadingFinished() ), m_loadingSpinner, SLOT( fadeOut() ) );
onViewChanged(); // Fetch covers if albums were added to model before model was attached to view
}
@ -139,16 +130,6 @@ AlbumView::onItemActivated( const QModelIndex& index )
}
void
AlbumView::onViewChanged()
{
if ( m_timer.isActive() )
m_timer.stop();
m_timer.start();
}
void
AlbumView::onItemCountChanged( unsigned int items )
{
@ -166,45 +147,6 @@ AlbumView::onItemCountChanged( unsigned int items )
}
void
AlbumView::onScrollTimeout()
{
if ( m_timer.isActive() )
m_timer.stop();
if ( !m_proxyModel->rowCount() )
return;
QRect viewRect = viewport()->rect();
int rowHeight = m_proxyModel->data( QModelIndex(), Qt::SizeHintRole ).toSize().height();
viewRect.adjust( 0, -rowHeight, 0, rowHeight );
bool started = false;
bool done = false;
for ( int i = 0; i < m_proxyModel->rowCount(); i++ )
{
if ( started && done )
break;
for ( int j = 0; j < m_proxyModel->columnCount(); j++ )
{
QModelIndex idx = m_proxyModel->index( i, j );
if ( !viewRect.contains( visualRect( idx ) ) )
{
done = true;
break;
}
started = true;
done = false;
if ( !m_model->getCover( m_proxyModel->mapToSource( idx ) ) )
break;
}
}
}
void
AlbumView::paintEvent( QPaintEvent* event )
{

View File

@ -53,7 +53,7 @@ public:
void setModel( QAbstractItemModel* model );
virtual QWidget* widget() { return this; }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->getPlaylistInterface(); }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->playlistInterface(); }
virtual QString title() const { return m_model->title(); }
virtual QString description() const { return m_model->description(); }
@ -76,9 +76,6 @@ private slots:
void onFilterChanged( const QString& filter );
void onViewChanged();
void onScrollTimeout();
private:
AlbumModel* m_model;
AlbumProxyModel* m_proxyModel;
@ -88,8 +85,6 @@ private:
bool m_inited;
bool m_autoFitItems;
QTimer m_timer;
};
#endif // ALBUMVIEW_H

View File

@ -80,12 +80,6 @@ ArtistView::ArtistView( QWidget* parent )
setFont( f );
#endif
m_timer.setInterval( SCROLL_TIMEOUT );
connect( verticalScrollBar(), SIGNAL( rangeChanged( int, int ) ), SLOT( onViewChanged() ) );
connect( verticalScrollBar(), SIGNAL( valueChanged( int ) ), SLOT( onViewChanged() ) );
connect( &m_timer, SIGNAL( timeout() ), SLOT( onScrollTimeout() ) );
connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
connect( this, SIGNAL( customContextMenuRequested( const QPoint& ) ), SLOT( onCustomContextMenu( const QPoint& ) ) );
connect( m_contextMenu, SIGNAL( triggered( int ) ), SLOT( onMenuTriggered( int ) ) );
@ -135,7 +129,6 @@ ArtistView::setTreeModel( TreeModel* model )
connect( m_model, SIGNAL( itemCountChanged( unsigned int ) ), SLOT( onItemCountChanged( unsigned int ) ) );
connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
connect( m_proxyModel, SIGNAL( rowsInserted( QModelIndex, int, int ) ), SLOT( onViewChanged() ) );
guid(); // this will set the guid on the header
@ -188,7 +181,7 @@ ArtistView::onItemActivated( const QModelIndex& index )
else if ( !item->result().isNull() && item->result()->isOnline() )
{
m_model->setCurrentItem( item->index );
AudioEngine::instance()->playItem( m_proxyModel->getPlaylistInterface(), item->result() );
AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), item->result() );
}
}
}
@ -248,9 +241,9 @@ ArtistView::onFilterChanged( const QString& )
if ( selectedIndexes().count() )
scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter );
if ( !proxyModel()->getPlaylistInterface()->filter().isEmpty() && !proxyModel()->getPlaylistInterface()->trackCount() && model()->trackCount() )
if ( !proxyModel()->playlistInterface()->filter().isEmpty() && !proxyModel()->playlistInterface()->trackCount() && model()->trackCount() )
{
m_overlay->setText( tr( "Sorry, your filter '%1' did not match any results." ).arg( proxyModel()->getPlaylistInterface()->filter() ) );
m_overlay->setText( tr( "Sorry, your filter '%1' did not match any results." ).arg( proxyModel()->playlistInterface()->filter() ) );
m_overlay->show();
}
else
@ -307,45 +300,6 @@ ArtistView::startDrag( Qt::DropActions supportedActions )
}
void
ArtistView::onViewChanged()
{
if ( m_timer.isActive() )
m_timer.stop();
m_timer.start();
}
void
ArtistView::onScrollTimeout()
{
qDebug() << Q_FUNC_INFO;
if ( m_timer.isActive() )
m_timer.stop();
QModelIndex left = indexAt( viewport()->rect().topLeft() );
while ( left.isValid() && left.parent().isValid() )
left = left.parent();
QModelIndex right = indexAt( viewport()->rect().bottomLeft() );
while ( right.isValid() && right.parent().isValid() )
right = right.parent();
int max = m_proxyModel->getPlaylistInterface()->trackCount();
if ( right.isValid() )
max = right.row() + 1;
if ( !max )
return;
for ( int i = left.row(); i < max; i++ )
{
m_model->getCover( m_proxyModel->mapToSource( m_proxyModel->index( i, 0 ) ) );
}
}
void
ArtistView::onCustomContextMenu( const QPoint& pos )
{

View File

@ -62,7 +62,7 @@ public:
void setTreeModel( TreeModel* model );
virtual QWidget* widget() { return this; }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->getPlaylistInterface(); }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->playlistInterface(); }
virtual QString title() const { return m_model->title(); }
virtual QString description() const { return m_model->description(); }
@ -95,8 +95,6 @@ private slots:
void onItemCountChanged( unsigned int items );
void onFilterChanged( const QString& filter );
void onFilteringStarted();
void onViewChanged();
void onScrollTimeout();
void onCustomContextMenu( const QPoint& pos );
void onMenuTriggered( int action );
@ -115,7 +113,6 @@ private:
Tomahawk::ContextMenu* m_contextMenu;
bool m_showModes;
QTimer m_timer;
mutable QString m_guid;
};

View File

@ -33,7 +33,7 @@ CollectionProxyModel::CollectionProxyModel( QObject* parent )
}
Tomahawk::playlistinterface_ptr
CollectionProxyModel::getPlaylistInterface()
CollectionProxyModel::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -32,7 +32,7 @@ public:
explicit CollectionProxyModel( QObject* parent = 0 );
virtual ~CollectionProxyModel() {}
virtual Tomahawk::playlistinterface_ptr getPlaylistInterface();
virtual Tomahawk::playlistinterface_ptr playlistInterface();
};

View File

@ -60,6 +60,7 @@ CollectionView::setTrackModel( TrackModel* model )
setColumnHidden( TrackModel::Score, true ); // Hide score column per default
setColumnHidden( TrackModel::Origin, true ); // Hide origin column per default
setColumnHidden( TrackModel::Composer, true ); //Hide composer column per default
setGuid( QString( "collectionview/%1" ).arg( model->columnCount() ) );
sortByColumn( TrackModel::Artist, Qt::AscendingOrder );

View File

@ -39,7 +39,7 @@ public:
virtual void setModel( QAbstractItemModel* model );
virtual QWidget* widget() { return this; }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->getPlaylistInterface(); }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->playlistInterface(); }
virtual QString title() const { return model()->title(); }
virtual QString description() const { return model()->description(); }

View File

@ -203,7 +203,7 @@ DynamicWidget::onRevisionLoaded( const Tomahawk::DynamicPlaylistRevision& rev )
Tomahawk::playlistinterface_ptr
DynamicWidget::playlistInterface() const
{
return m_view->proxyModel()->getPlaylistInterface();
return m_view->proxyModel()->playlistInterface();
}
@ -243,7 +243,7 @@ DynamicWidget::layoutFloatingWidgets()
void
DynamicWidget::playlistChanged( Tomahawk::playlistinterface_ptr pl )
{
if( pl == m_view->proxyModel()->getPlaylistInterface() ) { // same playlist
if( pl == m_view->proxyModel()->playlistInterface() ) { // same playlist
m_activePlaylist = true;
} else {
m_activePlaylist = false;

View File

@ -42,10 +42,11 @@ LoadingSpinner::LoadingSpinner( QWidget* parent )
connect( m_showHide, SIGNAL( finished() ), this, SLOT( hideFinished() ) );
m_anim = new QMovie( RESPATH "/images/loading-animation.gif" );
m_anim->jumpToNextFrame();
connect( m_anim, SIGNAL( frameChanged( int ) ), this, SLOT( update() ) );
resize( 31, 31 );
resize( m_anim->currentPixmap().size() );
setSizePolicy( QSizePolicy::Fixed, QSizePolicy::Fixed );
hide();
}
@ -96,7 +97,7 @@ LoadingSpinner::hideFinished()
QSize
LoadingSpinner::sizeHint() const
{
return QSize( 31, 31 );
return m_anim->currentPixmap().size();
}

View File

@ -56,9 +56,6 @@ PlaylistItemDelegate::PlaylistItemDelegate( TrackView* parent, TrackProxyModel*
m_bottomOption = QTextOption( Qt::AlignBottom );
m_bottomOption.setWrapMode( QTextOption::NoWrap );
m_centerOption = QTextOption( Qt::AlignVCenter );
m_centerOption.setWrapMode( QTextOption::NoWrap );
m_defaultAvatar = TomahawkUtils::createAvatarFrame( QPixmap( RESPATH "images/user-avatar.png" ) );
}
@ -252,6 +249,9 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
TrackModelItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
Q_ASSERT( item );
QTextOption textOption( Qt::AlignVCenter | (Qt::Alignment)index.data( Qt::TextAlignmentRole ).toUInt() );
textOption.setWrapMode( QTextOption::NoWrap );
QStyleOptionViewItemV4 opt = option;
prepareStyleOption( &opt, index, item );
opt.text.clear();
@ -294,27 +294,25 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
}
else if ( item->isPlaying() )
{
QRect r = opt.rect.adjusted( 3, 0, 0, 0 );
// Paint Now Playing Speaker Icon
if ( m_view->header()->visualIndex( index.column() ) == 0 )
{
QRect r = opt.rect.adjusted( 3, 0, 0, 0 );
// Paint Now Playing Speaker Icon
if ( m_view->header()->visualIndex( index.column() ) == 0 )
{
r.adjust( 0, 0, 0, -3 );
painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon );
r.adjust( 25, 0, 0, 3 );
}
painter->setPen( opt.palette.text().color() );
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, r.width() - 3 );
painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, m_centerOption );
r.adjust( 0, 0, 0, -3 );
painter->drawPixmap( r.adjusted( 3, 1, 18 - r.width(), 1 ), m_nowPlayingIcon );
r.adjust( 25, 0, 0, 3 );
}
painter->setPen( opt.palette.text().color() );
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, r.width() - 3 );
painter->drawText( r.adjusted( 0, 1, 0, 0 ), text, textOption );
}
else
{
painter->setPen( opt.palette.text().color() );
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, opt.rect.width() - 3 );
painter->drawText( opt.rect.adjusted( 3, 1, 0, 0 ), text, m_centerOption );
QString text = painter->fontMetrics().elidedText( index.data().toString(), Qt::ElideRight, opt.rect.width() - 6 );
painter->drawText( opt.rect.adjusted( 3, 1, -3, 0 ), text, textOption );
}
painter->restore();

View File

@ -59,7 +59,6 @@ private:
mutable QPixmap m_arrowIcon;
QTextOption m_topOption;
QTextOption m_centerOption;
QTextOption m_bottomOption;
TrackView* m_view;

View File

@ -152,7 +152,7 @@ PlaylistModel::append( const Tomahawk::album_ptr& album )
m_isTemporary = true;
}
append( album->getPlaylistInterface()->tracks() );
append( album->playlistInterface()->tracks() );
}
@ -172,7 +172,7 @@ PlaylistModel::append( const Tomahawk::artist_ptr& artist )
m_isTemporary = true;
}
append( artist->getPlaylistInterface()->tracks() );
append( artist->playlistInterface()->tracks() );
}

View File

@ -28,7 +28,7 @@ PlaylistProxyModel::PlaylistProxyModel( QObject* parent )
}
Tomahawk::playlistinterface_ptr
PlaylistProxyModel::getPlaylistInterface()
PlaylistProxyModel::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -31,7 +31,7 @@ public:
explicit PlaylistProxyModel( QObject* parent = 0 );
virtual ~PlaylistProxyModel() {}
virtual Tomahawk::playlistinterface_ptr getPlaylistInterface();
virtual Tomahawk::playlistinterface_ptr playlistInterface();
};
#endif // PLAYLISTPROXYMODEL_H

View File

@ -62,6 +62,7 @@ PlaylistView::setPlaylistModel( PlaylistModel* model )
TrackView::setTrackModel( m_model );
setColumnHidden( TrackModel::Age, true ); // Hide age column per default
setColumnHidden( TrackModel::Composer, true ); // Hide composer column per default
if ( guid().isEmpty() )
{

View File

@ -38,7 +38,7 @@ public:
virtual void setModel( QAbstractItemModel* model );
virtual QWidget* widget() { return this; }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->getPlaylistInterface(); }
virtual Tomahawk::playlistinterface_ptr playlistInterface() const { return proxyModel()->playlistInterface(); }
virtual bool showFilter() const { return true; }

View File

@ -32,7 +32,7 @@ QueueProxyModel::QueueProxyModel( TrackView* parent )
qDebug() << Q_FUNC_INFO;
connect( parent, SIGNAL( itemActivated( QModelIndex ) ), this, SLOT( onIndexActivated( QModelIndex ) ) );
connect( getPlaylistInterface().data(), SIGNAL( sourceTrackCountChanged( unsigned int ) ), this, SLOT( onTrackCountChanged( unsigned int ) ) );
connect( playlistInterface().data(), SIGNAL( sourceTrackCountChanged( unsigned int ) ), this, SLOT( onTrackCountChanged( unsigned int ) ) );
}
@ -58,7 +58,7 @@ QueueProxyModel::onTrackCountChanged( unsigned int count )
Tomahawk::playlistinterface_ptr
QueueProxyModel::getPlaylistInterface()
QueueProxyModel::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -34,7 +34,7 @@ public:
explicit QueueProxyModel( TrackView* parent = 0 );
virtual ~QueueProxyModel();
virtual Tomahawk::playlistinterface_ptr getPlaylistInterface();
virtual Tomahawk::playlistinterface_ptr playlistInterface();
private slots:
void onIndexActivated( const QModelIndex& index );

View File

@ -21,6 +21,7 @@
#include "playlistproxymodelplaylistinterface.h"
#include "result.h"
#include "dllmacro.h"
class QueueProxyModel;

View File

@ -38,7 +38,7 @@
<bool>true</bool>
</property>
<property name="text">
<string>Open Queue</string>
<string>Show Queue</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>

View File

@ -27,7 +27,7 @@ TrackHeader::TrackHeader( TrackView* parent )
, m_parent( parent )
{
QList< double > columnWeights;
columnWeights << 0.18 << 0.18 << 0.17 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.10; // << 0.05;
columnWeights << 0.16 << 0.16 << 0.14 << 0.12 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.05 << 0.09; // << 0.03;
setDefaultColumnWeights( columnWeights );
}

View File

@ -93,7 +93,7 @@ TrackModel::columnCount( const QModelIndex& parent ) const
case Detailed:
default:
return 11;
return 12;
break;
}
}
@ -136,6 +136,11 @@ TrackModel::data( const QModelIndex& index, int role ) const
return QSize( 0, 18 );
}
if ( role == Qt::TextAlignmentRole )
{
return QVariant( columnAlignment( index.column() ) );
}
if ( role == StyleRole )
{
return m_style;
@ -178,14 +183,17 @@ TrackModel::data( const QModelIndex& index, int role ) const
return query->results().first()->album()->name();
break;
case Composer:
if ( !query->results().first()->composer().isNull() )
return query->results().first()->composer()->name();
break;
case Duration:
return TomahawkUtils::timeToString( query->results().first()->duration() );
break;
case Bitrate:
if ( query->results().first()->bitrate() == 0 )
return QString();
else
if ( query->results().first()->bitrate() > 0 )
return query->results().first()->bitrate();
break;
@ -194,9 +202,7 @@ TrackModel::data( const QModelIndex& index, int role ) const
break;
case Year:
if ( query->results().first()->year() == 0 )
return QString();
else
if ( query->results().first()->year() != 0 )
return query->results().first()->year();
break;
@ -213,9 +219,16 @@ TrackModel::data( const QModelIndex& index, int role ) const
break;
case AlbumPos:
if ( query->results().first()->albumpos() == 0 )
return QString();
return QString::number( query->results().first()->albumpos() );
QString tPos;
if ( query->results().first()->albumpos() != 0 )
{
tPos = QString::number( query->results().first()->albumpos() );
if( query->results().first()->discnumber() == 0 )
return tPos;
else
return QString( "%1.%2" ).arg( QString::number( query->results().first()->discnumber() ) )
.arg( tPos );
}
break;
}
}
@ -230,12 +243,17 @@ TrackModel::headerData( int section, Qt::Orientation orientation, int role ) con
Q_UNUSED( orientation );
QStringList headers;
headers << tr( "Artist" ) << tr( "Title" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Score" );
headers << tr( "Artist" ) << tr( "Title" ) << tr( "Composer" ) << tr( "Album" ) << tr( "Track" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" ) << tr( "Score" );
if ( role == Qt::DisplayRole && section >= 0 )
{
return headers.at( section );
}
if ( role == Qt::TextAlignmentRole )
{
return QVariant( columnAlignment( section ) );
}
return QVariant();
}
@ -534,3 +552,23 @@ TrackModel::setStyle( TrackModel::TrackItemStyle style )
{
m_style = style;
}
Qt::Alignment
TrackModel::columnAlignment( int column ) const
{
switch( column )
{
case Age:
case AlbumPos:
case Bitrate:
case Duration:
case Filesize:
case Year:
return Qt::AlignHCenter;
break;
default:
return Qt::AlignLeft;
}
}

View File

@ -44,15 +44,16 @@ public:
enum Columns {
Artist = 0,
Track = 1,
Album = 2,
AlbumPos = 3,
Duration = 4,
Bitrate = 5,
Age = 6,
Year = 7,
Filesize = 8,
Origin = 9,
Score = 10,
Composer = 2,
Album = 3,
AlbumPos = 4,
Duration = 5,
Bitrate = 6,
Age = 7,
Year = 8,
Filesize = 9,
Origin = 10,
Score = 11
};
explicit TrackModel( QObject* parent = 0 );
@ -135,6 +136,8 @@ private slots:
void onPlaybackStopped();
private:
Qt::Alignment columnAlignment( int column ) const;
TrackModelItem* m_rootItem;
QPersistentModelIndex m_currentIndex;
Tomahawk::QID m_currentUuid;

View File

@ -55,7 +55,7 @@ TrackProxyModel::setSourceTrackModel( TrackModel* sourceModel )
m_model = sourceModel;
if ( m_model && m_model->metaObject()->indexOfSignal( "trackCountChanged(uint)" ) > -1 )
connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), getPlaylistInterface().data(), SIGNAL( sourceTrackCountChanged( unsigned int ) ) );
connect( m_model, SIGNAL( trackCountChanged( unsigned int ) ), playlistInterface().data(), SIGNAL( sourceTrackCountChanged( unsigned int ) ) );
QSortFilterProxyModel::setSourceModel( m_model );
}
@ -177,6 +177,7 @@ TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) c
QString track1 = q1->track();
QString track2 = q2->track();
unsigned int albumpos1 = 0, albumpos2 = 0;
unsigned int discnumber1 = 0, discnumber2 = 0;
unsigned int bitrate1 = 0, bitrate2 = 0;
unsigned int mtime1 = 0, mtime2 = 0;
unsigned int size1 = 0, size2 = 0;
@ -189,6 +190,7 @@ TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) c
album1 = r->album()->name();
track1 = r->track();
albumpos1 = r->albumpos();
discnumber1 = r->discnumber();
bitrate1 = r->bitrate();
mtime1 = r->modificationTime();
id1 = r->trackId();
@ -201,6 +203,7 @@ TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) c
album2 = r->album()->name();
track2 = r->track();
albumpos2 = r->albumpos();
discnumber2 = r->discnumber();
bitrate2 = r->bitrate();
mtime2 = r->modificationTime();
id2 = r->trackId();
@ -220,10 +223,15 @@ TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) c
{
if ( album1 == album2 )
{
if ( albumpos1 == albumpos2 )
return id1 < id2;
if( discnumber1 == discnumber2 )
{
if ( albumpos1 == albumpos2 )
return id1 < id2;
return albumpos1 < albumpos2;
return albumpos1 < albumpos2;
}
return discnumber1 < discnumber2;
}
return QString::localeAwareCompare( album1, album2 ) < 0;
@ -235,10 +243,15 @@ TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) c
{
if ( album1 == album2 )
{
if ( albumpos1 == albumpos2 )
return id1 < id2;
if( discnumber1 == discnumber2 )
{
if ( albumpos1 == albumpos2 )
return id1 < id2;
return albumpos1 < albumpos2;
return albumpos1 < albumpos2;
}
return discnumber1 < discnumber2;
}
return QString::localeAwareCompare( album1, album2 ) < 0;
@ -275,7 +288,7 @@ TrackProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) c
Tomahawk::playlistinterface_ptr
TrackProxyModel::getPlaylistInterface()
TrackProxyModel::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -52,7 +52,7 @@ public:
virtual TrackModelItem* itemFromIndex( const QModelIndex& index ) const { return sourceModel()->itemFromIndex( index ); }
virtual Tomahawk::playlistinterface_ptr getPlaylistInterface();
virtual Tomahawk::playlistinterface_ptr playlistInterface();
signals:
void filterChanged( const QString& filter );

View File

@ -55,7 +55,7 @@ public:
virtual bool shuffled() const { return m_shuffled; }
public slots:
virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setRepeatMode( Tomahawk::PlaylistInterface::RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); }
protected:

View File

@ -132,9 +132,6 @@ TrackView::setTrackModel( TrackModel* model )
m_proxyModel->setSourceTrackModel( m_model );
}
if ( m_model && m_model->metaObject()->indexOfSignal( "itemSizeChanged(QModelIndex)" ) > -1 )
connect( m_model, SIGNAL( itemSizeChanged( QModelIndex ) ), SLOT( onItemResized( QModelIndex ) ) );
connect( m_model, SIGNAL( loadingStarted() ), m_loadingSpinner, SLOT( fadeIn() ) );
connect( m_model, SIGNAL( loadingFinished() ), m_loadingSpinner, SLOT( fadeOut() ) );
@ -182,7 +179,7 @@ TrackView::onItemActivated( const QModelIndex& index )
{
tDebug() << "Result activated:" << item->query()->toString() << item->query()->results().first()->url();
m_proxyModel->setCurrentIndex( index );
AudioEngine::instance()->playItem( m_proxyModel->getPlaylistInterface(), item->query()->results().first() );
AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), item->query()->results().first() );
}
emit itemActivated( index );
@ -369,9 +366,9 @@ TrackView::onFilterChanged( const QString& )
if ( selectedIndexes().count() )
scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter );
if ( !proxyModel()->getPlaylistInterface()->filter().isEmpty() && !proxyModel()->getPlaylistInterface()->trackCount() && model()->trackCount() )
if ( !proxyModel()->playlistInterface()->filter().isEmpty() && !proxyModel()->playlistInterface()->trackCount() && model()->trackCount() )
{
m_overlay->setText( tr( "Sorry, your filter '%1' did not match any results." ).arg( proxyModel()->getPlaylistInterface()->filter() ) );
m_overlay->setText( tr( "Sorry, your filter '%1' did not match any results." ).arg( proxyModel()->playlistInterface()->filter() ) );
m_overlay->show();
}
else

View File

@ -27,7 +27,7 @@ TreeHeader::TreeHeader( ArtistView* parent )
, m_parent( parent )
{
QList< double > columnWeights;
columnWeights << 0.50 << 0.07 << 0.07 << 0.07 << 0.07 << 0.07; // << 0.12;
columnWeights << 0.42 << 0.12 << 0.07 << 0.07 << 0.07 << 0.07 << 0.07; // << 0.11;
setDefaultColumnWeights( columnWeights );
}

View File

@ -152,8 +152,17 @@ TreeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
QRect r = option.rect.adjusted( 4, 4, -option.rect.width() + option.rect.height() - 4, -4 );
// painter->drawPixmap( r, QPixmap( RESPATH "images/cover-shadow.png" ) );
QPixmap cover;
if ( !item->album().isNull() )
{
cover.loadFromData( item->album()->cover() );
}
else if ( !item->artist().isNull() )
{
cover.loadFromData( item->artist()->cover() );
}
QPixmap scover;
QPixmap cover = item->cover;
if ( cover.isNull() )
{
if ( !item->artist().isNull() )

View File

@ -47,8 +47,6 @@ TreeModel::TreeModel( QObject* parent )
connect( Tomahawk::InfoSystem::InfoSystem::instance(),
SIGNAL( info( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ),
SLOT( infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData, QVariant ) ) );
connect( Tomahawk::InfoSystem::InfoSystem::instance(), SIGNAL( finished( QString ) ), SLOT( infoSystemFinished( QString ) ) );
}
@ -89,40 +87,6 @@ TreeModel::collection() const
}
void
TreeModel::getCover( const QModelIndex& index )
{
TreeModelItem* item = itemFromIndex( index );
if ( !item->cover.isNull() )
return;
Tomahawk::InfoSystem::InfoStringHash trackInfo;
Tomahawk::InfoSystem::InfoRequestData requestData;
if ( !item->artist().isNull() )
{
trackInfo["artist"] = item->artist()->name();
requestData.type = Tomahawk::InfoSystem::InfoArtistImages;
}
else if ( !item->album().isNull() )
{
trackInfo["artist"] = item->album()->artist()->name();
trackInfo["album"] = item->album()->name();
requestData.type = Tomahawk::InfoSystem::InfoAlbumCoverArt;
}
else
return;
trackInfo["pptr"] = QString::number( (qlonglong)item );
m_coverHash.insert( (qlonglong)item, index );
requestData.caller = m_infoId;
requestData.input = QVariant::fromValue< Tomahawk::InfoSystem::InfoStringHash >( trackInfo );
requestData.customData = QVariantMap();
Tomahawk::InfoSystem::InfoSystem::instance()->getInfo( requestData );
}
void
TreeModel::setCurrentItem( const QModelIndex& index )
{
@ -238,8 +202,9 @@ int
TreeModel::columnCount( const QModelIndex& parent ) const
{
Q_UNUSED( parent );
if ( m_columnStyle == AllColumns )
return 7;
return 8;
else if ( m_columnStyle == TrackOnly )
return 1;
@ -307,6 +272,12 @@ TreeModel::data( const QModelIndex& index, int role ) const
else if ( !entry->result().isNull() )
{
const result_ptr& result = entry->result();
unsigned int discnumber = 0;
if ( !entry->query().isNull() )
discnumber = entry->query()->discnumber();
if ( discnumber == 0 )
discnumber = result->discnumber();
unsigned int albumpos = 0;
if ( !entry->query().isNull() )
albumpos = entry->query()->albumpos();
@ -316,26 +287,25 @@ TreeModel::data( const QModelIndex& index, int role ) const
switch( index.column() )
{
case Name:
return QString( "%1%2" ).arg( albumpos > 0 ? QString( "%1. ").arg( albumpos ) : QString() )
.arg( result->track() );
return QString( "%1%2%3" ).arg( discnumber > 0 ? QString( "%1." ).arg( discnumber ) : QString() )
.arg( albumpos > 0 ? QString( "%1. ").arg( albumpos ) : QString() )
.arg( result->track() );
case Duration:
return TomahawkUtils::timeToString( result->duration() );
case Bitrate:
if ( result->bitrate() == 0 )
return QString();
else
if ( result->bitrate() > 0 )
return result->bitrate();
break;
case Age:
return TomahawkUtils::ageToString( QDateTime::fromTime_t( result->modificationTime() ) );
case Year:
if ( result->year() == 0 )
return QString();
else
if ( result->year() != 0 )
return result->year();
break;
case Filesize:
return TomahawkUtils::filesizeToString( result->size() );
@ -346,6 +316,11 @@ TreeModel::data( const QModelIndex& index, int role ) const
case AlbumPosition:
return result->albumpos();
case Composer:
if ( !result->composer().isNull() )
return result->composer()->name();
break;
default:
return QVariant();
}
@ -356,8 +331,9 @@ TreeModel::data( const QModelIndex& index, int role ) const
switch( index.column() )
{
case Name:
return QString( "%1%2" ).arg( query->albumpos() > 0 ? QString( "%1. ").arg( query->albumpos() ) : QString() )
.arg( query->track() );
return QString( "%1%2%3" ).arg( query->discnumber() > 0 ? QString( "%1." ).arg( query->discnumber() ) : QString() )
.arg( query->albumpos() > 0 ? QString( "%1. ").arg( query->albumpos() ) : QString() )
.arg( query->track() );
case AlbumPosition:
return entry->query()->albumpos();
@ -375,7 +351,7 @@ QVariant
TreeModel::headerData( int section, Qt::Orientation orientation, int role ) const
{
QStringList headers;
headers << tr( "Name" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" );
headers << tr( "Name" ) << tr( "Composer" ) << tr( "Duration" ) << tr( "Bitrate" ) << tr( "Age" ) << tr( "Year" ) << tr( "Size" ) << tr( "Origin" );
if ( orientation == Qt::Horizontal && role == Qt::DisplayRole && section >= 0 )
{
return headers.at( section );
@ -654,7 +630,7 @@ TreeModel::addTracks( const album_ptr& album, const QModelIndex& parent, bool au
if ( m_mode == DatabaseMode )
{
DatabaseCommand_AllTracks* cmd = new DatabaseCommand_AllTracks( m_collection );
cmd->setAlbum( album.data() );
cmd->setAlbum( album );
cmd->setData( QVariant( rows ) );
connect( cmd, SIGNAL( tracks( QList<Tomahawk::query_ptr>, QVariant ) ),
@ -807,8 +783,6 @@ TreeModel::onAlbumsAdded( const QList<Tomahawk::album_ptr>& albums, const QModel
albumitem = new TreeModelItem( album, parentItem );
albumitem->index = createIndex( parentItem->children.count() - 1, 0, albumitem );
connect( albumitem, SIGNAL( dataChanged() ), SLOT( onDataChanged() ) );
getCover( albumitem->index );
}
emit endInsertRows();
@ -876,31 +850,6 @@ TreeModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QV
switch ( requestData.type )
{
case Tomahawk::InfoSystem::InfoAlbumCoverArt:
case Tomahawk::InfoSystem::InfoArtistImages:
{
Tomahawk::InfoSystem::InfoStringHash pptr = requestData.input.value< Tomahawk::InfoSystem::InfoStringHash >();
QVariantMap returnedData = output.value< QVariantMap >();
const QByteArray ba = returnedData["imgbytes"].toByteArray();
if ( ba.length() )
{
QPixmap pm;
pm.loadFromData( ba );
bool ok;
qlonglong p = pptr["pptr"].toLongLong( &ok );
TreeModelItem* ai = itemFromIndex( m_coverHash.take( p ) );
if ( !ai )
return;
if ( !pm.isNull() )
ai->cover = pm;
emit dataChanged( ai->index, ai->index.sibling( ai->index.row(), columnCount( QModelIndex() ) - 1 ) );
}
break;
}
case Tomahawk::InfoSystem::InfoArtistReleases:
{
QVariantMap returnedData = output.value< QVariantMap >();
@ -957,6 +906,11 @@ TreeModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QV
QStringList tracks = returnedData[ "tracks" ].toStringList();
QList<query_ptr> ql;
//TODO: Figure out how to do this with a multi-disk album without breaking the
// current behaviour. I just know too little about InfoSystem to deal with
// it right now, I've only taken the liberty of adding Query::setDiscNumber
// which should make this easier. --Teo 11/2011
unsigned int trackNo = 1;
foreach ( const QString& trackName, tracks )
@ -997,13 +951,6 @@ TreeModel::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QV
}
void
TreeModel::infoSystemFinished( QString target )
{
Q_UNUSED( target );
}
void
TreeModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
{

View File

@ -44,6 +44,7 @@ Q_OBJECT
public:
enum Columns {
Name = 0,
Composer,
Duration,
Bitrate,
Age,
@ -97,8 +98,6 @@ public:
void addAlbums( const Tomahawk::artist_ptr& artist, const QModelIndex& parent, bool autoRefetch = false );
void addTracks( const Tomahawk::album_ptr& album, const QModelIndex& parent, bool autoRefetch = false );
void getCover( const QModelIndex& index );
ColumnStyle columnStyle() const { return m_columnStyle; }
void setColumnStyle( ColumnStyle style );
@ -150,7 +149,6 @@ private slots:
void onTracksFound( const QList<Tomahawk::query_ptr>& tracks, const QVariant& variant );
void infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVariant output );
void infoSystemFinished( QString target );
void onPlaybackStarted( const Tomahawk::result_ptr& result );
void onPlaybackStopped();
@ -174,7 +172,6 @@ private:
QList<Tomahawk::artist_ptr> m_artistsFilter;
Tomahawk::collection_ptr m_collection;
QHash<qlonglong, QPersistentModelIndex> m_coverHash;
QList<Tomahawk::InfoSystem::InfoStringHash> m_receivedInfoData;
};

View File

@ -82,6 +82,8 @@ TreeModelItem::TreeModelItem( const Tomahawk::album_ptr& album, TreeModelItem* p
}
toberemoved = false;
connect( album.data(), SIGNAL( updated() ), SIGNAL( dataChanged() ) );
}
@ -109,6 +111,8 @@ TreeModelItem::TreeModelItem( const Tomahawk::artist_ptr& artist, TreeModelItem*
}
toberemoved = false;
connect( artist.data(), SIGNAL( updated() ), SIGNAL( dataChanged() ) );
}

View File

@ -48,8 +48,6 @@ public:
bool isPlaying() { return m_isPlaying; }
void setIsPlaying( bool b ) { m_isPlaying = b; emit dataChanged(); }
void setCover( const QPixmap& cover ) { this->cover = cover; emit dataChanged(); }
QString name() const;
QString artistName() const;
QString albumName() const;
@ -60,7 +58,6 @@ public:
int childCount;
QPersistentModelIndex index;
QAbstractItemModel* model;
QPixmap cover;
bool toberemoved;
bool fetchingMore;

View File

@ -41,6 +41,7 @@ TreeProxyModel::TreeProxyModel( QObject* parent )
setSourceTreeModel( 0 );
}
QPersistentModelIndex
TreeProxyModel::currentIndex() const
{
@ -109,6 +110,7 @@ TreeProxyModel::onModelReset()
m_albumsFilter.clear();
}
void
TreeProxyModel::newFilterFromPlaylistInterface( const QString &pattern )
{
@ -142,6 +144,7 @@ TreeProxyModel::newFilterFromPlaylistInterface( const QString &pattern )
}
}
void
TreeProxyModel::onFilterArtists( const QList<Tomahawk::artist_ptr>& artists )
{
@ -286,20 +289,39 @@ TreeProxyModel::lessThan( const QModelIndex& left, const QModelIndex& right ) co
unsigned int albumpos1 = 0;
unsigned int albumpos2 = 0;
unsigned int discnumber1 = 0;
unsigned int discnumber2 = 0;
if ( !p1->query().isNull() )
{
albumpos1 = p1->query()->albumpos();
discnumber1 = p1->query()->discnumber();
}
if ( !p2->query().isNull() )
{
albumpos2 = p2->query()->albumpos();
discnumber2 = p2->query()->discnumber();
}
if ( albumpos1 == 0 && !p1->result().isNull() )
albumpos1 = p1->result()->albumpos();
if ( discnumber1 == 0 && !p1->result().isNull() )
discnumber1 = p1->result()->discnumber();
if ( albumpos2 == 0 && !p2->result().isNull() )
albumpos2 = p2->result()->albumpos();
if ( discnumber2 == 0 && !p2->result().isNull() )
discnumber2 = p2->result()->discnumber();
const QString& lefts = textForItem( p1 );
const QString& rights = textForItem( p2 );
if ( albumpos1 != albumpos2 )
return albumpos1 < albumpos2;
if( discnumber1 != discnumber2 )
return discnumber1 < discnumber2;
else
{
if ( albumpos1 != albumpos2 )
return albumpos1 < albumpos2;
}
if ( lefts == rights )
return (qint64)&p1 < (qint64)&p2;
@ -363,7 +385,7 @@ TreeProxyModel::textForItem( TreeModelItem* item ) const
Tomahawk::playlistinterface_ptr
TreeProxyModel::getPlaylistInterface()
TreeProxyModel::playlistInterface()
{
if ( m_playlistInterface.isNull() )
{

View File

@ -57,7 +57,7 @@ public:
virtual TreeModelItem* itemFromIndex( const QModelIndex& index ) const { return sourceModel()->itemFromIndex( index ); }
virtual Tomahawk::playlistinterface_ptr getPlaylistInterface();
virtual Tomahawk::playlistinterface_ptr playlistInterface();
signals:
void filterChanged( const QString& filter );

View File

@ -74,7 +74,7 @@ signals:
void nextTrackReady();
public slots:
virtual void setRepeatMode( RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setRepeatMode( Tomahawk::PlaylistInterface::RepeatMode mode ) { m_repeatMode = mode; emit repeatModeChanged( mode ); }
virtual void setShuffled( bool enabled ) { m_shuffled = enabled; emit shuffleModeChanged( enabled ); }
private:

View File

@ -24,6 +24,7 @@ using namespace Tomahawk;
PlaylistInterface::PlaylistInterface ()
: QObject()
, m_latchMode( StayOnSong )
{
qRegisterMetaType<Tomahawk::PlaylistInterface::RepeatMode>( "Tomahawk::PlaylistInterface::RepeatMode" );
}

View File

@ -39,6 +39,7 @@ public:
enum SeekRestrictions { NoSeekRestrictions, NoSeek };
enum SkipRestrictions { NoSkipRestrictions, NoSkipForwards, NoSkipBackwards, NoSkip };
enum RetryMode { NoRetry, Retry };
enum LatchMode { StayOnSong, RealTime };
explicit PlaylistInterface();
virtual ~PlaylistInterface();
@ -55,14 +56,20 @@ public:
virtual Tomahawk::result_ptr siblingItem( int itemsAway ) = 0;
virtual PlaylistInterface::RepeatMode repeatMode() const = 0;
virtual bool shuffled() const = 0;
virtual PlaylistInterface::ViewMode viewMode() const { return Unknown; }
virtual PlaylistInterface::SeekRestrictions seekRestrictions() const { return NoSeekRestrictions; }
virtual PlaylistInterface::SkipRestrictions skipRestrictions() const { return NoSkipRestrictions; }
virtual PlaylistInterface::RetryMode retryMode() const { return NoRetry; }
virtual quint32 retryInterval() const { return 30000; }
virtual PlaylistInterface::LatchMode latchMode() const { return m_latchMode; }
virtual void setLatchMode( PlaylistInterface::LatchMode latchMode ) { m_latchMode = latchMode; }
virtual QString filter() const { return m_filter; }
virtual void setFilter( const QString& pattern ) { m_filter = pattern; }
@ -82,8 +89,12 @@ signals:
void shuffleModeChanged( bool enabled );
void trackCountChanged( unsigned int tracks );
void sourceTrackCountChanged( unsigned int tracks );
void latchModeChanged( Tomahawk::PlaylistInterface::LatchMode mode );
void nextTrackReady();
protected:
LatchMode m_latchMode;
private:
Q_DISABLE_COPY( PlaylistInterface )

View File

@ -56,15 +56,6 @@ public:
virtual void setFilter( const QString& /*pattern*/ ) {}
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );
void trackCountChanged( unsigned int tracks );
void sourceTrackCountChanged( unsigned int tracks );
void nextTrackReady();
public slots:
virtual void setRepeatMode( PlaylistInterface::RepeatMode ) {}
virtual void setShuffled( bool ) {}

Some files were not shown because too many files have changed in this diff Show More