1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-03-20 07:49:42 +01:00

more work on the drag and drop menu

This commit is contained in:
Michael Zanetti 2011-08-21 04:09:19 +02:00
parent 13db62b71c
commit a227ae4bcb
11 changed files with 279 additions and 55 deletions

View File

@ -95,6 +95,18 @@ DropJob::acceptsMimeData( const QMimeData* data, bool tracksOnly )
return false;
}
void
DropJob::setGetWholeArtists( bool getWholeArtists )
{
m_getWholeArtists = getWholeArtists;
}
void
DropJob::setGetWholeAlbums( bool getWholeAlbums )
{
m_getWholeAlbums = getWholeAlbums;
}
void
DropJob::tracksFromMimeData( const QMimeData* data, bool allowDuplicates, bool onlyLocal, bool top10 )
@ -158,7 +170,19 @@ DropJob::tracksFromQueryList( const QMimeData* data )
if ( query && !query->isNull() )
{
tDebug() << "Dropped query item:" << query->data()->artist() << "-" << query->data()->track();
queries << *query;
if ( m_getWholeArtists )
{
queries << getArtist( query->data()->artist() );
}
else if ( m_getWholeAlbums )
{
queries << getAlbum( query->data()->artist(), query->data()->album() );
}
else
{
queries << *query;
}
}
}
@ -182,8 +206,20 @@ DropJob::tracksFromResultList( const QMimeData* data )
{
tDebug() << "Dropped result item:" << result->data()->artist()->name() << "-" << result->data()->track();
query_ptr q = result->data()->toQuery();
q->addResults( QList< result_ptr >() << *result );
queries << q;
if ( m_getWholeArtists )
{
queries << getArtist( q->artist() );
}
else if ( m_getWholeAlbums )
{
queries << getAlbum( q->artist(), q->album() );
}
else
{
q->addResults( QList< result_ptr >() << *result );
queries << q;
}
}
}
@ -204,16 +240,10 @@ DropJob::tracksFromAlbumMetaData( const QMimeData *data )
QString album;
stream >> album;
artist_ptr artistPtr = Artist::get( artist );
album_ptr albumPtr = Album::get( artistPtr, album );
if ( albumPtr->tracks().isEmpty() )
{
connect( albumPtr.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
m_queryCount++;
}
if ( m_getWholeArtists )
queries << getArtist( artist );
else
queries << albumPtr->tracks();
queries << getAlbum( artist, album );
}
return queries;
}
@ -232,15 +262,7 @@ DropJob::tracksFromArtistMetaData( const QMimeData *data )
if ( !m_top10 )
{
artist_ptr artistPtr = Artist::get( artist );
if ( artistPtr->tracks().isEmpty() )
{
connect( artistPtr.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
m_queryCount++;
}
else
queries << artistPtr->tracks();
queries << getArtist( artist );
}
else
{
@ -435,3 +457,34 @@ DropJob::infoSystemInfo( Tomahawk::InfoSystem::InfoRequestData requestData, QVar
onTracksAdded( results );
}
}
QList< query_ptr >
DropJob::getArtist( const QString &artist )
{
artist_ptr artistPtr = Artist::get( artist );
if ( artistPtr->tracks().isEmpty() )
{
connect( artistPtr.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
m_queryCount++;
return QList< query_ptr >();
}
else
return artistPtr->tracks();
}
QList< query_ptr >
DropJob::getAlbum(const QString &artist, const QString &album)
{
artist_ptr artistPtr = Artist::get( artist );
album_ptr albumPtr = Album::get( artistPtr, album );
if ( albumPtr->tracks().isEmpty() )
{
connect( albumPtr.data(), SIGNAL( tracksAdded( QList<Tomahawk::query_ptr> ) ),
SLOT( onTracksAdded( QList<Tomahawk::query_ptr> ) ) );
m_queryCount++;
return QList< query_ptr >();
}
else
return albumPtr->tracks();
}

View File

@ -45,6 +45,9 @@ public:
*/
static bool acceptsMimeData( const QMimeData* data, bool tracksOnly = true );
static QStringList mimeTypes();
void setGetWholeArtists( bool getWholeArtists );
void setGetWholeAlbums( bool getWholeAlbums );
void tracksFromMimeData( const QMimeData* data, bool allowDuplicates = false, bool onlyLocal = false, bool top10 = false );
signals:
@ -69,12 +72,17 @@ private:
QList< Tomahawk::query_ptr > tracksFromAlbumMetaData( const QMimeData* d );
QList< Tomahawk::query_ptr > tracksFromMixedData( const QMimeData* d );
QList< Tomahawk::query_ptr > getArtist( const QString& artist );
QList< Tomahawk::query_ptr > getAlbum( const QString& artist, const QString& album );
void removeDuplicates();
void removeRemoteSources();
int m_queryCount;
bool m_allowDuplicates;
bool m_onlyLocal;
bool m_getWholeArtists;
bool m_getWholeAlbums;
bool m_top10;
QList< Tomahawk::query_ptr > m_resultList;

View File

@ -318,6 +318,96 @@ TreeModel::mimeData( const QModelIndexList &indexes ) const
QByteArray resultData;
QDataStream resultStream( &resultData, QIODevice::WriteOnly );
// lets try with artist only
bool fail = false;
foreach ( const QModelIndex& i, indexes)
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
TreeModelItem* item = itemFromIndex( i );
if ( !item )
continue;
if ( !item->artist().isNull() )
{
const artist_ptr& artist = item->artist();
resultStream << artist->name();
}
else
{
fail = true;
break;
}
}
if ( !fail )
{
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.metadata.artist", resultData );
return mimeData;
}
// lets try with album only
fail = false;
foreach ( const QModelIndex& i, indexes)
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
TreeModelItem* item = itemFromIndex( i );
if ( !item )
continue;
if ( !item->album().isNull() )
{
const album_ptr& album = item->album();
resultStream << album->artist()->name();
resultStream << album->name();
}
else
{
fail = true;
break;
}
}
if ( !fail )
{
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.metadata.album", resultData );
return mimeData;
}
// lets try with tracks only
fail = false;
foreach ( const QModelIndex& i, indexes)
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )
continue;
TreeModelItem* item = itemFromIndex( i );
if ( !item )
continue;
if ( !item->result().isNull() )
{
const result_ptr& result = item->result();
resultStream << qlonglong( &result );
}
else
{
fail = true;
break;
}
}
if ( !fail )
{
QMimeData* mimeData = new QMimeData();
mimeData->setData( "application/tomahawk.result.list", resultData );
return mimeData;
}
// Ok... we have to use mixed
foreach ( const QModelIndex& i, indexes )
{
if ( i.column() > 0 || indexes.contains( i.parent() ) )

View File

@ -139,6 +139,12 @@ CategoryAddItem::willAcceptDrag( const QMimeData* data ) const
return false;
}
SourceTreeItem::DropTypes
CategoryAddItem::supportedDropTypes( const QMimeData* data ) const
{
return DropTypesNone;
}
bool
CategoryAddItem::dropMimeData( const QMimeData* data, Qt::DropAction )

