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 )
52 delete bottomLeftText
;
53 delete bottomRightText
;
60 QGraphicsRectItem
* foreground
;
61 Playlist::TextItem
* bottomLeftText
;
62 Playlist::TextItem
* bottomRightText
;
63 Playlist::TextItem
* topLeftText
;
64 Playlist::TextItem
* topRightText
;
69 QRectF preDragLocation
;
74 const qreal
Playlist::GraphicsItem::ALBUM_WIDTH
= 50.0;
75 const qreal
Playlist::GraphicsItem::MARGIN
= 4.0;
76 QFontMetricsF
* Playlist::GraphicsItem::s_fm
= 0;
77 QSvgRenderer
* Playlist::GraphicsItem::s_svgRenderer
= 0;
79 Playlist::GraphicsItem::GraphicsItem()
84 , m_groupModeChanged ( false )
89 s_fm
= new QFontMetricsF( QFont() );
90 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + 2 * MARGIN
;
93 if ( !s_svgRenderer
) {
94 s_svgRenderer
= new QSvgRenderer( KStandardDirs::locate( "data","amarok/images/playlist_items.svg" ));
95 if ( ! s_svgRenderer
->isValid() )
96 debug() << "svg is kaputski";
99 setFlag( QGraphicsItem::ItemIsSelectable
);
100 setFlag( QGraphicsItem::ItemIsMovable
);
101 setAcceptDrops( true );
102 // setHandlesChildEvents( true ); // don't let drops etc hit the text items, doing stupid things
105 Playlist::GraphicsItem::~GraphicsItem()
111 Playlist::GraphicsItem::paint( QPainter
* painter
, const QStyleOptionGraphicsItem
* option
, QWidget
* widget
)
114 // 1) You do not talk about ::paint method
115 // 2) You DO NOT talk about ::paint method
116 // 3) Do not show or hide item that are already shown or hidden, respectively
117 // 4) Do not setBrush without making sure its hasn't already been set to that brush().
118 // 5) If this is your first night at ::paint method, you HAVE to paint.
119 Q_UNUSED( painter
); Q_UNUSED( widget
);
121 //debug() << "painting row: " << m_currentRow;
122 const QModelIndex index
= The::playlistModel()->index( m_currentRow
, 0 );
124 if( !m_items
|| ( option
->rect
.width() != m_items
->lastWidth
) || m_groupModeChanged
)
129 const Meta::TrackPtr track
= index
.data( ItemRole
).value
< Playlist::Item
* >()->track();
130 m_items
= new Playlist::GraphicsItem::ActiveItems();
131 m_items
->track
= track
;
134 m_groupModeChanged
= false;
135 resize( m_items
->track
, option
->rect
.width() );
139 if ( m_groupMode
== Collapsed
) {
140 // just make sure text items are hidden and then get the heck out of here...
141 // whoops... this has got to be moved here below the check for (!m_items) or
142 // it will evetually crasah....
143 if( m_items
->topRightText
->isVisible() )
144 m_items
->topRightText
->hide();
145 if( m_items
->topLeftText
->isVisible() )
146 m_items
->topLeftText
->hide();
147 if( m_items
->bottomRightText
->isVisible() )
148 m_items
->bottomRightText
->hide();
149 if( m_items
->bottomLeftText
->isVisible() )
150 m_items
->bottomLeftText
->hide();
156 // paint item background:
159 if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) {
161 //make the album group header stand out
162 //painter->fillRect( option->rect, QBrush( Qt::darkCyan ) );
163 trackRect
= QRectF( option
->rect
.x(), ALBUM_WIDTH
+ 2 * MARGIN
, option
->rect
.width(), s_fm
->height() /*+ MARGIN*/ );
164 if (m_groupMode
== Head
)
165 headRect
= option
->rect
;
167 headRect
= QRectF( option
->rect
.x(), option
->rect
.y(), option
->rect
.width(), option
->rect
.height() - 2 );
170 trackRect
= option
->rect
;
172 if ( ( m_groupMode
!= Body
) && !( ( m_groupMode
== Head
) ) )
173 trackRect
.setHeight( trackRect
.height() - 2 ); // add a little space between items
177 if ( m_groupMode
== None
) {
179 QString key
= QString("track:%1x%2").arg(trackRect
.width()).arg(trackRect
.height());
180 QPixmap
background( (int)( trackRect
.width() ), (int)( trackRect
.height() ) );
181 background
.fill( Qt::transparent
);
184 if (!QPixmapCache::find(key
, background
)) {
185 QPainter
pt( &background
);
186 s_svgRenderer
->render( &pt
, "track", trackRect
);
187 QPixmapCache::insert(key
, background
);
189 painter
->drawPixmap( 0, 0, background
);
190 } else if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) {
193 if ( m_groupMode
== Head
)
196 svgName
= "collapsed_head";
198 QString key
= QString("%1:%2x%3").arg( svgName
).arg( trackRect
.width() ).arg( trackRect
.height() );
199 QPixmap
background( headRect
.width(), headRect
.height() );
200 background
.fill( Qt::transparent
);
202 if ( !QPixmapCache::find( key
, background
) ) {
203 QPainter
pt( &background
);
204 s_svgRenderer
->render( &pt
, svgName
, headRect
);
205 QPixmapCache::insert( key
, background
);
207 painter
->drawPixmap( 0, 0, background
);
209 //"Just for fun" stuff below this point
211 QString collapseString
;
212 if ( m_groupMode
== Head
)
213 collapseString
= "collapse_button";
215 collapseString
= "expand_button";
218 key
= QString("%1:%2x%3").arg( collapseString
).arg( 16 ).arg( 16 );
219 QPixmap
collapsePixmap( 16, 16 );
220 collapsePixmap
.fill( Qt::transparent
);
222 if (!QPixmapCache::find(key
, collapsePixmap
)) {
223 QPainter
pt2( &collapsePixmap
);
224 s_svgRenderer
->render( &pt2
, collapseString
, QRectF( 0, 0, 16, 16 ) );
225 QPixmapCache::insert(key
, collapsePixmap
);
228 painter
->drawPixmap( option
->rect
.width() - ( 16 + MARGIN
) , MARGIN
, collapsePixmap
);
232 } else if ( m_groupMode
== Body
) {
234 QString key
= QString("body:%1x%2").arg(trackRect
.width()).arg(trackRect
.height());
235 QPixmap
background( (int)( trackRect
.width() ), (int)( trackRect
.height() ) );
236 background
.fill( Qt::transparent
);
238 if (!QPixmapCache::find(key
, background
)) {
239 QPainter
pt( &background
);
240 s_svgRenderer
->render( &pt
, "body", trackRect
);
241 QPixmapCache::insert(key
, background
);
243 painter
->drawPixmap( 0, 0, background
);
244 } else if ( m_groupMode
== End
) {
246 QString key
= QString( "tail:%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
, "tail", trackRect
);
253 QPixmapCache::insert(key
, background
);
255 painter
->drawPixmap( 0, 0, background
);
261 if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) || ( m_groupMode
== Body
) || ( m_groupMode
== End
) ) {
262 if( m_currentRow
% 2 ) {
264 QString key
= QString( "alternate:%1x%2" ).arg( trackRect
.width() - 10 ).arg(trackRect
.height() );
265 QPixmap
background( (int)( trackRect
.width() - 10 ), (int)( trackRect
.height() ) );
267 QRectF tempRect
= trackRect
;
268 tempRect
.setWidth( tempRect
.width() - 10 );
269 if ( m_groupMode
== End
)
270 tempRect
.setHeight( tempRect
.height() - 4 );
272 if (!QPixmapCache::find( key
, background
) ) {
273 background
.fill( Qt::transparent
);
274 QPainter
pt( &background
);
275 s_svgRenderer
->render( &pt
, "body_background", tempRect
);
276 QPixmapCache::insert( key
, background
);
279 if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
))
280 painter
->drawPixmap( 5, (int)( MARGIN
+ ALBUM_WIDTH
+ 2 ), background
);
282 painter
->drawPixmap( 5, 0, background
);
289 if ( m_groupMode
< Body
) {
290 //if we are not grouped, or are the head of a group, paint cover:
292 if( m_items
->track
->album() )
293 albumPixmap
= m_items
->track
->album()->image( int( ALBUM_WIDTH
) );
294 painter
->drawPixmap( (int)( MARGIN
), (int)( MARGIN
), albumPixmap
);
295 //and make sure the top text elements are shown
296 if( !m_items
->topRightText
->isVisible() )
297 m_items
->topRightText
->show();
298 if( !m_items
->topLeftText
->isVisible() )
299 m_items
->topLeftText
->show();
302 //if not, make sure that the top text items are not shown
303 if( m_items
->topRightText
->isVisible() )
304 m_items
->topRightText
->hide();
305 if( m_items
->topLeftText
->isVisible() )
306 m_items
->topLeftText
->hide();
307 if( !m_items
->bottomRightText
->isVisible() )
308 m_items
->bottomRightText
->show();
309 if( !m_items
->bottomLeftText
->isVisible() )
310 m_items
->bottomLeftText
->show();
313 //set selection marker if needed
315 if( option
->state
& QStyle::State_Selected
)
317 painter
->fillRect( trackRect
, QBrush( QColor( 0, 0, 255, 128 ) ) );
322 //set overlay if item is active:
323 if( index
.data( ActiveTrackRole
).toBool() )
325 if( !m_items
->foreground
)
327 m_items
->foreground
= new QGraphicsRectItem( trackRect
, this );
328 m_items
->foreground
->setPos( 0.0, trackRect
.top() );
329 m_items
->foreground
->setZValue( 5.0 );
330 QRadialGradient
gradient(trackRect
.width() / 2.0, trackRect
.height() / 2.0, trackRect
.width() / 2.0, 20 + trackRect
.width() / 2.0, trackRect
.height() / 2.0 );
331 QColor start
= option
->palette
.highlight().color().light();
332 start
.setAlpha( 51 );
333 QColor end
= option
->palette
.highlight().color().dark();
335 gradient
.setColorAt( 0.0, start
);
336 gradient
.setColorAt( 1.0, end
);
337 QBrush
brush( gradient
);
338 m_items
->foreground
->setBrush( brush
);
339 m_items
->foreground
->setPen( QPen( Qt::NoPen
) );
341 if( !m_items
->foreground
->isVisible() )
342 m_items
->foreground
->show();
344 else if( m_items
->foreground
&& m_items
->foreground
->isVisible() )
345 m_items
->foreground
->hide();
349 Playlist::GraphicsItem::init( Meta::TrackPtr track
)
353 font
.setPointSize( font
.pointSize() - 1 );
354 #define NewText( X ) \
355 X = new Playlist::TextItem( this ); \
356 X->setTextInteractionFlags( Qt::TextEditorInteraction ); \
358 NewText( m_items
->topLeftText
)
359 NewText( m_items
->bottomLeftText
)
360 NewText( m_items
->topRightText
)
361 NewText( m_items
->bottomRightText
)
366 Playlist::GraphicsItem::resize( Meta::TrackPtr track
, int totalWidth
)
368 if( totalWidth
== -1 /*|| totalWidth == m_items->lastWidth */) //no change needed
370 if( m_items
->lastWidth
!= -5 ) //this isn't the first "resize"
371 prepareGeometryChange();
372 m_items
->lastWidth
= totalWidth
;
373 QString prettyLength
= Meta::secToPrettyTime( track
->length() );
376 album
= track
->album()->name();
378 const qreal lineTwoY
= m_height
/ 2 + MARGIN
;
379 const qreal textWidth
= ( ( qreal( totalWidth
) - ALBUM_WIDTH
) / 2.0 );
380 const qreal leftAlignX
= ALBUM_WIDTH
+ MARGIN
;
381 qreal topRightAlignX
;
382 qreal bottomRightAlignX
;
385 qreal middle
= textWidth
+ ALBUM_WIDTH
+ ( MARGIN
* 2.0 );
386 qreal rightWidth
= totalWidth
- qMax( s_fm
->width( album
)
387 , s_fm
->width( prettyLength
) );
388 topRightAlignX
= qMax( middle
, rightWidth
);
391 //lets use all the horizontal space we can get for now..
392 int lengthStringWidth
= (int)(s_fm
->width( prettyLength
));
393 bottomRightAlignX
= ( totalWidth
- 4 * MARGIN
) - lengthStringWidth
;
398 qreal spaceForTopLeft
= totalWidth
- ( totalWidth
- topRightAlignX
) - leftAlignX
;
399 qreal spaceForBottomLeft
= totalWidth
- ( totalWidth
- bottomRightAlignX
) - leftAlignX
;
401 if ( m_groupMode
== Head_Collapsed
) {
403 m_items
->bottomLeftText
->setEditableText( QString("%1 tracks").arg( QString::number( m_items
->groupedTracks
) ) , spaceForBottomLeft
);
404 m_items
->bottomRightText
->setEditableText( "", totalWidth
- bottomRightAlignX
);
408 m_items
->bottomLeftText
->setEditableText( QString("%1 - %2").arg( QString::number( track
->trackNumber() ), track
->name() ) , spaceForBottomLeft
);
409 m_items
->bottomRightText
->setEditableText( prettyLength
, totalWidth
- bottomRightAlignX
);
411 if ( m_groupMode
== None
) {
413 m_items
->topRightText
->setPos( topRightAlignX
, MARGIN
);
414 m_items
->topRightText
->setEditableText( album
, totalWidth
- topRightAlignX
);
418 if( track
->artist() )
419 artist
= track
->artist()->name();
420 m_items
->topLeftText
->setEditableText( artist
, spaceForTopLeft
);
421 m_items
->topLeftText
->setPos( leftAlignX
, MARGIN
);
424 m_items
->bottomLeftText
->setPos( leftAlignX
, lineTwoY
);
425 m_items
->bottomRightText
->setPos( bottomRightAlignX
, lineTwoY
);
426 } else if ( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) {
428 int headingCenter
= (int)( MARGIN
+ ( ALBUM_WIDTH
- s_fm
->height()) / 2 );
430 m_items
->topRightText
->setPos( topRightAlignX
, headingCenter
);
431 m_items
->topRightText
->setEditableText( album
, totalWidth
- topRightAlignX
);
435 //various artist handling:
436 //if the album has no albumartist, use Various Artists, otherwise use the albumartist's name
437 if( track
->album()->albumArtist() )
438 artist
= track
->album()->albumArtist()->name();
441 artist
= findArtistForCurrentAlbum();
442 if( artist
.isEmpty() )
443 artist
= i18n( "Various Artists" );
445 m_items
->topLeftText
->setEditableText( artist
, spaceForTopLeft
);
446 m_items
->topLeftText
->setPos( leftAlignX
, headingCenter
);
449 int underImageY
= (int)( MARGIN
+ ALBUM_WIDTH
+ 2 );
451 m_items
->bottomLeftText
->setPos( MARGIN
* 3, underImageY
);
452 m_items
->bottomRightText
->setPos( bottomRightAlignX
, underImageY
);
455 m_items
->bottomLeftText
->setPos( MARGIN
* 3, 0 );
456 m_items
->bottomRightText
->setPos( bottomRightAlignX
, 0 );
459 m_items
->lastWidth
= totalWidth
;
463 Playlist::GraphicsItem::findArtistForCurrentAlbum() const
465 if( !( ( m_groupMode
== Head
) || ( m_groupMode
== Head_Collapsed
) ) )
468 const QModelIndex index
= The::playlistModel()->index( m_currentRow
, 0 );
469 if( !( index
.data( GroupRole
).toInt() == Head
) || ( index
.data( GroupRole
).toInt() == Head_Collapsed
) )
476 Meta::TrackPtr currentTrack
= index
.data( TrackRole
).value
< Meta::TrackPtr
>();
477 if( currentTrack
->artist() )
478 artist
= currentTrack
->artist()->name();
481 //it's an album group, and the current row is the head, so the next row is either Body or End
482 //that means we have to execute the loop at least once
484 int row
= m_currentRow
+ 1;
487 idx
= The::playlistModel()->index( row
++, 0 );
488 Meta::TrackPtr track
= idx
.data( TrackRole
).value
< Meta::TrackPtr
>();
489 if( track
->artist() )
491 if( artist
!= track
->artist()->name() )
499 while( idx
.data( GroupRole
).toInt() == Body
);
506 Playlist::GraphicsItem::boundingRect() const
508 // the viewport()->size() takes scrollbars into account
509 return QRectF( 0.0, 0.0, The::playlistView()->viewport()->size().width(), m_height
);
513 Playlist::GraphicsItem::play()
515 The::playlistModel()->play( m_currentRow
);
519 Playlist::GraphicsItem::mouseDoubleClickEvent( QGraphicsSceneMouseEvent
*event
)
527 QGraphicsItem::mouseDoubleClickEvent( event
);
531 Playlist::GraphicsItem::mousePressEvent( QGraphicsSceneMouseEvent
*event
)
533 if( event
->buttons() & Qt::RightButton
|| !m_items
)
538 m_items
->preDragLocation
= mapToScene( boundingRect() ).boundingRect();
540 //did we hit the collapse / expand button?
542 QRectF
rect( boundingRect().width() - ( 16 + MARGIN
), MARGIN
, 16, 16 );
543 if ( rect
.contains( event
->pos() ) ) {
544 if ( m_groupMode
== Head_Collapsed
)
545 The::playlistModel()->setCollapsed( m_currentRow
, false );
546 else if ( m_groupMode
== Head
)
547 The::playlistModel()->setCollapsed( m_currentRow
, true );
551 QGraphicsItem::mousePressEvent( event
);
554 // With help from QGraphicsView::mouseMoveEvent()
556 Playlist::GraphicsItem::mouseMoveEvent( QGraphicsSceneMouseEvent
*event
)
558 if( (event
->buttons() & Qt::LeftButton
) && ( flags() & QGraphicsItem::ItemIsMovable
) && m_items
)
560 QPointF scenePosition
= event
->scenePos();
562 if( scenePosition
.y() < 0 )
565 bool dragOverOriginalPosition
= m_items
->preDragLocation
.contains( scenePosition
);
567 //make sure item is drawn on top of other items
570 // Determine the list of selected items
571 QList
<QGraphicsItem
*> selectedItems
= scene()->selectedItems();
573 selectedItems
<< this;
574 // Move all selected items
575 foreach( QGraphicsItem
*item
, selectedItems
)
577 if( (item
->flags() & QGraphicsItem::ItemIsMovable
) && (!item
->parentItem() || !item
->parentItem()->isSelected()) )
579 Playlist::GraphicsItem
*above
= 0;
581 if( item
== this && !dragOverOriginalPosition
)
583 diff
= event
->scenePos() - event
->lastScenePos();
584 QList
<QGraphicsItem
*> collisions
= scene()->items( event
->scenePos() );
585 foreach( QGraphicsItem
*i
, collisions
)
587 Playlist::GraphicsItem
*c
= dynamic_cast<Playlist::GraphicsItem
*>( i
);
597 diff
= item
->mapToParent( item
->mapFromScene(event
->scenePos()))
598 - item
->mapToParent(item
->mapFromScene(event
->lastScenePos()));
601 item
->moveBy( 0, diff
.y() );
602 if( item
->flags() & ItemIsSelectable
)
603 item
->setSelected( true );
605 if( dragOverOriginalPosition
)
606 Playlist::DropVis::instance()->show( m_items
->preDragLocation
.y() );
608 Playlist::DropVis::instance()->show( above
);
614 QGraphicsItem::mouseMoveEvent( event
);
619 Playlist::GraphicsItem::dragEnterEvent( QGraphicsSceneDragDropEvent
*event
)
621 foreach( QString mime
, The::playlistModel()->mimeTypes() )
623 if( event
->mimeData()->hasFormat( mime
) )
626 Playlist::DropVis::instance()->show( this );
633 Playlist::GraphicsItem::dropEvent( QGraphicsSceneDragDropEvent
* event
)
637 The::playlistModel()->dropMimeData( event
->mimeData(), Qt::CopyAction
, m_currentRow
, 0, QModelIndex() );
638 Playlist::DropVis::instance()->hide();
642 Playlist::GraphicsItem::refresh()
645 if( !m_items
|| !m_items
->track
)
648 if( m_items
->track
->album() )
649 albumPixmap
= m_items
->track
->album()->image( int( ALBUM_WIDTH
) );
651 //m_items->albumArt->hide();
652 //delete ( m_items->albumArt );
653 //m_items->albumArt = new QGraphicsPixmapItem( albumPixmap, this );
654 //m_items->albumArt->setPos( 0.0, MARGIN );
657 void Playlist::GraphicsItem::mouseReleaseEvent( QGraphicsSceneMouseEvent
*event
)
659 bool dragOverOriginalPosition
= m_items
->preDragLocation
.contains( event
->scenePos() );
660 if( dragOverOriginalPosition
)
662 setPos( m_items
->preDragLocation
.topLeft() );
663 Playlist::DropVis::instance()->hide();
667 Playlist::GraphicsItem
*above
= 0;
668 QList
<QGraphicsItem
*> collisions
= scene()->items( event
->scenePos() );
669 foreach( QGraphicsItem
*i
, collisions
)
671 Playlist::GraphicsItem
*c
= dynamic_cast<Playlist::GraphicsItem
*>( i
);
678 // if we've dropped ourself ontop of another item, then we need to shuffle the tracks below down
681 setPos( above
->pos() );
682 The::playlistView()->moveItem( this, above
);
684 //Don't just drop item into the void, make it the last item!
686 The::playlistView()->moveItem( this, 0 );
687 //setPos( above->pos() );
688 //The::playlistView()->moveItem( this, above );
692 //make sure item resets its z value
694 Playlist::DropVis::instance()->hide();
697 void Playlist::GraphicsItem::setRow(int row
)
702 const QModelIndex index
= The::playlistModel()->index( m_currentRow
, 0 );
704 //figure out our group state and set height accordingly
705 int currentGroupState
= index
.data( GroupRole
).toInt();
707 if ( currentGroupState
!= m_groupMode
) {
709 debug() << "Group changed for row " << row
;
711 prepareGeometryChange();
714 m_groupMode
= currentGroupState
;
715 m_groupModeChanged
= true;
717 switch ( m_groupMode
) {
721 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + 2 * MARGIN
+ 2;
725 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + MARGIN
+ s_fm
->height();
728 debug() << "Collapsed head";
729 m_height
= qMax( ALBUM_WIDTH
, s_fm
->height() * 2 ) + MARGIN
+ s_fm
->height() + 10;
731 const Meta::TrackPtr track
= index
.data( ItemRole
).value
< Playlist::Item
* >()->track();
732 m_items
= new Playlist::GraphicsItem::ActiveItems();
733 m_items
->track
= track
;
736 m_items
->groupedTracks
= index
.data( GroupedTracksRole
).toInt();
740 m_height
= s_fm
->height()/*+ 2 * MARGIN*/;
744 m_height
= s_fm
->height() + 6 /*+ 2 * MARGIN*/;
747 debug() << "Collapsed";
751 debug() << "ERROR!!??";
756 void Playlist::GraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent
* event
)
760 /*if ( m_groupMode == Head_Collapsed )
761 The::playlistModel()->setCollapsed( m_currentRow, false ); */