PageRenderTime 643ms CodeModel.GetById 100ms app.highlight 462ms RepoModel.GetById 63ms app.codeStats 1ms

/src/libtomahawk/widgets/QueryLabel.cpp

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