View File

@ -33,6 +33,7 @@ public:
virtual int peerSortValue() const;
virtual bool willAcceptDrag(const QMimeData* data) const;
virtual DropTypes supportedDropTypes(const QMimeData* data) const;
virtual bool dropMimeData(const QMimeData* data, Qt::DropAction action);
private slots:

View File

@ -139,9 +139,25 @@ PlaylistItem::willAcceptDrag( const QMimeData* data ) const
}
PlaylistItem::DropTypes
PlaylistItem::supportedDropTypes() const
PlaylistItem::supportedDropTypes( const QMimeData* data ) const
{
return DropTypeAllItems | DropTypeLocalItems | DropTypeTop10;
if ( data->hasFormat( "application/tomahawk.query.list" ) )
return DropTypeThisTrack | DropTypeThisAlbum | DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
else if ( data->hasFormat( "application/tomahawk.result.list" ) )
return DropTypeThisTrack | DropTypeThisAlbum | DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
else if ( data->hasFormat( "application/tomahawk.metadata.album" ) )
return DropTypeThisAlbum | DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
else if ( data->hasFormat( "application/tomahawk.metadata.artist" ) )
return DropTypeAllFromArtist | DropTypeLocalItems | DropTypeTop50;
else if ( data->hasFormat( "application/tomahawk.mixed" ) )
{
return DropTypesNone;
}
else if ( data->hasFormat( "text/plain" ) )
{
return DropTypesNone;
}
return DropTypesNone;
}
@ -159,10 +175,21 @@ PlaylistItem::dropMimeData( const QMimeData* data, Qt::DropAction action )
DropJob *dj = new DropJob();
connect( dj, SIGNAL( tracks( QList< Tomahawk::query_ptr > ) ), this, SLOT( parsedDroppedTracks( QList< Tomahawk::query_ptr > ) ) );
if ( dropType() == DropTypeAllFromArtist )
dj->setGetWholeArtists( true );
if ( dropType() == DropTypeThisAlbum )
dj->setGetWholeAlbums( true );
if ( dropType() == DropTypeLocalItems )
{
dj->setGetWholeArtists( true );
dj->tracksFromMimeData( data, false, true );
else if ( dropType() == DropTypeTop10 )
}
else if ( dropType() == DropTypeTop50 )
{
dj->setGetWholeArtists( true );
dj->tracksFromMimeData( data, false, false, true );
}
else
dj->tracksFromMimeData( data, false, false );

