1
0
mirror of https://github.com/tomahawk-player/tomahawk.git synced 2025-01-17 14:28:24 +01:00

Merge pull request #489 from tomahawk-player/unify-download-buttons

Unify DownloadButtons
This commit is contained in:
Christian Muehlhaeuser 2016-05-11 21:15:23 +02:00
commit 77e9b69679
12 changed files with 431 additions and 351 deletions

View File

@ -146,6 +146,7 @@ set( libGuiSources
widgets/ClickableLabel.cpp
widgets/ComboBox.cpp
widgets/DropDownButton.cpp
widgets/DownloadButton.cpp
widgets/ElidedLabel.cpp
widgets/FilterHeader.cpp
widgets/CaptionLabel.cpp

View File

@ -24,6 +24,8 @@
#include "TomahawkSettings.h"
#include "infosystem/InfoSystem.h"
#include "utils/Logger.h"
#include "Result.h"
#include "Query.h"
DownloadManager* DownloadManager::s_instance = 0;
@ -85,6 +87,36 @@ DownloadManager::localFileForDownload( const QString& url ) const
}
QUrl
DownloadManager::localUrlForDownload( const Tomahawk::query_ptr& query ) const
{
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
if ( result )
{
return localUrlForDownload( result );
}
return QUrl();
}
QUrl
DownloadManager::localUrlForDownload( const Tomahawk::result_ptr& result ) const
{
if ( result && !result->downloadFormats().isEmpty() &&
!localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() )
{
return QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ) ).absolutePath() );
}
else if ( result && result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished )
{
return QUrl::fromLocalFile( QFileInfo( result->downloadJob()->localFile() ).absolutePath() );
}
return QUrl();
}
void
DownloadManager::storeJobs( const QList<downloadjob_ptr>& jobs )
{

View File

@ -45,6 +45,8 @@ public:
void storeJobs( const QList<downloadjob_ptr>& jobs );
QString localFileForDownload( const QString& url ) const;
QUrl localUrlForDownload( const Tomahawk::result_ptr& result ) const;
QUrl localUrlForDownload( const Tomahawk::query_ptr& query ) const;
public slots:
bool addJob( const downloadjob_ptr& job );

View File

@ -28,6 +28,7 @@
#include "utils/TomahawkUtilsGui.h"
#include "utils/DpiScaler.h"
#include "ViewManager.h"
#include "widgets/DownloadButton.h"
#include <QLabel>
#include <QVBoxLayout>
@ -164,6 +165,10 @@ ColumnViewPreviewWidget::ColumnViewPreviewWidget( ColumnView* parent )
m_ageValue->setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
gridLayout->addWidget( m_ageValue, 4, 1 );
m_downloadButton = new DownloadButton( this );
mainLayout->addWidget( m_downloadButton );
mainLayout->addStretch();
TomahawkUtils::unmarginLayout( mainLayout );
@ -217,6 +222,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
m_bitrateValue->setText( tr( "%1 kbps" ).arg( query->results().first()->bitrate() ) );
m_durationValue->setText( TomahawkUtils::timeToString( query->track()->duration() ) );
m_ageValue->setText( TomahawkUtils::ageToString( QDateTime::fromTime_t( query->results().first()->modificationTime() ) ) );
m_downloadButton->setQuery( query );
m_yearValue->setVisible( query->track()->year() > 0 );
m_yearLabel->setVisible( query->track()->year() > 0 );
@ -226,6 +232,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
m_durationValue->setVisible( query->track()->duration() > 0 );
m_ageLabel->setVisible( query->results().first()->modificationTime() > 0 );
m_ageValue->setVisible( query->results().first()->modificationTime() > 0 );
m_downloadButton->setVisible( true );
}
else
{
@ -237,6 +244,7 @@ ColumnViewPreviewWidget::setQuery( const Tomahawk::query_ptr& query )
m_durationValue->setVisible( false );
m_ageLabel->setVisible( false );
m_ageValue->setVisible( false );
m_downloadButton->setVisible( false );
}
setMinimumHeight( sizeHint().height() );

View File

