1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-21 00:09:47 +01:00

* Auto advance to the next track in TreeView.

* Show proper icon for TreeView.
* Drag operations for tracks in TreeView / -Model.
* Various shutdown fixes.
* Properly hook up SipHandler signals again.
This commit is contained in:
Christian Muehlhaeuser 2011-05-12 00:35:05 +02:00
parent 1f7f360d36
commit 44585933dc
26 changed files with 341 additions and 123 deletions

View File

@ -82,7 +82,6 @@ public:
void init();
static TomahawkApp* instance();
SipHandler* sipHandler();
XMPPBot* xmppBot() { return m_xmppBot; }
#ifndef TOMAHAWK_HEADLESS

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -53,11 +53,10 @@ ControlConnection::~ControlConnection()
if ( !m_source.isNull() )
m_source->setOffline();
delete m_pingtimer;
m_servent->unregisterControlConnection(this);
if( m_dbsyncconn )
m_dbsyncconn->deleteLater();
m_servent->unregisterControlConnection( this );
delete m_dbsyncconn;
}

View File

@ -41,29 +41,43 @@ Pipeline::instance()
Pipeline::Pipeline( QObject* parent )
: QObject( parent )
, m_index_ready( false )
, m_running( false )
{
s_instance = this;
}
Pipeline::~Pipeline()
{
m_running = false;
}
void
Pipeline::databaseReady()
{
connect( Database::instance(), SIGNAL( indexReady() ), this, SLOT( indexReady() ), Qt::QueuedConnection );
connect( Database::instance(), SIGNAL( indexReady() ), this, SLOT( start() ), Qt::QueuedConnection );
Database::instance()->loadIndex();
}
void Pipeline::indexReady()
void
Pipeline::start()
{
qDebug() << Q_FUNC_INFO << "shunting this many pending queries:" << m_queries_pending.size();
m_index_ready = true;
m_running = true;
shuntNext();
}
void
Pipeline::stop()
{
m_running = false;
}
void
Pipeline::removeResolver( Resolver* r )
{
@ -210,7 +224,7 @@ Pipeline::reportResults( QID qid, const QList< result_ptr >& results )
void
Pipeline::shuntNext()
{
if ( !m_index_ready )
if ( !m_running )
return;
query_ptr q;
@ -245,6 +259,9 @@ Pipeline::shuntNext()
void
Pipeline::timeoutShunt( const query_ptr& q )
{
if ( !m_running )
return;
// are we still waiting for a timeout?
if ( m_qidsTimeout.contains( q->id() ) )
{
@ -259,6 +276,9 @@ Pipeline::timeoutShunt( const query_ptr& q )
void
Pipeline::shunt( const query_ptr& q )
{
if ( !m_running )
return;
qDebug() << Q_FUNC_INFO << q->solved() << q->toString() << q->id();
unsigned int lastweight = 0;
unsigned int lasttimeout = 0;

View File

@ -44,6 +44,7 @@ public:
static Pipeline* instance();
explicit Pipeline( QObject* parent = 0 );
virtual ~Pipeline();
void reportResults( QID qid, const QList< result_ptr >& results );
@ -67,6 +68,9 @@ public slots:
void resolve( const query_ptr& q, bool prioritized = false );
void resolve( const QList<query_ptr>& qlist, bool prioritized = false );
void resolve( QID qid, bool prioritized = false );
void start();
void stop();
void databaseReady();
signals:
@ -77,8 +81,6 @@ private slots:
void shunt( const query_ptr& q );
void shuntNext();
void indexReady();
private:
void setQIDState( const Tomahawk::query_ptr& query, int state );
int incQIDState( const Tomahawk::query_ptr& query );
@ -95,7 +97,7 @@ private:
// store queries here until DB index is loaded, then shunt them all
QList< query_ptr > m_queries_pending;
bool m_index_ready;
bool m_running;
static Pipeline* s_instance;
};

View File

@ -125,33 +125,14 @@ ArtistView::onItemActivated( const QModelIndex& index )
else if ( !item->album().isNull() )
ViewManager::instance()->show( item->album() );
else if ( !item->result().isNull() )
AudioEngine::instance()->playItem( 0, item->result() );
{
m_model->setCurrentItem( item->index );
AudioEngine::instance()->playItem( m_proxyModel, item->result() );
}
}
}
void
ArtistView::dragEnterEvent( QDragEnterEvent* event )
{
qDebug() << Q_FUNC_INFO;
QTreeView::dragEnterEvent( event );
}
void
ArtistView::dragMoveEvent( QDragMoveEvent* event )
{
QTreeView::dragMoveEvent( event );
}
void
ArtistView::dropEvent( QDropEvent* event )
{
QTreeView::dropEvent( event );
}
void
ArtistView::paintEvent( QPaintEvent* event )
{
@ -178,15 +159,32 @@ ArtistView::onFilterChanged( const QString& )
void
ArtistView::startDrag( Qt::DropActions supportedActions )
{
Q_UNUSED( supportedActions );
}
QList<QPersistentModelIndex> pindexes;
QModelIndexList indexes;
foreach( const QModelIndex& idx, selectedIndexes() )
{
if ( ( m_proxyModel->flags( idx ) & Qt::ItemIsDragEnabled ) )
{
indexes << idx;
pindexes << idx;
}
}
if ( indexes.count() == 0 )
return;
QPixmap
ArtistView::createDragPixmap( int itemCount ) const
{
Q_UNUSED( itemCount );
return QPixmap();
qDebug() << "Dragging" << indexes.count() << "indexes";
QMimeData* data = m_proxyModel->mimeData( indexes );
if ( !data )
return;
QDrag* drag = new QDrag( this );
drag->setMimeData( data );
const QPixmap p = TomahawkUtils::createDragPixmap( indexes.count() );
drag->setPixmap( p );
drag->setHotSpot( QPoint( -20, -20 ) );
drag->exec( supportedActions, Qt::CopyAction );
}
@ -232,3 +230,11 @@ ArtistView::onScrollTimeout()
QVariant::fromValue< Tomahawk::InfoSystem::InfoCriteriaHash >( trackInfo ), Tomahawk::InfoSystem::InfoCustomData() );
}
}
bool
ArtistView::jumpToCurrentTrack()
{
scrollTo( m_proxyModel->currentItem(), QAbstractItemView::PositionAtCenter );
return true;
}

