Logo Search packages:      
Sourcecode: lastfm version File versions  Download package

searchresultdialog.cpp

/***************************************************************************
 *   Copyright (C) 2005 - 2006 by Christian Muehlhaeuser, Last.fm Ltd.     *
 *   chris@last.fm                                                         *
 *                                                                         *
 *   This program 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 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program 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 this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   51 Franklin Steet, Fifth Floor, Boston, MA  02111-1307, USA.          *
 ***************************************************************************/

#include <QtGui>
#include <QStyle>

#include "searchresultdialog.h"
#include "settings.h"
#include "webserviceconnector.h"


ImageReceiver::ImageReceiver( QUrl url )
    : CoverLoader( this, QApplication::applicationDirPath() + "/cache/" )
    , m_coverBuffer( new QBuffer() )
{
    connect( this, SIGNAL( requestFinished( bool ) ), this, SLOT( coverLoaded( bool ) ) );

    setHost( url.host() );
    if ( Settings::instance()->proxyUsage() && !Settings::instance()->proxyHost().isEmpty() )
        setProxy( Settings::instance()->proxyHost(), Settings::instance()->proxyPort(), Settings::instance()->proxyUsername(), Settings::instance()->proxyPassword() );

    if ( !url.encodedQuery().isEmpty() )
        get( url.path() + "?" + QString( url.encodedQuery() ), m_coverBuffer );
    else
        get( url.path(), m_coverBuffer );
}


void
ImageReceiver::coverLoaded( bool error )
{
    if ( !error && m_coverBuffer->size() > 0 )
    {
        QImage p( pathToCachedCopy() );
        p.scaledToHeight( 50, Qt::SmoothTransformation ).save( pathToCachedCopy(), QImageReader::imageFormat ( pathToCachedCopy() ) );

        emit imageReceived();
    }
}


SearchResultDialog::SearchResultDialog( QWidget *parent, int mode, QString searchToken )
    : QDialog( parent )
    , m_animation( new QMovie( QApplication::applicationDirPath() + "/data/search_active.mng" ) )
{
    ui.setupUi( this );
    ui.resultList->setEnabled( false );
    ui.listenButton->setEnabled( false );
    ui.spinningLabel->setMovie( m_animation );

    ExtendedInfoDelegate *delegate = new ExtendedInfoDelegate();

    m_bestResultModel = new QStandardItemModel();
    ui.bestResultWidget->setModel( m_bestResultModel );
    ui.bestResultWidget->setItemDelegate( delegate );

    m_suggestionModel = new QStandardItemModel();
    ui.resultList->setModel( m_suggestionModel );
    ui.resultList->setItemDelegate( delegate );

    connect( ui.listenButton, SIGNAL( clicked() ), this, SLOT( searchResultStation() ) );
    connect( ui.bestResultWidget, SIGNAL( doubleClicked( const QModelIndex ) ), this, SLOT( doubleClicked( const QModelIndex ) ) );
    connect( ui.resultList, SIGNAL( doubleClicked( const QModelIndex ) ), this, SLOT( doubleClicked( const QModelIndex ) ) );
    connect( WebserviceConnector::instance(), SIGNAL( searchArtistResult( QString, QString, bool, QStringList, QStringList ) ), this, SLOT( searchArtistResult( QString, QString, bool, QStringList, QStringList ) ) );
    connect( WebserviceConnector::instance(), SIGNAL( searchTagResult( QStringList, QList<QStringList> ) ), this, SLOT( searchTagResult( QStringList, QList<QStringList> ) ) );
//     connect( WebserviceConnector::instance(), SIGNAL( changeStationPrepared() ), this, SLOT( changeStationPrepared() ) );

    m_animation->start();
    connect( m_animation, SIGNAL( finished() ), m_animation, SLOT( start() ) );

    search( mode, searchToken );
}