@ -30,6 +30,7 @@ class QueryLabel;
class PlayableCover;
class QLabel;
class ScrollingLabel;
class DownloadButton;
class DLLEXPORT ColumnViewPreviewWidget : public QWidget
{
@ -71,6 +72,8 @@ private:
ScrollingLabel* m_trackLabel;
QueryLabel* m_artistLabel;
DownloadButton* m_downloadButton;
};
#endif // COLUMNVIEWPREVIEWWIDGET_H

View File

@ -19,16 +19,6 @@
#include "GridItemDelegate.h"
#include <QApplication>
#include <QDesktopServices>
#include <QPainter>
#include <QAbstractItemView>
#include <QMouseEvent>
#include <QTimeLine>
#include "DownloadManager.h"
#include "DownloadJob.h"
#include "Artist.h"
#include "Query.h"
#include "Result.h"
@ -39,17 +29,22 @@
#include "playlist/PlayableItem.h"
#include "playlist/PlayableProxyModel.h"
#include "widgets/HoverControls.h"
#include "widgets/DropDownButton.h"
#include "widgets/DownloadButton.h"
#include "widgets/ImageButton.h"
#include "utils/TomahawkStyle.h"
#include "utils/TomahawkUtilsGui.h"
#include "utils/PixmapDelegateFader.h"
#include "utils/Closure.h"
#include "utils/AnimatedSpinner.h"
#include "utils/WebPopup.h"
#include "utils/DpiScaler.h"
#include "utils/Logger.h"
#include <QApplication>
#include <QPainter>
#include <QAbstractItemView>
#include <QMouseEvent>
#include <QTimeLine>
namespace {
static const int FADE_DURATION = 400;
};
@ -325,43 +320,10 @@ GridItemDelegate::paint( QPainter* painter, const QStyleOptionViewItem& option,
QRect r = textRect;
r.setY( textRect.y() + textRect.height() + 8 );
r.setHeight( 32 );
m_buyButtonRects[ index ] = r;
QString text;
bool itemsAvailable = false;
if ( item->result() &&
( ( !item->result()->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() ) ||
( item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished ) ) )
if( DownloadButton::drawPrimitive(painter, r, item->query(), m_hoveringOverBuyButton == index ) )
{
text = tr( "View in Finder" );
}
else if ( item->query() && item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
{
text = tr( "Download %1" ).arg( item->query()->results().first()->downloadFormats().first().extension.toUpper() );
itemsAvailable = true;
}
else if ( item->query()->numResults( true ) && !item->query()->results().first()->purchaseUrl().isEmpty() )
{
text = tr( "Buy" );
}
if ( !item->result() || !item->result()->downloadJob() || item->result()->downloadJob()->state() == DownloadJob::Finished )
{
if ( !text.isEmpty() )
DropDownButton::drawPrimitive( painter, r, text, m_hoveringOverBuyButton == index, itemsAvailable );
else
m_buyButtonRects.remove( index );
}
else
{
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
painter->drawRect( r.adjusted( 2, 2, -2, -2 ) );
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
QRect fillp = r.adjusted( 3, 3, -3, -3 );
fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
painter->drawRect( fillp );
m_buyButtonRects[ index ] = r;
}
}
}
@ -623,25 +585,7 @@ GridItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, const Q
if ( hoveringBuyButton )
{
if ( event->type() == QEvent::MouseButtonRelease )
{
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
if ( !item )
return false;
if ( item->query() && item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
{
m_model->sourceModel()->setAllColumnsEditable( true );
m_view->edit( index );
m_model->sourceModel()->setAllColumnsEditable( false );
return true;
}
else
{
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
}
}
return DownloadButton::handleEditorEvent( event, m_view, m_model, index );
}
return false;
@ -871,63 +815,7 @@ GridItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& opt
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
Q_ASSERT( item );
if ( item->result() && !item->result()->downloadFormats().isEmpty() &&
!DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
{
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ) ).absolutePath() ) );
}
else if ( item->result() && item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished )
{
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( item->result()->downloadJob()->localFile() ).absolutePath() ) );
}
else if ( item->result() &&
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
{
QStringList formats;
foreach ( const DownloadFormat& format, item->result()->downloadFormats() )
{
formats << tr( "Download %1" ).arg( format.extension.toUpper() );
}
DropDownButton* editor = new DropDownButton( parent );
editor->addItems( formats );
NewClosure( editor, SIGNAL( clicked() ),
const_cast<GridItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
NewClosure( editor, SIGNAL( activated( int ) ),
const_cast<GridItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
return editor;
}
return 0;
}
void
GridItemDelegate::addDownloadJob( const QModelIndex& index, QWidget* editor )
{
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
Q_ASSERT( item );
m_view->closePersistentEditor( index );
DropDownButton* cb = static_cast< DropDownButton* >(editor);
if ( !item->result()->downloadFormats().isEmpty() )
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().at( cb->currentIndex() ) ) );
}
void
GridItemDelegate::closeEditor( const QModelIndex& index, QWidget* editor )
{
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
Q_ASSERT( item );
m_view->closePersistentEditor( index );
DropDownButton* cb = static_cast< DropDownButton* >(editor);
editor->deleteLater();
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
}
@ -936,7 +824,7 @@ GridItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionViewI
{
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
comboBox->move( option.rect.x() + 4, option.rect.y() );

View File

@ -87,9 +87,6 @@ private slots:
void fadingFrameChanged( const QPersistentModelIndex& );
void fadingFrameFinished( const QPersistentModelIndex& );
void closeEditor( const QModelIndex& index, QWidget* editor );
void addDownloadJob( const QModelIndex& index, QWidget* editor );
private:
QTimeLine* createTimeline( QTimeLine::Direction direction, int startFrame = 0 );
void clearButtons();

View File

@ -20,15 +20,6 @@
#include "PlaylistItemDelegate.h"
#include <QAbstractTextDocumentLayout>
#include <QApplication>
#include <QDateTime>
#include <QDesktopServices>
#include <QMouseEvent>
#include <QPainter>
#include <QDesktopServices>
#include <QToolTip>
#include "Query.h"
#include "Result.h"
#include "Artist.h"
@ -36,8 +27,6 @@
#include "Source.h"
#include "SourceList.h"
#include "DownloadManager.h"
#include "DownloadJob.h"
#include "PlayableModel.h"
#include "PlayableItem.h"
#include "PlayableProxyModel.h"
@ -45,16 +34,22 @@
#include "ViewHeader.h"
#include "ViewManager.h"
#include "widgets/DropDownButton.h"
#include "widgets/DownloadButton.h"
#include "audio/AudioEngine.h"
#include "utils/ImageRegistry.h"
#include "utils/PixmapDelegateFader.h"
#include "utils/Closure.h"
#include "utils/TomahawkStyle.h"
#include "utils/TomahawkUtilsGui.h"
#include "utils/WebPopup.h"
#include "utils/Logger.h"
#include <QAbstractTextDocumentLayout>
#include <QApplication>
#include <QDateTime>
#include <QMouseEvent>
#include <QPainter>
#include <QToolTip>
using namespace Tomahawk;
@ -125,63 +120,7 @@ PlaylistItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem&
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
Q_ASSERT( item );
if ( /*index.column() == PlayableModel::Download &&*/ item->result() && !item->result()->downloadFormats().isEmpty() &&
!DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
{
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ) ).absolutePath() ) );
}
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() && item->result()->downloadJob() && item->result()->downloadJob()->state() == DownloadJob::Finished )
{
QDesktopServices::openUrl( QUrl::fromLocalFile( QFileInfo( item->result()->downloadJob()->localFile() ).absolutePath() ) );
}
else if ( /*index.column() == PlayableModel::Download &&*/ item->result() &&
!item->result()->downloadFormats().isEmpty() && !item->result()->downloadJob() )
{
QStringList formats;
foreach ( const DownloadFormat& format, item->result()->downloadFormats() )
{
formats << tr( "Download %1" ).arg( format.extension );
}
DropDownButton* editor = new DropDownButton( parent );
editor->addItems( formats );
NewClosure( editor, SIGNAL( clicked() ),
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
NewClosure( editor, SIGNAL( activated( int ) ),
const_cast<PlaylistItemDelegate*>(this), SLOT( addDownloadJob( const QModelIndex&, QWidget* ) ), index, (QWidget*)editor );
return editor;
}
return 0;
}
void
PlaylistItemDelegate::addDownloadJob( const QModelIndex& index, QWidget* editor )
{
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
Q_ASSERT( item );
m_view->closePersistentEditor( index );
DropDownButton* cb = static_cast< DropDownButton* >(editor);
if ( !item->result()->downloadFormats().isEmpty() )
DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().at( cb->currentIndex() ) ) );
}
void
PlaylistItemDelegate::closeEditor( const QModelIndex& index, QWidget* editor )
{
PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
Q_ASSERT( item );
m_view->closePersistentEditor( index );
DropDownButton* cb = static_cast< DropDownButton* >(editor);
editor->deleteLater();
return DownloadButton::handleCreateEditor( parent, item->query(), m_view, index );
}
@ -190,7 +129,7 @@ PlaylistItemDelegate::updateEditorGeometry( QWidget* editor, const QStyleOptionV
{
QStyledItemDelegate::updateEditorGeometry( editor, option, index );
DropDownButton* comboBox = static_cast<DropDownButton*>(editor);
DownloadButton* comboBox = static_cast<DownloadButton*>(editor);
comboBox->resize( option.rect.size() - QSize( 8, 0 ) );
comboBox->move( option.rect.x() + 4, option.rect.y() );
@ -277,69 +216,7 @@ PlaylistItemDelegate::paintDetailed( QPainter* painter, const QStyleOptionViewIt
else */
if ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download )
{
if ( item->result() && !item->result()->downloadFormats().isEmpty() )
{
QStyleOptionComboBox optc;
optc.rect = opt.rect.adjusted( 4, 0, -4, 0 );
optc.editable = false;
optc.currentText = tr( "Download %1" ).arg( item->result()->downloadFormats().first().extension );
optc.palette = m_view->palette();
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
optc.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
else
optc.state = QStyle::State_Active | QStyle::State_Enabled;
if ( !DownloadManager::instance()->localFileForDownload( item->result()->downloadFormats().first().url.toString() ).isEmpty() )
{
painter->setPen( opt.palette.text().color() );
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
painter->drawText( opt.rect, text, textOption );
}
else if ( !item->result()->downloadJob() )
{
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
/* QApplication::style()->drawComplexControl( QStyle::CC_ComboBox, &optc, painter, 0 );
optc.rect.adjust( 4, 0, 0, 0 );
QApplication::style()->drawControl( QStyle::CE_ComboBoxLabel, &optc, painter, 0 );*/
}
else
{
if ( item->result()->downloadJob()->state() == DownloadJob::Finished )
{
painter->setPen( opt.palette.text().color() );
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, opt.rect.width() - 3 );
painter->drawText( opt.rect, text, textOption );
}
else
{
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
painter->drawRect( optc.rect.adjusted( 2, 2, -2, -2 ) );
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
QRect fillp = optc.rect.adjusted( 3, 3, -3, -3 );
fillp.setWidth( float(fillp.width()) * ( float(item->result()->downloadJob()->progressPercentage()) / 100.0 ) );
painter->drawRect( fillp );
/* QStyleOptionProgressBarV2 optp;
optp.rect = optc.rect;
optp.minimum = 0;
optp.maximum = 100;
optp.progress = item->result()->downloadJob()->progressPercentage();
optp.palette = m_view->palette();
optp.palette.setColor( QPalette::Highlight, QColor( "#E61878" ) );
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
optp.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
else
optp.state = QStyle::State_Active | QStyle::State_Enabled;
QApplication::style()->drawControl( QStyle::CE_ProgressBar, &optp, painter, 0 );*/
}
}
}
DownloadButton::drawPrimitive( painter, opt.rect.adjusted( 4, 0, -4, 0 ), item->query(), hoveringOver() == index );
}
else if ( item->isPlaying() )
{
@ -657,67 +534,14 @@ PlaylistItemDelegate::drawTrack( QPainter* painter, const QStyleOptionViewItem&
stateWidth += r.width() + 16;
}
if ( hasOnlineResults && !item->query()->results().first()->purchaseUrl().isEmpty() )
{
QRect r = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
r.setWidth( 144 );
DropDownButton::drawPrimitive( painter, r, tr( "Buy" ), m_hoveringOverBuyButton == index, false );
m_buyButtonRects[ index ] = r;
stateWidth += r.width() + 16;
}
}
if ( hasOnlineResults && !item->query()->results().first()->downloadFormats().isEmpty() )
QRect downloadButtonRect = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
downloadButtonRect.setWidth( 144 );
stateWidth += downloadButtonRect.width() + 16;
if ( DownloadButton::drawPrimitive( painter, downloadButtonRect, item->query(), m_hoveringOverDownloadButton == index ) )
{
painter->save();
QStyleOptionComboBox optc;
optc.rect = stateRect.adjusted( -stateWidth -144, 6, 0, -6 );
optc.rect.setWidth( 144 );
m_downloadDropDownRects[ index ] = optc.rect;
stateWidth += optc.rect.width() + 16;
optc.editable = false;
optc.currentText = tr( "Download %1" ).arg( item->query()->results().first()->downloadFormats().first().extension.toUpper() );
optc.palette = m_view->palette();
if ( option.state & QStyle::State_Selected && option.state & QStyle::State_Active )
optc.state = QStyle::State_Active | QStyle::State_Selected | QStyle::State_Enabled;
else
optc.state = QStyle::State_Active | QStyle::State_Enabled;
if ( !DownloadManager::instance()->localFileForDownload( item->query()->results().first()->downloadFormats().first().url.toString() ).isEmpty() )
{
painter->setPen( optc.palette.text().color() );
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, optc.rect.width() - 3 );
painter->drawText( optc.rect, text, QTextOption( Qt::AlignCenter ) );
}
else if ( !item->query()->results().first()->downloadJob() )
{
DropDownButton::drawPrimitive( painter, optc.rect, optc.currentText, hoveringOver() == index, true );
}
else
{
if ( item->query()->results().first()->downloadJob()->state() == DownloadJob::Finished )
{
painter->setPen( optc.palette.text().color() );
const QString text = painter->fontMetrics().elidedText( tr( "View in Finder" ), Qt::ElideRight, optc.rect.width() - 3 );
painter->drawText( optc.rect, text, QTextOption( Qt::AlignCenter ) );
}
else
{
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
painter->drawRect( optc.rect.adjusted( 2, 2, -2, -2 ) );
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
QRect fillp = optc.rect.adjusted( 3, 3, -3, -3 );
fillp.setWidth( float(fillp.width()) * ( float(item->query()->results().first()->downloadJob()->progressPercentage()) / 100.0 ) );
painter->drawRect( fillp );
}
}
painter->restore();
m_downloadDropDownRects[ index ] = downloadButtonRect;
}
const int remWidth = r.width() - numberWidth - durationWidth;
@ -835,7 +659,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
bool hoveringArtist = false;
bool hoveringInfo = false;
bool hoveringLove = false;
bool hoveringBuy = false;
bool hoveringDownloadDropDown = false;
Tomahawk::source_ptr hoveredAvatar;
QRect hoveredAvatarRect;
@ -858,12 +681,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
hoveringLove = loveRect.contains( ev->pos() );
}
if ( m_buyButtonRects.contains( index ) )
{
const QRect buyRect = m_buyButtonRects[ index ];
const QMouseEvent* ev = static_cast< QMouseEvent* >( event );
hoveringBuy = buyRect.contains( ev->pos() );
}
if ( m_downloadDropDownRects.contains( index ) )
{
const QRect downloadDropDownRect = m_downloadDropDownRects[ index ];
@ -887,7 +704,7 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
if ( event->type() == QEvent::MouseMove )
{
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringBuy )
if ( hoveringInfo || hoveringLove || hoveringArtist || hoveringDownloadDropDown )
m_view->setCursor( Qt::PointingHandCursor );
else
m_view->setCursor( Qt::ArrowCursor );
@ -911,19 +728,19 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
emit updateIndex( m_hoveringOverArtist );
m_hoveringOverArtist = QModelIndex();
}
if ( hoveringBuy && m_hoveringOverBuyButton != index )
if ( hoveringDownloadDropDown && m_hoveringOverDownloadButton != index )
{
QPersistentModelIndex ti = m_hoveringOverBuyButton;
m_hoveringOverBuyButton = index;
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
m_hoveringOverDownloadButton = index;
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
item->requestRepaint();
emit updateIndex( m_hoveringOverBuyButton );
emit updateIndex( m_hoveringOverDownloadButton );
}
if ( !hoveringBuy && m_hoveringOverBuyButton.isValid() )
if ( !hoveringDownloadDropDown && m_hoveringOverDownloadButton.isValid() )
{
QPersistentModelIndex ti = m_hoveringOverBuyButton;
m_hoveringOverBuyButton = QModelIndex();
QPersistentModelIndex ti = m_hoveringOverDownloadButton;
m_hoveringOverDownloadButton = QModelIndex();
PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( ti ) );
item->requestRepaint();
@ -957,10 +774,10 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
{
item->query()->queryTrack()->setLoved( !item->query()->queryTrack()->loved() );
}
else if ( hoveringBuy )
else if ( hoveringDownloadDropDown || ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) )
{
WebPopup* popup = new WebPopup( item->query()->results().first()->purchaseUrl(), QSize( 400, 800 ) );
connect( item->query()->results().first().data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
if ( DownloadButton::handleEditorEvent( event , m_view, m_model, index ) )
return true;
}
else if ( hoveringInfo )
{
@ -996,13 +813,6 @@ PlaylistItemDelegate::editorEvent( QEvent* event, QAbstractItemModel* model, con
}
}
}
else if ( ( m_view->proxyModel()->style() == PlayableProxyModel::Locker && index.column() == PlayableModel::Download ) || hoveringDownloadDropDown )
{
m_model->sourceModel()->setAllColumnsEditable( true );
m_view->edit( index );
m_model->sourceModel()->setAllColumnsEditable( false );
return true;
}
event->accept();
return true;
@ -1022,10 +832,9 @@ PlaylistItemDelegate::resetHoverIndex()
m_hoveringOver = QModelIndex();
m_hoveringOverArtist = QModelIndex();
m_hoveringOverBuyButton = QModelIndex();
m_hoveringOverDownloadButton = QModelIndex();
m_infoButtonRects.clear();
m_loveButtonRects.clear();
m_buyButtonRects.clear();
m_artistNameRects.clear();
QModelIndex itemIdx = m_model->mapToSource( idx );