View File

@ -34,7 +34,7 @@ public:
virtual Qt::ItemFlags flags() const;
virtual void activate();
virtual bool willAcceptDrag( const QMimeData* data ) const;
virtual DropTypes supportedDropTypes() const;
virtual DropTypes supportedDropTypes( const QMimeData* data ) const;
virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action );
virtual QIcon icon() const;
virtual bool setData(const QVariant& v, bool role);

View File

@ -34,11 +34,13 @@ class SourceTreeItem : public QObject
public:
enum DropType
{
DropTypesNone = 0x00,
DropTypeAllItems = 0x01,
DropTypeLocalItems = 0x02,
DropTypeTop10 = 0x04,
DropTypesAllTypes = 0xff
DropTypesNone = 0x00,
DropTypeThisTrack = 0x01,
DropTypeThisAlbum = 0x02,
DropTypeAllFromArtist = 0x04,
DropTypeLocalItems = 0x08,
DropTypeTop50 = 0x10,
DropTypesAllTypes = 0xff
};
Q_DECLARE_FLAGS( DropTypes, DropType )
@ -66,7 +68,7 @@ public:
virtual bool setData( const QVariant&, bool ) { return false; }
virtual int peerSortValue() const { return 0; } // How to sort relative to peers in the tree.
virtual int IDValue() const { return 0; }
virtual DropTypes supportedDropTypes() const { return DropTypesNone; }
virtual DropTypes supportedDropTypes( const QMimeData* mimeData ) const { Q_UNUSED( mimeData ); return DropTypesNone; }
virtual void setDropType( DropType type ) { m_dropType = type; }
virtual DropType dropType() const { return m_dropType; }

View File

@ -3,6 +3,7 @@
#include "items/sourcetreeitem.h"
#include "items/collectionitem.h"
#include "items/playlistitems.h"
#include "items/categoryitems.h"
#include "utils/tomahawkutils.h"
#include "items/temporarypageitem.h"
@ -23,6 +24,7 @@ SourceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex&
else if ( index == m_dropHoverIndex )
{
QSize originalSize = QStyledItemDelegate::sizeHint( option, index );
qDebug() << "droptypecount is" << dropTypeCount( item );
return originalSize + QSize( 0, originalSize.height() * dropTypeCount( item ) );
}
else
@ -137,22 +139,31 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
painter->restore();
}
else if ( type == SourcesModel::StaticPlaylist )
else if ( type == SourcesModel::StaticPlaylist || type == SourcesModel::CategoryAdd )
{
painter->save();
QFont normal = painter->font();
QFont bold = painter->font();
bold.setBold( true );
PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item );
Q_ASSERT( plItem );
QString name = index.data().toString();
if ( plItem && !plItem->playlist().isNull() )
if ( type == SourcesModel::StaticPlaylist )
{
name = plItem->playlist()->title();
PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item );
Q_ASSERT( plItem );
if ( plItem && !plItem->playlist().isNull() )
{
name = plItem->playlist()->title();
}
}
else if ( type == SourcesModel::CategoryAdd )
{
CategoryAddItem* cItem = qobject_cast< CategoryAddItem* >( item );
Q_ASSERT( cItem );
name = cItem->text();
}
int height = option.rect.height();
@ -182,31 +193,50 @@ SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, co
painter->drawRoundedRect( selectionRect, 5, 5 );
int count = 1;
if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeAllItems ) )
SourceTreeItem::DropTypes dropTypes = item->supportedDropTypes( m_dropMimeData );
if ( dropTypes.testFlag( SourceTreeItem::DropTypeThisTrack ) )
{
text = tr( "All items" );
text = tr( "This track" );
textRect = option.rect.adjusted( iconRect.width() + 8, 2 + ( count * height ), 0, 0 );
painter->drawText( textRect, text );
if ( count == hoveredDropTypeIndex )
m_hoveredDropType = SourceTreeItem::DropTypeAllItems;
m_hoveredDropType = SourceTreeItem::DropTypeThisTrack;
count++;
}
if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeLocalItems ) )
if ( dropTypes.testFlag( SourceTreeItem::DropTypeThisAlbum ) )
{
text = tr( "Local items" );
text = tr( "This album" );
textRect = option.rect.adjusted( iconRect.width() + 8, 2 + ( count * height ), 0, 0 );
painter->drawText( textRect, text );
if ( count == hoveredDropTypeIndex )
m_hoveredDropType = SourceTreeItem::DropTypeThisAlbum;
count++;
}
if ( dropTypes.testFlag( SourceTreeItem::DropTypeAllFromArtist ) )
{
text = tr( "All from artist" );
textRect = option.rect.adjusted( iconRect.width() + 8, 2 + ( count * height ), 0, 0 );
painter->drawText( textRect, text );
if ( count == hoveredDropTypeIndex )
m_hoveredDropType = SourceTreeItem::DropTypeAllFromArtist;
count++;
}
if ( dropTypes.testFlag( SourceTreeItem::DropTypeLocalItems ) )
{
text = tr( "All local from Artist" );
textRect = option.rect.adjusted( iconRect.width() + 8, 2 + ( count * height ), 0, 0 );
painter->drawText( textRect, text );
if ( count == hoveredDropTypeIndex )
m_hoveredDropType = SourceTreeItem::DropTypeLocalItems;
count++;
}
if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeTop10 ) )
if ( dropTypes.testFlag( SourceTreeItem::DropTypeTop50 ) )
{
text = tr( "Top 10" );
text = tr( "Top 50" );
textRect = option.rect.adjusted( iconRect.width() + 8, 2 + ( count * height ), 0, 0 );
painter->drawText( textRect, text );
if ( count == hoveredDropTypeIndex )
m_hoveredDropType = SourceTreeItem::DropTypeTop10;
m_hoveredDropType = SourceTreeItem::DropTypeTop50;
count++;
}
}
@ -282,13 +312,19 @@ int
SourceDelegate::dropTypeCount( SourceTreeItem* item ) const
{
int menuCount = 0;
if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeAllItems ) )
if ( item->supportedDropTypes( m_dropMimeData ).testFlag( SourceTreeItem::DropTypeThisTrack ) )
menuCount++;
if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeLocalItems ) )
if ( item->supportedDropTypes( m_dropMimeData ).testFlag( SourceTreeItem::DropTypeThisAlbum ) )
menuCount++;
if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeTop10 ) )
if ( item->supportedDropTypes( m_dropMimeData ).testFlag( SourceTreeItem::DropTypeAllFromArtist ) )
menuCount++;
if ( item->supportedDropTypes( m_dropMimeData ).testFlag( SourceTreeItem::DropTypeLocalItems ) )
menuCount++;
if ( item->supportedDropTypes( m_dropMimeData ).testFlag( SourceTreeItem::DropTypeTop50 ) )
menuCount++;
return menuCount;

