1 /***************************************************************************
2 * copyright : (C) 2007 Ian Monroe <ian@monroe.nu> *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License version 2 *
6 * as published by the Free Software Foundation. *
7 ***************************************************************************/
10 #include "meta/MetaUtility.h"
11 #include "AmarokMimeData.h"
12 #include "PlaylistGraphicsItem.h"
13 #include "PlaylistGraphicsView.h"
14 #include "PlaylistDropVis.h"
15 #include "PlaylistModel.h"
16 #include "PlaylistTextItem.h"
17 #include "TheInstances.h"
19 #include "KStandardDirs"
23 #include <QFontMetricsF>
24 #include <QGraphicsScene>
25 #include <QGraphicsTextItem>
26 #include <QGraphicsPixmapItem>
27 #include <QGraphicsRectItem>
28 #include <QGraphicsSceneMouseEvent>
29 #include <QGraphicsView>
32 #include <QPixmapCache>
33 #include <QRadialGradient>
35 #include <QStyleOptionGraphicsItem>
39 struct Playlist::GraphicsItem::ActiveItems
44 , bottomRightText( 0 )
53 delete bottomLeftText
;
54 delete bottomRightText
;
61 QGraphicsPixmapItem
* foreground
;
62 Playlist::TextItem
* bottomLeftText
;
63 Playlist::TextItem
* bottomRightText
;
64 Playlist::TextItem
* topLeftText
;
65 Playlist::TextItem
* topRightText
;
67 QColor overlayGradientStart
;
68 QColor overlayGradientEnd
;
74 QRectF preDragLocation
;
79 const qreal
Playlist::GraphicsItem::ALBUM_WIDTH
= 50.0;
80 const qreal
Playlist::GraphicsItem::MARGIN
= 4.0;
81 QFontMetricsF
* Playlist::GraphicsItem::s_fm
= 0;
82 QSvgRenderer
* Playlist::GraphicsItem::s_svgRenderer
= 0;
84 Playlist::GraphicsItem::GraphicsItem()
89 , m_groupModeChanged ( false )
90 , m_collapsible ( true )
95 s_fm
= new QFontMetricsF( QFont() );
96 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + 2 * MARGIN
;
99 if ( !s_svgRenderer
) {
100 s_svgRenderer
= new QSvgRenderer( KStandardDirs::locate( "data","amarok/images/playlist_items.svg" ));
101 if ( ! s_svgRenderer
->isValid() )
102 debug() << "svg is kaputski";
105 setFlag( QGraphicsItem::ItemIsSelectable
);
106 setFlag( QGraphicsItem::ItemIsMovable
);
107 setAcceptDrops( true );
108 // setHandlesChildEvents( true ); // don't let drops etc hit the text items, doing stupid things
111 Playlist::GraphicsItem::~GraphicsItem()
117 Playlist::GraphicsItem::paint( QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
120 // 1) You do not talk about ::paint method
121 // 2) You DO NOT talk about ::paint method
122 // 3) Do not show or hide item that are already shown or hidden, respectively
123 // 4) Do not setBrush without making sure its hasn't already been set to that brush().
124 // 5) If this is your first night at ::paint method, you HAVE to paint.
125 Q_UNUSED( painter
); Q_UNUSED( widget
);
127 //debug() << "painting row: " << m_currentRow;
128 const QModelIndex index
= The::playlistModel()->index( m_currentRow
, 0 );
130 if( !m_items
|| ( option
->rect
.width() != m_items
->lastWidth
) || m_groupModeChanged
)
135 const Meta::TrackPtr track
= index
.data( ItemRole
).value
< Playlist::Item
* >()->track();
136 m_items
= new Playlist::GraphicsItem::ActiveItems();
137 m_items
->track
= track
;
140 m_groupModeChanged
= false;
141 resize( m_items
->track
, option
->rect
.width() );
145 if ( m_groupMode
== Collapsed
) {
146 // just make sure text items are hidden and then get the heck out of here...
147 // whoops... this has got to be moved here below the check for (!m_items) or
148 // it will evetually crasah....
149 if( m_items
->topRightText
->isVisible() )
150 m_items
->topRightText
->hide();
151 if( m_items
->topLeftText
->isVisible() )
152 m_items
->topLeftText
->hide();
153 if( m_items
->bottomRightText
->isVisible() )
154 m_items
->bottomRightText
->hide();
155 if( m_items
->bottomLeftText
->isVisible() )
156 m_items
->bottomLeftText
->hide();
162 // paint item background:
165 if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) {
167 //make the album group header stand out
168 //painter->fillRect( option->rect, QBrush( Qt::darkCyan ) );
169 trackRect
= QRectF( option
->rect
.x(), ALBUM_WIDTH
+ 2 * MARGIN
, option
->rect
.width(), s_fm
->height() /*+ MARGIN*/ );
170 if (m_groupMode
== Head
)
171 headRect
= option
->rect
;
173 headRect
= QRectF( option
->rect
.x(), option
->rect
.y(), option
->rect
.width(), option
->rect
.height() - 2 );
176 trackRect
= option
->rect
;
178 if ( ( m_groupMode
!= Body
) && !( ( m_groupMode
== Head
) ) )
179 trackRect
.setHeight( trackRect
.height() - 2 ); // add a little space between items
183 if ( m_groupMode
== None
) {
185 QString key
= QString("track:%1x%2").arg(trackRect
.width()).arg(trackRect
.height());
186 QPixmap
background( (int)( trackRect
.width() ), (int)( trackRect
.height() ) );
187 background
.fill( Qt::transparent
);
190 if (!QPixmapCache::find(key
, background
)) {
191 QPainter
pt( &background
);
192 s_svgRenderer
->render( &pt
, "track", trackRect
);
193 QPixmapCache::insert(key
, background
);
195 painter
->drawPixmap( 0, 0, background
);
196 } else if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) {
199 if ( m_groupMode
== Head
)
202 svgName
= "collapsed_head";
204 QString key
= QString("%1:%2x%3").arg( svgName
).arg( headRect
.width() ).arg( headRect
.height() );
205 QPixmap
background( headRect
.width(), headRect
.height() );
206 background
.fill( Qt::transparent
);
208 if ( !QPixmapCache::find( key
, background
) ) {
209 QPainter
pt( &background
);
210 s_svgRenderer
->render( &pt
, svgName
, headRect
);
211 QPixmapCache::insert( key
, background
);
213 painter
->drawPixmap( 0, 0, background
);
215 //"Just for fun" stuff below this point
217 //ask if we are allowed to collapse thid group:
218 //m_collapsible = index.data( GroupedCollapsibleRole ).toBool();
220 QString collapseString
;
221 if ( m_groupMode
== Head
) {
223 collapseString
= "collapse_button";
225 collapseString
= "collapse_button_grayed_out";
227 collapseString
= "expand_button";
230 key
= QString("%1:%2x%3").arg( collapseString
).arg( 16 ).arg( 16 );
231 QPixmap
collapsePixmap( 16, 16 );
232 collapsePixmap
.fill( Qt::transparent
);
234 if (!QPixmapCache::find(key
, collapsePixmap
)) {
235 QPainter
pt2( &collapsePixmap
);
236 s_svgRenderer
->render( &pt2
, collapseString
, QRectF( 0, 0, 16, 16 ) );
237 QPixmapCache::insert(key
, collapsePixmap
);
240 painter
->drawPixmap( option
->rect
.width() - ( 16 + MARGIN
) , MARGIN
, collapsePixmap
);
244 } else if ( m_groupMode
== Body
) {
246 QString key
= QString("body:%1x%2").arg(trackRect
.width()).arg(trackRect
.height());
247 QPixmap
background( (int)( trackRect
.width() ), (int)( trackRect
.height() ) );
248 background
.fill( Qt::transparent
);
250 if (!QPixmapCache::find(key
, background
)) {
251 QPainter
pt( &background
);
252 s_svgRenderer
->render( &pt
, "body", trackRect
);
253 QPixmapCache::insert(key
, background
);
255 painter
->drawPixmap( 0, 0, background
);
256 } else if ( m_groupMode
== End
) {
258 QString key
= QString( "tail:%1x%2" ).arg( trackRect
.width() ).arg(trackRect
.height()) ;
259 QPixmap
background( (int)( trackRect
.width() ), (int)( trackRect
.height() ) );
260 background
.fill( Qt::transparent
);
262 if (!QPixmapCache::find(key
, background
)) {
263 QPainter
pt( &background
);
264 s_svgRenderer
->render( &pt
, "tail", trackRect
);
265 QPixmapCache::insert(key
, background
);
267 painter
->drawPixmap( 0, 0, background
);
273 if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) || ( m_groupMode
== Body
) || ( m_groupMode
== End
) ) {
274 if ( index
.data( GroupedAlternateRole
).toBool() ) {
276 QString key
= QString( "alternate:%1x%2" ).arg( trackRect
.width() - 10 ).arg(trackRect
.height() );
277 QPixmap
background( (int)( trackRect
.width() - 10 ), (int)( trackRect
.height() ) );
279 QRectF tempRect
= trackRect
;
280 tempRect
.setWidth( tempRect
.width() - 10 );
281 if ( m_groupMode
== End
)
282 tempRect
.setHeight( tempRect
.height() - 4 );
284 if (!QPixmapCache::find( key
, background
) ) {
285 background
.fill( Qt::transparent
);
286 QPainter
pt( &background
);
287 s_svgRenderer
->render( &pt
, "body_background", tempRect
);
288 QPixmapCache::insert( key
, background
);
291 if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
))
292 painter
->drawPixmap( 5, (int)( MARGIN
+ ALBUM_WIDTH
+ 2 ), background
);
294 painter
->drawPixmap( 5, 0, background
);
301 if ( m_groupMode
< Body
) {
302 //if we are not grouped, or are the head of a group, paint cover:
304 if( m_items
->track
->album() )
305 albumPixmap
= m_items
->track
->album()->image( int( ALBUM_WIDTH
) );
306 painter
->drawPixmap( (int)( MARGIN
), (int)( MARGIN
), albumPixmap
);
307 //and make sure the top text elements are shown
308 if( !m_items
->topRightText
->isVisible() )
309 m_items
->topRightText
->show();
310 if( !m_items
->topLeftText
->isVisible() )
311 m_items
->topLeftText
->show();
314 //if not, make sure that the top text items are not shown
315 if( m_items
->topRightText
->isVisible() )
316 m_items
->topRightText
->hide();
317 if( m_items
->topLeftText
->isVisible() )
318 m_items
->topLeftText
->hide();
319 if( !m_items
->bottomRightText
->isVisible() )
320 m_items
->bottomRightText
->show();
321 if( !m_items
->bottomLeftText
->isVisible() )
322 m_items
->bottomLeftText
->show();
325 //set selection marker if needed
327 if( option
->state
& QStyle::State_Selected
)
329 painter
->fillRect( trackRect
, QBrush( QColor( 0, 0, 255, 128 ) ) );
334 //set overlay if item is active:
335 if( index
.data( ActiveTrackRole
).toBool() )
337 if( !m_items
->foreground
)
340 debug() << "Creating active track overlay";
341 m_items
->foreground
= new QGraphicsPixmapItem( this );
342 m_items
->foreground
->setPos( 0.0, trackRect
.top() );
343 m_items
->foreground
->setZValue( 10.0 );
346 QString key
= QString("active_overlay:%1x%2").arg(trackRect
.width()).arg(trackRect
.height());
347 QPixmap
background( (int)( trackRect
.width() ), (int)( trackRect
.height() ) );
348 background
.fill( Qt::transparent
);
350 debug() << "Key string: " << key
;
352 if (!QPixmapCache::find(key
, background
)) {
353 QPainter
pt( &background
);
354 s_svgRenderer
->render( &pt
, "active_overlay", QRectF( 0, 0, trackRect
.width(), trackRect
.height() ) );
355 QPixmapCache::insert(key
, background
);
357 m_items
->foreground
->setPixmap( background
);
358 m_items
->foreground
->show();
362 /*QRadialGradient gradient(trackRect.width() / 2.0, trackRect.height() / 2.0, trackRect.width() / 2.0, 20 + trackRect.width() / 2.0, trackRect.height() / 2.0 );
363 m_items->overlayGradientStart = option->palette.highlightedText().color().light();
364 m_items->overlayGradientStart.setAlpha( 80 );
365 m_items->overlayGradientEnd = option->palette.highlightedText().color().dark();
366 m_items->overlayGradientEnd.setAlpha( 80 );
367 gradient.setColorAt( 0.0, m_items->overlayGradientStart );
368 gradient.setColorAt( 1.0, m_items->overlayGradientEnd );
369 QBrush brush( gradient );
370 m_items->foreground->setBrush( brush );
371 m_items->foreground->setPen( QPen( Qt::NoPen ) );*/
373 if( !m_items
->foreground
->isVisible() )
374 m_items
->foreground
->show();
375 } else if( m_items
->foreground
&& m_items
->foreground
->isVisible() )
376 m_items
->foreground
->hide();
380 Playlist::GraphicsItem::init( Meta::TrackPtr track
)
384 font
.setPointSize( font
.pointSize() - 1 );
385 #define NewText( X ) \
386 X = new Playlist::TextItem( this ); \
387 X->setTextInteractionFlags( Qt::TextEditorInteraction ); \
389 NewText( m_items
->topLeftText
)
390 NewText( m_items
->bottomLeftText
)
391 NewText( m_items
->topRightText
)
392 NewText( m_items
->bottomRightText
)
397 Playlist::GraphicsItem::resize( Meta::TrackPtr track
, int totalWidth
)
399 if( totalWidth
== -1 /*|| totalWidth == m_items->lastWidth */) //no change needed
401 if( m_items
->lastWidth
!= -5 ) //this isn't the first "resize"
402 prepareGeometryChange();
403 m_items
->lastWidth
= totalWidth
;
405 QString prettyLength
;
407 if ( m_groupMode
== Head_Collapsed
) {
409 for( uint i
= m_currentRow
; i
< m_currentRow
+ m_items
->groupedTracks
; i
++ )
410 seconds
+= The::playlistModel()->itemList()[ i
]->track()->length();
411 prettyLength
= Meta::secToPrettyTime( seconds
);
413 prettyLength
= Meta::secToPrettyTime( track
->length() );
417 album
= track
->album()->name();
419 const qreal lineTwoY
= m_height
/ 2 + MARGIN
;
420 const qreal textWidth
= ( ( qreal( totalWidth
) - ALBUM_WIDTH
) / 2.0 );
421 const qreal leftAlignX
= ALBUM_WIDTH
+ MARGIN
;
422 qreal topRightAlignX
;
423 qreal bottomRightAlignX
;
426 qreal middle
= textWidth
+ ALBUM_WIDTH
+ ( MARGIN
* 2.0 );
427 qreal rightWidth
= totalWidth
- qMax( s_fm
->width( album
)
428 , s_fm
->width( prettyLength
) );
429 topRightAlignX
= qMax( middle
, rightWidth
);
432 //lets use all the horizontal space we can get for now..
433 int lengthStringWidth
= (int)(s_fm
->width( prettyLength
));
434 bottomRightAlignX
= ( totalWidth
- 4 * MARGIN
) - lengthStringWidth
;
439 qreal spaceForTopLeft
= totalWidth
- ( totalWidth
- topRightAlignX
) - leftAlignX
;
440 qreal spaceForBottomLeft
= totalWidth
- ( totalWidth
- bottomRightAlignX
) - leftAlignX
;
442 if ( m_groupMode
== Head_Collapsed
) {
444 m_items
->bottomLeftText
->setEditableText( QString("%1 tracks").arg( QString::number( m_items
->groupedTracks
) ) , spaceForBottomLeft
);
445 QFont f
= m_items
->bottomLeftText
->font();
447 m_items
->bottomLeftText
->setFont( f
);
448 m_items
->bottomRightText
->setEditableText( prettyLength
, totalWidth
- bottomRightAlignX
);
451 m_items
->bottomLeftText
->setFont( m_items
->bottomRightText
->font() );
452 m_items
->bottomLeftText
->setEditableText( QString("%1 - %2").arg( QString::number( track
->trackNumber() ), track
->name() ) , spaceForBottomLeft
);
453 m_items
->bottomRightText
->setEditableText( prettyLength
, totalWidth
- bottomRightAlignX
);
455 if ( m_groupMode
== None
) {
457 m_items
->topRightText
->setPos( topRightAlignX
, MARGIN
);
458 m_items
->topRightText
->setEditableText( album
, totalWidth
- topRightAlignX
);
462 if( track
->artist() )
463 artist
= track
->artist()->name();
464 m_items
->topLeftText
->setEditableText( artist
, spaceForTopLeft
);
465 m_items
->topLeftText
->setPos( leftAlignX
, MARGIN
);
468 m_items
->bottomLeftText
->setPos( leftAlignX
, lineTwoY
);
469 m_items
->bottomRightText
->setPos( bottomRightAlignX
, lineTwoY
);
470 } else if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) {
472 int headingCenter
= (int)( MARGIN
+ ( ALBUM_WIDTH
- s_fm
->height()) / 2 );
474 m_items
->topRightText
->setPos( topRightAlignX
, headingCenter
);
475 m_items
->topRightText
->setEditableText( album
, totalWidth
- topRightAlignX
);
479 //various artist handling:
480 //if the album has no albumartist, use Various Artists, otherwise use the albumartist's name
481 if( track
->album()->albumArtist() )
482 artist
= track
->album()->albumArtist()->name();
485 artist
= findArtistForCurrentAlbum();
486 if( artist
.isEmpty() )
487 artist
= i18n( "Various Artists" );
489 m_items
->topLeftText
->setEditableText( artist
, spaceForTopLeft
);
490 m_items
->topLeftText
->setPos( leftAlignX
, headingCenter
);
493 int underImageY
= (int)( MARGIN
+ ALBUM_WIDTH
+ 2 );
495 m_items
->bottomLeftText
->setPos( MARGIN
* 3, underImageY
);
496 m_items
->bottomRightText
->setPos( bottomRightAlignX
, underImageY
);
499 m_items
->bottomLeftText
->setPos( MARGIN
* 3, 0 );
500 m_items
->bottomRightText
->setPos( bottomRightAlignX
, 0 );
503 //make sure the activ eitem overlay has the correct width
507 if( m_items
->foreground
)
511 if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) {
512 trackRect
= QRectF( 0, ALBUM_WIDTH
+ 2 * MARGIN
, totalWidth
, s_fm
->height() /*+ MARGIN*/ );
514 trackRect
= QRectF( 0, 0, totalWidth
, m_height
);
515 if ( ( m_groupMode
!= Body
) && !( ( m_groupMode
== Head
) ) )
516 trackRect
.setHeight( trackRect
.height() - 2 ); // add a little space between items
519 debug() << "Resizing active track overlay";
521 QString key
= QString("active_overlay:%1x%2").arg(trackRect
.width()).arg(trackRect
.height());
523 debug() << "Key string: " << key
;
524 QPixmap
background( (int)( trackRect
.width() ), (int)( trackRect
.height() ) );
525 background
.fill( Qt::transparent
);
528 if (!QPixmapCache::find(key
, background
)) {
529 QPainter
pt( &background
);
530 s_svgRenderer
->render( &pt
, "active_overlay", trackRect
);
531 QPixmapCache::insert(key
, background
);
533 m_items
->foreground
->setPixmap( background
);
534 m_items
->foreground
->setZValue( 10.0 );
540 m_items
->lastWidth
= totalWidth
;
544 Playlist::GraphicsItem::findArtistForCurrentAlbum() const
546 if( !( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) )
549 const QModelIndex index
= The::playlistModel()->index( m_currentRow
, 0 );
550 if( ! ( ( index
.data( GroupRole
).toInt() == Head
) || ( index
.data( GroupRole
).toInt() == Head_Collapsed
) ) )
557 Meta::TrackPtr currentTrack
= index
.data( TrackRole
).value
< Meta::TrackPtr
>();
558 if( currentTrack
->artist() )
559 artist
= currentTrack
->artist()->name();
562 //it's an album group, and the current row is the head, so the next row is either Body or End
563 //that means we have to execute the loop at least once
565 int row
= m_currentRow
+ 1;
568 idx
= The::playlistModel()->index( row
++, 0 );
569 Meta::TrackPtr track
= idx
.data( TrackRole
).value
< Meta::TrackPtr
>();
570 if( track
->artist() )
572 if( artist
!= track
->artist()->name() )
580 while( idx
.data( GroupRole
).toInt() == Body
);
587 Playlist::GraphicsItem::boundingRect() const
589 // the viewport()->size() takes scrollbars into account
590 return QRectF( 0.0, 0.0, The::playlistView()->viewport()->size().width(), m_height
);
594 Playlist::GraphicsItem::play()
596 The::playlistModel()->play( m_currentRow
);
600 Playlist::GraphicsItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent
*event
)
608 QGraphicsItem::mouseDoubleClickEvent( event
);
612 Playlist::GraphicsItem::mousePressEvent( QGraphicsSceneMouseEvent
*event
)
614 if( event
->buttons() & Qt::RightButton
|| !m_items
)
619 m_items
->preDragLocation
= mapToScene( boundingRect() ).boundingRect();
621 //did we hit the collapse / expand button?
622 if ( m_collapsible
) {
623 QRectF
rect( boundingRect().width() - ( 16 + MARGIN
), MARGIN
, 16, 16 );
624 if ( rect
.contains( event
->pos() ) ) {
625 if ( m_groupMode
== Head_Collapsed
)
626 The::playlistModel()->setCollapsed( m_currentRow
, false );
627 else if ( m_groupMode
== Head
)
628 The::playlistModel()->setCollapsed( m_currentRow
, true );
633 QGraphicsItem::mousePressEvent( event
);
636 // With help from QGraphicsView::mouseMoveEvent()
638 Playlist::GraphicsItem::mouseMoveEvent( QGraphicsSceneMouseEvent
*event
)
640 if( (event
->buttons() & Qt::LeftButton
) && ( flags() & QGraphicsItem::ItemIsMovable
) && m_items
)
642 QPointF scenePosition
= event
->scenePos();
644 if( scenePosition
.y() < 0 )
647 bool dragOverOriginalPosition
= m_items
->preDragLocation
.contains( scenePosition
);
649 //make sure item is drawn on top of other items
652 // Determine the list of selected items
653 QList
<QGraphicsItem
*> selectedItems
= scene()->selectedItems();
655 selectedItems
<< this;
656 // Move all selected items
657 foreach( QGraphicsItem
*item
, selectedItems
)
659 if( (item
->flags() & QGraphicsItem::ItemIsMovable
) && (!item
->parentItem() || !item
->parentItem()->isSelected()) )
661 Playlist::GraphicsItem
*above
= 0;
663 if( item
== this && !dragOverOriginalPosition
)
665 diff
= event
->scenePos() - event
->lastScenePos();
666 QList
<QGraphicsItem
*> collisions
= scene()->items( event
->scenePos() );
667 foreach( QGraphicsItem
*i
, collisions
)
669 Playlist::GraphicsItem
*c
= dynamic_cast<Playlist::GraphicsItem
*>( i
);
679 diff
= item
->mapToParent( item
->mapFromScene(event
->scenePos()))
680 - item
->mapToParent(item
->mapFromScene(event
->lastScenePos()));
683 item
->moveBy( 0, diff
.y() );
684 if( item
->flags() & ItemIsSelectable
)
685 item
->setSelected( true );
687 if( dragOverOriginalPosition
)
688 Playlist::DropVis::instance()->show( m_items
->preDragLocation
.y() );
690 Playlist::DropVis::instance()->show( above
);
696 QGraphicsItem::mouseMoveEvent( event
);
701 Playlist::GraphicsItem::dragEnterEvent( QGraphicsSceneDragDropEvent
*event
)
703 foreach( QString mime
, The::playlistModel()->mimeTypes() )
705 if( event
->mimeData()->hasFormat( mime
) )
708 Playlist::DropVis::instance()->show( this );
715 Playlist::GraphicsItem::dropEvent( QGraphicsSceneDragDropEvent
* event
)
719 The::playlistModel()->dropMimeData( event
->mimeData(), Qt::CopyAction
, m_currentRow
, 0, QModelIndex() );
720 Playlist::DropVis::instance()->hide();
724 Playlist::GraphicsItem::refresh()
727 if( !m_items
|| !m_items
->track
)
730 if( m_items
->track
->album() )
731 albumPixmap
= m_items
->track
->album()->image( int( ALBUM_WIDTH
) );
733 //m_items->albumArt->hide();
734 //delete ( m_items->albumArt );
735 //m_items->albumArt = new QGraphicsPixmapItem( albumPixmap, this );
736 //m_items->albumArt->setPos( 0.0, MARGIN );
739 void Playlist::GraphicsItem::mouseReleaseEvent( QGraphicsSceneMouseEvent
*event
)
741 bool dragOverOriginalPosition
= m_items
->preDragLocation
.contains( event
->scenePos() );
742 if( dragOverOriginalPosition
)
744 setPos( m_items
->preDragLocation
.topLeft() );
745 Playlist::DropVis::instance()->hide();
749 Playlist::GraphicsItem
*above
= 0;
750 QList
<QGraphicsItem
*> collisions
= scene()->items( event
->scenePos() );
751 foreach( QGraphicsItem
*i
, collisions
)
753 Playlist::GraphicsItem
*c
= dynamic_cast<Playlist::GraphicsItem
*>( i
);
760 // if we've dropped ourself ontop of another item, then we need to shuffle the tracks below down
763 setPos( above
->pos() );
764 The::playlistView()->moveItem( this, above
);
766 //Don't just drop item into the void, make it the last item!
768 The::playlistView()->moveItem( this, 0 );
769 //setPos( above->pos() );
770 //The::playlistView()->moveItem( this, above );
774 //make sure item resets its z value
776 Playlist::DropVis::instance()->hide();
779 void Playlist::GraphicsItem::setRow(int row
)
784 const QModelIndex index
= The::playlistModel()->index( m_currentRow
, 0 );
786 //figure out our group state and set height accordingly
787 int currentGroupState
= index
.data( GroupRole
).toInt();
789 if ( currentGroupState
!= m_groupMode
) {
791 debug() << "Group changed for row " << row
;
793 prepareGeometryChange();
796 m_groupMode
= currentGroupState
;
797 m_groupModeChanged
= true;
799 switch ( m_groupMode
) {
803 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + 2 * MARGIN
+ 2;
807 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + MARGIN
+ s_fm
->height() + 4;
810 debug() << "Collapsed head";
811 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + MARGIN
+ s_fm
->height() + 10;
813 const Meta::TrackPtr track
= index
.data( ItemRole
).value
< Playlist::Item
* >()->track();
814 m_items
= new Playlist::GraphicsItem::ActiveItems();
815 m_items
->track
= track
;
818 m_items
->groupedTracks
= index
.data( GroupedTracksRole
).toInt();
822 m_height
= s_fm
->height()/*+ 2 * MARGIN*/;
826 m_height
= s_fm
->height() + 6 /*+ 2 * MARGIN*/;
829 debug() << "Collapsed";
833 debug() << "ERROR!!??";
838 void Playlist::GraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent
* event
)
842 /*if ( m_groupMode == Head_Collapsed )
843 The::playlistModel()->setCollapsed( m_currentRow, false ); */