void
SearchResultDialog::search( int mode, QString searchToken )
{
    m_mode = mode;
    m_searchToken = searchToken;

    ui.statusLabel->setText( QString( "Searching for %1 ..." ).arg( searchToken ) );

    switch ( mode )
    {
        case 0:
            WebserviceConnector::instance()->searchArtist( searchToken );
           break;

        case 1:
            WebserviceConnector::instance()->searchTag( searchToken );
            break;
    }
}


void
SearchResultDialog::searchArtistResult( const QString &artist, const QString& image, bool streamable, const QStringList &result, const QStringList& resultImages )
{
    if ( artist.isEmpty() )
    {
        ui.statusLabel->setText( QString( "Artist %1 not found!" ).arg( artist ) );
    }
    else
    if ( !streamable )
    {
        ui.statusLabel->setText( QString( "Artist %1 not streamable!" ).arg( artist ) );
    }
    else
    {
        ui.listenButton->setEnabled( true );
        ui.resultList->setEnabled( true );
        ui.statusLabel->setText( QString( "Your search for %1 returned %2 items." ).arg( artist ).arg( result.count() > 10 ? 10 : result.count() ) );

        ImageReceiver *ir = new ImageReceiver( QUrl( image ) );
        connect( ir, SIGNAL( imageReceived() ), ui.bestResultWidget, SLOT( repaint() ) );

        m_bestResultModel->insertRows( 0, 1 );
        m_bestResultModel->insertColumns( 0, 1 );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( artist ), Qt::DisplayRole );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( ir->pathToCachedCopy() ), Qt::UserRole );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( result ), Qt::DecorationRole );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( QString( "artist/%1/similarartists" ).arg( artist ) ), Qt::WhatsThisRole );

        int max = result.count() < 9 ? result.count() : 9;
        m_suggestionModel->insertRows( 0, max );
        m_suggestionModel->insertColumns( 0, 1 );
        for ( int i = 0; i < max; i++ )
        {
            ImageReceiver *irs = new ImageReceiver( QUrl( resultImages.at( i ) ) );
            connect( irs, SIGNAL( imageReceived() ), ui.resultList, SLOT( repaint() ) );

            m_suggestionModel->setData( m_suggestionModel->index( i, 0, QModelIndex() ), QVariant( result.at( i ) ), Qt::DisplayRole );
            m_suggestionModel->setData( m_suggestionModel->index( i, 0, QModelIndex() ), QVariant( irs->pathToCachedCopy() ), Qt::UserRole );
            m_suggestionModel->setData( m_suggestionModel->index( i, 0, QModelIndex() ), QVariant( result ), Qt::DecorationRole );
            m_suggestionModel->setData( m_bestResultModel->index( i, 0, QModelIndex() ), QVariant( QString( "artist/%1/similarartists" ).arg( result.at( i ) ) ), Qt::WhatsThisRole );
        }
    }
}


void
SearchResultDialog::searchTagResult( const QStringList &result, const QList<QStringList> &topArtistList )
{
    if ( result.isEmpty() )
    {
        ui.statusLabel->setText( QString( "Nothing found for %1" ).arg( m_searchToken ) );
    }
    else
    {
        ui.listenButton->setEnabled( true );
        ui.resultList->setEnabled( true );
        ui.statusLabel->setText( QString( "Your search for %1 returned %2 items." ).arg( m_searchToken ).arg( result.count() > 20 ? 20 : result.count() ) );

        m_bestResultModel->insertRows( 0, 1 );
        m_bestResultModel->insertColumns( 0, 1 );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( result.at( 0 ) ), Qt::DisplayRole );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( QString( "" ) ), Qt::UserRole );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( topArtistList.at( 0 ) ), Qt::DecorationRole );
        m_bestResultModel->setData( m_bestResultModel->index( 0, 0, QModelIndex() ), QVariant( QString( "globaltags/%1" ).arg( result.at( 0 ) ) ), Qt::WhatsThisRole );

        int max = result.count() < 20 ? result.count() : 20;
        m_suggestionModel->insertRows( 0, max - 1 );
        m_suggestionModel->insertColumns( 0, 1 );
        for ( int i = 1; i < max; i++ )
        {
            m_suggestionModel->setData( m_suggestionModel->index( i - 1, 0, QModelIndex() ), QVariant( result.at( i ) ), Qt::DisplayRole );
            m_suggestionModel->setData( m_suggestionModel->index( i - 1, 0, QModelIndex() ), QVariant( QString( "" ) ), Qt::UserRole );
            m_suggestionModel->setData( m_suggestionModel->index( i - 1, 0, QModelIndex() ), QVariant( topArtistList.at( i ) ), Qt::DecorationRole );
            m_suggestionModel->setData( m_bestResultModel->index( i - 1, 0, QModelIndex() ), QVariant( QString( "globaltags/%1" ).arg( result.at( i ) ) ), Qt::WhatsThisRole );
        }
    }
}