View File

@ -57,8 +57,6 @@ signals:
private slots:
void doUpdateIndex( const QPersistentModelIndex& index );
void closeEditor( const QModelIndex& index, QWidget* editor );
void addDownloadJob( const QModelIndex& index, QWidget* editor );
protected:
void prepareStyleOption( QStyleOptionViewItemV4* option, const QModelIndex& index, PlayableItem* item ) const;
@ -116,13 +114,12 @@ private:
mutable QHash< QPersistentModelIndex, QSharedPointer< Tomahawk::PixmapDelegateFader > > m_pixmaps;
mutable QHash< QPersistentModelIndex, QRect > m_infoButtonRects;
mutable QHash< QPersistentModelIndex, QRect > m_loveButtonRects;
mutable QHash< QPersistentModelIndex, QRect > m_buyButtonRects;
mutable QHash< QPersistentModelIndex, QRect > m_downloadDropDownRects;
mutable QHash< QPersistentModelIndex, QRect > m_artistNameRects;
mutable QHash< QPersistentModelIndex, QHash< Tomahawk::source_ptr, QRect > > m_avatarBoxRects;
QPersistentModelIndex m_hoveringOver;
QPersistentModelIndex m_hoveringOverArtist;
QPersistentModelIndex m_hoveringOverBuyButton;
QPersistentModelIndex m_hoveringOverDownloadButton;
mutable QPersistentModelIndex m_nowPlaying;
TrackView* m_view;