View File

@ -11,7 +11,7 @@ class SourceDelegate : public QStyledItemDelegate
public:
SourceDelegate( QAbstractItemView* parent = 0 ) : QStyledItemDelegate( parent ), m_parent( parent ) {}
void setDropHoverIndex( const QModelIndex &index ) { m_dropHoverIndex = index; }
void setDropHoverIndex( const QModelIndex &index, const QMimeData *mimeData ) { m_dropHoverIndex = index; m_dropMimeData = const_cast< QMimeData* >( mimeData ); }
SourceTreeItem::DropType hoveredDropType() const;
@ -26,6 +26,7 @@ private:
QAbstractItemView* m_parent;
mutable int m_iconHeight;
QModelIndex m_dropHoverIndex;
QMimeData *m_dropMimeData;
mutable SourceTreeItem::DropType m_hoveredDropType; // Hack to keep easily track of the current highlighted DropType in paint()
};

View File

@ -439,7 +439,7 @@ SourceTreeView::dragLeaveEvent( QDragLeaveEvent* event )
m_dragging = false;
setDirtyRegion( m_dropRect );
m_delegate->setDropHoverIndex( QModelIndex() );
m_delegate->setDropHoverIndex( QModelIndex(), 0 );
dataChanged(m_dropIndex, m_dropIndex);
m_dropIndex = QPersistentModelIndex();
}
@ -456,7 +456,7 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
setDirtyRegion( m_dropRect );
const QPoint pos = event->pos();
const QModelIndex index = indexAt( pos );
m_delegate->setDropHoverIndex( QModelIndex() );
m_delegate->setDropHoverIndex( QModelIndex(), event->mimeData() );
dataChanged(m_dropIndex, m_dropIndex);
m_dropIndex = QPersistentModelIndex( index );
@ -469,7 +469,7 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event )
if( item->willAcceptDrag( event->mimeData() ) )
{
accept = true;
m_delegate->setDropHoverIndex( index );
m_delegate->setDropHoverIndex( index, event->mimeData() );
dataChanged(index, index);
}
}
@ -504,7 +504,7 @@ SourceTreeView::dropEvent( QDropEvent* event )
QTreeView::dropEvent( event );
m_dragging = false;
m_dropIndex = QPersistentModelIndex();
m_delegate->setDropHoverIndex( QModelIndex() );
m_delegate->setDropHoverIndex( QModelIndex(), 0 );
dataChanged( index, index );
}