diff --git a/src/libtomahawk/database/databasecommand_resolve.cpp b/src/libtomahawk/database/databasecommand_resolve.cpp index dd8a16500..38149e83d 100644 --- a/src/libtomahawk/database/databasecommand_resolve.cpp +++ b/src/libtomahawk/database/databasecommand_resolve.cpp @@ -81,11 +81,9 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) typedef QPair scorepair_t; // STEP 1 - QList< QPair > artists = lib->searchTable( "artist", m_query->artist(), false ); - QList< QPair > tracks = lib->searchTable( "track", m_query->track(), false ); - QList< QPair > albums = lib->searchTable( "album", m_query->album(), false ); + QList< QPair > tracks = lib->search( m_query ); - if ( artists.length() == 0 || tracks.length() == 0 ) + if ( tracks.length() == 0 ) { qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track(); emit results( m_query->id(), res ); @@ -95,13 +93,10 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) // STEP 2 TomahawkSqlQuery files_query = lib->newquery(); - QStringList artsl, trksl; - for ( int k = 0; k < artists.count(); k++ ) - artsl.append( QString::number( artists.at( k ).first ) ); + QStringList trksl; for ( int k = 0; k < tracks.count(); k++ ) trksl.append( QString::number( tracks.at( k ).first ) ); - QString artsToken = QString( "file_join.artist IN (%1)" ).arg( artsl.join( "," ) ); QString trksToken = QString( "file_join.track IN (%1)" ).arg( trksl.join( "," ) ); QString sql = QString( "SELECT " @@ -124,8 +119,7 @@ DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) "artist.id = file_join.artist AND " "track.id = file_join.track AND " "file.id = file_join.file AND " - "(%1 AND %2)" ) - .arg( artsToken ) + "(%1)" ) .arg( trksToken ); files_query.prepare( sql ); @@ -201,34 +195,9 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) typedef QPair scorepair_t; // STEP 1 - QList< QPair > artistPairs = lib->searchTable( "artist", m_query->fullTextQuery(), false, 20 ); - QList< QPair > albumPairs = lib->searchTable( "album", m_query->fullTextQuery(), false, 20 ); - QList< QPair > trackArtistPairs = lib->searchTable( "trackartist", m_query->fullTextQuery(), true, 20 ); + QList< QPair > trackPairs = lib->search( m_query ); + QList< QPair > albumPairs = lib->searchAlbum( m_query, 20 ); - if ( artistPairs.length() == 0 && albumPairs.length() == 0 && trackArtistPairs.length() == 0 ) - { - qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track(); - emit results( m_query->id(), res ); - return; - } - - foreach ( const scorepair_t& artistPair, artistPairs ) - { - TomahawkSqlQuery query = lib->newquery(); - - QString sql = QString( "SELECT name FROM artist WHERE id = %1" ).arg( artistPair.first ); - query.prepare( sql ); - query.exec(); - - QList artistList; - while ( query.next() ) - { - Tomahawk::artist_ptr artist = Tomahawk::Artist::get( artistPair.first, query.value( 0 ).toString() ); - artistList << artist; - } - - emit artists( m_query->id(), artistList ); - } foreach ( const scorepair_t& albumPair, albumPairs ) { TomahawkSqlQuery query = lib->newquery(); @@ -247,13 +216,20 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) emit albums( m_query->id(), albumList ); } + + if ( trackPairs.length() == 0 ) + { + qDebug() << "No candidates found in first pass, aborting resolve" << m_query->fullTextQuery(); + emit results( m_query->id(), res ); + return; + } // STEP 2 TomahawkSqlQuery files_query = lib->newquery(); QStringList trksl; - for ( int k = 0; k < trackArtistPairs.count(); k++ ) - trksl.append( QString::number( trackArtistPairs.at( k ).first ) ); + for ( int k = 0; k < trackPairs.count(); k++ ) + trksl.append( QString::number( trackPairs.at( k ).first ) ); QString trksToken = QString( "file_join.track IN (%1)" ).arg( trksl.join( "," ) ); QString sql = QString( "SELECT " @@ -325,11 +301,11 @@ DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) result->setAlbumPos( files_query.value( 17 ).toUInt() ); result->setTrackId( files_query.value( 9 ).toUInt() ); - for ( int k = 0; k < trackArtistPairs.count(); k++ ) + for ( int k = 0; k < trackPairs.count(); k++ ) { - if ( trackArtistPairs.at( k ).first == (int)result->trackId() ) + if ( trackPairs.at( k ).first == (int)result->trackId() ) { - result->setScore( trackArtistPairs.at( k ).second ); + result->setScore( trackPairs.at( k ).second ); break; } } diff --git a/src/libtomahawk/database/databasecommand_updatesearchindex.cpp b/src/libtomahawk/database/databasecommand_updatesearchindex.cpp index ee1920608..5c3899ccd 100644 --- a/src/libtomahawk/database/databasecommand_updatesearchindex.cpp +++ b/src/libtomahawk/database/databasecommand_updatesearchindex.cpp @@ -44,40 +44,40 @@ DatabaseCommand_UpdateSearchIndex::~DatabaseCommand_UpdateSearchIndex() } -void -DatabaseCommand_UpdateSearchIndex::indexTable( DatabaseImpl* db, const QString& table, const QString& query ) -{ - qDebug() << Q_FUNC_INFO; - - TomahawkSqlQuery q = db->newquery(); - qDebug() << "Building index for" << table; - q.exec( QString( "SELECT %1" ).arg( query ) ); - - QMap< unsigned int, QString > fields; - QString value; - while ( q.next() ) - { - value = ""; - for ( int v = 1; v < q.record().count(); v++ ) - value += q.value( v ).toString() + " "; - - fields.insert( q.value( 0 ).toUInt(), value.trimmed() ); - } - - db->m_fuzzyIndex->appendFields( table, fields ); - qDebug() << "Building index for" << table << "finished."; -} - - void DatabaseCommand_UpdateSearchIndex::exec( DatabaseImpl* db ) { db->m_fuzzyIndex->beginIndexing(); - indexTable( db, "artist", "id, name FROM artist" ); - indexTable( db, "album", "id, name FROM album" ); - indexTable( db, "track", "id, name FROM track" ); - indexTable( db, "trackartist", "track.id, artist.name, track.name FROM track, artist WHERE artist.id = track.artist" ); + QMap< unsigned int, QMap< QString, QString > > data; + TomahawkSqlQuery q = db->newquery(); + + q.exec( "SELECT track.id, track.name, artist.name, artist.id FROM track, artist WHERE artist.id = track.artist" ); + while ( q.next() ) + { + QMap< QString, QString > track; + track.insert( "track", q.value( 1 ).toString() ); + track.insert( "artist", q.value( 2 ).toString() ); + track.insert( "artistid", q.value( 3 ).toString() ); + + data.insert( q.value( 0 ).toUInt(), track ); + } + + db->m_fuzzyIndex->appendFields( data ); + data.clear(); + + q.exec( "SELECT album.id, album.name FROM album" ); + while ( q.next() ) + { + QMap< QString, QString > album; + album.insert( "album", q.value( 1 ).toString() ); + + data.insert( q.value( 0 ).toUInt(), album ); + } + + db->m_fuzzyIndex->appendFields( data ); + + qDebug() << "Building index finished."; db->m_fuzzyIndex->endIndexing(); } diff --git a/src/libtomahawk/database/databasecommand_updatesearchindex.h b/src/libtomahawk/database/databasecommand_updatesearchindex.h index 5698cda7e..09aeba89c 100644 --- a/src/libtomahawk/database/databasecommand_updatesearchindex.h +++ b/src/libtomahawk/database/databasecommand_updatesearchindex.h @@ -35,13 +35,7 @@ public: virtual bool doesMutates() const { return true; } virtual void exec( DatabaseImpl* db ); -signals: - void indexUpdated(); - private: - void indexTable( DatabaseImpl* db, const QString& table, const QString& query ); - - QString table; IndexingJobItem* m_statusJob; }; diff --git a/src/libtomahawk/database/databaseimpl.cpp b/src/libtomahawk/database/databaseimpl.cpp index c56714b58..4f600fc5b 100644 --- a/src/libtomahawk/database/databaseimpl.cpp +++ b/src/libtomahawk/database/databaseimpl.cpp @@ -78,7 +78,7 @@ DatabaseImpl::DatabaseImpl( const QString& dbname, Database* parent ) // in case of unclean shutdown last time: query.exec( "UPDATE source SET isonline = 'false'" ); -// schemaUpdated = true; // REMOVE ME + schemaUpdated = true; // REMOVE ME m_fuzzyIndex = new FuzzyIndex( *this, schemaUpdated ); if ( schemaUpdated ) QTimer::singleShot( 0, this, SLOT( updateIndex() ) ); @@ -409,13 +409,36 @@ DatabaseImpl::albumId( int artistid, const QString& name_orig, bool autoCreate ) QList< QPair > -DatabaseImpl::searchTable( const QString& table, const QString& name, bool fulltext, uint limit ) +DatabaseImpl::search( const Tomahawk::query_ptr& query, uint limit ) { QList< QPair > resultslist; - if ( table != "artist" && table != "track" && table != "album" && table != "trackartist" ) + + QMap< int, float > resultsmap = m_fuzzyIndex->search( query ); + foreach ( int i, resultsmap.keys() ) + { + resultslist << QPair( i, (float)resultsmap.value( i ) ); + } + qSort( resultslist.begin(), resultslist.end(), DatabaseImpl::scorepairSorter ); + + if ( !limit ) return resultslist; - QMap< int, float > resultsmap = m_fuzzyIndex->search( table, name, fulltext ); + QList< QPair > resultscapped; + for ( int i = 0; i < (int)limit && i < resultsmap.count(); i++ ) + { + resultscapped << resultslist.at( i ); + } + + return resultscapped; +} + + +QList< QPair > +DatabaseImpl::searchAlbum( const Tomahawk::query_ptr& query, uint limit ) +{ + QList< QPair > resultslist; + + QMap< int, float > resultsmap = m_fuzzyIndex->searchAlbum( query ); foreach ( int i, resultsmap.keys() ) { resultslist << QPair( i, (float)resultsmap.value( i ) ); diff --git a/src/libtomahawk/database/databaseimpl.h b/src/libtomahawk/database/databaseimpl.h index 878e8194f..052ae68aa 100644 --- a/src/libtomahawk/database/databaseimpl.h +++ b/src/libtomahawk/database/databaseimpl.h @@ -56,7 +56,8 @@ public: int trackId( int artistid, const QString& name_orig, bool autoCreate ); int albumId( int artistid, const QString& name_orig, bool autoCreate ); - QList< QPair > searchTable( const QString& table, const QString& name, bool fulltext, uint limit = 0 ); + QList< QPair > search( const Tomahawk::query_ptr& query, uint limit = 0 ); + QList< QPair > searchAlbum( const Tomahawk::query_ptr& query, uint limit = 0 ); QList< int > getTrackFids( int tid ); static QString sortname( const QString& str, bool replaceArticle = false ); @@ -79,8 +80,6 @@ public: signals: void indexReady(); -public slots: - private slots: void updateIndex(); diff --git a/src/libtomahawk/database/fuzzyindex.cpp b/src/libtomahawk/database/fuzzyindex.cpp index 1770854f2..f9cf8802c 100644 --- a/src/libtomahawk/database/fuzzyindex.cpp +++ b/src/libtomahawk/database/fuzzyindex.cpp @@ -22,6 +22,7 @@ #include #include +#include #include "databaseimpl.h" #include "utils/tomahawkutils.h" @@ -84,7 +85,7 @@ FuzzyIndex::beginIndexing() } qDebug() << "Creating new index writer."; - IndexWriter luceneWriter = IndexWriter( m_luceneDir, m_analyzer, true ); + IndexWriter luceneWriter( m_luceneDir, m_analyzer, true ); } catch( CLuceneError& error ) { @@ -103,31 +104,49 @@ FuzzyIndex::endIndexing() void -FuzzyIndex::appendFields( const QString& table, const QMap< unsigned int, QString >& fields ) +FuzzyIndex::appendFields( const QMap< unsigned int, QMap< QString, QString > >& trackData ) { try { - tDebug() << "Appending to index:" << table << fields.count(); + tDebug() << "Appending to index:" << trackData.count(); bool create = !IndexReader::indexExists( TomahawkUtils::appDataDir().absoluteFilePath( "tomahawk.lucene" ).toStdString().c_str() ); - IndexWriter luceneWriter = IndexWriter( m_luceneDir, m_analyzer, create ); + IndexWriter luceneWriter( m_luceneDir, m_analyzer, create ); Document doc; - QMapIterator< unsigned int, QString > it( fields ); + QMapIterator< unsigned int, QMap< QString, QString > > it( trackData ); while ( it.hasNext() ) { it.next(); unsigned int id = it.key(); - QString name = it.value(); - { - Field* field = _CLNEW Field( table.toStdWString().c_str(), DatabaseImpl::sortname( name ).toStdWString().c_str(), - Field::STORE_YES | Field::INDEX_TOKENIZED ); - doc.add( *field ); - } + QMap< QString, QString > values = it.value(); + if ( values.contains( "track" ) ) { - Field* field = _CLNEW Field( _T( "id" ), QString::number( id ).toStdWString().c_str(), Field::STORE_YES | Field::INDEX_NO ); - doc.add( *field ); + doc.add( *( _CLNEW Field( _T( "fulltext" ), DatabaseImpl::sortname( QString( "%1 %2" ).arg( values.value( "artist" ) ).arg( values.value( "track" ) ) ).toStdWString().c_str(), + Field::STORE_NO | Field::INDEX_UNTOKENIZED ) ) ); + + doc.add( *( _CLNEW Field( _T( "track" ), DatabaseImpl::sortname( values.value( "track" ) ).toStdWString().c_str(), + Field::STORE_NO | Field::INDEX_UNTOKENIZED ) ) ); + + doc.add( *( _CLNEW Field( _T( "artist" ), DatabaseImpl::sortname( values.value( "artist" ) ).toStdWString().c_str(), + Field::STORE_NO | Field::INDEX_UNTOKENIZED ) ) ); + + doc.add( *( _CLNEW Field( _T( "artistid" ), values.value( "artistid" ).toStdWString().c_str(), + Field::STORE_YES | Field::INDEX_NO ) ) ); + + doc.add( *( _CLNEW Field( _T( "trackid" ), QString::number( id ).toStdWString().c_str(), + Field::STORE_YES | Field::INDEX_NO ) ) ); } + else if ( values.contains( "album" ) ) + { + doc.add( *( _CLNEW Field( _T( "album" ), DatabaseImpl::sortname( values.value( "album" ) ).toStdWString().c_str(), + Field::STORE_NO | Field::INDEX_UNTOKENIZED ) ) ); + + doc.add( *( _CLNEW Field( _T( "albumid" ), QString::number( id ).toStdWString().c_str(), + Field::STORE_YES | Field::INDEX_NO ) ) ); + } + else + Q_ASSERT( false ); luceneWriter.addDocument( &doc ); doc.clear(); @@ -152,7 +171,7 @@ FuzzyIndex::loadLuceneIndex() QMap< int, float > -FuzzyIndex::search( const QString& table, const QString& name, bool fulltext ) +FuzzyIndex::search( const Tomahawk::query_ptr& query ) { QMutexLocker lock( &m_mutex ); @@ -171,47 +190,112 @@ FuzzyIndex::search( const QString& table, const QString& name, bool fulltext ) m_luceneSearcher = _CLNEW IndexSearcher( m_luceneReader ); } - if ( name.isEmpty() ) - return resultsmap; + float minScore; + const TCHAR** fields = 0; + MultiFieldQueryParser parser( fields, m_analyzer ); + BooleanQuery* qry = _CLNEW BooleanQuery(); - Hits* hits = 0; - Query* qry = 0; - QueryParser parser( table.toStdWString().c_str(), m_analyzer ); - - if ( fulltext ) + if ( query->isFullTextQuery() ) { - QString escapedName = QString::fromWCharArray( parser.escape( name.toStdWString().c_str() ) ); + QString escapedQuery = QString::fromWCharArray( parser.escape( DatabaseImpl::sortname( query->fullTextQuery() ).toStdWString().c_str() ) ); + + Term* term = _CLNEW Term( _T( "track" ), escapedQuery.toStdWString().c_str() ); + Query* fqry = _CLNEW FuzzyQuery( term ); + qry->add( fqry, true, BooleanClause::SHOULD ); - QStringList sl = DatabaseImpl::sortname( escapedName ).split( " ", QString::SkipEmptyParts ); - qry = parser.parse( QString( "%1:%2~" ).arg( table ).arg( sl.join( "~ " ) ).toStdWString().c_str() ); + term = _CLNEW Term( _T( "artist" ), escapedQuery.toStdWString().c_str() ); + fqry = _CLNEW FuzzyQuery( term ); + qry->add( fqry, true, BooleanClause::SHOULD ); + + term = _CLNEW Term( _T( "fulltext" ), escapedQuery.toStdWString().c_str() ); + fqry = _CLNEW FuzzyQuery( term ); + qry->add( fqry, true, BooleanClause::SHOULD ); + + minScore = 0.00; } else { -// qry = _CLNEW FuzzyQuery( _CLNEW Term( table.toStdWString().c_str(), DatabaseImpl::sortname( name ).toStdWString().c_str() ) ); - QString escapedName = QString::fromWCharArray( parser.escape( name.toStdWString().c_str() ) ); + QString track = QString::fromWCharArray( parser.escape( DatabaseImpl::sortname( query->track() ).toStdWString().c_str() ) ); + QString artist = QString::fromWCharArray( parser.escape( DatabaseImpl::sortname( query->artist() ).toStdWString().c_str() ) ); +// QString album = QString::fromWCharArray( parser.escape( query->album().toStdWString().c_str() ) ); - QStringList sl = DatabaseImpl::sortname( escapedName ).split( " ", QString::SkipEmptyParts ); - qry = parser.parse( QString( "%1:\"%2\"~" ).arg( table ).arg( sl.join( " " ) ).toStdWString().c_str() ); + Term* term = _CLNEW Term( _T( "track" ), track.toStdWString().c_str() ); + Query* fqry = _CLNEW FuzzyQuery( term ); + qry->add( fqry, true, BooleanClause::MUST ); + + term = _CLNEW Term( _T( "artist" ), artist.toStdWString().c_str() ); + fqry = _CLNEW FuzzyQuery( term ); + qry->add( fqry, true, BooleanClause::MUST ); + + minScore = 0.05; } - hits = m_luceneSearcher->search( qry ); + Hits* hits = m_luceneSearcher->search( qry ); for ( uint i = 0; i < hits->length(); i++ ) { Document* d = &hits->doc( i ); float score = hits->score( i ); - int id = QString::fromWCharArray( d->get( _T( "id" ) ) ).toInt(); - QString result = QString::fromWCharArray( d->get( table.toStdWString().c_str() ) ); + int id = QString::fromWCharArray( d->get( _T( "trackid" ) ) ).toInt(); - if ( DatabaseImpl::sortname( result ) == DatabaseImpl::sortname( name ) ) - score = 1.0; - else - score = qMin( score, (float)0.99 ); - - if ( score > 0.20 ) + if ( score > minScore ) { resultsmap.insert( id, score ); -// qDebug() << "Hitres:" << result << id << score << table << name; +// tDebug() << "Index hit:" << id << score << QString::fromWCharArray( ((Query*)qry)->toString() ); + } + } + + delete hits; + delete qry; + } + catch( CLuceneError& error ) + { + tDebug() << "Caught CLucene error:" << error.what(); + Q_ASSERT( false ); + } + + return resultsmap; +} + + +QMap< int, float > +FuzzyIndex::searchAlbum( const Tomahawk::query_ptr& query ) +{ + Q_ASSERT( query->isFullTextQuery() ); + + QMutexLocker lock( &m_mutex ); + + QMap< int, float > resultsmap; + try + { + if ( !m_luceneReader ) + { + if ( !IndexReader::indexExists( TomahawkUtils::appDataDir().absoluteFilePath( "tomahawk.lucene" ).toStdString().c_str() ) ) + { + qDebug() << Q_FUNC_INFO << "index didn't exist."; + return resultsmap; + } + + m_luceneReader = IndexReader::open( m_luceneDir ); + m_luceneSearcher = _CLNEW IndexSearcher( m_luceneReader ); + } + + QueryParser parser( _T( "album" ), m_analyzer ); + QString escapedName = QString::fromWCharArray( parser.escape( DatabaseImpl::sortname( query->fullTextQuery() ).toStdWString().c_str() ) ); + + Query* qry = _CLNEW FuzzyQuery( _CLNEW Term( _T( "album" ), escapedName.toStdWString().c_str() ) ); + Hits* hits = m_luceneSearcher->search( qry ); + for ( uint i = 0; i < hits->length(); i++ ) + { + Document* d = &hits->doc( i ); + + float score = hits->score( i ); + int id = QString::fromWCharArray( d->get( _T( "albumid" ) ) ).toInt(); + + if ( score > 0.30 ) + { + resultsmap.insert( id, score ); +// tDebug() << "Index hit:" << id << score; } } diff --git a/src/libtomahawk/database/fuzzyindex.h b/src/libtomahawk/database/fuzzyindex.h index 12929c8ae..2938a1f55 100644 --- a/src/libtomahawk/database/fuzzyindex.h +++ b/src/libtomahawk/database/fuzzyindex.h @@ -25,6 +25,8 @@ #include #include +#include "query.h" + namespace lucene { namespace analysis @@ -58,7 +60,7 @@ public: void beginIndexing(); void endIndexing(); - void appendFields( const QString& table, const QMap< unsigned int, QString >& fields ); + void appendFields( const QMap< unsigned int, QMap< QString, QString > >& trackData ); signals: void indexReady(); @@ -66,7 +68,8 @@ signals: public slots: void loadLuceneIndex(); - QMap< int, float > search( const QString& table, const QString& name, bool fulltext ); + QMap< int, float > search( const Tomahawk::query_ptr& query ); + QMap< int, float > searchAlbum( const Tomahawk::query_ptr& query ); private: DatabaseImpl& m_db; diff --git a/src/libtomahawk/playlist/albummodel.cpp b/src/libtomahawk/playlist/albummodel.cpp index 9c552e070..08cc3f653 100644 --- a/src/libtomahawk/playlist/albummodel.cpp +++ b/src/libtomahawk/playlist/albummodel.cpp @@ -304,7 +304,18 @@ AlbumModel::addAlbums( const QList& albums ) if ( m_overwriteOnAdd ) clear(); - if ( !albums.count() ) + QList trimmedAlbums; + foreach ( const album_ptr& album, albums ) + { + if ( !album.isNull() && album->name().length() ) + { + if ( findItem( album ) || trimmedAlbums.contains( album ) ) + continue; + trimmedAlbums << album; + } + } + + if ( !trimmedAlbums.count() ) { emit itemCountChanged( rowCount( QModelIndex() ) ); return; @@ -313,12 +324,12 @@ AlbumModel::addAlbums( const QList& albums ) int c = rowCount( QModelIndex() ); QPair< int, int > crows; crows.first = c; - crows.second = c + albums.count() - 1; + crows.second = c + trimmedAlbums.count() - 1; emit beginInsertRows( QModelIndex(), crows.first, crows.second ); AlbumItem* albumitem; - foreach( const album_ptr& album, albums ) + foreach( const album_ptr& album, trimmedAlbums ) { albumitem = new AlbumItem( album, m_rootItem ); albumitem->index = createIndex( m_rootItem->children.count() - 1, 0, albumitem ); @@ -339,7 +350,18 @@ AlbumModel::addArtists( const QList& artists ) if ( m_overwriteOnAdd ) clear(); - if ( !artists.count() ) + QList trimmedArtists; + foreach ( const artist_ptr& artist, artists ) + { + if ( !artist.isNull() && artist->name().length() ) + { + if ( findItem( artist ) || trimmedArtists.contains( artist ) ) + continue; + trimmedArtists << artist; + } + } + + if ( !trimmedArtists.count() ) { emit itemCountChanged( rowCount( QModelIndex() ) ); return; @@ -348,12 +370,12 @@ AlbumModel::addArtists( const QList& artists ) int c = rowCount( QModelIndex() ); QPair< int, int > crows; crows.first = c; - crows.second = c + artists.count() - 1; + crows.second = c + trimmedArtists.count() - 1; emit beginInsertRows( QModelIndex(), crows.first, crows.second ); AlbumItem* albumitem; - foreach( const artist_ptr& artist, artists ) + foreach ( const artist_ptr& artist, trimmedArtists ) { albumitem = new AlbumItem( artist, m_rootItem ); albumitem->index = createIndex( m_rootItem->children.count() - 1, 0, albumitem ); @@ -396,3 +418,35 @@ AlbumModel::onDataChanged() AlbumItem* p = (AlbumItem*)sender(); emit dataChanged( p->index, p->index.sibling( p->index.row(), columnCount( QModelIndex() ) - 1 ) ); } + + +AlbumItem* +AlbumModel::findItem( const artist_ptr& artist ) const +{ + for ( int i = 0; i < rowCount( QModelIndex() ); i++ ) + { + AlbumItem* item = itemFromIndex( index( i, 0, QModelIndex() ) ); + if ( !item->artist().isNull() && item->artist() == artist ) + { + return item; + } + } + + return 0; +} + + +AlbumItem* +AlbumModel::findItem( const album_ptr& album ) const +{ + for ( int i = 0; i < rowCount( QModelIndex() ); i++ ) + { + AlbumItem* item = itemFromIndex( index( i, 0, QModelIndex() ) ); + if ( !item->album().isNull() && item->album() == album ) + { + return item; + } + } + + return 0; +} diff --git a/src/libtomahawk/playlist/albummodel.h b/src/libtomahawk/playlist/albummodel.h index 01d8f0569..e163db437 100644 --- a/src/libtomahawk/playlist/albummodel.h +++ b/src/libtomahawk/playlist/albummodel.h @@ -71,6 +71,9 @@ public: virtual void setTitle( const QString& title ) { m_title = title; } virtual void setDescription( const QString& description ) { m_description = description; } + AlbumItem* findItem( const Tomahawk::artist_ptr& artist ) const; + AlbumItem* findItem( const Tomahawk::album_ptr& album ) const; + AlbumItem* itemFromIndex( const QModelIndex& index ) const { if ( index.isValid() ) diff --git a/src/libtomahawk/widgets/searchwidget.cpp b/src/libtomahawk/widgets/searchwidget.cpp index e8efdfbcc..0ccbda4ab 100644 --- a/src/libtomahawk/widgets/searchwidget.cpp +++ b/src/libtomahawk/widgets/searchwidget.cpp @@ -130,6 +130,9 @@ SearchWidget::jumpToCurrentTrack() void SearchWidget::onResultsFound( const QList& results ) { + QList artists; + QList albums; + foreach( const Tomahawk::result_ptr& result, results ) { if ( !result->collection().isNull() && !result->isOnline() ) @@ -143,7 +146,13 @@ SearchWidget::onResultsFound( const QList& results ) q->addResults( rl ); m_resultsModel->append( q ); + + artists << result->artist(); + albums << result->album(); } + + m_artistsModel->addArtists( artists ); + m_albumsModel->addAlbums( albums ); } diff --git a/src/sip/zeroconf/zeroconf.cpp b/src/sip/zeroconf/zeroconf.cpp index a0957f9a8..e983b4cdd 100644 --- a/src/sip/zeroconf/zeroconf.cpp +++ b/src/sip/zeroconf/zeroconf.cpp @@ -32,7 +32,7 @@ ZeroconfFactory::createPlugin( const QString& pluginId ) return new ZeroconfPlugin( pluginId.isEmpty() ? generateId() : pluginId ); } -ZeroconfPlugin::ZeroconfPlugin() : SipPlugin( "") {} +ZeroconfPlugin::ZeroconfPlugin() : SipPlugin( "" ) {} ZeroconfPlugin::ZeroconfPlugin ( const QString& pluginId ) : SipPlugin( pluginId )