void
SearchResultDialog::doubleClicked( const QModelIndex & index )
{
    if ( m_mode == 0 )
        WebserviceConnector::instance()->changeStation( "artist/" + QUrl( index.model()->data( index, Qt::DisplayRole ).toString() ).toEncoded() + "/similarartists" );
    else
        WebserviceConnector::instance()->changeStation( "globaltags/" + QUrl( index.model()->data( index, Qt::DisplayRole ).toString() ).toEncoded() );

    close();
}


void
SearchResultDialog::searchResultStation()
{
}


ExtendedInfoDelegate::ExtendedInfoDelegate( QObject *parent )
    : QAbstractItemDelegate( parent )
{
}


void
ExtendedInfoDelegate::paint( QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
    QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled;
    bool selected = option.showDecorationSelected && ( option.state & QStyle::State_Selected );

    QString simArtists;
    QStringList list = index.model()->data( index, Qt::DecorationRole ).toStringList();
    for ( int i = 0; i < 8 && i < list.count(); i++ )
        simArtists += ( i > 0 ? ", " : "" ) + list.at( i );

    QString imgToken = QString( "<td><img src='%1'></td><td width='8'></td>" )
                          .arg( index.model()->data( index, Qt::UserRole ).toString() );

    QString infoToken = simArtists.count() > 0 ? QString( "featuring Artists like: %1" ).arg( simArtists ) : "";
    if ( !QFile( index.model()->data( index, Qt::UserRole ).toString() ).exists() )
        imgToken = "";

    painter->setViewTransformEnabled( true );
    QRect cr = option.rect;
    QTextDocument doc;
    doc.setHtml( QString( "<html><body leftmargin='0' topmargin='0'><table cellspacing='0' cellpadding='0' border='0'><tr>"
                          "<td><table><tr>%1</tr></table></td>"
                          "<td><font size='+1'><b>%2</b></font>"
                          "<br><font size='-1'>%3</font></td>"
                          "</tr></table></body></html>" )
                    .arg( imgToken )
                    .arg( index.model()->data( index, Qt::DisplayRole ).toString() )
                    .arg( infoToken ) );

    doc.setPageSize( QSize( cr.width(), INT_MAX ) );
    QAbstractTextDocumentLayout::PaintContext context;

    if ( selected )
        context.palette.setColor( QPalette::Text, option.palette.color( cg, QPalette::HighlightedText ) );

    // draw the background color
    if ( selected )
        painter->fillRect( option.rect, option.palette.brush( cg, QPalette::Highlight ) );

    QRect r = cr;
    r.translate( -cr.x(), -cr.y() );
    painter->save();
    painter->translate( cr.x(), cr.y() );
    painter->setClipRect( r );
    doc.documentLayout()->draw( painter, context );

    painter->restore();
}


QSize
ExtendedInfoDelegate::sizeHint ( const QStyleOptionViewItem & option, const QModelIndex & index ) const
{
    return QSize( 400, 61 );
}

Generated by  Doxygen 1.6.0   Back to index