PageRenderTime 51ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/src/libtomahawk/widgets/DownloadButton.cpp

http://github.com/tomahawk-player/tomahawk
C++ | 282 lines | 207 code | 51 blank | 24 comment | 42 complexity | c9da9edf386e571ab23a6c8f8cb7b582 MD5 | raw file
Possible License(s): LGPL-2.1, BSD-3-Clause, GPL-3.0, GPL-2.0
  1. /* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
  2. *
  3. * Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
  4. * Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
  5. *
  6. * Tomahawk is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Tomahawk is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
  18. */
  19. #include "DownloadButton.h"
  20. #include "Artist.h"
  21. #include "Album.h"
  22. #include "Result.h"
  23. #include "DownloadManager.h"
  24. #include "utils/TomahawkStyle.h"
  25. #include "utils/WebPopup.h"
  26. #include "utils/Logger.h"
  27. #include <QPainter>
  28. #include <QEvent>
  29. #include <QAbstractItemView>
  30. #include <QDesktopServices>
  31. using namespace Tomahawk;
  32. DownloadButton::DownloadButton( const Tomahawk::query_ptr& query, QWidget* parent, QAbstractItemView* view, const QModelIndex& index )
  33. : DropDownButton( parent )
  34. , m_view( view )
  35. , m_index( index )
  36. {
  37. init();
  38. setQuery( query );
  39. }
  40. DownloadButton::DownloadButton( QWidget* parent )
  41. : DropDownButton( parent )
  42. {
  43. init();
  44. }
  45. void
  46. DownloadButton::init()
  47. {
  48. connect( this, SIGNAL( clicked() ), this, SLOT( addDownloadJob() ) );
  49. connect( this, SIGNAL( activated( int ) ), this, SLOT( addDownloadJob() ) );
  50. }
  51. DownloadButton::~DownloadButton()
  52. {
  53. }
  54. void
  55. DownloadButton::setQuery( const query_ptr& query )
  56. {
  57. if ( !m_query.isNull() )
  58. {
  59. m_query->disconnect( this );
  60. }
  61. if ( !m_result.isNull() )
  62. {
  63. m_result->disconnect( this );
  64. }
  65. clear();
  66. m_result.clear();
  67. m_query = query;
  68. if ( query.isNull() )
  69. return;
  70. Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
  71. if ( result.isNull() )
  72. return;
  73. QStringList formats;
  74. foreach ( const DownloadFormat& format, result->downloadFormats() )
  75. {
  76. formats << QObject::tr( "Download %1" ).arg( format.extension.toUpper() );
  77. }
  78. addItems( formats );
  79. }
  80. void
  81. DownloadButton::addDownloadJob()
  82. {
  83. if ( m_query.isNull() )
  84. return;
  85. Tomahawk::result_ptr result = m_query->numResults( true ) ? m_query->results().first() : Tomahawk::result_ptr();
  86. if ( result.isNull() )
  87. return;
  88. if ( handleClickPreDownload( m_query ) )
  89. return;
  90. if ( !result->downloadFormats().isEmpty() )
  91. {
  92. if ( m_view && m_index.isValid() )
  93. {
  94. m_view->closePersistentEditor( m_index );
  95. }
  96. else
  97. {
  98. m_result = result;
  99. connect( result.data(), SIGNAL( updated() ), SLOT( update() ) );
  100. connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( update() ) );
  101. }
  102. DownloadManager::instance()->addJob( result->toDownloadJob( result->downloadFormats().at( currentIndex() ) ) );
  103. }
  104. else
  105. {
  106. handleClickPostDownload( m_query );
  107. }
  108. }
  109. void
  110. DownloadButton::paintEvent( QPaintEvent* event )
  111. {
  112. QPainter p( this );
  113. setupPainter( &p );
  114. if ( DownloadButton::drawPrimitive( &p, contentsRect(), m_query, m_hovering ) )
  115. setCursor( Qt::PointingHandCursor );
  116. else
  117. setCursor( Qt::ArrowCursor );
  118. }
  119. bool
  120. DownloadButton::drawPrimitive( QPainter* painter, const QRect& rect, const Tomahawk::query_ptr& query, bool hovering )
  121. {
  122. if ( query.isNull() )
  123. return false;
  124. Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
  125. if ( result.isNull() )
  126. return false;
  127. if ( result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
  128. {
  129. // if downloadJob exists and is not finished, paint a progress bar
  130. painter->save();
  131. painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
  132. painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
  133. painter->drawRect( rect.adjusted( 2, 2, -2, -2 ) );
  134. painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
  135. painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
  136. QRect fillp = rect.adjusted( 3, 3, -3, -3 );
  137. fillp.setWidth( float(fillp.width()) * ( float( result->downloadJob()->progressPercentage() ) / 100.0 ) );
  138. painter->drawRect( fillp );
  139. painter->restore();
  140. }
  141. else
  142. {
  143. QString text;
  144. bool itemsAvailable = false;
  145. if ( result &&
  146. ( ( !result->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() ) ||
  147. ( result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished ) ) )
  148. {
  149. text = QObject::tr( "View in Finder" );
  150. }
  151. else if ( !result->downloadFormats().isEmpty() )
  152. {
  153. text = tr( "Download %1" ).arg( query->results().first()->downloadFormats().first().extension.toUpper() );
  154. itemsAvailable = true;
  155. }
  156. else if ( !result->purchaseUrl().isEmpty() )
  157. {
  158. text = tr( "Buy" );
  159. }
  160. if ( !text.isEmpty() )
  161. DropDownButton::drawPrimitive( painter, rect, text, hovering, itemsAvailable );
  162. else
  163. {
  164. // this result can neither be bought nor downloaded
  165. return false;
  166. }
  167. }
  168. return true;
  169. }
  170. bool
  171. DownloadButton::handleEditorEvent(QEvent* event , QAbstractItemView* view, PlayableProxyModel* model, const QModelIndex& index)
  172. {
  173. if ( event->type() == QEvent::MouseButtonRelease )
  174. {
  175. PlayableItem* item = model->sourceModel()->itemFromIndex( model->mapToSource( index ) );
  176. if ( !item && ! item->query() )
  177. return false;
  178. if ( handleClickPreDownload( item->query() ) )
  179. return true;
  180. if( item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
  181. {
  182. model->sourceModel()->setAllColumnsEditable( true );
  183. view->edit( index );
  184. model->sourceModel()->setAllColumnsEditable( false );
  185. return true;
  186. }
  187. return handleClickPostDownload( item->query() );
  188. }
  189. return false;
  190. }
  191. bool
  192. DownloadButton::handleClickPreDownload( const Tomahawk::query_ptr& query )
  193. {
  194. // view in folder
  195. if ( !DownloadManager::instance()->localUrlForDownload( query ).isEmpty() )
  196. {
  197. QDesktopServices::openUrl( DownloadManager::instance()->localUrlForDownload( query ) );
  198. return true;
  199. }
  200. // download in progress
  201. Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
  202. if ( result && result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
  203. {
  204. // do nothing, handled
  205. return true;
  206. }
  207. return false;
  208. }
  209. bool
  210. DownloadButton::handleClickPostDownload( const Tomahawk::query_ptr& query )
  211. {
  212. // handle buy click
  213. Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
  214. if ( result && !result->purchaseUrl().isEmpty() )
  215. {
  216. WebPopup* popup = new WebPopup( result->purchaseUrl(), QSize( 400, 800 ) );
  217. connect( result.data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
  218. return true;
  219. }
  220. return false;
  221. }
  222. QWidget*
  223. DownloadButton::handleCreateEditor( QWidget* parent, const query_ptr& query, QAbstractItemView* view, const QModelIndex& index )
  224. {
  225. Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
  226. if ( result && !result->downloadFormats().isEmpty() && !result->downloadJob() )
  227. {
  228. return new DownloadButton( query, parent, view, index );
  229. }
  230. return 0;
  231. }