From f539551068b2fb12a564d242f08795f68dd02e47 Mon Sep 17 00:00:00 2001 From: Teo Mrnjavac Date: Thu, 26 Sep 2013 14:54:47 +0200 Subject: [PATCH] Add SentBox (like LoveBox) to Inbox --- src/libtomahawk/Track.cpp | 6 +- src/libtomahawk/Track.h | 4 +- src/libtomahawk/TrackData.cpp | 44 ++++--- src/libtomahawk/TrackData.h | 2 +- .../playlist/PlaylistItemDelegate.cpp | 110 +++++++++++++++++- .../playlist/PlaylistItemDelegate.h | 4 + .../playlist/PlaylistLargeItemDelegate.cpp | 33 +----- .../playlist/PlaylistLargeItemDelegate.h | 2 - 8 files changed, 150 insertions(+), 55 deletions(-) diff --git a/src/libtomahawk/Track.cpp b/src/libtomahawk/Track.cpp index 8a735f948..d55457ccc 100644 --- a/src/libtomahawk/Track.cpp +++ b/src/libtomahawk/Track.cpp @@ -570,11 +570,11 @@ Track::socialActionDescription( const QString& action, DescriptionMode mode ) co } -QList< Tomahawk::source_ptr > -Track::sourcesWithSocialAction( const QString& action, const QVariant& value, bool filterDupeNames ) +QList< Tomahawk::SocialAction > +Track::socialActions( const QString& actionName, const QVariant& value, bool filterDupeSourceNames ) { Q_D( Track ); - return d->trackData->sourcesWithSocialAction( action, value, filterDupeNames ); + return d->trackData->socialActions( actionName, value, filterDupeSourceNames ); } diff --git a/src/libtomahawk/Track.h b/src/libtomahawk/Track.h index ab95436cb..3e3fdf5ff 100644 --- a/src/libtomahawk/Track.h +++ b/src/libtomahawk/Track.h @@ -109,8 +109,8 @@ public: void loadSocialActions( bool force = false ); QList< Tomahawk::SocialAction > allSocialActions() const; - QList< Tomahawk::source_ptr > sourcesWithSocialAction( const QString& action, const QVariant& value = QVariant(), bool filterDupeNames = false ); - QString socialActionDescription( const QString& action, DescriptionMode mode ) const; + QList< Tomahawk::SocialAction > socialActions( const QString& actionName, const QVariant& value = QVariant(), bool filterDupeSourceNames = false ); + QString socialActionDescription( const QString& actionName, DescriptionMode mode ) const; QList similarTracks() const; QStringList lyrics() const; diff --git a/src/libtomahawk/TrackData.cpp b/src/libtomahawk/TrackData.cpp index 56c986b3b..dc2cdbf78 100644 --- a/src/libtomahawk/TrackData.cpp +++ b/src/libtomahawk/TrackData.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2013, Christian Muehlhaeuser + * Copyright 2013, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -277,44 +278,55 @@ TrackData::allSocialActions() const } -QList< Tomahawk::source_ptr > -TrackData::sourcesWithSocialAction( const QString& action, const QVariant& value, bool filterDupeNames ) +QList< Tomahawk::SocialAction > +TrackData::socialActions( const QString& actionName, const QVariant& value, bool filterDupeSourceNames ) { QMutexLocker locker( &s_memberMutex ); - QList< Tomahawk::source_ptr > sources; + QList< Tomahawk::SocialAction > filtered; foreach ( const Tomahawk::SocialAction& sa, m_allSocialActions ) { - if ( sa.action == action ) + if ( sa.action == actionName ) { if ( !value.isNull() && sa.value != value ) { - sources.removeAll( sa.source ); + Tomahawk::source_ptr srcWithBadValue = sa.source; + QList< Tomahawk::SocialAction>::iterator it = filtered.begin(); + while ( it != filtered.end() ) + { + if ( it->source == srcWithBadValue ) + it = filtered.erase( it ); + else + ++it; + } continue; } bool dupe = false; - if ( sources.contains( sa.source ) ) - dupe = true; - if ( filterDupeNames ) + for ( QList< Tomahawk::SocialAction>::iterator it = filtered.begin(); + it != filtered.end(); ++it ) { - foreach ( const Tomahawk::source_ptr& source, sources ) + if ( it->source == sa.source || + ( filterDupeSourceNames && + ( it->source->friendlyName() == sa.source->friendlyName() ) ) ) { - if ( source->friendlyName() == sa.source->friendlyName() ) - { - dupe = true; - break; - } + dupe = true; + // we store the earliest timestamp in the sa we're keeping + if ( it->timestamp.toInt() > sa.timestamp.toInt() ) + it->timestamp = sa.timestamp; + // and always the new value + it->value = sa.value; + break; } } if ( dupe ) continue; - sources << sa.source; + filtered << sa; } } - return sources; + return filtered; } diff --git a/src/libtomahawk/TrackData.h b/src/libtomahawk/TrackData.h index 303973217..69d99510a 100644 --- a/src/libtomahawk/TrackData.h +++ b/src/libtomahawk/TrackData.h @@ -80,7 +80,7 @@ public: void loadSocialActions( bool force = false ); QList< Tomahawk::SocialAction > allSocialActions() const; - QList< Tomahawk::source_ptr > sourcesWithSocialAction( const QString& action, const QVariant& value = QVariant(), bool filterDupeNames = false ); + QList< Tomahawk::SocialAction > socialActions( const QString& actionName, const QVariant& value = QVariant(), bool filterDupeSourceNames = false ); void setAllSocialActions( const QList< Tomahawk::SocialAction >& socialActions ); void loadStats(); diff --git a/src/libtomahawk/playlist/PlaylistItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistItemDelegate.cpp index b3a12aa07..b04a77547 100644 --- a/src/libtomahawk/playlist/PlaylistItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistItemDelegate.cpp @@ -2,6 +2,7 @@ * * Copyright 2010-2011, Christian Muehlhaeuser * Copyright 2010-2011, Jeff Mitchell + * Copyright 2013, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,10 +20,11 @@ #include "PlaylistItemDelegate.h" +#include #include -#include -#include #include +#include +#include #include @@ -338,8 +340,10 @@ PlaylistItemDelegate::drawLoveBox( QPainter* painter, const QRect& rect, Playabl const int width = 2 + rect.height() - 4 * 2; QList< QPixmap > pixmaps; - foreach ( const Tomahawk::source_ptr& source, item->query()->queryTrack()->sourcesWithSocialAction( "Love", true, true ) ) - pixmaps << source->avatar( TomahawkUtils::Original, QSize( height, height ) ); + foreach ( const Tomahawk::SocialAction& sa, item->query()->queryTrack()->socialActions( "Love", true, true ) ) + { + pixmaps << sa.source->avatar( TomahawkUtils::Original, QSize( height, height ) ); + } const int max = 5; const unsigned int count = qMin( pixmaps.count(), max ); @@ -383,6 +387,104 @@ PlaylistItemDelegate::drawLoveBox( QPainter* painter, const QRect& rect, Playabl } +QRect +PlaylistItemDelegate::drawSentBox( QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, PlayableItem* item, const QModelIndex& index ) const +{ + const int height = rect.height() - 4 * 2; + const int width = 2 + rect.height() - 4 * 2; + + QList< QPixmap > pixmaps; + QDateTime earliestTimestamp = QDateTime::currentDateTime(); + foreach ( const Tomahawk::SocialAction& sa, item->query()->queryTrack()->socialActions( "Inbox", QVariant() /*neither true nor false!*/, true ) ) + { + QDateTime saTimestamp = QDateTime::fromTime_t( sa.timestamp.toInt() ); + if ( saTimestamp < earliestTimestamp && saTimestamp.toTime_t() > 0 ) + earliestTimestamp = saTimestamp; + + pixmaps << sa.source->avatar( TomahawkUtils::Original, QSize( height, height ) ); + } + const int max = 5; + const unsigned int count = qMin( pixmaps.count(), max ); + + painter->save(); + + painter->setRenderHint( QPainter::Antialiasing, true ); + painter->setBrush( Qt::transparent ); + QPen pen = painter->pen().color(); + pen.setWidthF( 0.2 ); + painter->setPen( pen ); + + QTextDocument textDoc; + textDoc.setHtml( QString( "%1" ) + .arg( TomahawkUtils::ageToString( earliestTimestamp, true ) ) ); + textDoc.setDocumentMargin( 0 ); + textDoc.setDefaultFont( painter->font() ); + textDoc.setDefaultTextOption( m_bottomOption ); + + QRect innerRect = rect.adjusted( rect.width() - width * count - 4 * 4 - + textDoc.idealWidth(), + 0, 0, 0 ); + + QRect textRect = innerRect.adjusted( innerRect.width() - textDoc.idealWidth() - 4, 4, -4, -4 ); + + drawRichText( painter, option, textRect, Qt::AlignVCenter|Qt::AlignRight, textDoc ); + + if ( !pixmaps.isEmpty() && !textDoc.isEmpty() ) + painter->drawRoundedRect( innerRect, 4, 4, Qt::RelativeSize ); + + unsigned int i = 0; + foreach ( QPixmap pixmap, pixmaps ) + { + if ( i >= max ) + break; + + QRect r = innerRect.adjusted( 4, 4, -4, -4 ); + r.adjust( width * i, 0, 0, 0 ); + r.setWidth( width ); + + if ( pixmap.isNull() ) + pixmap = TomahawkUtils::defaultPixmap( TomahawkUtils::DefaultSourceAvatar, TomahawkUtils::Original, QSize( r.height(), r.height() ) ); + painter->drawPixmap( r.adjusted( 1, 0, -1, 0 ), pixmap ); + + i++; + } + + +/* TomahawkUtils::ImageType type = item->query()->queryTrack()->loved() ? TomahawkUtils::Loved : TomahawkUtils::NotLoved; + QRect r = innerRect.adjusted( innerRect.width() - rect.height() + 4, 4, -4, -4 ); + painter->drawPixmap( r, TomahawkUtils::defaultPixmap( type, TomahawkUtils::Original, QSize( r.height(), r.height() ) ) ); + m_loveButtonRects[ index ] = r; +*/ + painter->restore(); + return rect; +} + + +void +PlaylistItemDelegate::drawRichText( QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, int flags, QTextDocument& text ) const +{ + Q_UNUSED( option ); + + text.setPageSize( QSize( rect.width(), QWIDGETSIZE_MAX ) ); + QAbstractTextDocumentLayout* layout = text.documentLayout(); + + const int height = qRound( layout->documentSize().height() ); + int y = rect.y(); + if ( flags & Qt::AlignBottom ) + y += ( rect.height() - height ); + else if ( flags & Qt::AlignVCenter ) + y += ( rect.height() - height ) / 2; + + QAbstractTextDocumentLayout::PaintContext context; + context.palette.setColor( QPalette::Text, painter->pen().color() ); + + painter->save(); + painter->translate( rect.x(), y ); + layout->draw( painter, context ); + painter->restore(); +} + + QRect PlaylistItemDelegate::drawSourceIcon( QPainter* painter, const QRect& rect, PlayableItem* item, float height ) const { diff --git a/src/libtomahawk/playlist/PlaylistItemDelegate.h b/src/libtomahawk/playlist/PlaylistItemDelegate.h index 20d210c79..6f3eae896 100644 --- a/src/libtomahawk/playlist/PlaylistItemDelegate.h +++ b/src/libtomahawk/playlist/PlaylistItemDelegate.h @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2013, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +22,7 @@ #include #include +#include #include "DllMacro.h" @@ -65,6 +67,8 @@ protected: QRect drawSourceIcon( QPainter* painter, const QRect& rect, PlayableItem* item, float height ) const; QRect drawCover( QPainter* painter, const QRect& rect, PlayableItem* item, const QModelIndex& index ) const; QRect drawLoveBox( QPainter* painter, const QRect& rect, PlayableItem* item, const QModelIndex& index ) const; + void drawRichText( QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, int flags, QTextDocument& text ) const; + QRect drawSentBox( QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, PlayableItem* item, const QModelIndex& index ) const; void paintDetailed( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; void paintShort( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const; diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp index 8dc91ad7b..a415b4ade 100644 --- a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.cpp @@ -1,6 +1,7 @@ /* === This file is part of Tomahawk Player - === * * Copyright 2010-2011, Christian Muehlhaeuser + * Copyright 2013, Teo Mrnjavac * * Tomahawk is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -20,7 +21,6 @@ #include #include -#include #include #include "Query.h" @@ -69,31 +69,6 @@ PlaylistLargeItemDelegate::sizeHint( const QStyleOptionViewItem& option, const Q } -void -PlaylistLargeItemDelegate::drawRichText( QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, int flags, QTextDocument& text ) const -{ - Q_UNUSED( option ); - - text.setPageSize( QSize( rect.width(), QWIDGETSIZE_MAX ) ); - QAbstractTextDocumentLayout* layout = text.documentLayout(); - - const int height = qRound( layout->documentSize().height() ); - int y = rect.y(); - if ( flags & Qt::AlignBottom ) - y += ( rect.height() - height ); - else if ( flags & Qt::AlignVCenter ) - y += ( rect.height() - height ) / 2; - - QAbstractTextDocumentLayout::PaintContext context; - context.palette.setColor( QPalette::Text, painter->pen().color() ); - - painter->save(); - painter->translate( rect.x(), y ); - layout->draw( painter, context ); - painter->restore(); -} - - void PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const { @@ -217,6 +192,7 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& if ( !( option.state & QStyle::State_Selected || item->isPlaying() ) ) painter->setPen( opt.palette.text().color().darker() ); +//TODO: replace usage of lowerText which is not drawn any more with appropriate loveBox/sentBox style boxes textDoc.setHtml( lowerText ); textDoc.setDocumentMargin( 0 ); textDoc.setDefaultFont( painter->font() ); @@ -229,7 +205,10 @@ PlaylistLargeItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& leftRect = rightRect.adjusted( -128, 4, 0, -4 ); leftRect.setWidth( 96 ); - drawLoveBox( painter, leftRect, item, index ); + if ( m_mode == Inbox ) + drawSentBox( painter, opt, leftRect, item, index ); + else + drawLoveBox( painter, leftRect, item, index ); if ( track->duration() > 0 ) { diff --git a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h index d67f047a7..f5387c2c4 100644 --- a/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h +++ b/src/libtomahawk/playlist/PlaylistLargeItemDelegate.h @@ -50,8 +50,6 @@ protected slots: virtual void modelChanged(); private: - void drawRichText( QPainter* painter, const QStyleOptionViewItem& option, const QRect& rect, int flags, QTextDocument& text ) const; - TrackView* m_view; PlayableProxyModel* m_model; DisplayMode m_mode;