View File

@ -51,11 +51,12 @@ public:
virtual QString title() const { return m_model->title(); }
virtual QString description() const { return m_model->description(); }
virtual QPixmap pixmap() const { return QPixmap( RESPATH "images/music-icon.png" ); }
virtual bool showStatsBar() const { return false; }
virtual bool showModes() const { return true; }
virtual bool jumpToCurrentTrack() { return false; }
virtual bool jumpToCurrentTrack();
QString guid() const { return QString( "ArtistView" ); }
@ -64,9 +65,6 @@ public slots:
protected:
virtual void startDrag( Qt::DropActions supportedActions );
virtual void dragEnterEvent( QDragEnterEvent* event );
virtual void dragMoveEvent( QDragMoveEvent* event );
virtual void dropEvent( QDropEvent* event );
virtual void resizeEvent( QResizeEvent* event );
void paintEvent( QPaintEvent* event );
@ -77,8 +75,6 @@ private slots:
void onScrollTimeout();
private:
QPixmap createDragPixmap( int itemCount ) const;
TreeHeader* m_header;
TreeModel* m_model;
TreeProxyModel* m_proxyModel;

View File

@ -300,6 +300,7 @@ PlaylistModel::onRevisionLoaded( Tomahawk::PlaylistRevision revision )
bool
PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
{
qDebug() << "LALALA";
Q_UNUSED( column );
if ( action == Qt::IgnoreAction || isReadOnly() )
return true;
@ -319,11 +320,30 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
qDebug() << data->formats();
QList<Tomahawk::query_ptr> queries;
if ( data->hasFormat( "application/tomahawk.result.list" ) )
{
QByteArray itemData = data->data( "application/tomahawk.result.list" );
QDataStream stream( &itemData, QIODevice::ReadOnly );
while ( !stream.atEnd() )
{
qlonglong qptr;
stream >> qptr;
Tomahawk::result_ptr* result = reinterpret_cast<Tomahawk::result_ptr*>(qptr);
if ( result && !result->isNull() )
{
qDebug() << "Dropped result item:" << result->data()->artist() << "-" << result->data()->track() << action;
queries << result->data()->toQuery();
}
}
}
if ( data->hasFormat( "application/tomahawk.query.list" ) )
{
QByteArray itemData = data->data( "application/tomahawk.query.list" );
QDataStream stream( &itemData, QIODevice::ReadOnly );
QList<Tomahawk::query_ptr> queries;
while ( !stream.atEnd() )
{
@ -337,7 +357,10 @@ PlaylistModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int r
queries << *query;
}
}
}
if ( queries.count() )
{
emit beginInsertRows( QModelIndex(), beginRow, beginRow + queries.count() - 1 );
foreach( const Tomahawk::query_ptr& query, queries )
{

View File

@ -143,7 +143,6 @@ TrackProxyModel::siblingItem( int itemsAway )
if ( idx.isValid() ) do
{
TrackModelItem* item = itemFromIndex( mapToSource( idx ) );
qDebug() << item->query()->toString();
if ( item && item->query()->playable() )
{
qDebug() << "Next PlaylistItem found:" << item->query()->toString() << item->query()->results().at( 0 )->url();

View File

@ -285,6 +285,19 @@ TrackView::dropEvent( QDropEvent* event )
qDebug() << "Drop Event accepted at row:" << index.row();
event->acceptProposedAction();
if ( !model()->isReadOnly() )
{
model()->dropMimeData( event->mimeData(), event->proposedAction(), index.row(), 0, index.parent() );
}
}
else if ( event->mimeData()->hasFormat( "application/tomahawk.result.list" ) )
{
const QPoint pos = event->pos();
const QModelIndex index = indexAt( pos );
qDebug() << "Drop Event accepted at row:" << index.row();
event->acceptProposedAction();
if ( !model()->isReadOnly() )
{
model()->dropMimeData( event->mimeData(), event->proposedAction(), index.row(), 0, index.parent() );
@ -345,6 +358,7 @@ TrackView::onFilterChanged( const QString& )
m_overlay->hide();
}
void
TrackView::copyLink()
{

View File

@ -55,6 +55,29 @@ TreeModel::~TreeModel()
}
void
TreeModel::setCurrentItem( const QModelIndex& index )
{
qDebug() << Q_FUNC_INFO;
TreeModelItem* oldEntry = itemFromIndex( m_currentIndex );
if ( oldEntry )
{
// oldEntry->setIsPlaying( false );
}
TreeModelItem* entry = itemFromIndex( index );
if ( entry )
{
m_currentIndex = index;
// entry->setIsPlaying( true );
}
else
{
m_currentIndex = QModelIndex();
}
}
QModelIndex
TreeModel::index( int row, int column, const QModelIndex& parent ) const
{
@ -257,9 +280,13 @@ TreeModel::flags( const QModelIndex& index ) const
Qt::ItemFlags defaultFlags = QAbstractItemModel::flags( index );
if ( index.isValid() && index.column() == 0 )
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
else
return defaultFlags;
{
TreeModelItem* item = itemFromIndex( index );
if ( item && !item->result().isNull() )
return Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled | defaultFlags;
}
return defaultFlags;
}
@ -267,7 +294,7 @@ QStringList
TreeModel::mimeTypes() const
{
QStringList types;
types << "application/tomahawk.query.list";
types << "application/tomahawk.result.list";
return types;
}
@ -277,8 +304,8 @@ TreeModel::mimeData( const QModelIndexList &indexes ) const
{
qDebug() << Q_FUNC_INFO;
QByteArray queryData;
QDataStream queryStream( &queryData, QIODevice::WriteOnly );
QByteArray resultData;
QDataStream resultStream( &resultData, QIODevice::WriteOnly );
foreach ( const QModelIndex& i, indexes )
{
@ -287,15 +314,15 @@ TreeModel::mimeData( const QModelIndexList &indexes ) const
QModelIndex idx = index( i.row(), 0, i.parent() );
TreeModelItem* item = itemFromIndex( idx );
if ( item )
if ( item && !item->result().isNull() )
{
const album_ptr& album = item->album();
queryStream << qlonglong( &album );
const result_ptr& result = item->result();
resultStream << qlonglong( &result );
}
}
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.query.list", queryData );
mimeData->setData( "application/tomahawk.result.list", resultData );
return mimeData;
}
@ -396,7 +423,10 @@ TreeModel::addCollection( const collection_ptr& collection )
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
m_title = tr( "All Artists from %1" ).arg( collection->source()->friendlyName() );
if ( collection->source()->isLocal() )
setTitle( tr( "Your Collection" ) );
else
setTitle( tr( "Collection of %1" ).arg( collection->source()->friendlyName() ) );
}
@ -418,7 +448,10 @@ TreeModel::addFilteredCollection( const collection_ptr& collection, unsigned int
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
m_title = tr( "All albums from %1" ).arg( collection->source()->friendlyName() );
if ( collection->source()->isLocal() )
setTitle( tr( "Your Collection" ) );
else
setTitle( tr( "Collection of %1" ).arg( collection->source()->friendlyName() ) );
}

View File

@ -74,6 +74,8 @@ public:
virtual QStringList mimeTypes() const;
virtual Qt::ItemFlags flags( const QModelIndex& index ) const;
virtual QPersistentModelIndex currentItem() { return m_currentIndex; }
void addAllCollections();
void addCollection( const Tomahawk::collection_ptr& collection );
void addFilteredCollection( const Tomahawk::collection_ptr& collection, unsigned int amount, DatabaseCommand_AllArtists::SortOrder order );
@ -97,6 +99,8 @@ public:
}
public slots:
virtual void setCurrentItem( const QModelIndex& index );
virtual void setRepeatMode( PlaylistInterface::RepeatMode /*mode*/ ) {}
virtual void setShuffled( bool /*shuffled*/ ) {}

View File

@ -140,7 +140,28 @@ Tomahawk::result_ptr
TreeProxyModel::siblingItem( int itemsAway )
{
qDebug() << Q_FUNC_INFO;
return Tomahawk::result_ptr( 0 );
QModelIndex idx = currentItem();
// Try to find the next available PlaylistItem (with results)
if ( idx.isValid() ) do
{
idx = index( idx.row() + ( itemsAway > 0 ? 1 : -1 ), 0, idx.parent() );
if ( !idx.isValid() )
break;
TreeModelItem* item = itemFromIndex( mapToSource( idx ) );
if ( item && item->result()->isOnline() )
{
qDebug() << "Next PlaylistItem found:" << item->result()->url();
setCurrentItem( idx );
return item->result();
}
}
while ( idx.isValid() );
setCurrentItem( QModelIndex() );
return Tomahawk::result_ptr();
}

View File

@ -36,6 +36,9 @@ public:
virtual TreeModel* sourceModel() const { return m_model; }
virtual void setSourceModel( TreeModel* sourceModel );
virtual QPersistentModelIndex currentItem() const { return mapFromSource( m_model->currentItem() ); }
virtual void setCurrentItem( const QModelIndex& index ) { m_model->setCurrentItem( mapToSource( index ) ); }
virtual QList<Tomahawk::query_ptr> tracks() { Q_ASSERT( FALSE ); QList<Tomahawk::query_ptr> queries; return queries; }
virtual int unfilteredTrackCount() const { return sourceModel()->rowCount( QModelIndex() ); }
@ -53,6 +56,8 @@ public:
virtual bool shuffled() const { return m_shuffled; }
virtual PlaylistInterface::ViewMode viewMode() const { return PlaylistInterface::Tree; }
TreeModelItem* itemFromIndex( const QModelIndex& index ) const { return sourceModel()->itemFromIndex( index ); }
signals:
void repeatModeChanged( PlaylistInterface::RepeatMode mode );
void shuffleModeChanged( bool enabled );

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -30,7 +30,14 @@ using namespace Tomahawk;
Result::Result()
: QObject()
, m_duration( 0 )
, m_bitrate( 0 )
, m_size( 0 )
, m_albumpos( 0 )
, m_modtime( 0 )
, m_year( 0 )
, m_score( 0 )
, m_id( 0 )
{
}
@ -40,21 +47,21 @@ Result::~Result()
}
artist_ptr
artist_ptr
Result::artist() const
{
return m_artist;
}
album_ptr
album_ptr
Result::album() const
{
return m_album;
}
collection_ptr
collection_ptr
Result::collection() const
{
return m_collection;
@ -87,6 +94,13 @@ Result::id() const
}
bool
Result::isOnline() const
{
return ( !collection().isNull() && collection()->source()->isOnline() );
}
QVariant
Result::toVariant() const
{

View File

@ -1,5 +1,5 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
*
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
@ -55,6 +55,8 @@ public:
float score() const;
RID id() const;
bool isOnline() const;
collection_ptr collection() const;
Tomahawk::artist_ptr artist() const;
Tomahawk::album_ptr album() const;

View File

@ -40,13 +40,16 @@
SipHandler* SipHandler::s_instance = 0;
SipHandler* SipHandler::instance()
SipHandler*
SipHandler::instance()
{
if( s_instance == 0 )
s_instance = new SipHandler( 0 );
if ( !s_instance )
new SipHandler( 0 );
return s_instance;
}
SipHandler::SipHandler( QObject* parent )
: QObject( parent )
, m_connected( false )
@ -61,10 +64,14 @@ SipHandler::SipHandler( QObject* parent )
SipHandler::~SipHandler()
{
qDebug() << Q_FUNC_INFO;
disconnectAll();
qDeleteAll( m_allPlugins );
}
const QPixmap SipHandler::avatar( const QString& name ) const
const QPixmap
SipHandler::avatar( const QString& name ) const
{
qDebug() << Q_FUNC_INFO << "Getting avatar" << name << m_usernameAvatars.keys();
if( m_usernameAvatars.keys().contains( name ) )
@ -80,12 +87,14 @@ const QPixmap SipHandler::avatar( const QString& name ) const
}
}
const SipInfo
SipHandler::sipInfo(const QString& peerId) const
{
return m_peersSipInfos.value( peerId );
}
void
SipHandler::onSettingsChanged()
{
@ -554,10 +563,11 @@ SipHandler::onStateChanged( SipPlugin::ConnectionState state )
{
m_connectedPlugins.removeAll( sip );
emit disconnected( sip );
} else if ( sip->connectionState() == SipPlugin::Connected )
}
else if ( sip->connectionState() == SipPlugin::Connected )
{
m_connectedPlugins.removeAll( sip );
emit disconnected( sip );
m_connectedPlugins << sip;
emit connected( sip );
}
emit stateChanged( sip, state );

View File

@ -59,7 +59,7 @@ class DLLEXPORT SipPlugin : public QObject
public:
enum SipErrorCode { AuthError, ConnectionError }; // Placeholder for errors, to be defined
enum ConnectionState { Disconnected, Connecting, Connected };
enum ConnectionState { Disconnected, Connecting, Connected, Disconnecting };
explicit SipPlugin( const QString& pluginId, QObject* parent = 0 );
virtual ~SipPlugin() {}

View File

@ -45,7 +45,6 @@ SourceList::instance()
SourceList::SourceList( QObject* parent )
: QObject( parent )
{
loadSources();
}

View File

@ -43,6 +43,7 @@ public:
void setWebSource( const Tomahawk::source_ptr& websrc );
const Tomahawk::source_ptr webSource() const;
void loadSources();
void removeAllRemote();
QList<Tomahawk::source_ptr> sources( bool onlyOnline = false ) const;
@ -62,7 +63,6 @@ private slots:
void sourceSynced();
private:
void loadSources();
void add( const Tomahawk::source_ptr& source );
QMap< QString, Tomahawk::source_ptr > m_sources;

View File

@ -60,7 +60,7 @@ QtScriptResolver::QtScriptResolver( const QString& scriptPath )
QtScriptResolver::~QtScriptResolver()
{
Tomahawk::Pipeline::instance()->removeResolver( this );
delete m_engine;
// delete m_engine;
}

View File

@ -96,7 +96,7 @@ JabberPlugin::JabberPlugin( const QString& pluginId )
// instantiate XmlConsole
if( readXmlConsoleEnabled() )
{
m_xmlConsole = new XmlConsole( m_client );
m_xmlConsole = new XmlConsole( m_client );
m_xmlConsole->show();
}
@ -141,7 +141,11 @@ JabberPlugin::JabberPlugin( const QString& pluginId )
JabberPlugin::~JabberPlugin()
{
delete m_avatarManager;
delete m_roster;
delete m_client;
delete m_xmlConsole;
delete m_ui;
}
void
@ -222,7 +226,6 @@ JabberPlugin::connectPlugin( bool startup )
//FIXME: we're badly workarounding some missing reconnection api here, to be fixed soon
QTimer::singleShot( 1000, m_client, SLOT( connectToServer() ) );
connect(m_client->connection(), SIGNAL(error(Jreen::Connection::SocketError)), SLOT(onError(Jreen::Connection::SocketError)));
m_state = Connecting;
@ -251,7 +254,9 @@ JabberPlugin::disconnectPlugin()
m_peers.clear();
m_legacy_peers.clear();
m_client->disconnectFromServer(true);
m_client->disconnectFromServer( true );
m_state = Disconnecting;
emit stateChanged( m_state );
}
void
@ -572,6 +577,11 @@ void JabberPlugin::removeMenuHelper()
void JabberPlugin::onNewMessage(const Jreen::Message& message)
{
if ( m_state != Connected )
return;
qDebug() << Q_FUNC_INFO << "message type" << message.subtype();
QString from = message.from().full();
QString msg = message.body();
@ -608,6 +618,8 @@ void JabberPlugin::onNewMessage(const Jreen::Message& message)
void JabberPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const Jreen::Presence& presence )
{
Q_UNUSED(item);
if ( m_state != Connected )
return;
Jreen::JID jid = presence.from();
QString fulljid( jid.full() );
@ -652,6 +664,9 @@ void JabberPlugin::onPresenceReceived( const Jreen::RosterItem::Ptr &item, const
void JabberPlugin::onSubscriptionReceived(const Jreen::RosterItem::Ptr& item, const Jreen::Presence& presence)
{
if ( m_state != Connected )
return;
qDebug() << Q_FUNC_INFO << "presence type: " << presence.subtype();
if(item)
qDebug() << Q_FUNC_INFO << presence.from().full() << "subs" << item->subscription() << "ask" << item->ask();
@ -739,6 +754,9 @@ JabberPlugin::onSubscriptionRequestConfirmed( int result )
void JabberPlugin::onNewIq(const Jreen::IQ& iq, int context)
{
if ( m_state != Connected )
return;
if( context == RequestDisco )
{
qDebug() << Q_FUNC_INFO << "Received disco IQ...";
@ -885,6 +903,9 @@ void JabberPlugin::handlePeerStatus(const Jreen::JID& jid, Jreen::Presence::Type
void JabberPlugin::onNewAvatar(const QString& jid)
{
qDebug() << Q_FUNC_INFO << jid;
if ( m_state != Connected )
return;
Q_ASSERT(!m_avatarManager->avatar( jid ).isNull());
// find peers for the jid

View File

@ -111,36 +111,56 @@ PlaylistItem::willAcceptDrag( const QMimeData* data ) const
bool
PlaylistItem::dropMimeData( const QMimeData* data, Qt::DropAction action )
{
if( data->hasFormat( "application/tomahawk.query.list" ) ) {
if ( !m_playlist.isNull() && m_playlist->author()->isLocal() ) {
QList< Tomahawk::query_ptr > queries;
if ( data->hasFormat( "application/tomahawk.result.list" ) )
{
QByteArray itemData = data->data( "application/tomahawk.result.list" );
QDataStream stream( &itemData, QIODevice::ReadOnly );
QByteArray itemData = data->data( "application/tomahawk.query.list" );
QDataStream stream( &itemData, QIODevice::ReadOnly );
QList< Tomahawk::query_ptr > queries;
while ( !stream.atEnd() )
{
qlonglong qptr;
stream >> qptr;
while ( !stream.atEnd() )
Tomahawk::result_ptr* result = reinterpret_cast<Tomahawk::result_ptr*>(qptr);
if ( result && !result->isNull() )
{
qlonglong qptr;
stream >> qptr;
Tomahawk::query_ptr* query = reinterpret_cast<Tomahawk::query_ptr*>(qptr);
if ( query && !query->isNull() )
{
qDebug() << "Dropped query item:" << query->data()->artist() << "-" << query->data()->track();
queries << *query;
}
qDebug() << "Dropped result item:" << result->data()->artist() << "-" << result->data()->track();
queries << result->data()->toQuery();
}
qDebug() << "on playlist:" << m_playlist->title() << m_playlist->guid();
// TODO do we need to use this in the refactor?
// QString rev = item->currentlyLoadedPlaylistRevision( playlist->guid() );
m_playlist->addEntries( queries, m_playlist->currentrevision() );
return true;
}
}
if ( data->hasFormat( "application/tomahawk.query.list" ) )
{
QByteArray itemData = data->data( "application/tomahawk.query.list" );
QDataStream stream( &itemData, QIODevice::ReadOnly );
while ( !stream.atEnd() )
{
qlonglong qptr;
stream >> qptr;
Tomahawk::query_ptr* query = reinterpret_cast<Tomahawk::query_ptr*>(qptr);
if ( query && !query->isNull() )
{
qDebug() << "Dropped query item:" << query->data()->artist() << "-" << query->data()->track();
queries << *query;
}
}
}
if ( queries.count() && !m_playlist.isNull() && m_playlist->author()->isLocal() )
{
qDebug() << "on playlist:" << m_playlist->title() << m_playlist->guid();
// TODO do we need to use this in the refactor?
// QString rev = item->currentlyLoadedPlaylistRevision( playlist->guid() );
m_playlist->addEntries( queries, m_playlist->currentrevision() );
return true;
}
return false;
}

View File

@ -87,12 +87,14 @@ SourcesModel::data( const QModelIndex& index, int role ) const
return QVariant();
}
int
SourcesModel::columnCount( const QModelIndex& parent ) const
{
return 1;
}
int
SourcesModel::rowCount( const QModelIndex& parent ) const
{
@ -103,6 +105,7 @@ SourcesModel::rowCount( const QModelIndex& parent ) const
return itemFromIndex( parent )->children().count();
}
QModelIndex
SourcesModel::parent( const QModelIndex& child ) const
{
@ -119,6 +122,7 @@ SourcesModel::parent( const QModelIndex& child ) const
return createIndex( rowForItem( parent ), 0, parent );
}
QModelIndex
SourcesModel::index( int row, int column, const QModelIndex& parent ) const
{
@ -137,6 +141,7 @@ SourcesModel::index( int row, int column, const QModelIndex& parent ) const
}
bool
SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role )
{
@ -144,14 +149,17 @@ SourcesModel::setData( const QModelIndex& index, const QVariant& value, int role
return item->setData( value, role );
}
QStringList
SourcesModel::mimeTypes() const
{
QStringList types;
types << "application/tomahawk.query.list";
types << "application/tomahawk.result.list";
return types;
}
QMimeData*
SourcesModel::mimeData( const QModelIndexList& indexes ) const
{
@ -159,6 +167,7 @@ SourcesModel::mimeData( const QModelIndexList& indexes ) const
return new QMimeData();
}
bool
SourcesModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
{
@ -173,12 +182,14 @@ SourcesModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int ro
return item->dropMimeData( data, action );
}
Qt::DropActions
SourcesModel::supportedDropActions() const
{
return Qt::CopyAction;
}
Qt::ItemFlags
SourcesModel::flags( const QModelIndex& index ) const
{
@ -200,6 +211,7 @@ SourcesModel::appendItem( const Tomahawk::source_ptr& source )
endInsertRows();
}
bool
SourcesModel::removeItem( const Tomahawk::source_ptr& source )
{
@ -228,6 +240,7 @@ SourcesModel::removeItem( const Tomahawk::source_ptr& source )
return false;
}
void
SourcesModel::viewPageActivated( Tomahawk::ViewPage* page )
{
@ -244,6 +257,7 @@ SourcesModel::viewPageActivated( Tomahawk::ViewPage* page )
}
}
void
SourcesModel::loadSources()
{
@ -275,6 +289,7 @@ SourcesModel::onSourceRemoved( const source_ptr& source )
removeItem( source );
}
void
SourcesModel::itemUpdated()
{
@ -303,6 +318,7 @@ SourcesModel::onItemRowsAddedBegin( int first, int last )
beginInsertRows( idx, first, last );
}
void
SourcesModel::onItemRowsAddedDone()
{
@ -311,6 +327,7 @@ SourcesModel::onItemRowsAddedDone()
endInsertRows();
}
void
SourcesModel::onItemRowsRemovedBegin( int first, int last )
{
@ -324,6 +341,7 @@ SourcesModel::onItemRowsRemovedBegin( int first, int last )
beginRemoveRows( idx, first, last );
}
void
SourcesModel::onItemRowsRemovedDone()
{
@ -332,6 +350,7 @@ SourcesModel::onItemRowsRemovedDone()
endRemoveRows();
}
void
SourcesModel::linkSourceItemToPage( SourceTreeItem* item, ViewPage* p )
{
@ -356,6 +375,7 @@ SourcesModel::itemFromIndex( const QModelIndex& idx ) const
return reinterpret_cast< SourceTreeItem* >( idx.internalPointer() );
}
QModelIndex
SourcesModel::indexFromItem( SourceTreeItem* item ) const
{
@ -396,6 +416,7 @@ SourcesModel::indexFromItem( SourceTreeItem* item ) const
return idx;
}
int
SourcesModel::rowForItem( SourceTreeItem* item ) const
{

View File

@ -160,6 +160,7 @@ SourceTreeView::hideOfflineSources()
m_proxyModel->hideOfflineSources();
}
void
SourceTreeView::onItemActivated( const QModelIndex& index )
{
@ -182,6 +183,7 @@ SourceTreeView::onItemExpanded( const QModelIndex& idx )
}
}
void
SourceTreeView::selectRequest( const QModelIndex& idx )
{
@ -260,7 +262,8 @@ SourceTreeView::dragEnterEvent( QDragEnterEvent* event )
qDebug() << Q_FUNC_INFO;
QTreeView::dragEnterEvent( event );
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) )
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" )
|| event->mimeData()->hasFormat( "application/tomahawk.result.list" ) )
{
m_dragging = true;
m_dropRect = QRect();
@ -278,7 +281,8 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
bool accept = false;
QTreeView::dragMoveEvent( event );
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) )
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" )
|| event->mimeData()->hasFormat( "application/tomahawk.result.list" ) )
{
setDirtyRegion( m_dropRect );
const QPoint pos = event->pos();
@ -292,7 +296,9 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
const SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index );
if( item->willAcceptDrag( event->mimeData() ) )
accept = true;
} else {
}
else
{
m_dropRect = QRect();
}
@ -344,6 +350,7 @@ SourceTreeView::drawRow( QPainter* painter, const QStyleOptionViewItem& option,
QTreeView::drawRow( painter, option, index );
}
template< typename T > T*
SourceTreeView::itemFromIndex( const QModelIndex& index ) const
{
@ -389,7 +396,6 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
}
}
SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() );
SourceTreeItem* item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >();
Q_ASSERT( item );

