/src/libtomahawk/widgets/QueryLabel.cpp

http://github.com/tomahawk-player/tomahawk · C++ · 507 lines · 387 code · 100 blank · 20 comment · 47 complexity · 48dc1adf65199889f7d4a3aef362c089 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 "QueryLabel.h"
  19. #include "Artist.h"
  20. #include "Album.h"
  21. #include "Query.h"
  22. #include "ContextMenu.h"
  23. #include "utils/TomahawkStyle.h"
  24. #include "utils/TomahawkUtilsGui.h"
  25. #include "utils/Logger.h"
  26. #include "ViewManager.h"
  27. #include "Source.h"
  28. #include <QApplication>
  29. #include <QEvent>
  30. #include <QFontMetrics>
  31. #include <QMouseEvent>
  32. #include <QPainter>
  33. #include <QDrag>
  34. #include <QMimeData>
  35. using namespace Tomahawk;
  36. QueryLabel::QueryLabel( QWidget* parent, Qt::WindowFlags flags )
  37. : QLabel( parent, flags )
  38. , m_type( None )
  39. {
  40. init();
  41. }
  42. QueryLabel::QueryLabel( DisplayType type, QWidget* parent, Qt::WindowFlags flags )
  43. : QLabel( parent, flags )
  44. , m_type( type )
  45. {
  46. init();
  47. }
  48. QueryLabel::QueryLabel( const Tomahawk::result_ptr& result, DisplayType type, QWidget* parent, Qt::WindowFlags flags )
  49. : QLabel( parent, flags )
  50. , m_type( type )
  51. , m_result( result )
  52. {
  53. init();
  54. }
  55. QueryLabel::QueryLabel( const Tomahawk::query_ptr& query, DisplayType type, QWidget* parent, Qt::WindowFlags flags )
  56. : QLabel( parent, flags )
  57. , m_type( type )
  58. , m_query( query )
  59. {
  60. init();
  61. }
  62. QueryLabel::~QueryLabel()
  63. {
  64. }
  65. void
  66. QueryLabel::init()
  67. {
  68. m_contextMenu = new ContextMenu( this );
  69. m_contextMenu->setSupportedActions( ContextMenu::ActionQueue | ContextMenu::ActionCopyLink | ContextMenu::ActionStopAfter | ContextMenu::ActionLove | ContextMenu::ActionPage );
  70. setMouseTracking( true );
  71. setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
  72. m_mode = Qt::ElideRight;
  73. m_hovering = false;
  74. }
  75. QString
  76. QueryLabel::text() const
  77. {
  78. if ( !m_result && !m_query && !m_artist && !m_album )
  79. return m_text;
  80. if ( m_type & Artist && artist() )
  81. {
  82. return artist()->name();
  83. }
  84. else if ( m_type & Album && album() )
  85. {
  86. return album()->name();
  87. }
  88. else if ( m_type & Track && query() )
  89. {
  90. return query()->track()->track();
  91. }
  92. return QString();
  93. }
  94. void
  95. QueryLabel::setText( const QString& text )
  96. {
  97. clear();
  98. QLabel::setText( m_text );
  99. m_text = text;
  100. updateGeometry();
  101. update();
  102. emit textChanged( m_text );
  103. emit resultChanged( m_result );
  104. }
  105. void
  106. QueryLabel::clear()
  107. {
  108. m_text.clear();
  109. m_result.clear();
  110. m_query.clear();
  111. m_artist.clear();
  112. m_album.clear();
  113. QLabel::clear();
  114. }
  115. void
  116. QueryLabel::onResultChanged()
  117. {
  118. m_query = m_result->toQuery();
  119. m_artist = m_result->track()->artistPtr();
  120. m_album = m_result->track()->albumPtr();
  121. updateGeometry();
  122. update();
  123. emit textChanged( text() );
  124. }
  125. void
  126. QueryLabel::setResult( const Tomahawk::result_ptr& result )
  127. {
  128. if ( !result )
  129. return;
  130. if ( !m_result || m_result.data() != result.data() )
  131. {
  132. m_result = result;
  133. connect( m_result.data(), SIGNAL( updated() ), SLOT( onResultChanged() ) );
  134. onResultChanged();
  135. emit resultChanged( m_result );
  136. }
  137. }
  138. void
  139. QueryLabel::setQuery( const Tomahawk::query_ptr& query )
  140. {
  141. if ( !query )
  142. return;
  143. if ( !m_query || m_query.data() != query.data() )
  144. {
  145. m_query = query;
  146. m_artist = Artist::get( query->track()->artist() );
  147. m_album = Album::get( m_artist, query->track()->album() );
  148. m_result.clear();
  149. updateGeometry();
  150. update();
  151. emit textChanged( text() );
  152. emit queryChanged( m_query );
  153. }
  154. }
  155. void
  156. QueryLabel::setArtist( const artist_ptr& artist )
  157. {
  158. m_artist = artist;
  159. updateGeometry();
  160. update();
  161. emit textChanged( text() );
  162. }
  163. void
  164. QueryLabel::setAlbum( const album_ptr& album )
  165. {
  166. m_album = album;
  167. updateGeometry();
  168. update();
  169. emit textChanged( text() );
  170. }
  171. Qt::TextElideMode
  172. QueryLabel::elideMode() const
  173. {
  174. return m_mode;
  175. }
  176. void
  177. QueryLabel::setElideMode( Qt::TextElideMode mode )
  178. {
  179. if ( m_mode != mode )
  180. {
  181. m_mode = mode;
  182. updateGeometry();
  183. update();
  184. }
  185. }
  186. QSize
  187. QueryLabel::sizeHint() const
  188. {
  189. const QFontMetrics& fm = fontMetrics();
  190. QSize size( fm.width( text() ) + contentsMargins().left() + contentsMargins().right(),
  191. fm.height() + contentsMargins().top() + contentsMargins().bottom() );
  192. return size;
  193. }
  194. QSize
  195. QueryLabel::minimumSizeHint() const
  196. {
  197. switch ( m_mode )
  198. {
  199. case Qt::ElideNone:
  200. return sizeHint();
  201. default:
  202. {
  203. const QFontMetrics& fm = fontMetrics();
  204. QSize size( fm.width( "..." ), fm.height() + contentsMargins().top() + contentsMargins().bottom() );
  205. return size;
  206. }
  207. }
  208. }
  209. void
  210. QueryLabel::paintEvent( QPaintEvent* /* event */ )
  211. {
  212. QPainter p( this );
  213. p.setRenderHint( QPainter::TextAntialiasing );
  214. QRect r = contentsRect();
  215. if ( m_hovering )
  216. {
  217. QFont f = p.font();
  218. f.setUnderline( true );
  219. p.setFont( f );
  220. }
  221. const QFontMetrics fm( p.font() );
  222. p.drawText( r, alignment(), fm.elidedText( text(), m_mode, r.width() ) );
  223. }
  224. void
  225. QueryLabel::changeEvent( QEvent* event )
  226. {
  227. QLabel::changeEvent( event );
  228. switch ( event->type() )
  229. {
  230. case QEvent::FontChange:
  231. case QEvent::ApplicationFontChange:
  232. updateGeometry();
  233. update();
  234. break;
  235. default:
  236. break;
  237. }
  238. }
  239. void
  240. QueryLabel::contextMenuEvent( QContextMenuEvent* event )
  241. {
  242. m_contextMenu->clear();
  243. switch( m_type )
  244. {
  245. case Artist:
  246. {
  247. m_contextMenu->setArtist( artist() );
  248. break;
  249. }
  250. case Album:
  251. {
  252. m_contextMenu->setAlbum( album() );
  253. break;
  254. }
  255. default:
  256. m_contextMenu->setQuery( m_query );
  257. }
  258. m_contextMenu->exec( event->globalPos() );
  259. }
  260. void
  261. QueryLabel::mousePressEvent( QMouseEvent* event )
  262. {
  263. QLabel::mousePressEvent( event );
  264. m_time.restart();
  265. m_dragPos = event->pos();
  266. }
  267. void
  268. QueryLabel::mouseReleaseEvent( QMouseEvent* event )
  269. {
  270. QLabel::mouseReleaseEvent( event );
  271. m_dragPos = QPoint();
  272. if ( m_time.elapsed() < qApp->doubleClickInterval() )
  273. {
  274. switch ( m_type )
  275. {
  276. case Artist:
  277. {
  278. ViewManager::instance()->show( artist() );
  279. break;
  280. }
  281. case Album:
  282. {
  283. ViewManager::instance()->show( album() );
  284. break;
  285. }
  286. default:
  287. emit clicked();
  288. // ViewManager::instance()->show( m_query );
  289. }
  290. }
  291. }
  292. void
  293. QueryLabel::mouseMoveEvent( QMouseEvent* event )
  294. {
  295. QLabel::mouseMoveEvent( event );
  296. if ( event->buttons() & Qt::LeftButton &&
  297. ( m_dragPos - event->pos() ).manhattanLength() >= QApplication::startDragDistance() )
  298. {
  299. startDrag();
  300. leaveEvent( 0 );
  301. return;
  302. }
  303. if ( !m_hovering )
  304. {
  305. m_hovering = true;
  306. setCursor( Qt::PointingHandCursor );
  307. repaint();
  308. }
  309. }
  310. void
  311. QueryLabel::leaveEvent( QEvent* event )
  312. {
  313. QLabel::leaveEvent( event );
  314. m_hovering = false;
  315. repaint();
  316. }
  317. void
  318. QueryLabel::startDrag()
  319. {
  320. QDrag* drag = new QDrag( this );
  321. QByteArray data;
  322. QDataStream dataStream( &data, QIODevice::WriteOnly );
  323. QMimeData* mimeData = new QMimeData();
  324. mimeData->setText( text() );
  325. bool failed = false;
  326. switch( m_type )
  327. {
  328. case Artist:
  329. {
  330. if ( !artist() )
  331. {
  332. failed = true;
  333. break;
  334. }
  335. dataStream << artist()->name();
  336. mimeData->setData( "application/tomahawk.metadata.artist", data );
  337. drag->setPixmap( TomahawkUtils::createDragPixmap( TomahawkUtils::MediaTypeArtist ) );
  338. break;
  339. }
  340. case Album:
  341. {
  342. if ( !album() )
  343. {
  344. failed = true;
  345. break;
  346. }
  347. dataStream << artist()->name();
  348. dataStream << album()->name();
  349. mimeData->setData( "application/tomahawk.metadata.album", data );
  350. drag->setPixmap( TomahawkUtils::createDragPixmap( TomahawkUtils::MediaTypeAlbum ) );
  351. break;
  352. }
  353. default:
  354. {
  355. if ( !query() )
  356. {
  357. failed = true;
  358. break;
  359. }
  360. dataStream << qlonglong( &m_query );
  361. mimeData->setData( "application/tomahawk.query.list", data );
  362. drag->setPixmap( TomahawkUtils::createDragPixmap( TomahawkUtils::MediaTypeTrack ) );
  363. break;
  364. }
  365. }
  366. if ( failed )
  367. {
  368. delete mimeData;
  369. delete drag;
  370. return;
  371. }
  372. // QPoint hotSpot = event->pos() - child->pos();
  373. // drag->setHotSpot( hotSpot );
  374. drag->setMimeData( mimeData );
  375. drag->exec( Qt::CopyAction );
  376. }
  377. void
  378. QueryLabel::setType( DisplayType type )
  379. {
  380. m_type = type;
  381. updateGeometry();
  382. update();
  383. }
  384. Tomahawk::artist_ptr
  385. QueryLabel::artist() const
  386. {
  387. if ( m_artist )
  388. return m_artist;
  389. else if ( m_album )
  390. return m_album->artist();
  391. else if ( m_result )
  392. return m_result->track()->artistPtr();
  393. else if ( m_query )
  394. return m_query->track()->artistPtr();
  395. return artist_ptr();
  396. }
  397. Tomahawk::album_ptr
  398. QueryLabel::album() const
  399. {
  400. if ( m_album )
  401. return m_album;
  402. else if ( m_result )
  403. return m_result->track()->albumPtr();
  404. else if ( m_query )
  405. return m_query->track()->albumPtr();
  406. return album_ptr();
  407. }