Exemple #1
0
QSize
TreeItemDelegate::sizeHint( const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    QSize size = QStyledItemDelegate::sizeHint( option, index );

    if ( index.isValid() )
    {
        PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );
        if ( item )
        {
            if ( item->album() )
            {
                size.setHeight( option.fontMetrics.height() * 3 );
                return size;
            }
            else if ( item->query() || item->result() )
            {
                size.setHeight( option.fontMetrics.height() * 1.6 );
                return size;
            }
        }
    }
    
    // artist per default
    size.setHeight( option.fontMetrics.height() * 4 );
    return size;
}
Exemple #2
0
void
TreeView::updateHoverIndex( const QPoint& pos )
{
    QModelIndex idx = indexAt( pos );

    if ( idx != m_hoveredIndex )
    {
        m_hoveredIndex = idx;
        repaint();
    }

    if ( !m_model || m_proxyModel->style() != PlayableProxyModel::Collection )
        return;

    PlayableItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( idx ) );
    if ( idx.column() == 0 && !item->query().isNull() )
    {
        if ( pos.x() > header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) - 16 &&
             pos.x() < header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) )
        {
            setCursor( Qt::PointingHandCursor );
            return;
        }
    }

    if ( cursor().shape() != Qt::ArrowCursor )
        setCursor( Qt::ArrowCursor );
}
QWidget*
PlaylistItemDelegate::createEditor( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    PlayableItem* item = m_model->itemFromIndex( m_model->mapToSource( index ) );
    Q_ASSERT( item );

    if ( index.column() == PlayableModel::Download && item->result() &&
         !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;
    }
Exemple #4
0
void
TreeView::mousePressEvent( QMouseEvent* event )
{
    QTreeView::mousePressEvent( event );

    if ( !m_model || m_proxyModel->style() != PlayableProxyModel::Collection )
        return;

    QModelIndex idx = indexAt( event->pos() );
    if ( event->pos().x() > header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) - 16 &&
         event->pos().x() < header()->sectionViewportPosition( idx.column() ) + header()->sectionSize( idx.column() ) )
    {
        PlayableItem* item = proxyModel()->itemFromIndex( proxyModel()->mapToSource( idx ) );
        if ( item->query().isNull() )
            return;

        switch ( idx.column() )
        {
            case 0:
            {
                ViewManager::instance()->show( item->query()->displayQuery() );
                break;
            }

            default:
                break;
        }
    }
}
Exemple #5
0
void
DynamicWidget::steeringChanged()
{
    // When steering changes, toss all the tracks that are upcoming, and re-fetch.
    // We have to find the currently playing item
    QModelIndex playing;
    for ( int i = 0; i < m_view->proxyModel()->rowCount( QModelIndex() ); ++i )
    {
        const QModelIndex  cur = m_view->proxyModel()->index( i, 0, QModelIndex() );
        PlayableItem* item = m_view->proxyModel()->itemFromIndex( m_view->proxyModel()->mapToSource( cur ) );
        if ( item && item->isPlaying() )
        {
            playing = cur;
            break;
        }
    }
    if ( !playing.isValid() )
        return;

    const int upcoming = m_view->proxyModel()->rowCount( QModelIndex() ) - 1 - playing.row();
    tDebug() << "Removing tracks after current in station, found" << upcoming;

    QModelIndexList toRemove;
    for ( int i = playing.row() + 1; i < m_view->proxyModel()->rowCount( QModelIndex() ); i++ )
    {
        toRemove << m_view->proxyModel()->index( i, 0, QModelIndex() );
    }

    m_view->proxyModel()->removeIndexes( toRemove );

    m_playlist->generator()->fetchNext();
}
void
TreeProxyModel::onRowsInserted( const QModelIndex& parent, int /* start */, int /* end */ )
{
    if ( m_filter.isEmpty() )
        return;
    if ( sender() != m_model )
        return;

    PlayableItem* pi = m_model->itemFromIndex( m_model->index( parent.row(), 0, parent.parent() ) );
    if ( pi->artist().isNull() )
        return;

    Tomahawk::AlbumsRequest* cmd = 0;
    if ( !m_model->collection().isNull() )
        cmd = m_model->collection()->requestAlbums( pi->artist() );
    else
        cmd = new Tomahawk::DatabaseCommand_AllAlbums( Tomahawk::collection_ptr(), pi->artist() );

    cmd->setFilter( m_filter );

    connect( dynamic_cast< QObject* >( cmd ), SIGNAL( albums( QList<Tomahawk::album_ptr> ) ),
             SLOT( onFilterAlbums( QList<Tomahawk::album_ptr> ) ) );

    cmd->enqueue();
}
Exemple #7
0
void
GridView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{
    QListView::currentChanged( current, previous );

    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
    if ( item )
    {
        if ( !item->album().isNull() )
            ViewManager::instance()->context()->setAlbum( item->album() );
    }
}
Tomahawk::result_ptr
PlayableProxyModelPlaylistInterface::resultAt( qint64 index ) const
{
    if ( m_proxyModel.isNull() )
        return result_ptr();

    PlayableItem* item = reinterpret_cast<PlayableItem*>( (void*)index );
    if ( item && item->result() )
        return item->result();

    return result_ptr();
}
Tomahawk::result_ptr
PlayableProxyModelPlaylistInterface::currentItem() const
{
    if ( m_proxyModel.isNull() )
        return Tomahawk::result_ptr();

    PlayableProxyModel* proxyModel = m_proxyModel.data();

    PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->currentIndex() ) );
    if ( item && !item->query().isNull() && item->query()->playable() )
        return item->query()->results().at( 0 );
    return Tomahawk::result_ptr();
}
void
CollectionViewPage::onDownloadAll()
{
    for ( int i = 0; i < m_flatModel->rowCount( QModelIndex() ); i++ )
    {
        PlayableItem* item = m_flatModel->itemFromIndex( m_flatModel->index( i, 0, QModelIndex() ) );
        if ( !item )
            continue;

        if ( !item->result()->downloadFormats().isEmpty() )
            DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
    }
}
void
PlaylistModel::insertEntries( const QList< Tomahawk::plentry_ptr >& entries, int row, const QModelIndex& parent, const QList< Tomahawk::PlaybackLog >& logs )
{
    Q_D( PlaylistModel );
    if ( !entries.count() )
    {
        emit itemCountChanged( rowCount( QModelIndex() ) );
        finishLoading();
        return;
    }

    int c = row;
    QPair< int, int > crows;
    crows.first = c;
    crows.second = c + entries.count() - 1;

    if ( !d->isLoading )
    {
        d->savedInsertPos = row;
        d->savedInsertTracks = entries;
    }

    emit beginInsertRows( parent, crows.first, crows.second );

    QList< Tomahawk::query_ptr > queries;
    int i = 0;
    PlayableItem* plitem;
    foreach( const plentry_ptr& entry, entries )
    {
        PlayableItem* pItem = itemFromIndex( parent );
        plitem = new PlayableItem( entry, pItem, row + i );
        plitem->index = createIndex( row + i, 0, plitem );

        if ( logs.count() > i )
            plitem->setPlaybackLog( logs.at( i ) );

        i++;

        if ( entry->query()->id() == currentItemUuid() )
            setCurrentIndex( plitem->index );

        if ( !entry->query()->resolvingFinished() && !entry->query()->playable() )
        {
            queries << entry->query();
            d->waitingForResolved.append( entry->query().data() );
            connect( entry->query().data(), SIGNAL( playableStateChanged( bool ) ),
                     SLOT( onQueryBecamePlayable( bool ) ),
                     Qt::UniqueConnection );
            connect( entry->query().data(), SIGNAL( resolvingFinished( bool ) ),
                     SLOT( trackResolved( bool ) ) );
        }
Exemple #12
0
void
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{
    QTreeView::currentChanged( current, previous );

    if ( !m_updateContextView )
        return;

    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
    if ( item )
    {
        ViewManager::instance()->context()->setQuery( item->query() );
    }
}
Exemple #13
0
void
TrackView::startAutoPlay( const QModelIndex& index )
{
    if ( tryToPlayItem( index ) )
        return;

    // item isn't playable but still resolving
    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
    if ( item && !item->query().isNull() && !item->query()->resolvingFinished() )
    {
        m_autoPlaying = item->query(); // So we can kill it if user starts autoplaying this playlist again
        NewClosure( item->query().data(), SIGNAL( resolvingFinished( bool ) ), this, SLOT( autoPlayResolveFinished( Tomahawk::query_ptr, int ) ),
                    item->query(), index.row() );
        return;
    }
Exemple #14
0
void
TrackView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{
    QTreeView::currentChanged( current, previous );

    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
    if ( item && item->query() )
    {
        emit querySelected( item->query() );
    }
    else
    {
        emit querySelected( query_ptr() );
    }
}
void
QueueProxyModel::onPlaybackStarted( const Tomahawk::result_ptr& result )
{
    for ( int i = 0; i < rowCount(); i++ )
    {
        QModelIndex idx = index( i, 0 );
        PlayableItem* item = itemFromIndex( mapToSource( idx ) );
        if ( item && item->query() && ( item->query()->results().contains( result ) ||
                                        item->query()->track()->equals( result->track() ) ) )
        {
            removeIndex( idx );
            if ( !rowCount() )
                ViewManager::instance()->hideQueue();
        }
    }
}
void
GridItemDelegate::onPlayClicked( const QPersistentModelIndex& index )
{
    QPoint pos = m_playButton[ index ]->pos();
    clearButtons();

    AnimatedSpinner* spinner = new AnimatedSpinner( m_view );
    spinner->setAutoCenter( false );
    spinner->fadeIn();
    spinner->move( pos );
    spinner->setFocusPolicy( Qt::NoFocus );
    spinner->installEventFilter( this );

    m_spinner[ index ] = spinner;

    PlayableItem* item = m_model->sourceModel()->itemFromIndex( m_model->mapToSource( index ) );

    NewClosure(  AudioEngine::instance(), SIGNAL( started( Tomahawk::result_ptr ) ),
                const_cast<GridItemDelegate*>(this), SLOT( onPlaybackStarted( QPersistentModelIndex ) ), QPersistentModelIndex( index ) );

    if ( item )
    {
        if ( !item->query().isNull() )
            AudioEngine::instance()->playItem( m_model->playlistInterface(), item->query() );
        else if ( !item->album().isNull() )
            AudioEngine::instance()->playItem( item->album() );
        else if ( !item->artist().isNull() )
            AudioEngine::instance()->playItem( item->artist() );
    }
}
QList< Tomahawk::query_ptr >
PlayableProxyModelPlaylistInterface::tracks()
{
    if ( m_proxyModel.isNull() )
        return QList< Tomahawk::query_ptr >();

    PlayableProxyModel* proxyModel = m_proxyModel.data();
    QList<Tomahawk::query_ptr> queries;

    for ( int i = 0; i < proxyModel->rowCount( QModelIndex() ); i++ )
    {
        PlayableItem* item = proxyModel->itemFromIndex( proxyModel->mapToSource( proxyModel->index( i, 0 ) ) );
        if ( item )
            queries << item->query();
    }

    return queries;
}
Exemple #18
0
bool
TreeModel::canFetchMore( const QModelIndex& parent ) const
{
    PlayableItem* parentItem = itemFromIndex( parent );

    if ( parentItem->fetchingMore() )
        return false;

    if ( !parentItem->artist().isNull() )
    {
        return true;
    }
    else if ( !parentItem->album().isNull() )
    {
        return true;
    }

    return false;
}
Exemple #19
0
void
ColumnView::onCustomContextMenu( const QPoint& pos )
{
    m_contextMenu->clear();

    QModelIndex idx = indexAt( pos );
    idx = idx.sibling( idx.row(), 0 );
    m_contextMenuIndex = idx;

    if ( !idx.isValid() )
        return;

    QList<query_ptr> queries;
    QList<artist_ptr> artists;
    QList<album_ptr> albums;

    QModelIndexList indexes = selectedIndexes();
    if ( !indexes.contains( idx ) )
    {
        indexes.clear();
        indexes << idx;
    }

    foreach ( const QModelIndex& index, indexes )
    {
        if ( index.column() || indexes.contains( index.parent() ) )
            continue;

        PlayableItem* item = m_proxyModel->itemFromIndex( m_proxyModel->mapToSource( index ) );

        if ( item && !item->result().isNull() )
            queries << item->result()->toQuery();
        else if ( item && !item->query().isNull() )
            queries << item->query();
        if ( item && !item->artist().isNull() )
            artists << item->artist();
        if ( item && !item->album().isNull() )
            albums << item->album();
    }

    m_contextMenu->setQueries( queries );
    m_contextMenu->setArtists( artists );
    m_contextMenu->setAlbums( albums );
    m_contextMenu->setPlaylistInterface( proxyModel()->playlistInterface() );

    m_contextMenu->exec( viewport()->mapToGlobal( pos ) );
}
void
TreeProxyModel::onRowsInserted( const QModelIndex& parent, int /* start */, int /* end */ )
{
    if ( m_filter.isEmpty() )
        return;
    if ( sender() != m_model )
        return;

    PlayableItem* pi = m_model->itemFromIndex( m_model->index( parent.row(), 0, parent.parent() ) );
    if ( pi->artist().isNull() )
        return;

    DatabaseCommand_AllAlbums* cmd = new DatabaseCommand_AllAlbums( m_model->collection() );
    cmd->setArtist( pi->artist() );
    cmd->setFilter( m_filter );

    connect( cmd, SIGNAL( albums( QList<Tomahawk::album_ptr>, QVariant ) ),
                    SLOT( onFilterAlbums( QList<Tomahawk::album_ptr> ) ) );

    Database::instance()->enqueue( QSharedPointer<DatabaseCommand>( cmd ) );
}
Exemple #21
0
void
TreeModel::getCover( const QModelIndex& index )
{
    PlayableItem* item = itemFromIndex( index );

    if ( !item->artist().isNull() && !item->artist()->coverLoaded() )
        item->artist()->cover( QSize( 0, 0 ) );
    else if ( !item->album().isNull() && !item->album()->coverLoaded() )
        item->album()->cover( QSize( 0, 0 ) );
}
Exemple #22
0
bool
PlayableProxyModel::dupeFilterAcceptsRow( int sourceRow, PlayableItem* pi, const QModelIndex& sourceParent, PlayableProxyModelFilterMemo& memo ) const
{
    if ( !m_hideDupeItems )
        return true;

    for ( int i = 0; i < sourceRow; i++ )
    {
        PlayableItem* di = itemFromIndex( sourceModel()->index( i, 0, sourceParent ) );
        if ( !di )
            continue;

        bool b = ( pi->query() && pi->query()->equals( di->query() ) ) ||
                 ( pi->album() && pi->album() == di->album() ) ||
                 ( pi->artist() && pi->artist()->name() == di->artist()->name() );

        if ( b && filterAcceptsRowInternal( i, di, sourceParent, memo ) )
            return false;
    }

    return true;
}
void
RecentlyPlayedModel::onPlaybackFinished( const Tomahawk::track_ptr& track, const Tomahawk::PlaybackLog& log )
{
    int count = trackCount();

    if ( count )
    {
        PlayableItem* oldestItem = itemFromIndex( index( count - 1, 0, QModelIndex() ) );
        if ( oldestItem->playbackLog().timestamp >= log.timestamp )
            return;

        PlayableItem* youngestItem = itemFromIndex( index( 0, 0, QModelIndex() ) );
        if ( youngestItem->playbackLog().timestamp <= log.timestamp )
            insertQuery( track->toQuery(), 0, log );
        else
        {
            for ( int i = 0; i < count - 1; i++ )
            {
                PlayableItem* item1 = itemFromIndex( index( i, 0, QModelIndex() ) );
                PlayableItem* item2 = itemFromIndex( index( i + 1, 0, QModelIndex() ) );

                if ( item1->playbackLog().timestamp >= log.timestamp && item2->playbackLog().timestamp <= log.timestamp )
                {
                    insertQuery( track->toQuery(), i + 1, log );
                    break;
                }
            }
        }
    }
    else
        insertQuery( track->toQuery(), 0, log );

    if ( trackCount() > (int)m_limit )
        remove( m_limit );

    ensureResolved();
}
void
QueueProxyModel::onIndexChanged( const QModelIndex& index )
{
    PlayableItem* item = itemFromIndex( mapToSource( index ) );
    if ( item && item->query() )
    {
        tDebug() << item->query()->toString() << item->query()->resolvingFinished() << item->query()->playable();
    }
    if ( !item || !item->query() || ( item->query()->resolvingFinished() && !item->query()->playable() ) )
    {
        removeIndex( index );
    }
}
Exemple #25
0
void
TreeView::onItemActivated( const QModelIndex& index )
{
    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
    if ( item )
    {
        if ( !item->artist().isNull() )
        {
            ViewManager::instance()->show( item->artist() );
        }
        else if ( !item->album().isNull() )
        {
            ViewManager::instance()->show( item->album() );
        }
        else if ( !item->result().isNull() && item->result()->isOnline() )
        {
            AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), item->result() );
        }
        else if ( !item->query().isNull() )
        {
            AudioEngine::instance()->playItem( m_proxyModel->playlistInterface(), item->query() );
        }
    }
}
Exemple #26
0
void
CollectionViewPage::onDownloadAll()
{
    if ( DownloadManager::instance()->state() == DownloadManager::Running )
    {
        DownloadManager::instance()->cancelAll();
    }
    else
    {
        for ( int i = 0; i < m_trackView->proxyModel()->rowCount( QModelIndex() ); i++ )
        {
            PlayableItem* item = m_trackView->proxyModel()->itemFromIndex( m_trackView->proxyModel()->mapToSource( m_trackView->proxyModel()->index( i, 0, QModelIndex() ) ) );
            if ( !item )
                continue;

            QList< DownloadFormat > formats = item->query()->results().first()->downloadFormats();
            if ( formats.isEmpty() || !DownloadManager::instance()->localFileForDownload( formats.first().url.toString() ).isEmpty() )
                continue;

            if ( !item->result()->downloadFormats().isEmpty() )
                DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
        }
    }
}
Exemple #27
0
void
ContextView::onDownloadAll()
{
    for ( int i = 0; i < m_trackView->proxyModel()->rowCount( QModelIndex() ); i++ )
    {
        PlayableItem* item = m_trackView->proxyModel()->itemFromIndex( m_trackView->proxyModel()->mapToSource( m_trackView->proxyModel()->index( i, 0, QModelIndex() ) ) );
        if ( !item || !item->query() || !item->query()->results().count() )
            continue;
        if ( !item->query()->results().first()->downloadFormats().count() )
            continue;

        if ( !DownloadManager::instance()->localFileForDownload( item->query()->results().first()->downloadFormats().first().url.toString() ).isEmpty() )
            continue;
        if ( !item->result()->downloadFormats().isEmpty() )
            DownloadManager::instance()->addJob( item->result()->toDownloadJob( item->result()->downloadFormats().first() ) );
    }
}
Exemple #28
0
void
TreeModel::fetchMore( const QModelIndex& parent )
{
    PlayableItem* parentItem = itemFromIndex( parent );
    if ( !parentItem || parentItem->fetchingMore() )
        return;

    parentItem->setFetchingMore( true );
    if ( !parentItem->artist().isNull() )
    {
        tDebug() << Q_FUNC_INFO << "Loading Artist:" << parentItem->artist()->name();
        fetchAlbums( parentItem->artist() );
    }
    else if ( !parentItem->album().isNull() )
    {
        tDebug() << Q_FUNC_INFO << "Loading Album:" << parentItem->album()->artist()->name() << parentItem->album()->name() << parentItem->album()->id();
        addTracks( parentItem->album(), parent );
    }
    else
        Q_ASSERT( false );
}
Exemple #29
0
void
TreeView::currentChanged( const QModelIndex& current, const QModelIndex& previous )
{
    QTreeView::currentChanged( current, previous );

    if ( !m_updateContextView )
        return;

    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( current ) );
    if ( item )
    {
        if ( !item->result().isNull() )
            ViewManager::instance()->context()->setQuery( item->result()->toQuery() );
        else if ( !item->artist().isNull() )
            ViewManager::instance()->context()->setArtist( item->artist() );
        else if ( !item->album().isNull() )
            ViewManager::instance()->context()->setAlbum( item->album() );
        else if ( !item->query().isNull() )
            ViewManager::instance()->context()->setQuery( item->query() );
    }
}
Exemple #30
0
void
GridView::onItemActivated( const QModelIndex& index )
{
    PlayableItem* item = m_model->itemFromIndex( m_proxyModel->mapToSource( index ) );
    if ( item )
    {
//        qDebug() << "Result activated:" << item->album()->tracks().first()->toString() << item->album()->tracks().first()->results().first()->url();
//        APP->audioEngine()->playItem( item->album().data(), item->album()->tracks().first()->results().first() );

        if ( !item->album().isNull() )
            ViewManager::instance()->show( item->album() );
        else if ( !item->artist().isNull() )
            ViewManager::instance()->show( item->artist() );
        else if ( !item->query().isNull() )
            ViewManager::instance()->show( item->query() );
    }
}