/src/libtomahawk/playlist/albumview.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 228 lines · 165 code · 44 blank · 19 comment · 21 complexity · ab7eeb4ec18f3f88eedeebbde48d1d4d MD5 · raw file

  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4. *
  5. * Tomahawk is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation, either version 3 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * Tomahawk is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "albumview.h"
  19. #include <QHeaderView>
  20. #include <QKeyEvent>
  21. #include <QPainter>
  22. #include <QScrollBar>
  23. #include <qmath.h>
  24. #include "audio/audioengine.h"
  25. #include "tomahawksettings.h"
  26. #include "artist.h"
  27. #include "albumitem.h"
  28. #include "albumitemdelegate.h"
  29. #include "albummodel.h"
  30. #include "viewmanager.h"
  31. #include "utils/logger.h"
  32. #include "dynamic/widgets/LoadingSpinner.h"
  33. #define SCROLL_TIMEOUT 280
  34. using namespace Tomahawk;
  35. AlbumView::AlbumView( QWidget* parent )
  36. : QListView( parent )
  37. , m_model( 0 )
  38. , m_proxyModel( 0 )
  39. , m_delegate( 0 )
  40. , m_loadingSpinner( new LoadingSpinner( this ) )
  41. , m_overlay( new OverlayWidget( this ) )
  42. , m_inited( false )
  43. {
  44. setDragEnabled( true );
  45. setDropIndicatorShown( false );
  46. setDragDropOverwriteMode( false );
  47. setUniformItemSizes( true );
  48. setSpacing( 16 );
  49. setContentsMargins( 0, 0, 0, 0 );
  50. setMouseTracking( true );
  51. setResizeMode( Adjust );
  52. setViewMode( IconMode );
  53. setVerticalScrollMode( QAbstractItemView::ScrollPerPixel );
  54. setAutoFitItems( true );
  55. setProxyModel( new AlbumProxyModel( this ) );
  56. connect( this, SIGNAL( doubleClicked( QModelIndex ) ), SLOT( onItemActivated( QModelIndex ) ) );
  57. }
  58. AlbumView::~AlbumView()
  59. {
  60. qDebug() << Q_FUNC_INFO;
  61. }
  62. void
  63. AlbumView::setProxyModel( AlbumProxyModel* model )
  64. {
  65. m_proxyModel = model;
  66. m_delegate = new AlbumItemDelegate( this, m_proxyModel );
  67. connect( m_delegate, SIGNAL( updateIndex( QModelIndex ) ), this, SLOT( update( QModelIndex ) ) );
  68. setItemDelegate( m_delegate );
  69. QListView::setModel( m_proxyModel );
  70. }
  71. void
  72. AlbumView::setModel( QAbstractItemModel* model )
  73. {
  74. Q_UNUSED( model );
  75. qDebug() << "Explicitly use setAlbumModel instead";
  76. Q_ASSERT( false );
  77. }
  78. void
  79. AlbumView::setAlbumModel( AlbumModel* model )
  80. {
  81. m_model = model;
  82. if ( m_proxyModel )
  83. {
  84. m_proxyModel->setSourceAlbumModel( m_model );
  85. m_proxyModel->sort( 0 );
  86. }
  87. connect( m_proxyModel, SIGNAL( filterChanged( QString ) ), SLOT( onFilterChanged( QString ) ) );
  88. connect( m_model, SIGNAL( itemCountChanged( unsigned int ) ), SLOT( onItemCountChanged( unsigned int ) ) );
  89. connect( m_model, SIGNAL( loadingStarted() ), m_loadingSpinner, SLOT( fadeIn() ) );
  90. connect( m_model, SIGNAL( loadingFinished() ), m_loadingSpinner, SLOT( fadeOut() ) );
  91. }
  92. void
  93. AlbumView::onItemActivated( const QModelIndex& index )
  94. {
  95. AlbumItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
  96. if ( item )
  97. {
  98. // qDebug() << "Result activated:" << item->album()->tracks().first()->toString() << item->album()->tracks().first()->results().first()->url();
  99. // APP->audioEngine()->playItem( item->album().data(), item->album()->tracks().first()->results().first() );
  100. if ( !item->album().isNull() )
  101. ViewManager::instance()->show( item->album() );
  102. else if ( !item->artist().isNull() )
  103. ViewManager::instance()->show( item->artist() );
  104. }
  105. }
  106. void
  107. AlbumView::onItemCountChanged( unsigned int items )
  108. {
  109. if ( items == 0 )
  110. {
  111. if ( m_model->collection().isNull() || ( !m_model->collection().isNull() && m_model->collection()->source()->isLocal() ) )
  112. m_overlay->setText( tr( "After you have scanned your music collection you will find your latest album additions right here." ) );
  113. else
  114. m_overlay->setText( tr( "This collection doesn't have any recent albums." ) );
  115. m_overlay->show();
  116. }
  117. else
  118. m_overlay->hide();
  119. }
  120. void
  121. AlbumView::paintEvent( QPaintEvent* event )
  122. {
  123. if ( !autoFitItems() || m_inited || !m_proxyModel->rowCount() )
  124. QListView::paintEvent( event );
  125. }
  126. void
  127. AlbumView::resizeEvent( QResizeEvent* event )
  128. {
  129. if ( autoFitItems() )
  130. {
  131. #ifdef Q_WS_X11
  132. int scrollbar = verticalScrollBar()->isVisible() ? verticalScrollBar()->width() : 0;
  133. #else
  134. int scrollbar = verticalScrollBar()->rect().width();
  135. #endif
  136. int rectWidth = contentsRect().width() - scrollbar - 16 - 3;
  137. QSize itemSize = m_proxyModel->data( QModelIndex(), Qt::SizeHintRole ).toSize();
  138. int itemsPerRow = qFloor( rectWidth / ( itemSize.width() + 16 ) );
  139. int rightSpacing = rectWidth - ( itemsPerRow * ( itemSize.width() + 16 ) );
  140. int newSpacing = 16 + floor( rightSpacing / ( itemsPerRow + 1 ) );
  141. if ( itemsPerRow < 1 )
  142. setSpacing( 16 );
  143. else
  144. setSpacing( newSpacing );
  145. if ( !m_inited )
  146. {
  147. m_inited = true;
  148. repaint();
  149. }
  150. }
  151. QListView::resizeEvent( event );
  152. }
  153. void
  154. AlbumView::onFilterChanged( const QString& )
  155. {
  156. if ( selectedIndexes().count() )
  157. scrollTo( selectedIndexes().at( 0 ), QAbstractItemView::PositionAtCenter );
  158. }
  159. void
  160. AlbumView::startDrag( Qt::DropActions supportedActions )
  161. {
  162. QList<QPersistentModelIndex> pindexes;
  163. QModelIndexList indexes;
  164. foreach( const QModelIndex& idx, selectedIndexes() )
  165. {
  166. if ( ( m_proxyModel->flags( idx ) & Qt::ItemIsDragEnabled ) )
  167. {
  168. indexes << idx;
  169. pindexes << idx;
  170. }
  171. }
  172. if ( indexes.count() == 0 )
  173. return;
  174. qDebug() << "Dragging" << indexes.count() << "indexes";
  175. QMimeData* data = m_proxyModel->mimeData( indexes );
  176. if ( !data )
  177. return;
  178. QDrag* drag = new QDrag( this );
  179. drag->setMimeData( data );
  180. const QPixmap p = TomahawkUtils::createDragPixmap( TomahawkUtils::MediaTypeAlbum, indexes.count() );
  181. drag->setPixmap( p );
  182. drag->setHotSpot( QPoint( -20, -20 ) );
  183. /* Qt::DropAction action = */ drag->exec( supportedActions, Qt::CopyAction );
  184. }