View File

@ -0,0 +1,282 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#include "DownloadButton.h"
#include "Artist.h"
#include "Album.h"
#include "Result.h"
#include "DownloadManager.h"
#include "utils/TomahawkStyle.h"
#include "utils/WebPopup.h"
#include "utils/Logger.h"
#include <QPainter>
#include <QEvent>
#include <QAbstractItemView>
#include <QDesktopServices>
using namespace Tomahawk;
DownloadButton::DownloadButton( const Tomahawk::query_ptr& query, QWidget* parent, QAbstractItemView* view, const QModelIndex& index )
: DropDownButton( parent )
, m_view( view )
, m_index( index )
{
init();
setQuery( query );
}
DownloadButton::DownloadButton( QWidget* parent )
: DropDownButton( parent )
{
init();
}
void
DownloadButton::init()
{
connect( this, SIGNAL( clicked() ), this, SLOT( addDownloadJob() ) );
connect( this, SIGNAL( activated( int ) ), this, SLOT( addDownloadJob() ) );
}
DownloadButton::~DownloadButton()
{
}
void
DownloadButton::setQuery( const query_ptr& query )
{
if ( !m_query.isNull() )
{
m_query->disconnect( this );
}
if ( !m_result.isNull() )
{
m_result->disconnect( this );
}
clear();
m_result.clear();
m_query = query;
if ( query.isNull() )
return;
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
if ( result.isNull() )
return;
QStringList formats;
foreach ( const DownloadFormat& format, result->downloadFormats() )
{
formats << QObject::tr( "Download %1" ).arg( format.extension.toUpper() );
}
addItems( formats );
}
void
DownloadButton::addDownloadJob()
{
if ( m_query.isNull() )
return;
Tomahawk::result_ptr result = m_query->numResults( true ) ? m_query->results().first() : Tomahawk::result_ptr();
if ( result.isNull() )
return;
if ( handleClickPreDownload( m_query ) )
return;
if ( !result->downloadFormats().isEmpty() )
{
if ( m_view && m_index.isValid() )
{
m_view->closePersistentEditor( m_index );
}
else
{
m_result = result;
connect( result.data(), SIGNAL( updated() ), SLOT( update() ) );
connect( m_query.data(), SIGNAL( resultsChanged() ), SLOT( update() ) );
}
DownloadManager::instance()->addJob( result->toDownloadJob( result->downloadFormats().at( currentIndex() ) ) );
}
else
{
handleClickPostDownload( m_query );
}
}
void
DownloadButton::paintEvent( QPaintEvent* event )
{
QPainter p( this );
setupPainter( &p );
if ( DownloadButton::drawPrimitive( &p, contentsRect(), m_query, m_hovering ) )
setCursor( Qt::PointingHandCursor );
else
setCursor( Qt::ArrowCursor );
}
bool
DownloadButton::drawPrimitive( QPainter* painter, const QRect& rect, const Tomahawk::query_ptr& query, bool hovering )
{
if ( query.isNull() )
return false;
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
if ( result.isNull() )
return false;
if ( result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
{
// if downloadJob exists and is not finished, paint a progress bar
painter->save();
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND.darker() );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_BACKGROUND );
painter->drawRect( rect.adjusted( 2, 2, -2, -2 ) );
painter->setPen( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
painter->setBrush( TomahawkStyle::PLAYLIST_PROGRESS_FOREGROUND );
QRect fillp = rect.adjusted( 3, 3, -3, -3 );
fillp.setWidth( float(fillp.width()) * ( float( result->downloadJob()->progressPercentage() ) / 100.0 ) );
painter->drawRect( fillp );
painter->restore();
}
else
{
QString text;
bool itemsAvailable = false;
if ( result &&
( ( !result->downloadFormats().isEmpty() && !DownloadManager::instance()->localFileForDownload( result->downloadFormats().first().url.toString() ).isEmpty() ) ||
( result->downloadJob() && result->downloadJob()->state() == DownloadJob::Finished ) ) )
{
text = QObject::tr( "View in Finder" );
}
else if ( !result->downloadFormats().isEmpty() )
{
text = tr( "Download %1" ).arg( query->results().first()->downloadFormats().first().extension.toUpper() );
itemsAvailable = true;
}
else if ( !result->purchaseUrl().isEmpty() )
{
text = tr( "Buy" );
}
if ( !text.isEmpty() )
DropDownButton::drawPrimitive( painter, rect, text, hovering, itemsAvailable );
else
{
// this result can neither be bought nor downloaded
return false;
}
}
return true;
}
bool
DownloadButton::handleEditorEvent(QEvent* event , QAbstractItemView* view, PlayableProxyModel* model, const QModelIndex& index)
{
if ( event->type() == QEvent::MouseButtonRelease )
{
PlayableItem* item = model->sourceModel()->itemFromIndex( model->mapToSource( index ) );
if ( !item && ! item->query() )
return false;
if ( handleClickPreDownload( item->query() ) )
return true;
if( item->query()->numResults( true ) && !item->query()->results().first()->downloadFormats().isEmpty() )
{
model->sourceModel()->setAllColumnsEditable( true );
view->edit( index );
model->sourceModel()->setAllColumnsEditable( false );
return true;
}
return handleClickPostDownload( item->query() );
}
return false;
}
bool
DownloadButton::handleClickPreDownload( const Tomahawk::query_ptr& query )
{
// view in folder
if ( !DownloadManager::instance()->localUrlForDownload( query ).isEmpty() )
{
QDesktopServices::openUrl( DownloadManager::instance()->localUrlForDownload( query ) );
return true;
}
// download in progress
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
if ( result && result->downloadJob() && result->downloadJob()->state() != DownloadJob::Finished )
{
// do nothing, handled
return true;
}
return false;
}
bool
DownloadButton::handleClickPostDownload( const Tomahawk::query_ptr& query )
{
// handle buy click
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
if ( result && !result->purchaseUrl().isEmpty() )
{
WebPopup* popup = new WebPopup( result->purchaseUrl(), QSize( 400, 800 ) );
connect( result.data(), SIGNAL( destroyed() ), popup, SLOT( close() ) );
return true;
}
return false;
}
QWidget*
DownloadButton::handleCreateEditor( QWidget* parent, const query_ptr& query, QAbstractItemView* view, const QModelIndex& index )
{
Tomahawk::result_ptr result = query->numResults( true ) ? query->results().first() : Tomahawk::result_ptr();
if ( result && !result->downloadFormats().isEmpty() && !result->downloadJob() )
{
return new DownloadButton( query, parent, view, index );
}
return 0;
}