View File

@ -323,8 +323,14 @@ TomahawkApp::~TomahawkApp()
delete m_mainwindow;
delete m_audioEngine;
#endif
delete m_infoSystem;
delete SipHandler::instance();
Pipeline::instance()->stop();
delete m_database;
delete m_infoSystem;
qDebug() << "Finished shutdown.";
}
@ -343,11 +349,6 @@ TomahawkApp::audioControls()
}
#endif
SipHandler*
TomahawkApp::sipHandler()
{
return SipHandler::instance();
}
void
TomahawkApp::registerMetaTypes()
@ -476,6 +477,7 @@ TomahawkApp::disableScriptResolver( const QString& path )
}
}
Tomahawk::ExternalResolver*
TomahawkApp::resolverForPath( const QString& scriptPath )
{
@ -499,6 +501,7 @@ TomahawkApp::initLocalCollection()
collection_ptr dummycol( new WebCollection( dummy ) );
dummy->addCollection( dummycol );
SourceList::instance()->setWebSource( dummy );
SourceList::instance()->loadSources();
// to make the stats signal be emitted by our local source
// this will update the sidebar, etc.
@ -521,6 +524,7 @@ TomahawkApp::startServent()
}
}
void
TomahawkApp::setupSIP()
{

View File

@ -186,7 +186,7 @@ TomahawkWindow::TomahawkWindow( QWidget* parent )
// propagate sip menu
connect( SipHandler::instance(), SIGNAL( pluginAdded( SipPlugin* ) ), this, SLOT( onSipPluginAdded( SipPlugin* ) ) );
connect( SipHandler::instance(), SIGNAL( pluginRemoved( SipPlugin* ) ), this, SLOT( onSipPluginRemoved( SipPlugin* ) ) );
foreach( SipPlugin *plugin, APP->sipHandler()->allPlugins() )
foreach( SipPlugin *plugin, SipHandler::instance()->allPlugins() )
{
connect( plugin, SIGNAL( addMenu( QMenu* ) ), this, SLOT( pluginMenuAdded( QMenu* ) ) );
connect( plugin, SIGNAL( removeMenu( QMenu* ) ), this, SLOT( pluginMenuRemoved( QMenu* ) ) );
@ -267,7 +267,7 @@ TomahawkWindow::setupSignals()
// <Menu Items>
connect( ui->actionPreferences, SIGNAL( triggered() ), SLOT( showSettingsDialog() ) );
connect( ui->actionDiagnostics, SIGNAL( triggered() ), SLOT( showDiagnosticsDialog() ) );
connect( ui->actionToggleConnect, SIGNAL( triggered() ), APP->sipHandler(), SLOT( toggleConnect() ) );
connect( ui->actionToggleConnect, SIGNAL( triggered() ), SipHandler::instance(), SLOT( toggleConnect() ) );
// connect( ui->actionAddPeerManually, SIGNAL( triggered() ), SLOT( addPeerManually() ) );
connect( ui->actionRescanCollection, SIGNAL( triggered() ), SLOT( updateCollectionManually() ) );
connect( ui->actionLoadXSPF, SIGNAL( triggered() ), SLOT( loadSpiff() ));
@ -285,9 +285,9 @@ TomahawkWindow::setupSignals()
#endif
// <SipHandler>
connect( APP->sipHandler(), SIGNAL( connected() ), SLOT( onSipConnected() ) );
connect( APP->sipHandler(), SIGNAL( disconnected() ), SLOT( onSipDisconnected() ) );
connect( APP->sipHandler(), SIGNAL( authError() ), SLOT( onSipError() ) );
connect( SipHandler::instance(), SIGNAL( connected( SipPlugin* ) ), SLOT( onSipConnected() ) );
connect( SipHandler::instance(), SIGNAL( disconnected( SipPlugin* ) ), SLOT( onSipDisconnected() ) );
connect( SipHandler::instance(), SIGNAL( authError( SipPlugin* ) ), SLOT( onSipError() ) );
// set initial connection state
onSipDisconnected();