1
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
3
* Copyright 2010-2011, Christian Muehlhaeuser <muesli@tomahawk-player.org>
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.
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.
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/>.
19
#include "QueryLabel.h"
21
#include <QApplication>
23
#include <QFontMetrics>
24
#include <QMouseEvent>
30
#include "ContextMenu.h"
31
#include "utils/TomahawkUtilsGui.h"
32
#include "utils/Logger.h"
33
#include "ViewManager.h"
39
using namespace Tomahawk;
42
QueryLabel::QueryLabel( QWidget* parent, Qt::WindowFlags flags )
43
: QFrame( parent, flags )
50
QueryLabel::QueryLabel( DisplayType type, QWidget* parent, Qt::WindowFlags flags )
51
: QFrame( parent, flags )
58
QueryLabel::QueryLabel( const Tomahawk::result_ptr& result, DisplayType type, QWidget* parent, Qt::WindowFlags flags )
59
: QFrame( parent, flags )
67
QueryLabel::QueryLabel( const Tomahawk::query_ptr& query, DisplayType type, QWidget* parent, Qt::WindowFlags flags )
68
: QFrame( parent, flags )
76
QueryLabel::~QueryLabel()
84
m_contextMenu = new ContextMenu( this );
85
m_contextMenu->setSupportedActions( ContextMenu::ActionQueue | ContextMenu::ActionCopyLink | ContextMenu::ActionStopAfter | ContextMenu::ActionLove | ContextMenu::ActionPage );
88
setContentsMargins( 0, 0, 0, 0 );
89
setMouseTracking( true );
91
m_useCustomPen = false;
92
m_align = Qt::AlignLeft | Qt::AlignVCenter;
93
m_mode = Qt::ElideMiddle;
95
m_jumpLinkVisible = false;
100
QueryLabel::text() const
104
if ( m_result.isNull() && m_query.isNull() && m_artist.isNull() && m_album.isNull() )
107
if ( !m_result.isNull() )
109
if ( m_type & Artist )
111
text += m_result->artist()->name();
113
if ( m_type & Album && !m_result->album()->name().isEmpty() )
115
smartAppend( text, m_result->album()->name() );
117
if ( m_type & Track )
119
smartAppend( text, m_result->track() );
122
else if ( !m_query.isNull() )
124
if ( m_type & Artist )
126
text += m_query->artist();
128
if ( m_type & Album && !m_query->album().isEmpty() )
130
smartAppend( text, m_query->album() );
132
if ( m_type & Track )
134
smartAppend( text, m_query->track() );
137
else if ( !m_artist.isNull() )
139
text += m_artist->name();
141
else if ( !m_album.isNull() )
143
text += m_album->name();
151
QueryLabel::track() const
153
if ( m_result.isNull() && m_query.isNull() )
156
if ( !m_result.isNull() )
157
return m_result->track();
159
return m_query->track();
164
QueryLabel::setText( const QString& text )
166
setContentsMargins( m_textMargins );
176
emit textChanged( m_text );
177
emit resultChanged( m_result );
182
QueryLabel::onResultChanged()
184
m_query = m_result->toQuery();
185
m_artist = m_result->artist();
186
m_album = m_result->album();
190
emit textChanged( text() );
195
QueryLabel::setResult( const Tomahawk::result_ptr& result )
197
if ( result.isNull() )
200
if ( !m_text.isEmpty() && contentsMargins().left() != 0 ) // FIXME: hacky
201
m_textMargins = contentsMargins();
203
setContentsMargins( BOXMARGIN * 2, BOXMARGIN / 2, BOXMARGIN * 2, BOXMARGIN / 2);
205
if ( m_result.isNull() || m_result.data() != result.data() )
208
connect( m_result.data(), SIGNAL( updated() ), SLOT( onResultChanged() ) );
211
emit resultChanged( m_result );
217
QueryLabel::setQuery( const Tomahawk::query_ptr& query )
219
if ( query.isNull() )
222
setContentsMargins( BOXMARGIN * 2, BOXMARGIN / 2, BOXMARGIN * 2, BOXMARGIN / 2 );
224
if ( m_query.isNull() || m_query.data() != query.data() )
227
m_artist = Artist::get( query->artist() );
228
m_album = Album::get( m_artist, query->album() );
233
emit textChanged( text() );
234
emit queryChanged( m_query );
240
QueryLabel::setArtist( const artist_ptr& artist )
245
emit textChanged( text() );
250
QueryLabel::setAlbum( const album_ptr& album )
255
emit textChanged( text() );
260
QueryLabel::setJumpLinkVisible( bool visible )
262
m_jumpLinkVisible = visible;
268
QueryLabel::alignment() const
275
QueryLabel::setAlignment( Qt::Alignment alignment )
277
if ( m_align != alignment )
280
update(); // no geometry change, repaint is sufficient
286
QueryLabel::setTextPen( const QPen & pen )
288
m_useCustomPen = true;
294
QueryLabel::textPen() const
301
QueryLabel::elideMode() const
308
QueryLabel::setElideMode( Qt::TextElideMode mode )
310
if ( m_mode != mode )
319
QueryLabel::updateLabel()
321
m_hoverArea = QRect();
330
QueryLabel::setExtraContentsMargins( int left, int top, int right, int bottom )
332
QMargins margins = contentsMargins();
333
margins.setLeft( margins.left() + left );
334
margins.setTop( margins.top() + top );
335
margins.setRight( margins.right() + right );
336
margins.setBottom( margins.bottom() + bottom );
337
setContentsMargins( margins );
342
QueryLabel::sizeHint() const
344
const QFontMetrics& fm = fontMetrics();
345
QSize size( fm.width( text() ) + contentsMargins().left() * 2, fm.height() + contentsMargins().top() * 2 );
351
QueryLabel::minimumSizeHint() const
360
const QFontMetrics& fm = fontMetrics();
361
QSize size( fm.width( "..." ), fm.height() + contentsMargins().top() * 2 );
369
QueryLabel::paintEvent( QPaintEvent* event )
371
QFrame::paintEvent( event );
373
QRect r = contentsRect();
375
const QFontMetrics& fm = fontMetrics();
376
const QString elidedText = fm.elidedText( s, m_mode, r.width() );
379
p.setRenderHint( QPainter::Antialiasing );
381
if ( m_hoverArea.width() )
383
if ( elidedText != s )
385
m_hoverArea.setLeft( 0 );
386
m_hoverArea.setRight( fm.width( elidedText ) + contentsMargins().left() * 2 );
390
TomahawkUtils::drawQueryBackground( &p, m_hoverArea );
393
if ( elidedText != s || ( m_result.isNull() && m_query.isNull() && m_artist.isNull() && m_album.isNull() ) )
395
if ( m_hoverArea.width() )
397
p.setBrush( TomahawkUtils::Colors::SELECTION_BACKGROUND );
398
p.setPen( TomahawkUtils::Colors::SELECTION_FOREGROUND );
402
p.setBrush( palette().window() );
403
p.setPen( palette().color( foregroundRole() ) );
406
p.drawText( r, m_align, elidedText );
410
int dashX = fm.width( DASH );
411
int artistX = m_type & Artist ? fm.width( artist()->name() ) : 0;
412
int albumX = m_type & Album ? fm.width( album()->name() ) : 0;
413
int trackX = m_type & Track ? fm.width( track() ) : 0;
415
if ( m_useCustomPen )
416
p.setPen( m_textPen );
418
if ( m_type & Artist )
420
p.setBrush( palette().window() );
421
if ( !m_useCustomPen )
422
p.setPen( palette().color( foregroundRole() ) );
424
if ( m_hoverType == Artist )
426
p.setPen( palette().highlightedText().color() );
427
p.setBrush( palette().highlight() );
430
p.drawText( r, m_align, artist()->name() );
431
r.adjust( artistX, 0, 0, 0 );
433
if ( m_type & Album && !album()->name().isEmpty() )
435
p.setBrush( palette().window() );
436
if ( !m_useCustomPen )
437
p.setPen( palette().color( foregroundRole() ) );
439
if ( m_type & Artist )
441
p.drawText( r, m_align, DASH );
442
r.adjust( dashX, 0, 0, 0 );
444
if ( m_hoverType == Album )
446
p.setPen( palette().highlightedText().color() );
447
p.setBrush( palette().highlight() );
450
p.drawText( r, m_align, album()->name() );
451
r.adjust( albumX, 0, 0, 0 );
453
if ( m_type & Track )
455
p.setBrush( palette().window() );
456
if ( !m_useCustomPen )
457
p.setPen( palette().color( foregroundRole() ) );
459
if ( m_type & Artist || ( m_type & Album && !album()->name().isEmpty() ) )
461
p.drawText( r, m_align, DASH );
462
r.adjust( dashX, 0, 0, 0 );
464
if ( m_hoverType == Track )
466
p.setPen( palette().highlightedText().color() );
467
p.setBrush( palette().highlight() );
470
p.drawText( r, m_align, track() );
471
r.adjust( trackX, 0, 0, 0 );
474
if ( m_jumpLinkVisible )
476
r.adjust( 6, 0, 0, 0 );
477
r.setWidth( r.height() );
478
p.drawPixmap( r, TomahawkUtils::defaultPixmap( TomahawkUtils::JumpLink, TomahawkUtils::Original, r.size() ) );
487
QueryLabel::changeEvent( QEvent* event )
489
QFrame::changeEvent( event );
490
switch ( event->type() )
492
case QEvent::FontChange:
493
case QEvent::ApplicationFontChange:
504
QueryLabel::contextMenuEvent( QContextMenuEvent* event )
506
m_contextMenu->clear();
508
switch( m_hoverType )
512
m_contextMenu->setArtist( artist() );
517
m_contextMenu->setAlbum( album() );
522
m_contextMenu->setQuery( m_query );
525
m_contextMenu->exec( event->globalPos() );
530
QueryLabel::mousePressEvent( QMouseEvent* event )
532
QFrame::mousePressEvent( event );
534
m_dragPos = event->pos();
539
QueryLabel::mouseReleaseEvent( QMouseEvent* event )
541
QFrame::mouseReleaseEvent( event );
543
m_dragPos = QPoint();
544
if ( m_time.elapsed() < qApp->doubleClickInterval() )
546
switch( m_hoverType )
549
emit clickedArtist();
559
ViewManager::instance()->showCurrentTrack();
570
QueryLabel::mouseMoveEvent( QMouseEvent* event )
572
QFrame::mouseMoveEvent( event );
575
if ( event->buttons() & Qt::LeftButton &&
576
( m_dragPos - event->pos() ).manhattanLength() >= QApplication::startDragDistance() )
583
if ( m_query.isNull() && m_result.isNull() && m_artist.isNull() && m_album.isNull() )
585
m_hoverArea = QRect();
590
QFontMetrics fm = fontMetrics();
592
int dashX = fm.width( DASH );
593
int artistX = m_type & Artist ? fm.width( artist()->name() ) : 0;
594
int albumX = m_type & Album ? fm.width( album()->name() ) : 0;
595
int trackX = m_type & Track ? fm.width( track() ) : 0;
597
if ( m_type & Track )
599
trackX += contentsMargins().left();
601
if ( m_type & Album && !album()->name().isEmpty() )
603
trackX += albumX + dashX;
604
albumX += contentsMargins().left();
606
if ( m_type & Artist )
608
albumX += artistX + dashX;
609
trackX += artistX + dashX;
610
artistX += contentsMargins().left();
616
if ( m_align & Qt::AlignLeft )
618
if ( m_type & Artist && x < artistX )
620
m_hoverType = Artist;
621
hoverArea.setLeft( 0 );
622
hoverArea.setRight( artistX + contentsMargins().left() - 1 );
624
else if ( m_type & Album && !album()->name().isEmpty() && x < albumX && x > artistX )
627
int spacing = ( m_type & Artist ) ? dashX : 0;
628
hoverArea.setLeft( artistX + spacing - contentsMargins().left() );
629
hoverArea.setRight( albumX + contentsMargins().left() - 1 );
631
else if ( m_type & Track && x < trackX && x > albumX )
634
int spacing = ( m_type & Album && !album()->name().isEmpty() ) ? dashX : 0;
635
hoverArea.setLeft( albumX + spacing );
636
hoverArea.setRight( trackX + contentsMargins().left() - 1 );
638
else if ( m_jumpLinkVisible && x < trackX + 6 + fm.height() && x > trackX + 6 )
640
m_hoverType = Complete;
645
hoverArea.setLeft( 0 );
646
hoverArea.setRight( width() - 1 );
648
if ( m_type & Artist )
649
m_hoverType = Artist;
650
else if ( m_type & Album )
652
else if ( m_type & Track )
656
if ( hoverArea.width() )
659
hoverArea.setHeight( height() - 2 );
662
if ( m_hoverType != None )
663
setCursor( Qt::PointingHandCursor );
665
setCursor( Qt::ArrowCursor );
667
if ( hoverArea != m_hoverArea )
669
m_hoverArea = hoverArea;
676
QueryLabel::leaveEvent( QEvent* event )
679
m_hoverArea = QRect();
686
QueryLabel::startDrag()
688
if ( m_query.isNull() && m_album.isNull() && m_artist.isNull() )
691
QDrag *drag = new QDrag( this );
693
QDataStream dataStream( &data, QIODevice::WriteOnly );
694
QMimeData* mimeData = new QMimeData();
695
mimeData->setText( text() );
697
switch( m_hoverType )
701
dataStream << artist()->name();
702
mimeData->setData( "application/tomahawk.metadata.artist", data );
703
drag->setPixmap( TomahawkUtils::createDragPixmap( TomahawkUtils::MediaTypeArtist ) );
708
dataStream << artist()->name();
709
dataStream << album()->name();
710
mimeData->setData( "application/tomahawk.metadata.album", data );
711
drag->setPixmap( TomahawkUtils::createDragPixmap( TomahawkUtils::MediaTypeAlbum ) );
717
dataStream << qlonglong( &m_query );
718
mimeData->setData( "application/tomahawk.query.list", data );
719
drag->setPixmap( TomahawkUtils::createDragPixmap( TomahawkUtils::MediaTypeTrack ) );
724
drag->setMimeData( mimeData );
726
// QPoint hotSpot = event->pos() - child->pos();
727
// drag->setHotSpot( hotSpot );
729
drag->exec( Qt::CopyAction );
734
QueryLabel::smartAppend( QString& text, const QString& appendage ) const
737
if ( !text.isEmpty() )
740
text += s + appendage;