diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index e4553c2b4..f6a413d21 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -57,6 +57,7 @@ SET( tomahawkSourcesGui ${tomahawkSourcesGui} sourcetree/sourcesmodel.cpp sourcetree/sourcesproxymodel.cpp sourcetree/sourcetreeview.cpp + sourcetree/sourcedelegate.cpp sourcetree/items/sourcetreeitem.cpp sourcetree/items/collectionitem.cpp sourcetree/items/playlistitems.cpp diff --git a/src/sourcetree/items/playlistitems.cpp b/src/sourcetree/items/playlistitems.cpp index 02cc4e453..1e60efa9b 100644 --- a/src/sourcetree/items/playlistitems.cpp +++ b/src/sourcetree/items/playlistitems.cpp @@ -138,6 +138,12 @@ PlaylistItem::willAcceptDrag( const QMimeData* data ) const return !m_playlist.isNull() && m_playlist->author()->isLocal(); } +PlaylistItem::DropTypes +PlaylistItem::supportedDropTypes() const +{ + return DropTypeAllItems | DropTypeLocalItems | DropTypeTop10; +} + bool PlaylistItem::dropMimeData( const QMimeData* data, Qt::DropAction action ) diff --git a/src/sourcetree/items/playlistitems.h b/src/sourcetree/items/playlistitems.h index 8febb2d78..62ddefc2d 100644 --- a/src/sourcetree/items/playlistitems.h +++ b/src/sourcetree/items/playlistitems.h @@ -34,6 +34,7 @@ public: virtual Qt::ItemFlags flags() const; virtual void activate(); virtual bool willAcceptDrag( const QMimeData* data ) const; + virtual DropTypes supportedDropTypes() const; virtual bool dropMimeData( const QMimeData* data, Qt::DropAction action ); virtual QIcon icon() const; virtual bool setData(const QVariant& v, bool role); @@ -54,6 +55,7 @@ private: bool m_loaded; Tomahawk::playlist_ptr m_playlist; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(PlaylistItem::DropTypes) // can be a station or an auto playlist class DynamicPlaylistItem : public PlaylistItem diff --git a/src/sourcetree/items/sourcetreeitem.cpp b/src/sourcetree/items/sourcetreeitem.cpp index 5f82833c3..51e5ed14b 100644 --- a/src/sourcetree/items/sourcetreeitem.cpp +++ b/src/sourcetree/items/sourcetreeitem.cpp @@ -28,6 +28,7 @@ SourceTreeItem::SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, Sou , m_type( thisType ) , m_parent( parent ) , m_model( model ) + //, m_dropHovering( false ) { connect( this, SIGNAL( beginChildRowsAdded( int,int ) ), m_model, SLOT( onItemRowsAddedBegin( int,int ) ) ); connect( this, SIGNAL( beginChildRowsRemoved( int,int ) ), m_model, SLOT( onItemRowsRemovedBegin( int,int ) ) ); diff --git a/src/sourcetree/items/sourcetreeitem.h b/src/sourcetree/items/sourcetreeitem.h index f8f57dc3f..4234c3e10 100644 --- a/src/sourcetree/items/sourcetreeitem.h +++ b/src/sourcetree/items/sourcetreeitem.h @@ -32,6 +32,16 @@ class SourceTreeItem : public QObject { Q_OBJECT public: + enum DropType + { + DropTypesNone = 0x00, + DropTypeAllItems = 0x01, + DropTypeLocalItems = 0x02, + DropTypeTop10 = 0x04, + DropTypesAllTypes = 0xff + }; + Q_DECLARE_FLAGS( DropTypes, DropType ) + SourceTreeItem() : m_type( SourcesModel::Invalid ), m_parent( 0 ), m_model( 0 ) {} SourceTreeItem( SourcesModel* model, SourceTreeItem* parent, SourcesModel::RowType thisType, int index = -1 ); // if index is -1, append at end of parent's child list virtual ~SourceTreeItem(); @@ -56,6 +66,10 @@ 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 bool dropHovering() const { return m_dropHovering; } +// virtual void setDropHovering( bool dropHovering ) { m_dropHovering = dropHovering; emit updated(); } + virtual DropTypes supportedDropTypes() const { return DropTypesNone; } + virtual void setDropType( DropType type ) { m_dropType = type; } /// don't call me unless you are a sourcetreeitem. i prefer this to making everyone a friend void beginRowsAdded( int from, int to ) { emit beginChildRowsAdded( from, to ); } @@ -83,6 +97,8 @@ private: SourceTreeItem* m_parent; QList< SourceTreeItem* > m_children; SourcesModel* m_model; + + DropType m_dropType; }; Q_DECLARE_METATYPE( SourceTreeItem* ); diff --git a/src/sourcetree/sourcedelegate.cpp b/src/sourcetree/sourcedelegate.cpp new file mode 100644 index 000000000..5b8bb25d2 --- /dev/null +++ b/src/sourcetree/sourcedelegate.cpp @@ -0,0 +1,314 @@ +#include "sourcedelegate.h" + +#include "items/sourcetreeitem.h" +#include "items/collectionitem.h" +#include "items/playlistitems.h" + +#include "utils/tomahawkutils.h" + +#include +#include + +#define TREEVIEW_INDENT_ADD -7 + +QSize +SourceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + SourceTreeItem *item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >(); + + if ( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() == SourcesModel::Collection ) + return QSize( option.rect.width(), 44 ); + else if ( index == m_dropHoverIndex ) + { + QSize originalSize = QStyledItemDelegate::sizeHint( option, index ); + return originalSize + QSize( 0, originalSize.height() * dropTypeCount( item ) ); + } + else + return QStyledItemDelegate::sizeHint( option, index ); +} + + +void +SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + QStyleOptionViewItem o = option; + +#ifdef Q_WS_MAC + QFont savedFont = painter->font(); + QFont smaller = savedFont; + smaller.setPointSize( smaller.pointSize() - 2 ); + painter->setFont( smaller ); + o.font = smaller; +#endif + + if ( ( option.state & QStyle::State_Enabled ) == QStyle::State_Enabled ) + { + o.state = QStyle::State_Enabled; + + if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) + { + o.palette.setColor( QPalette::Text, o.palette.color( QPalette::HighlightedText ) ); + } + } + + SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() ); + SourceTreeItem* item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >(); + Q_ASSERT( item ); + + QStyleOptionViewItemV4 o3 = option; + if ( type != SourcesModel::Collection && type != SourcesModel::Category ) + o3.rect.setX( 0 ); + + QApplication::style()->drawControl( QStyle::CE_ItemViewItem, &o3, painter ); + + if ( type == SourcesModel::Collection ) + { + painter->save(); + + QFont normal = painter->font(); + QFont bold = painter->font(); + bold.setBold( true ); + + CollectionItem* colItem = qobject_cast< CollectionItem* >( item ); + Q_ASSERT( colItem ); + bool status = !( !colItem || colItem->source().isNull() || !colItem->source()->isOnline() ); + + QString tracks; + QString name = index.data().toString(); + int figWidth = 0; + + if ( status && colItem && !colItem->source().isNull() ) + { + tracks = QString::number( colItem->source()->trackCount() ); + figWidth = painter->fontMetrics().width( tracks ); + name = colItem->source()->friendlyName(); + } + + QRect iconRect = option.rect.adjusted( 4, 6, -option.rect.width() + option.rect.height() - 12 + 4, -6 ); + + QPixmap avatar = colItem->icon().pixmap( iconRect.size() ); + painter->drawPixmap( iconRect, avatar.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) ); + + if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) + { + painter->setPen( o.palette.color( QPalette::HighlightedText ) ); + } + + QRect textRect = option.rect.adjusted( iconRect.width() + 8, 6, -figWidth - 24, 0 ); + if ( status || colItem->source().isNull() ) + painter->setFont( bold ); + QString text = painter->fontMetrics().elidedText( name, Qt::ElideRight, textRect.width() ); + painter->drawText( textRect, text ); + + QString desc = status ? colItem->source()->textStatus() : tr( "Offline" ); + if ( colItem->source().isNull() ) + desc = tr( "All available tracks" ); + if ( status && desc.isEmpty() && !colItem->source()->currentTrack().isNull() ) + desc = colItem->source()->currentTrack()->artist() + " - " + colItem->source()->currentTrack()->track(); + if ( desc.isEmpty() ) + desc = tr( "Online" ); + + textRect = option.rect.adjusted( iconRect.width() + 8, painter->fontMetrics().height() + 6, -figWidth - 24, -4 ); + painter->setFont( normal ); + text = painter->fontMetrics().elidedText( desc, Qt::ElideRight, textRect.width() ); + QTextOption to( Qt::AlignBottom ); + painter->drawText( textRect, text, to ); + + if ( status ) + { + painter->setRenderHint( QPainter::Antialiasing ); + + QRect figRect = o.rect.adjusted( o.rect.width() - figWidth - 8, 0, -13, -o.rect.height() + 16 ); + int hd = ( option.rect.height() - figRect.height() ) / 2; + figRect.adjust( 0, hd, 0, hd ); +#ifdef Q_OS_WIN + figRect.adjust( -3, 0, 3, 0 ); +#endif + painter->setFont( bold ); + + QColor figColor( 167, 183, 211 ); + painter->setPen( figColor ); + painter->setBrush( figColor ); + + TomahawkUtils::drawBackgroundAndNumbers( painter, tracks, figRect ); + } + + painter->restore(); + } + else if ( type == SourcesModel::StaticPlaylist ) + { + painter->save(); + + QFont normal = painter->font(); + QFont bold = painter->font(); + bold.setBold( true ); + + PlaylistItem* plItem = qobject_cast< PlaylistItem* >( item ); + Q_ASSERT( plItem ); + +// QString tracks; + QString name = index.data().toString(); +// int figWidth = 0; + + if ( plItem && !plItem->playlist().isNull() ) + { +// tracks = QString::number( plItem->source()->trackCount() ); +// figWidth = painter->fontMetrics().width( tracks ); + name = plItem->playlist()->title(); + } + + int height = option.rect.height(); + if ( index == m_dropHoverIndex ) + height /= ( dropTypeCount( item ) + 1 ); + + QRect iconRect = option.rect.adjusted( 4, 1, -option.rect.width() + height - 2 + 4, -option.rect.height() + height -1 ); + + QPixmap avatar = index.data( Qt::DecorationRole ).value< QIcon >().pixmap( iconRect.width(), iconRect.height() ); + painter->drawPixmap( iconRect, avatar.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) ); + + if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) + { + painter->setPen( o.palette.color( QPalette::HighlightedText ) ); + } + + QRect textRect = option.rect.adjusted( iconRect.width() + 8, 2, /*-figWidth - 24*/ 0, 0 ); + QString text = painter->fontMetrics().elidedText( name, Qt::ElideRight, textRect.width() ); + painter->drawText( textRect, text ); + + if ( index == m_dropHoverIndex ) + { + QPoint cursorPos = m_parent->mapFromGlobal( QCursor::pos() ); + qDebug() << "cursorpos is" << cursorPos; + + int hoveredDropTypeIndex = ( cursorPos.y() - o.rect.y() ) / height; + int verticalOffset = height * hoveredDropTypeIndex; + QRect selectionRect = o.rect.adjusted( 0, verticalOffset, 0, -o.rect.height() + height + verticalOffset ); + painter->drawRoundedRect( selectionRect, 5, 5 ); + + int count = 1; + if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeAllItems ) ) + { + text = "All items"; + textRect = option.rect.adjusted( iconRect.width() + 8, 2 + ( count * height ), 0, 0 ); + painter->drawText( textRect, text ); + if ( count == hoveredDropTypeIndex ) + m_hoveredDropType = SourceTreeItem::DropTypeAllItems; + count++; + } + if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeLocalItems ) ) + { + text = "Local items"; + 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 ) ) + { + text = "Top 10"; + textRect = option.rect.adjusted( iconRect.width() + 8, 2 + ( count * height ), 0, 0 ); + painter->drawText( textRect, text ); + if ( count == hoveredDropTypeIndex ) + m_hoveredDropType = SourceTreeItem::DropTypeTop10; + count++; + } + + qDebug() << "***************+ verticaloffset:" << hoveredDropTypeIndex << count; + } + +// QString desc = status ? colItem->source()->textStatus() : tr( "Offline" ); +// if ( colItem->source().isNull() ) +// desc = tr( "All available tracks" ); +// if ( status && desc.isEmpty() && !colItem->source()->currentTrack().isNull() ) +// desc = colItem->source()->currentTrack()->artist() + " - " + colItem->source()->currentTrack()->track(); +// if ( desc.isEmpty() ) +// desc = tr( "Online" ); + +// textRect = option.rect.adjusted( iconRect.width() + 8, painter->fontMetrics().height() + 6, -figWidth - 24, -4 ); +// painter->setFont( normal ); +// text = painter->fontMetrics().elidedText( desc, Qt::ElideRight, textRect.width() ); +// QTextOption to( Qt::AlignBottom ); +// painter->drawText( textRect, text, to ); + +// if ( status ) +// { +// painter->setRenderHint( QPainter::Antialiasing ); + +// QRect figRect = o.rect.adjusted( o.rect.width() - figWidth - 8, 0, -13, -o.rect.height() + 16 ); +// int hd = ( option.rect.height() - figRect.height() ) / 2; +// figRect.adjust( 0, hd, 0, hd ); +//#ifdef Q_OS_WIN +// figRect.adjust( -3, 0, 3, 0 ); +//#endif +// painter->setFont( bold ); + +// QColor figColor( 167, 183, 211 ); +// painter->setPen( figColor ); +// painter->setBrush( figColor ); + +// TomahawkUtils::drawBackgroundAndNumbers( painter, tracks, figRect ); +// } + + painter->restore(); + + } + else + { + QStyledItemDelegate::paint( painter, o, index ); + /*QStyleOptionViewItemV4 opt = o; + initStyleOption( &opt, index ); + + // shrink the indentations. count how indented this item is and remove it + int indentMult = 0; + QModelIndex counter = index; + while ( counter.parent().isValid() ) + { + indentMult++; + counter = counter.parent(); + } + int realX = opt.rect.x() + indentMult * TREEVIEW_INDENT_ADD; + + opt.rect.setX( realX ); + const QWidget *widget = opt.widget; + QStyle *style = widget ? widget->style() : QApplication::style(); + style->drawControl( QStyle::CE_ItemViewItem, &opt, painter, widget ); */ + } + +#ifdef Q_WS_MAC + painter->setFont( savedFont ); +#endif +} + +void +SourceDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const +{ + if ( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() == SourcesModel::StaticPlaylist ) + editor->setGeometry( option.rect.adjusted( 20, 0, 0, 0 ) ); + else + QStyledItemDelegate::updateEditorGeometry( editor, option, index ); + + editor->setGeometry( editor->geometry().adjusted( 2*TREEVIEW_INDENT_ADD, 0, 0, 0 ) ); +} + +int +SourceDelegate::dropTypeCount( SourceTreeItem* item ) const +{ + int menuCount = 0; + if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeAllItems ) ) + menuCount++; + + if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeLocalItems ) ) + menuCount++; + + if ( item->supportedDropTypes().testFlag( SourceTreeItem::DropTypeTop10 ) ) + menuCount++; + + return menuCount; +} + +SourceTreeItem::DropType +SourceDelegate::hoveredDropType() const +{ + return m_hoveredDropType; +} diff --git a/src/sourcetree/sourcedelegate.h b/src/sourcetree/sourcedelegate.h new file mode 100644 index 000000000..a05f31b6f --- /dev/null +++ b/src/sourcetree/sourcedelegate.h @@ -0,0 +1,30 @@ +#ifndef SOURCEDELEGATE_H +#define SOURCEDELEGATE_H + +#include "sourcetreeview.h" +#include "items/sourcetreeitem.h" + +#include + +class SourceDelegate : public QStyledItemDelegate +{ +public: + SourceDelegate( QAbstractItemView* parent = 0 ) : QStyledItemDelegate( parent ), m_parent( parent ) {} + + void setDropHoverIndex( const QModelIndex &index ) { m_dropHoverIndex = index; } + + SourceTreeItem::DropType hoveredDropType() const; + +protected: + virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; + virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + virtual void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const; + virtual int dropTypeCount( SourceTreeItem* item ) const; + +private: + QAbstractItemView* m_parent; + QModelIndex m_dropHoverIndex; + mutable SourceTreeItem::DropType m_hoveredDropType; // Hack to keep easily track of the current highlighted DropType in paint() +}; + +#endif // SOURCEDELEGATE_H diff --git a/src/sourcetree/sourcetreeview.cpp b/src/sourcetree/sourcetreeview.cpp index 4297caffe..eaa68af99 100644 --- a/src/sourcetree/sourcetreeview.cpp +++ b/src/sourcetree/sourcetreeview.cpp @@ -32,6 +32,7 @@ #include "viewmanager.h" #include "sourcesproxymodel.h" #include "sourcelist.h" +#include "sourcedelegate.h" #include "sourcetree/items/playlistitems.h" #include "sourcetree/items/collectionitem.h" #include "audio/audioengine.h" @@ -46,33 +47,6 @@ using namespace Tomahawk; -#define TREEVIEW_INDENT_ADD -7 - - -class SourceDelegate : public QStyledItemDelegate -{ -public: - SourceDelegate( QAbstractItemView* parent = 0 ) : QStyledItemDelegate( parent ), m_parent( parent ) {} - -protected: - virtual QSize sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual void paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; - virtual void updateEditorGeometry( QWidget* editor, const QStyleOptionViewItem& option, const QModelIndex& index ) const - { - if ( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() == SourcesModel::StaticPlaylist ) - editor->setGeometry( option.rect.adjusted( 20, 0, 0, 0 ) ); - else - QStyledItemDelegate::updateEditorGeometry( editor, option, index ); - - editor->setGeometry( editor->geometry().adjusted( 2*TREEVIEW_INDENT_ADD, 0, 0, 0 ) ); - } - virtual bool editorEvent( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ); - -private: - QAbstractItemView* m_parent; - mutable int m_iconHeight; -}; - SourceTreeView::SourceTreeView( QWidget* parent ) : QTreeView( parent ) @@ -105,7 +79,8 @@ SourceTreeView::SourceTreeView( QWidget* parent ) // so investigate // setAnimated( true ); - setItemDelegate( new SourceDelegate( this ) ); + m_delegate = new SourceDelegate( this ); + setItemDelegate( m_delegate ); setContextMenuPolicy( Qt::CustomContextMenu ); connect( this, SIGNAL( customContextMenuRequested( QPoint ) ), SLOT( onCustomContextMenu( QPoint ) ) ); @@ -464,6 +439,13 @@ SourceTreeView::dragLeaveEvent( QDragLeaveEvent* event ) m_dragging = false; setDirtyRegion( m_dropRect ); +// SourceTreeItem* oldItem = m_dropIndex.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >(); +// if ( oldItem ) +// { +// oldItem->setDropHovering( false ); +// } + m_delegate->setDropHoverIndex( QModelIndex() ); + dataChanged(m_dropIndex, m_dropIndex); m_dropIndex = QPersistentModelIndex(); } @@ -479,6 +461,13 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event ) setDirtyRegion( m_dropRect ); const QPoint pos = event->pos(); const QModelIndex index = indexAt( pos ); +// SourceTreeItem* oldItem = m_dropIndex.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >(); +// if ( oldItem ) +// { +// oldItem->setDropHovering( false ); +// } + m_delegate->setDropHoverIndex( QModelIndex() ); + dataChanged(m_dropIndex, m_dropIndex); m_dropIndex = QPersistentModelIndex( index ); if ( index.isValid() ) @@ -486,9 +475,14 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event ) const QRect rect = visualRect( index ); m_dropRect = rect; - const SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index ); + SourceTreeItem* item = itemFromIndex< SourceTreeItem >( index ); if( item->willAcceptDrag( event->mimeData() ) ) + { accept = true; +// item->setDropHovering( true ); + m_delegate->setDropHoverIndex( index ); + dataChanged(index, index); + } } else { @@ -511,6 +505,15 @@ SourceTreeView::dragMoveEvent( QDragMoveEvent* event ) void SourceTreeView::dropEvent( QDropEvent* event ) { + const QPoint pos = event->pos(); + const QModelIndex index = indexAt( pos ); + PlaylistItem* item = itemFromIndex< PlaylistItem >( index ); + Q_ASSERT( item ); + + item->setDropType( m_delegate->hoveredDropType() ); + qDebug() << "dropType is " << m_delegate->hoveredDropType(); + m_delegate->setDropHoverIndex( QModelIndex() ); + dataChanged( index, index ); QTreeView::dropEvent( event ); m_dragging = false; m_dropIndex = QPersistentModelIndex(); @@ -576,190 +579,3 @@ SourceTreeView::itemFromIndex( const QModelIndex& index ) const return item; } - -QSize -SourceDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - if ( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() == SourcesModel::Collection ) - return QSize( option.rect.width(), 44 ); - else - return QStyledItemDelegate::sizeHint( option, index ); -} - - -void -SourceDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const -{ - QStyleOptionViewItem o = option; - -#ifdef Q_WS_MAC - QFont savedFont = painter->font(); - QFont smaller = savedFont; - smaller.setPointSize( smaller.pointSize() - 2 ); - painter->setFont( smaller ); - o.font = smaller; -#endif - - if ( ( option.state & QStyle::State_Enabled ) == QStyle::State_Enabled ) - { - o.state = QStyle::State_Enabled; - - if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) - { - o.palette.setColor( QPalette::Text, o.palette.color( QPalette::HighlightedText ) ); - } - } - - SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() ); - SourceTreeItem* item = index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >(); - Q_ASSERT( item ); - - QStyleOptionViewItemV4 o3 = option; - if ( type != SourcesModel::Collection && type != SourcesModel::Category ) - o3.rect.setX( 0 ); - - QApplication::style()->drawControl( QStyle::CE_ItemViewItem, &o3, painter ); - - if ( type == SourcesModel::Collection ) - { - painter->save(); - - QFont normal = painter->font(); - QFont bold = painter->font(); - bold.setBold( true ); - - CollectionItem* colItem = qobject_cast< CollectionItem* >( item ); - Q_ASSERT( colItem ); - bool status = !( !colItem || colItem->source().isNull() || !colItem->source()->isOnline() ); - - QString tracks; - QString name = index.data().toString(); - int figWidth = 0; - - if ( status && colItem && !colItem->source().isNull() ) - { - tracks = QString::number( colItem->source()->trackCount() ); - figWidth = painter->fontMetrics().width( tracks ); - name = colItem->source()->friendlyName(); - } - - QRect iconRect = option.rect.adjusted( 4, 6, -option.rect.width() + option.rect.height() - 12 + 4, -6 ); - - QPixmap avatar = colItem->icon().pixmap( iconRect.size() ); - painter->drawPixmap( iconRect, avatar.scaledToHeight( iconRect.height(), Qt::SmoothTransformation ) ); - - if ( ( option.state & QStyle::State_Selected ) == QStyle::State_Selected ) - { - painter->setPen( o.palette.color( QPalette::HighlightedText ) ); - } - - QRect textRect = option.rect.adjusted( iconRect.width() + 8, 6, -figWidth - 24, 0 ); - if ( status || colItem->source().isNull() ) - painter->setFont( bold ); - QString text = painter->fontMetrics().elidedText( name, Qt::ElideRight, textRect.width() ); - painter->drawText( textRect, text ); - - QString desc = status ? colItem->source()->textStatus() : tr( "Offline" ); - if ( colItem->source().isNull() ) - desc = tr( "All available tracks" ); - if ( status && desc.isEmpty() && !colItem->source()->currentTrack().isNull() ) - desc = colItem->source()->currentTrack()->artist() + " - " + colItem->source()->currentTrack()->track(); - if ( desc.isEmpty() ) - desc = tr( "Online" ); - - textRect = option.rect.adjusted( iconRect.width() + 8, painter->fontMetrics().height() + 6, -figWidth - 24, -4 ); - painter->setFont( normal ); - text = painter->fontMetrics().elidedText( desc, Qt::ElideRight, textRect.width() ); - QTextOption to( Qt::AlignBottom ); - painter->drawText( textRect, text, to ); - - if ( status ) - { - painter->setRenderHint( QPainter::Antialiasing ); - - QRect figRect = o.rect.adjusted( o.rect.width() - figWidth - 8, 0, -13, -o.rect.height() + 16 ); - int hd = ( option.rect.height() - figRect.height() ) / 2; - figRect.adjust( 0, hd, 0, hd ); -#ifdef Q_OS_WIN - figRect.adjust( -3, 0, 3, 0 ); -#endif - painter->setFont( bold ); - - QColor figColor( 167, 183, 211 ); - painter->setPen( figColor ); - painter->setBrush( figColor ); - - TomahawkUtils::drawBackgroundAndNumbers( painter, tracks, figRect ); - } - - painter->restore(); - } - else - { - QStyledItemDelegate::paint( painter, o, index ); - - if ( type == SourcesModel::TemporaryPage ) - { - TemporaryPageItem* gpi = qobject_cast< TemporaryPageItem* >( item ); - Q_ASSERT( gpi ); - - if ( gpi && o3.state & QStyle::State_MouseOver ) - { - // draw close icon - int padding = 3; - m_iconHeight = ( o3.rect.height() - 2*padding ); - QPixmap p( RESPATH "images/list-remove.png" ); - p = p.scaledToHeight( m_iconHeight, Qt::SmoothTransformation ); - - QRect r ( o3.rect.right() - padding - m_iconHeight, padding + o3.rect.y(), m_iconHeight, m_iconHeight ); - painter->drawPixmap( r, p ); - } - } - /*QStyleOptionViewItemV4 opt = o; - - // shrink the indentations. count how indented this item is and remove it - int indentMult = 0; - QModelIndex counter = index; - while ( counter.parent().isValid() ) - { - indentMult++; - counter = counter.parent(); - } - int realX = opt.rect.x() + indentMult * TREEVIEW_INDENT_ADD; - - opt.rect.setX( realX ); - const QWidget *widget = opt.widget; - QStyle *style = widget ? widget->style() : QApplication::style(); - style->drawControl( QStyle::CE_ItemViewItem, &opt, painter, widget ); */ - } - -#ifdef Q_WS_MAC - painter->setFont( savedFont ); -#endif -} - -bool -SourceDelegate::editorEvent ( QEvent* event, QAbstractItemModel* model, const QStyleOptionViewItem& option, const QModelIndex& index ) -{ - - if ( event->type() == QEvent::MouseButtonRelease ) - { - SourcesModel::RowType type = static_cast< SourcesModel::RowType >( index.data( SourcesModel::SourceTreeItemTypeRole ).toInt() ); - if ( type == SourcesModel::TemporaryPage ) - { - TemporaryPageItem* gpi = qobject_cast< TemporaryPageItem* >( index.data( SourcesModel::SourceTreeItemRole ).value< SourceTreeItem* >() ); - Q_ASSERT( gpi ); - QMouseEvent* ev = static_cast< QMouseEvent* >( event ); - - QStyleOptionViewItemV4 o = option; - initStyleOption( &o, index ); - int padding = 3; - QRect r ( o.rect.right() - padding - m_iconHeight, padding + o.rect.y(), m_iconHeight, m_iconHeight ); - - if ( r.contains( ev->pos() ) ) - gpi->removeFromList(); - } - } - - return QStyledItemDelegate::editorEvent ( event, model, option, index ); -} diff --git a/src/sourcetree/sourcetreeview.h b/src/sourcetree/sourcetreeview.h index 2eca36fa2..8bba33076 100644 --- a/src/sourcetree/sourcetreeview.h +++ b/src/sourcetree/sourcetreeview.h @@ -29,6 +29,7 @@ class CollectionModel; class PlaylistModel; class SourcesModel; class SourcesProxyModel; +class SourceDelegate; class SourceTreeView : public QTreeView { @@ -81,6 +82,7 @@ private: SourcesModel* m_model; SourcesProxyModel* m_proxyModel; QModelIndex m_contextMenuIndex; + SourceDelegate* m_delegate; QMenu m_playlistMenu; QMenu m_roPlaylistMenu;