mirror of
https://github.com/tomahawk-player/tomahawk.git
synced 2025-03-25 02:09:48 +01:00
Move drop handling into source model
Add a Add Station item (needs flag change) Cleanup restore dynamic playlists to wo rking though hidden so we don't crash fix lots of minor things in the sourcelist
This commit is contained in:
parent
4f5948db71
commit
ed27dcdeec
@ -84,7 +84,7 @@ Collection::addDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
|
||||
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
||||
<< "from source id" << source()->id()
|
||||
<< "numplaylists:" << m_playlists.length();
|
||||
// emit dynamicPlaylistsAdded( toadd );
|
||||
emit dynamicPlaylistsAdded( toadd );
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +114,7 @@ Collection::deleteDynamicPlaylist( const Tomahawk::dynplaylist_ptr& p )
|
||||
qDebug() << Q_FUNC_INFO << "Collection name" << name()
|
||||
<< "from source id" << source()->id()
|
||||
<< "numplaylists:" << m_playlists.length();
|
||||
// emit dynamicPlaylistsDeleted( todelete );
|
||||
emit dynamicPlaylistsDeleted( todelete );
|
||||
}
|
||||
|
||||
|
||||
|
@ -82,10 +82,10 @@ signals:
|
||||
void playlistsAdded( const QList<Tomahawk::playlist_ptr>& );
|
||||
void playlistsDeleted( const QList<Tomahawk::playlist_ptr>& );
|
||||
|
||||
void automaticPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
void automaticPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
void stationsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
void stationsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
void dynamicPlaylistsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
void dynamicPlaylistsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
// void stationsAdded( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
// void stationsDeleted( const QList<Tomahawk::dynplaylist_ptr>& );
|
||||
|
||||
public slots:
|
||||
virtual void addTracks( const QList<QVariant>& newitems ) = 0;
|
||||
|
@ -53,10 +53,12 @@ DatabaseCollection::loadDynamicPlaylists()
|
||||
qDebug() << Q_FUNC_INFO;
|
||||
DatabaseCommand_LoadAllDynamicPlaylists* cmd = new DatabaseCommand_LoadAllDynamicPlaylists( source() );
|
||||
|
||||
connect( cmd, SIGNAL( dynamicPlaylistLoaded( Tomahawk::source_ptr, QVariantList ) ),
|
||||
SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );/*
|
||||
connect( cmd, SIGNAL( autoPlaylistLoaded( Tomahawk::source_ptr, QVariantList ) ),
|
||||
SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );
|
||||
connect( cmd, SIGNAL( stationLoaded( Tomahawk::source_ptr, QVariantList ) ),
|
||||
SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );
|
||||
SLOT( dynamicPlaylistCreated( const Tomahawk::source_ptr&, const QVariantList& ) ) );*/
|
||||
|
||||
Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
|
||||
}
|
||||
|
@ -51,7 +51,7 @@ public slots:
|
||||
virtual void removeTracks( const QDir& dir );
|
||||
|
||||
private slots:
|
||||
// void dynamicPlaylistCreated( const Tomahawk::source_ptr& source, const QVariantList& data );
|
||||
void dynamicPlaylistCreated( const Tomahawk::source_ptr& source, const QVariantList& data );
|
||||
};
|
||||
|
||||
#endif // DATABASECOLLECTION_H
|
||||
|
@ -49,10 +49,12 @@ void DatabaseCommand_LoadAllDynamicPlaylists::exec( DatabaseImpl* dbi )
|
||||
<< query.value(6).toBool() //shared
|
||||
<< query.value(5).toInt() //lastmod
|
||||
<< query.value(0).toString(); //GUID
|
||||
emit dynamicPlaylistLoaded( source(), data );
|
||||
/*
|
||||
if( static_cast<GeneratorMode>( query.value(8).toInt() ) == Static )
|
||||
emit autoPlaylistLoaded( source(), data );
|
||||
else
|
||||
emit stationLoaded( source(), data );
|
||||
emit stationLoaded( source(), data );*/
|
||||
}
|
||||
|
||||
emit done();
|
||||
|
@ -39,8 +39,7 @@ public:
|
||||
virtual QString commandname() const { return "loadalldynamicplaylists"; }
|
||||
|
||||
signals:
|
||||
void autoPlaylistLoaded( const Tomahawk::source_ptr& source, const QVariantList& data );
|
||||
void stationLoaded( const Tomahawk::source_ptr& source, const QVariantList& data );
|
||||
void dynamicPlaylistLoaded( const Tomahawk::source_ptr& source, const QVariantList& data );
|
||||
void done();
|
||||
};
|
||||
|
||||
|
@ -47,6 +47,7 @@
|
||||
|
||||
#include "widgets/welcomewidget.h"
|
||||
#include "widgets/infowidgets/sourceinfowidget.h"
|
||||
#include <widgets/newplaylistwidget.h>
|
||||
|
||||
#define FILTER_TIMEOUT 280
|
||||
|
||||
@ -567,13 +568,16 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory )
|
||||
|
||||
if ( !playlistForInterface( currentPlaylistInterface() ).isNull() )
|
||||
emit playlistActivated( playlistForInterface( currentPlaylistInterface() ) );
|
||||
if ( !dynamicPlaylistForInterface( currentPlaylistInterface() ).isNull() )
|
||||
|
||||
else if ( dynamicPlaylistForInterface( currentPlaylistInterface() ) )
|
||||
emit dynamicPlaylistActivated( dynamicPlaylistForInterface( currentPlaylistInterface() ) );
|
||||
if ( !collectionForInterface( currentPlaylistInterface() ).isNull() )
|
||||
else if ( collectionForInterface( currentPlaylistInterface() ) )
|
||||
emit collectionActivated( collectionForInterface( currentPlaylistInterface() ) );
|
||||
if ( isSuperCollectionVisible() )
|
||||
else if ( isSuperCollectionVisible() )
|
||||
emit superCollectionActivated();
|
||||
if ( !currentPlaylistInterface() )
|
||||
else if( isNewPlaylistPageVisible() )
|
||||
emit newPlaylistActivated();
|
||||
else if ( !currentPlaylistInterface() )
|
||||
emit tempPageActivated();
|
||||
|
||||
if ( !AudioEngine::instance()->isPlaying() )
|
||||
@ -597,6 +601,12 @@ PlaylistManager::setPage( ViewPage* page, bool trackHistory )
|
||||
updateView();
|
||||
}
|
||||
|
||||
bool
|
||||
PlaylistManager::isNewPlaylistPageVisible() const
|
||||
{
|
||||
return dynamic_cast< NewPlaylistWidget* >( currentPage() ) != 0;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
PlaylistManager::unlinkPlaylist()
|
||||
|
@ -68,6 +68,7 @@ public:
|
||||
PlaylistView* queue() const;
|
||||
|
||||
bool isSuperCollectionVisible() const;
|
||||
bool isNewPlaylistPageVisible() const;
|
||||
|
||||
PlaylistInterface* currentPlaylistInterface() const;
|
||||
Tomahawk::ViewPage* currentPage() const;
|
||||
@ -108,6 +109,8 @@ signals:
|
||||
void playlistActivated( const Tomahawk::playlist_ptr& playlist );
|
||||
void dynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist );
|
||||
|
||||
void newPlaylistActivated();
|
||||
|
||||
public slots:
|
||||
bool showSuperCollection();
|
||||
void showWelcomePage();
|
||||
|
@ -67,6 +67,8 @@ SourcesModel::data( const QModelIndex& index, int role ) const
|
||||
return itemFromIndex( index )->type();
|
||||
case Qt::DisplayRole:
|
||||
return itemFromIndex( index )->text();
|
||||
case Qt::DecorationRole:
|
||||
return itemFromIndex( index )->icon();
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
@ -162,8 +164,15 @@ SourcesModel::mimeData( const QModelIndexList& indexes ) const
|
||||
bool
|
||||
SourcesModel::dropMimeData( const QMimeData* data, Qt::DropAction action, int row, int column, const QModelIndex& parent )
|
||||
{
|
||||
// TODO
|
||||
return false;
|
||||
SourceTreeItem* item;
|
||||
if( row == -1 && column == -1 )
|
||||
item = itemFromIndex( parent );
|
||||
else
|
||||
item = itemFromIndex( index( row, column, parent ) );
|
||||
|
||||
Q_ASSERT( item );
|
||||
|
||||
return item->dropMimeData( data, action );
|
||||
}
|
||||
|
||||
Qt::DropActions
|
||||
@ -241,6 +250,37 @@ SourcesModel::removeItem( const Tomahawk::source_ptr& source )
|
||||
return false;
|
||||
}
|
||||
|
||||
QModelIndex
|
||||
SourcesModel::indexFromPlaylist( const playlist_ptr& playlist )
|
||||
{
|
||||
QModelIndex idx;
|
||||
// No option but to iterate through everything... lame
|
||||
for( int i = 0; i < rowCount(); i++ ) {
|
||||
QModelIndex source = index( i, 0, QModelIndex() );
|
||||
CollectionItem* col = qobject_cast< CollectionItem* >( m_rootItem->children().at( i ) );
|
||||
if( col->source().isNull() )
|
||||
continue; // skip super collection
|
||||
|
||||
// get the playlist item and look through its children
|
||||
for( int k = 0; k < col->children().count(); k++ ) {
|
||||
CategoryItem* cat = qobject_cast< CategoryItem* >( col->children().at( k ) );
|
||||
if( cat && cat->categoryType() == SourcesModel::PlaylistsCategory ) { // this is it
|
||||
// now find the playlist itself
|
||||
foreach( SourceTreeItem* plItem, cat->children() ) {
|
||||
PlaylistItem* plI = qobject_cast< PlaylistItem* >( plItem );
|
||||
if( plI && plI->playlist() == playlist ) {
|
||||
return indexFromItem( plI );
|
||||
}
|
||||
}
|
||||
break; // only one playlist category per source anyway, stop looking here
|
||||
}
|
||||
}
|
||||
}
|
||||
qDebug() << "FAILED to find playlist in source tree:" << playlist->title();
|
||||
return idx;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourcesModel::onSourceChanged() {
|
||||
|
||||
|
@ -44,14 +44,13 @@ public:
|
||||
|
||||
Category = 1,
|
||||
|
||||
StaticPlaylist = 2,
|
||||
NewStaticPlaylist = 3,
|
||||
CategoryAdd = 2,
|
||||
|
||||
StaticPlaylist = 3,
|
||||
|
||||
AutomaticPlaylist = 4,
|
||||
|
||||
Stations = 5,
|
||||
NewStation = 6
|
||||
|
||||
};
|
||||
|
||||
enum CategoryType {
|
||||
@ -81,9 +80,14 @@ public:
|
||||
virtual Qt::DropActions supportedDropActions() const;
|
||||
virtual Qt::ItemFlags flags(const QModelIndex& index) const;
|
||||
|
||||
void appendItem( const Tomahawk::source_ptr& source );
|
||||
void appendItem( const Tomahawk::source_ptr& source );
|
||||
bool removeItem( const Tomahawk::source_ptr& source );
|
||||
|
||||
// HACK i don't like this
|
||||
// SLOW DON'T USE IF YOU CAN AVOID IT
|
||||
QModelIndex indexFromPlaylist( const Tomahawk::playlist_ptr& playlist );
|
||||
QModelIndex indexFromItem( SourceTreeItem* item ) const;
|
||||
|
||||
signals:
|
||||
void clicked( const QModelIndex& );
|
||||
|
||||
@ -104,8 +108,6 @@ public slots:
|
||||
void onItemRowsRemovedDone();
|
||||
private:
|
||||
SourceTreeItem* itemFromIndex( const QModelIndex& idx ) const;
|
||||
QModelIndex indexFromItem( SourceTreeItem* item ) const;
|
||||
|
||||
Tomahawk::playlist_ptr playlistFromItem( SourceTreeItem* item ) const;
|
||||
int rowForItem( SourceTreeItem* item ) const;
|
||||
// QModelIndex indexForSource( Tomahawk::Source* source ) const;
|
||||
|
@ -19,8 +19,11 @@
|
||||
|
||||
#include "playlist.h"
|
||||
#include "playlist/dynamic/DynamicPlaylist.h"
|
||||
#include <source.h>
|
||||
#include "source.h"
|
||||
#include <playlist/playlistmanager.h>
|
||||
#include "tomahawk/tomahawkapp.h"
|
||||
#include <QMimeData>
|
||||
#include <widgets/newplaylistwidget.h>
|
||||
|
||||
using namespace Tomahawk;
|
||||
|
||||
@ -30,6 +33,8 @@ SourceTreeItem::SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, Sou
|
||||
, m_parent( parent )
|
||||
, m_model( model )
|
||||
{
|
||||
// connect( this, SIGNAL( selectRequest() ), m_model, SLOT( onItemSelectRequest() ) );
|
||||
|
||||
connect( this, SIGNAL( beginChildRowsAdded( int,int ) ), m_model, SLOT( onItemRowsAddedBegin( int,int ) ) );
|
||||
connect( this, SIGNAL( beginChildRowsRemoved( int,int ) ), m_model, SLOT( onItemRowsRemovedBegin( int,int ) ) );
|
||||
connect( this, SIGNAL( childRowsAdded() ), m_model, SLOT( onItemRowsAddedDone() ) );
|
||||
@ -92,9 +97,8 @@ PlaylistItem::onPlaylistChanged()
|
||||
emit updated();
|
||||
}
|
||||
|
||||
|
||||
Qt::ItemFlags
|
||||
PlaylistItem::flags()
|
||||
PlaylistItem::flags() const
|
||||
{
|
||||
Qt::ItemFlags flags = SourceTreeItem::flags();
|
||||
|
||||
@ -120,6 +124,49 @@ PlaylistItem::setLoaded( bool loaded )
|
||||
m_loaded = loaded;
|
||||
}
|
||||
|
||||
bool
|
||||
PlaylistItem::willAcceptDrag( const QMimeData* data ) const
|
||||
{
|
||||
return !m_playlist.isNull() && m_playlist->author()->isLocal();
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
PlaylistItem::dropMimeData( const QMimeData* data, Qt::DropAction action )
|
||||
{
|
||||
if( data->hasFormat( "application/tomahawk.query.list" ) ) {
|
||||
if ( !m_playlist.isNull() && m_playlist->author()->isLocal() ) {
|
||||
|
||||
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;
|
||||
|
||||
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() << "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;
|
||||
}
|
||||
|
||||
|
||||
/// Dynamic Playlist Item
|
||||
/*
|
||||
@ -165,6 +212,98 @@ DynPlaylistItem::onDynamicPlaylistLoaded( Tomahawk::DynamicPlaylistRevision revi
|
||||
setLoaded( true );
|
||||
}*/
|
||||
|
||||
/// CategoryAddItem
|
||||
|
||||
CategoryAddItem::CategoryAddItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::CategoryType type )
|
||||
: SourceTreeItem( model, parent, SourcesModel::CategoryAdd )
|
||||
, m_categoryType( type )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
CategoryAddItem::~CategoryAddItem()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
QString
|
||||
CategoryAddItem::text() const
|
||||
{
|
||||
switch( m_categoryType ) {
|
||||
case SourcesModel::PlaylistsCategory:
|
||||
return tr( "New Playlist" );
|
||||
case SourcesModel::StationsCategory:
|
||||
return tr( "New Station" );
|
||||
}
|
||||
|
||||
return QString();
|
||||
}
|
||||
|
||||
void
|
||||
CategoryAddItem::activate()
|
||||
{
|
||||
switch( m_categoryType ) {
|
||||
case SourcesModel::PlaylistsCategory:
|
||||
// only show if none is shown yet
|
||||
if( !PlaylistManager::instance()->isNewPlaylistPageVisible() )
|
||||
PlaylistManager::instance()->show( new NewPlaylistWidget() );
|
||||
break;
|
||||
case SourcesModel::StationsCategory:
|
||||
// TODO
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Qt::ItemFlags
|
||||
CategoryAddItem::flags() const
|
||||
{
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
}
|
||||
|
||||
QIcon
|
||||
CategoryAddItem::icon() const
|
||||
{
|
||||
return QIcon( RESPATH "images/list-add.png" );
|
||||
}
|
||||
|
||||
// CategoryItem
|
||||
|
||||
CategoryItem::CategoryItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::CategoryType category, bool showAddItem )
|
||||
: SourceTreeItem( model, parent, SourcesModel::Category )
|
||||
, m_category( category )
|
||||
, m_addItem( 0 )
|
||||
, m_showAdd( showAddItem )
|
||||
{
|
||||
// in the constructor we're still being added to the parent, so we don't exist to have rows addded yet. so this is safe.
|
||||
// beginRowsAdded( 0, 0 );
|
||||
if( m_showAdd ) {
|
||||
m_addItem = new CategoryAddItem( model, this, m_category );
|
||||
appendChild( m_addItem );
|
||||
}
|
||||
// endRowsAdded();
|
||||
}
|
||||
|
||||
void
|
||||
CategoryItem::insertItem( SourceTreeItem* item )
|
||||
{
|
||||
insertItems( QList< SourceTreeItem* >() << item );
|
||||
}
|
||||
|
||||
void
|
||||
CategoryItem::insertItems( QList< SourceTreeItem* > items )
|
||||
{
|
||||
// add the items to the category, and connect to the signals
|
||||
int curCount = children().size();
|
||||
if( m_showAdd ) // if there's an add item, add it before that
|
||||
curCount--;
|
||||
beginRowsAdded( curCount, curCount + items.size() - 1 );
|
||||
foreach( SourceTreeItem* item, items ) {
|
||||
int index = m_showAdd ? children().count() - 1 : children().count();
|
||||
insertChild( children().count() - 1, item );
|
||||
}
|
||||
endRowsAdded();
|
||||
}
|
||||
|
||||
|
||||
/// CollectionItem
|
||||
|
||||
@ -176,10 +315,10 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
|
||||
return;
|
||||
}
|
||||
// create category item
|
||||
m_playlists = new CategoryItem( model(), this, SourcesModel::PlaylistsCategory );
|
||||
m_playlists = new CategoryItem( model(), this, SourcesModel::PlaylistsCategory, source->isLocal() );
|
||||
appendChild( m_playlists );
|
||||
|
||||
m_stations = new CategoryItem( model(), this, SourcesModel::StationsCategory );
|
||||
m_stations = new CategoryItem( model(), this, SourcesModel::StationsCategory, source->isLocal() );
|
||||
appendChild( m_stations );
|
||||
|
||||
// ugh :( we're being added by the model, no need to notify for added rows now
|
||||
@ -187,6 +326,9 @@ CollectionItem::CollectionItem( SourcesModel* mdl, SourceTreeItem* parent, cons
|
||||
onPlaylistsAdded( source->collection()->playlists() );
|
||||
m_playlists->blockSignals( false );
|
||||
|
||||
// HACK to load only for now
|
||||
source->collection()->dynamicPlaylists();
|
||||
|
||||
connect( source->collection().data(), SIGNAL( playlistsAdded( QList<Tomahawk::playlist_ptr> ) ),
|
||||
SLOT( onPlaylistsAdded( QList<Tomahawk::playlist_ptr> ) ) );
|
||||
connect( source->collection().data(), SIGNAL( playlistsDeleted( QList<Tomahawk::playlist_ptr> ) ),
|
||||
@ -202,7 +344,7 @@ CollectionItem::source() const
|
||||
QString
|
||||
CollectionItem::text() const
|
||||
{
|
||||
return m_source.isNull() ? "Super Collection" : m_source->friendlyName();
|
||||
return m_source.isNull() ? tr( "Super Collection" ) : m_source->friendlyName();
|
||||
}
|
||||
|
||||
void
|
||||
@ -222,24 +364,21 @@ CollectionItem::onPlaylistsAdded( const QList< playlist_ptr >& playlists )
|
||||
if( playlists.isEmpty() )
|
||||
return;
|
||||
|
||||
// add the items to the category, and connect to the signals
|
||||
int curCount = m_playlists->children().size();
|
||||
// TODO add items to one-minus the end of the category. this leaves room for the [ + New Playlist ] item
|
||||
m_playlists->beginRowsAdded( curCount, curCount + playlists.size() - 1 );
|
||||
|
||||
QList< SourceTreeItem* > items;
|
||||
foreach( const playlist_ptr& p, playlists )
|
||||
{
|
||||
PlaylistItem* plItem = new PlaylistItem( model(), m_playlists, p );
|
||||
m_playlists->appendChild( plItem );
|
||||
qDebug() << "Playlist added:" << p->title() << p->creator() << p->info();
|
||||
p->loadRevision();
|
||||
items << plItem;
|
||||
}
|
||||
m_playlists->endRowsAdded();
|
||||
m_playlists->insertItems( items );
|
||||
}
|
||||
|
||||
void
|
||||
CollectionItem::onPlaylistsDeleted( const QList< playlist_ptr >& playlists )
|
||||
{
|
||||
QList< SourceTreeItem* > items;
|
||||
foreach( const playlist_ptr& playlist, playlists ) {
|
||||
int curCount = m_playlists->children().count();
|
||||
for( int i = 0; i < curCount; i++ ) {
|
||||
@ -253,4 +392,3 @@ CollectionItem::onPlaylistsDeleted( const QList< playlist_ptr >& playlists )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,9 @@
|
||||
#include "playlist.h"
|
||||
#include "playlist/dynamic/DynamicPlaylist.h"
|
||||
#include "source.h"
|
||||
#include <QIcon>
|
||||
|
||||
class QMimeData;
|
||||
class SourceTreeItem : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -39,12 +41,16 @@ public:
|
||||
|
||||
QList< SourceTreeItem* > children() const { return m_children; }
|
||||
void appendChild( SourceTreeItem* item ) { m_children.append( item ); }
|
||||
void insertChild( int index, SourceTreeItem* item ) { m_children.insert( index, item ); }
|
||||
void removeChild( SourceTreeItem* item ) { m_children.removeAll( item ); }
|
||||
|
||||
// varies depending on the type of the item
|
||||
virtual QString text() const { return QString(); }
|
||||
virtual Qt::ItemFlags flags() { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; }
|
||||
virtual Qt::ItemFlags flags() const { return Qt::ItemIsSelectable | Qt::ItemIsEnabled; }
|
||||
virtual void activate() {}
|
||||
virtual QIcon icon() const { return QIcon(); }
|
||||
virtual bool willAcceptDrag( const QMimeData* data ) const { return false; }
|
||||
virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action ) { return false; }
|
||||
|
||||
/// don't call me unless you are a sourcetreeitem. i prefer this to making everyone a friend
|
||||
void beginRowsAdded( int from, int num ) { emit beginChildRowsAdded( from, num ); }
|
||||
@ -53,6 +59,7 @@ public:
|
||||
void endRowsRemoved() { emit childRowsRemoved(); }
|
||||
signals:
|
||||
void updated();
|
||||
void selectRequest();
|
||||
|
||||
void beginChildRowsAdded( int fromRow, int num );
|
||||
void childRowsAdded();
|
||||
@ -67,12 +74,27 @@ private:
|
||||
SourcesModel* m_model;
|
||||
};
|
||||
|
||||
class CategoryAddItem : public SourceTreeItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CategoryAddItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::CategoryType type );
|
||||
~CategoryAddItem();
|
||||
|
||||
virtual Qt::ItemFlags flags() const;
|
||||
virtual QString text() const;
|
||||
virtual void activate();
|
||||
virtual QIcon icon() const;
|
||||
|
||||
private:
|
||||
SourcesModel::CategoryType m_categoryType;
|
||||
};
|
||||
|
||||
class CategoryItem : public SourceTreeItem
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
CategoryItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::CategoryType category ) : SourceTreeItem( model, parent, SourcesModel::Category ), m_category( category ) {}
|
||||
CategoryItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::CategoryType category, bool showAddItem );
|
||||
|
||||
virtual QString text() const {
|
||||
switch( m_category )
|
||||
@ -85,15 +107,20 @@ public:
|
||||
return QString();
|
||||
}
|
||||
virtual void activate();
|
||||
virtual Qt::ItemFlags flags() { return Qt::ItemIsEnabled; }
|
||||
virtual Qt::ItemFlags flags() const { return Qt::ItemIsEnabled; }
|
||||
|
||||
// inserts an item at the end, but before the category add item
|
||||
void insertItem( SourceTreeItem* item );
|
||||
void insertItems( QList< SourceTreeItem* > item );
|
||||
|
||||
SourcesModel::CategoryType categoryType() { return m_category; }
|
||||
|
||||
private:
|
||||
SourcesModel::CategoryType m_category;
|
||||
CategoryAddItem* m_addItem;
|
||||
bool m_showAdd;
|
||||
};
|
||||
|
||||
|
||||
class CollectionItem : public SourceTreeItem
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -101,9 +128,10 @@ public:
|
||||
CollectionItem( SourcesModel* model, SourceTreeItem* parent, const Tomahawk::source_ptr& source );
|
||||
|
||||
virtual QString text() const;
|
||||
Tomahawk::source_ptr source() const;
|
||||
virtual void activate();
|
||||
|
||||
Tomahawk::source_ptr source() const;
|
||||
|
||||
private slots:
|
||||
void onPlaylistsAdded( const QList<Tomahawk::playlist_ptr>& playlists );
|
||||
void onPlaylistsDeleted( const QList<Tomahawk::playlist_ptr>& playlists );
|
||||
@ -114,6 +142,7 @@ private:
|
||||
CategoryItem* m_playlists;
|
||||
CategoryItem* m_stations;
|
||||
};
|
||||
|
||||
class PlaylistItem : public SourceTreeItem
|
||||
{
|
||||
Q_OBJECT
|
||||
@ -122,8 +151,10 @@ public:
|
||||
|
||||
virtual QString text() const;
|
||||
virtual Tomahawk::playlist_ptr playlist() const;
|
||||
virtual Qt::ItemFlags flags();
|
||||
virtual Qt::ItemFlags flags() const;
|
||||
virtual void activate();
|
||||
virtual bool willAcceptDrag( const QMimeData* data ) const;
|
||||
virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action );
|
||||
|
||||
protected:
|
||||
void setLoaded( bool loaded );
|
||||
|
@ -94,23 +94,25 @@ SourceTreeView::SourceTreeView( QWidget* parent )
|
||||
header()->setStretchLastSection( false );
|
||||
header()->setResizeMode( 0, QHeaderView::Stretch );
|
||||
|
||||
connect( m_proxyModel, SIGNAL( clicked( QModelIndex ) ), SIGNAL( clicked( QModelIndex ) ) );
|
||||
connect( m_model, SIGNAL( clicked( QModelIndex ) ), SIGNAL( clicked( QModelIndex ) ) );
|
||||
connect( this, SIGNAL( clicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
|
||||
|
||||
connect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( onSelectionChanged() ) );
|
||||
connect( this, SIGNAL( expanded( QModelIndex ) ), this, SLOT( onItemExpanded( QModelIndex ) ) );
|
||||
// connect( selectionModel(), SIGNAL( selectionChanged( QItemSelection, QItemSelection ) ), SLOT( onSelectionChanged() ) );
|
||||
|
||||
hideOfflineSources();
|
||||
|
||||
// connect( PlaylistManager::instance(), SIGNAL( playlistActivated( Tomahawk::playlist_ptr ) ),
|
||||
// SLOT( onPlaylistActivated( Tomahawk::playlist_ptr ) ) );
|
||||
connect( PlaylistManager::instance(), SIGNAL( playlistActivated( Tomahawk::playlist_ptr ) ),
|
||||
SLOT( onPlaylistActivated( Tomahawk::playlist_ptr ) ) );
|
||||
// connect( PlaylistManager::instance(), SIGNAL( dynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ),
|
||||
// SLOT( onDynamicPlaylistActivated( Tomahawk::dynplaylist_ptr ) ) );
|
||||
// connect( PlaylistManager::instance(), SIGNAL( collectionActivated( Tomahawk::collection_ptr ) ),
|
||||
// SLOT( onCollectionActivated( Tomahawk::collection_ptr ) ) );
|
||||
// connect( PlaylistManager::instance(), SIGNAL( superCollectionActivated() ),
|
||||
// SLOT( onSuperCollectionActivated() ) );
|
||||
// connect( PlaylistManager::instance(), SIGNAL( tempPageActivated() ),
|
||||
// SLOT( onTempPageActivated() ) );
|
||||
connect( PlaylistManager::instance(), SIGNAL( collectionActivated( Tomahawk::collection_ptr ) ),
|
||||
SLOT( onCollectionActivated( Tomahawk::collection_ptr ) ) );
|
||||
connect( PlaylistManager::instance(), SIGNAL( superCollectionActivated() ),
|
||||
SLOT( onSuperCollectionActivated() ) );
|
||||
connect( PlaylistManager::instance(), SIGNAL( tempPageActivated() ),
|
||||
SLOT( onTempPageActivated() ) );
|
||||
connect( PlaylistManager::instance(), SIGNAL( newPlaylistActivated() ),
|
||||
SLOT( onNewPlaylistPageActivated() ) );
|
||||
}
|
||||
|
||||
|
||||
@ -159,18 +161,19 @@ SourceTreeView::hideOfflineSources()
|
||||
m_proxyModel->hideOfflineSources();
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
void
|
||||
SourceTreeView::onPlaylistActivated( const Tomahawk::playlist_ptr& playlist )
|
||||
{
|
||||
QModelIndex idx = m_proxyModel->mapFromSource( m_model->playlistToIndex( playlist ) );
|
||||
QModelIndex idx = m_proxyModel->mapFromSource( m_model->indexFromPlaylist( playlist ) );
|
||||
if ( idx.isValid() )
|
||||
{
|
||||
setCurrentIndex( idx );
|
||||
selectionModel()->select( idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Current );
|
||||
// setCurrentIndex( idx );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
void
|
||||
SourceTreeView::onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist )
|
||||
{
|
||||
@ -179,28 +182,28 @@ SourceTreeView::onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& pla
|
||||
{
|
||||
setCurrentIndex( idx );
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::onCollectionActivated( const Tomahawk::collection_ptr& collection )
|
||||
{
|
||||
QModelIndex idx = m_proxyModel->mapFromSource( m_model->collectionToIndex( collection ) );
|
||||
if ( idx.isValid() )
|
||||
{
|
||||
setCurrentIndex( idx );
|
||||
}
|
||||
// QModelIndex idx = m_proxyModel->mapFromSource( m_model->collectionToIndex( collection ) );
|
||||
// if ( idx.isValid() )
|
||||
// {
|
||||
// setCurrentIndex( idx );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::onSuperCollectionActivated()
|
||||
{
|
||||
QModelIndex idx = m_proxyModel->index( 0, 0 );
|
||||
if ( idx.isValid() )
|
||||
{
|
||||
setCurrentIndex( idx );
|
||||
}
|
||||
// QModelIndex idx = m_proxyModel->index( 0, 0 );
|
||||
// if ( idx.isValid() )
|
||||
// {
|
||||
// setCurrentIndex( idx );
|
||||
// }
|
||||
}
|
||||
|
||||
|
||||
@ -208,7 +211,13 @@ void
|
||||
SourceTreeView::onTempPageActivated()
|
||||
{
|
||||
clearSelection();
|
||||
} */
|
||||
}
|
||||
|
||||
void
|
||||
SourceTreeView::onNewPlaylistPageActivated()
|
||||
{
|
||||
// nothing atm
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
@ -222,6 +231,18 @@ SourceTreeView::onItemActivated( const QModelIndex& index )
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::onItemExpanded( const QModelIndex& idx )
|
||||
{
|
||||
// make sure to expand children nodes for collections
|
||||
if( idx.data( SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::Collection ) {
|
||||
for( int i = 0; i < model()->rowCount( idx ); i++ ) {
|
||||
expand( model()->index( i, 0, idx ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
SourceTreeView::loadPlaylist()
|
||||
{
|
||||
@ -322,14 +343,9 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
|
||||
const QRect rect = visualRect( index );
|
||||
m_dropRect = rect;
|
||||
|
||||
|
||||
if ( model()->data( index, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist )
|
||||
{
|
||||
PlaylistItem* item = itemFromIndex< PlaylistItem >( index );
|
||||
playlist_ptr playlist = item->playlist();
|
||||
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
||||
accept = true;
|
||||
}
|
||||
const SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index );
|
||||
if( item->willAcceptDrag( event->mimeData() ) )
|
||||
accept = true;
|
||||
} else {
|
||||
m_dropRect = QRect();
|
||||
}
|
||||
@ -350,59 +366,6 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
|
||||
void
|
||||
SourceTreeView::dropEvent( QDropEvent* event )
|
||||
{
|
||||
bool accept = false;
|
||||
const QPoint pos = event->pos();
|
||||
const QModelIndex index = indexAt( pos );
|
||||
|
||||
if ( event->mimeData()->hasFormat( "application/tomahawk.query.list" ) )
|
||||
{
|
||||
const QPoint pos = event->pos();
|
||||
const QModelIndex index = indexAt( pos );
|
||||
|
||||
if ( index.isValid() )
|
||||
{
|
||||
if ( model()->data( index, SourcesModel::SourceTreeItemTypeRole ) == SourcesModel::StaticPlaylist )
|
||||
{
|
||||
PlaylistItem* item = itemFromIndex< PlaylistItem >( index );
|
||||
playlist_ptr playlist = item->playlist();
|
||||
if ( !playlist.isNull() && playlist->author()->isLocal() )
|
||||
{
|
||||
accept = true;
|
||||
QByteArray itemData = event->mimeData()->data( "application/tomahawk.query.list" );
|
||||
QDataStream stream( &itemData, QIODevice::ReadOnly );
|
||||
QList<Tomahawk::query_ptr> queries;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
qDebug() << "on playlist:" << playlist->title() << playlist->guid();
|
||||
|
||||
// TODO do we need to use this in the refactor?
|
||||
// QString rev = item->currentlyLoadedPlaylistRevision( playlist->guid() );
|
||||
playlist->addEntries( queries, playlist->currentrevision() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( accept )
|
||||
{
|
||||
event->setDropAction( Qt::CopyAction );
|
||||
event->accept();
|
||||
}
|
||||
else
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
QTreeView::dropEvent( event );
|
||||
m_dragging = false;
|
||||
}
|
||||
|
@ -37,7 +37,6 @@ Q_OBJECT
|
||||
public:
|
||||
explicit SourceTreeView( QWidget* parent = 0 );
|
||||
|
||||
public slots:
|
||||
void showOfflineSources();
|
||||
void hideOfflineSources();
|
||||
|
||||
@ -46,11 +45,15 @@ signals:
|
||||
void onOffline( const QModelIndex& index );
|
||||
|
||||
private slots:
|
||||
// void onPlaylistActivated( const Tomahawk::playlist_ptr& playlist );
|
||||
void onPlaylistActivated( const Tomahawk::playlist_ptr& playlist );
|
||||
// void onDynamicPlaylistActivated( const Tomahawk::dynplaylist_ptr& playlist );
|
||||
// void onCollectionActivated( const Tomahawk::collection_ptr& collection );
|
||||
// void onSuperCollectionActivated();
|
||||
// void onTempPageActivated();
|
||||
|
||||
void onCollectionActivated( const Tomahawk::collection_ptr& collection );
|
||||
void onSuperCollectionActivated();
|
||||
void onTempPageActivated();
|
||||
void onNewPlaylistPageActivated();
|
||||
|
||||
void onItemExpanded( const QModelIndex& idx );
|
||||
|
||||
void onItemActivated( const QModelIndex& index );
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user