View File

@ -0,0 +1,61 @@
/* === This file is part of Tomahawk Player - <http://tomahawk-player.org> ===
*
* Copyright 2015, Christian Muehlhaeuser <muesli@tomahawk-player.org>
* Copyright 2016, Dominik Schmidt <domme@tomahawk-player.org>
*
* Tomahawk is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Tomahawk is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Tomahawk. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef DOWNLOADBUTTON_H
#define DOWNLOADBUTTON_H
#include "DropDownButton.h"
#include "playlist/PlayableProxyModel.h"
#include "Typedefs.h"
#include "DllMacro.h"
class DLLEXPORT DownloadButton : public DropDownButton
{
Q_OBJECT
public:
explicit DownloadButton( const Tomahawk::query_ptr& query, QWidget* parent = nullptr, QAbstractItemView* view = nullptr, const QModelIndex& index = QModelIndex() );
explicit DownloadButton( QWidget* parent = nullptr );
virtual ~DownloadButton();
void setQuery( const Tomahawk::query_ptr& query );
static bool drawPrimitive( QPainter* p, const QRect& rect, const Tomahawk::query_ptr& query, bool hovering );
static bool handleEditorEvent( QEvent* event, QAbstractItemView* view, PlayableProxyModel* model, const QModelIndex& index );
static QWidget* handleCreateEditor( QWidget* parent, const Tomahawk::query_ptr& query , QAbstractItemView* view, const QModelIndex& index );
protected:
void paintEvent( QPaintEvent* event );
private slots:
void addDownloadJob();
private:
static bool handleClickPreDownload( const Tomahawk::query_ptr& query );
static bool handleClickPostDownload( const Tomahawk::query_ptr& query );
void init();
Tomahawk::query_ptr m_query;
Tomahawk::result_ptr m_result;
QAbstractItemView* m_view;
QModelIndex m_index;
};
#endif // DOWNLOADBUTTON_H

View File

@ -47,7 +47,7 @@ protected:
private slots:
private:
protected:
static void setupPainter( QPainter* p );
bool m_hovering;