From 2e9dc426962635ff05c8484a587c6dd4481966a3 Mon Sep 17 00:00:00 2001 From: Christian Muehlhaeuser Date: Sat, 4 Jun 2011 20:47:45 +0200 Subject: [PATCH] * Added basic search widget. --- src/CMakeLists.txt | 1 + src/libtomahawk/CMakeLists.txt | 3 + .../database/databasecommand_resolve.cpp | 167 ++++++++++++++++-- .../database/databasecommand_resolve.h | 5 +- src/libtomahawk/pipeline.cpp | 4 +- .../playlist/topbar/searchlineedit.h | 2 +- src/libtomahawk/playlist/trackproxymodel.cpp | 2 +- src/libtomahawk/query.cpp | 26 +++ src/libtomahawk/query.h | 15 +- src/libtomahawk/viewmanager.cpp | 9 +- src/libtomahawk/widgets/newplaylistwidget.cpp | 2 - src/resolvers/qtscriptresolver.cpp | 23 ++- src/resolvers/scriptresolver.cpp | 18 +- src/tomahawkwindow.cpp | 41 ++++- src/tomahawkwindow.h | 5 + 15 files changed, 281 insertions(+), 42 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9c0c1223b..99bceddc3 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -122,6 +122,7 @@ SET( tomahawkUI ${tomahawkUI} diagnosticsdialog.ui stackedsettingsdialog.ui proxydialog.ui + searchwidget.ui audiocontrols.ui ) diff --git a/src/libtomahawk/CMakeLists.txt b/src/libtomahawk/CMakeLists.txt index cea658e02..a0027b2d1 100644 --- a/src/libtomahawk/CMakeLists.txt +++ b/src/libtomahawk/CMakeLists.txt @@ -161,6 +161,7 @@ set( libSources utils/xspfgenerator.cpp widgets/newplaylistwidget.cpp + widgets/searchwidget.cpp widgets/playlisttypeselectordlg.cpp widgets/welcomewidget.cpp widgets/welcomeplaylistmodel.cpp @@ -325,6 +326,7 @@ set( libHeaders utils/xspfgenerator.h widgets/newplaylistwidget.h + widgets/searchwidget.h widgets/playlisttypeselectordlg.h widgets/welcomewidget.h widgets/welcomeplaylistmodel.h @@ -343,6 +345,7 @@ set( libHeaders_NoMOC set( libUI ${libUI} widgets/playlisttypeselectordlg.ui widgets/newplaylistwidget.ui + widgets/searchwidget.ui widgets/welcomewidget.ui widgets/infowidgets/sourceinfowidget.ui playlist/topbar/topbar.ui diff --git a/src/libtomahawk/database/databasecommand_resolve.cpp b/src/libtomahawk/database/databasecommand_resolve.cpp index 18975a8a5..876a9685f 100644 --- a/src/libtomahawk/database/databasecommand_resolve.cpp +++ b/src/libtomahawk/database/databasecommand_resolve.cpp @@ -36,23 +36,35 @@ DatabaseCommand_Resolve::DatabaseCommand_Resolve( const query_ptr& query ) void DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) { - QList res; if ( !m_query->resultHint().isEmpty() ) { qDebug() << "Using result-hint to speed up resolving:" << m_query->resultHint(); Tomahawk::result_ptr result = lib->resultFromHint( m_query ); -/* qDebug() << "Result null:" << result.isNull(); - qDebug() << "Collection null:" << result->collection().isNull(); - qDebug() << "Source null:" << result->collection()->source().isNull();*/ + /* qDebug() << "Result null:" << result.isNull(); + * qDebug() << "Collection null:" << result->collection().isNull(); + * qDebug() << "Source null:" << result->collection()->source().isNull();*/ if ( !result.isNull() && !result->collection().isNull() && result->collection()->source()->isOnline() ) { + QList res; res << result; emit results( m_query->id(), res ); return; } } + if ( m_query->isFullTextQuery() ) + fullTextResolve( lib ); + else + resolve( lib ); +} + + +void +DatabaseCommand_Resolve::resolve( DatabaseImpl* lib ) +{ + QList res; + /* Resolving is a 2 stage process. 1) find list of trk/art/alb IDs that are reasonable matches to the metadata given @@ -64,10 +76,10 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) // STEP 1 QList< int > artists = lib->searchTable( "artist", m_query->artist(), 10 ); - QList< int > tracks = lib->searchTable( "track", m_query->track(), 10 ); - QList< int > albums = lib->searchTable( "album", m_query->album(), 10 ); + QList< int > tracks = lib->searchTable( "track", m_query->track(), 10 ); + QList< int > albums = lib->searchTable( "album", m_query->album(), 10 ); - if( artists.length() == 0 || tracks.length() == 0 ) + if ( artists.length() == 0 || tracks.length() == 0 ) { qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track(); emit results( m_query->id(), res ); @@ -83,6 +95,9 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) foreach( int i, tracks ) trksl.append( QString::number( i ) ); + 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 " "url, mtime, size, md5, mimetype, duration, bitrate, file_join.artist, file_join.album, file_join.track, " "artist.name as artname, " @@ -98,10 +113,9 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) "artist.id = file_join.artist AND " "track.id = file_join.track AND " "file.id = file_join.file AND " - "file_join.artist IN (%1) AND " - "file_join.track IN (%2)" ) - .arg( artsl.join( "," ) ) - .arg( trksl.join( "," ) ); + "(%1 AND %2)" ) + .arg( artsToken ) + .arg( trksToken ); files_query.prepare( sql ); files_query.exec(); @@ -160,7 +174,136 @@ DatabaseCommand_Resolve::exec( DatabaseImpl* lib ) float score = how_similar( m_query, result ); result->setScore( score ); - if( score < MINSCORE ) + if ( m_query->fullTextQuery().isEmpty() && score < MINSCORE ) + continue; + + result->setCollection( s->collection() ); + res << result; + } + + emit results( m_query->id(), res ); +} + + +void +DatabaseCommand_Resolve::fullTextResolve( DatabaseImpl* lib ) +{ + QList res; + + /* + * Resolving is a 2 stage process. + * 1) find list of trk/art/alb IDs that are reasonable matches to the metadata given + * 2) find files in database by permitted sources and calculate score, ignoring + * results that are less than MINSCORE + */ + + typedef QPair scorepair_t; + + // STEP 1 + QList< int > artists = lib->searchTable( "artist", m_query->fullTextQuery(), 10 ); + QList< int > tracks = lib->searchTable( "track", m_query->fullTextQuery(), 10 ); + QList< int > albums = lib->searchTable( "album", m_query->fullTextQuery(), 10 ); + + if ( artists.length() == 0 && tracks.length() == 0 && albums.length() == 0 ) + { + qDebug() << "No candidates found in first pass, aborting resolve" << m_query->artist() << m_query->track(); + emit results( m_query->id(), res ); + return; + } + + // STEP 2 + TomahawkSqlQuery files_query = lib->newquery(); + + QStringList artsl, trksl, albsl; + foreach( int i, artists ) + artsl.append( QString::number( i ) ); + foreach( int i, tracks ) + trksl.append( QString::number( i ) ); + foreach( int i, albums ) + albsl.append( QString::number( i ) ); + + QString artsToken = QString( "file_join.artist IN (%1)" ).arg( artsl.join( "," ) ); + QString trksToken = QString( "file_join.track IN (%1)" ).arg( trksl.join( "," ) ); + QString albsToken = QString( "file_join.album IN (%1)" ).arg( albsl.join( "," ) ); + + QString sql = QString( "SELECT " + "url, mtime, size, md5, mimetype, duration, bitrate, file_join.artist, file_join.album, file_join.track, " + "artist.name as artname, " + "album.name as albname, " + "track.name as trkname, " + "file.source, " + "file_join.albumpos, " + "artist.id as artid, " + "album.id as albid " + "FROM file, file_join, artist, track " + "LEFT JOIN album ON album.id = file_join.album " + "WHERE " + "artist.id = file_join.artist AND " + "track.id = file_join.track AND " + "file.id = file_join.file AND " + "(%1 OR %2 OR %3)" ) + .arg( artists.length() > 0 ? artsToken : QString( "0" ) ) + .arg( tracks.length() > 0 ? trksToken : QString( "0" ) ) + .arg( albums.length() > 0 ? albsToken : QString( "0" ) ); + + files_query.prepare( sql ); + files_query.exec(); + + while( files_query.next() ) + { + Tomahawk::result_ptr result( new Tomahawk::Result() ); + source_ptr s; + + const QString url_str = files_query.value( 0 ).toString(); + if( files_query.value( 13 ).toUInt() == 0 ) + { + s = SourceList::instance()->getLocal(); + result->setUrl( url_str ); + } + else + { + s = SourceList::instance()->get( files_query.value( 13 ).toUInt() ); + if( s.isNull() ) + { + qDebug() << "WTF: Could not find source" << files_query.value( 13 ).toUInt(); + continue; + } + + result->setUrl( QString( "servent://%1\t%2" ).arg( s->userName() ).arg( url_str ) ); + } + + Tomahawk::artist_ptr artist = Tomahawk::Artist::get( files_query.value( 15 ).toUInt(), files_query.value( 10 ).toString() ); + Tomahawk::album_ptr album = Tomahawk::Album::get( files_query.value( 16 ).toUInt(), files_query.value( 11 ).toString(), artist ); + + result->setModificationTime( files_query.value( 1 ).toUInt() ); + result->setSize( files_query.value( 2 ).toUInt() ); + result->setMimetype( files_query.value( 4 ).toString() ); + result->setDuration( files_query.value( 5 ).toUInt() ); + result->setBitrate( files_query.value( 6 ).toUInt() ); + result->setArtist( artist ); + result->setAlbum( album ); + result->setTrack( files_query.value( 12 ).toString() ); + result->setRID( uuid() ); + result->setAlbumPos( files_query.value( 14 ).toUInt() ); + result->setId( files_query.value( 9 ).toUInt() ); + result->setYear( files_query.value( 17 ).toUInt() ); + + TomahawkSqlQuery attrQuery = lib->newquery(); + QVariantMap attr; + + attrQuery.prepare( "SELECT k, v FROM track_attributes WHERE id = ?" ); + attrQuery.bindValue( 0, result->dbid() ); + attrQuery.exec(); + while ( attrQuery.next() ) + { + attr[ attrQuery.value( 0 ).toString() ] = attrQuery.value( 1 ).toString(); + } + + result->setAttributes( attr ); + + float score = how_similar( m_query, result ); + result->setScore( score ); + if ( m_query->fullTextQuery().isEmpty() && score < MINSCORE ) continue; result->setCollection( s->collection() ); diff --git a/src/libtomahawk/database/databasecommand_resolve.h b/src/libtomahawk/database/databasecommand_resolve.h index 8c194451e..bc46d0de5 100644 --- a/src/libtomahawk/database/databasecommand_resolve.h +++ b/src/libtomahawk/database/databasecommand_resolve.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -44,6 +44,9 @@ signals: public slots: private: + void fullTextResolve( DatabaseImpl* lib ); + void resolve( DatabaseImpl* lib ); + Tomahawk::query_ptr m_query; float how_similar( const Tomahawk::query_ptr& q, const Tomahawk::result_ptr& r ); diff --git a/src/libtomahawk/pipeline.cpp b/src/libtomahawk/pipeline.cpp index 70b7edcdf..e99755887 100644 --- a/src/libtomahawk/pipeline.cpp +++ b/src/libtomahawk/pipeline.cpp @@ -190,7 +190,7 @@ Pipeline::reportResults( QID qid, const QList< result_ptr >& results ) m_rids.insert( r->id(), r ); } - if ( q->solved() ) + if ( q->solved() && !q->isFullTextQuery() ) { // qDebug() << "FINISHED RESOLVING EARLY" << q->toString(); q->onResolvingFinished(); @@ -206,7 +206,7 @@ Pipeline::reportResults( QID qid, const QList< result_ptr >& results ) if ( decQIDState( q ) == 0 ) { - if ( !q->solved() ) + if ( !q->solved() || q->isFullTextQuery() ) q->onResolvingFinished(); if ( m_qidsTimeout.contains( q->id() ) ) diff --git a/src/libtomahawk/playlist/topbar/searchlineedit.h b/src/libtomahawk/playlist/topbar/searchlineedit.h index bdfeddc94..4b7859881 100644 --- a/src/libtomahawk/playlist/topbar/searchlineedit.h +++ b/src/libtomahawk/playlist/topbar/searchlineedit.h @@ -33,7 +33,7 @@ class ClearButton; class SearchButton; -class SearchLineEdit : public LineEdit +class DLLEXPORT SearchLineEdit : public LineEdit { Q_OBJECT diff --git a/src/libtomahawk/playlist/trackproxymodel.cpp b/src/libtomahawk/playlist/trackproxymodel.cpp index 91f082ecd..dbc22c543 100644 --- a/src/libtomahawk/playlist/trackproxymodel.cpp +++ b/src/libtomahawk/playlist/trackproxymodel.cpp @@ -174,7 +174,7 @@ TrackProxyModel::filterAcceptsRow( int sourceRow, const QModelIndex& sourceParen if ( q->numResults() ) r = q->results().first(); - if ( !m_showOfflineResults && !r.isNull() && !r->collection()->source()->isOnline() ) + if ( !m_showOfflineResults && !r.isNull() && !r->isOnline() ) return false; if ( filterRegExp().isEmpty() ) diff --git a/src/libtomahawk/query.cpp b/src/libtomahawk/query.cpp index 413ab4c96..96dad8007 100644 --- a/src/libtomahawk/query.cpp +++ b/src/libtomahawk/query.cpp @@ -42,6 +42,17 @@ Query::get( const QString& artist, const QString& track, const QString& album, c } +query_ptr +Query::get( const QString& query, const QID& qid ) +{ + query_ptr q = query_ptr( new Query( query, qid ) ); + + if ( !qid.isEmpty() ) + Pipeline::instance()->resolve( q ); + return q; +} + + Query::Query( const QString& artist, const QString& track, const QString& album, const QID& qid ) : m_solved( false ) , m_playable( false ) @@ -59,6 +70,21 @@ Query::Query( const QString& artist, const QString& track, const QString& album, } +Query::Query( const QString& query, const QID& qid ) + : m_solved( false ) + , m_playable( false ) + , m_resolveFinished( false ) + , m_qid( qid ) + , m_fullTextQuery( query ) + , m_duration( -1 ) +{ + if ( !qid.isEmpty() ) + { + connect( Database::instance(), SIGNAL( indexReady() ), SLOT( refreshResults() ), Qt::QueuedConnection ); + } +} + + void Query::addResults( const QList< Tomahawk::result_ptr >& newresults ) { diff --git a/src/libtomahawk/query.h b/src/libtomahawk/query.h index ddc447729..59a218f45 100644 --- a/src/libtomahawk/query.h +++ b/src/libtomahawk/query.h @@ -1,5 +1,5 @@ /* === This file is part of Tomahawk Player - === - * + * * Copyright 2010-2011, Christian Muehlhaeuser * * Tomahawk is free software: you can redistribute it and/or modify @@ -46,7 +46,10 @@ friend class ::DatabaseCommand_LoadPlaylistEntries; public: static query_ptr get( const QString& artist, const QString& track, const QString& album, const QID& qid = QString() ); + static query_ptr get( const QString& query, const QID& qid ); + explicit Query( const QString& artist, const QString& track, const QString& album, const QID& qid ); + explicit Query( const QString& query, const QID& qid ); /// returns list of all results so far QList< result_ptr > results() const; @@ -64,8 +67,9 @@ public: /// true when any result has been found (score may be less than 1.0) bool playable() const { return m_playable; } + bool isFullTextQuery() const { return !m_fullTextQuery.isEmpty(); } bool resolvingFinished() const { return m_resolveFinished; } - + unsigned int lastPipelineWeight() const { return m_lastpipelineweight; } void setLastPipelineWeight( unsigned int w ) { m_lastpipelineweight = w; } @@ -75,7 +79,7 @@ public: void setResultHint( const QString& resultHint ) { m_resultHint = resultHint; } void setDuration( int duration ) { m_duration = duration; } void setResolveFinished( bool resolved ) { m_resolveFinished = resolved; } - + QVariant toVariant() const; QString toString() const; @@ -83,6 +87,7 @@ public: QString artist() const { return m_artist; } QString album() const { return m_album; } QString track() const { return m_track; } + QString fullTextQuery() const { return m_fullTextQuery; } int duration() const { return m_duration; } signals: @@ -92,7 +97,7 @@ signals: void resultsChanged(); void solvedStateChanged( bool state ); void resolvingFinished( bool hasResults ); - + public slots: /// (indirectly) called by resolver plugins when results are found void addResults( const QList< Tomahawk::result_ptr >& ); @@ -118,6 +123,8 @@ private: QString m_artist; QString m_album; QString m_track; + QString m_fullTextQuery; + int m_duration; QString m_resultHint; diff --git a/src/libtomahawk/viewmanager.cpp b/src/libtomahawk/viewmanager.cpp index 1fbd10fb9..806895722 100644 --- a/src/libtomahawk/viewmanager.cpp +++ b/src/libtomahawk/viewmanager.cpp @@ -584,7 +584,7 @@ ViewManager::setPage( ViewPage* page, bool trackHistory ) // save the old playlist shuffle state in config before we change playlists saveCurrentPlaylistSettings(); - + unlinkPlaylist(); if ( !m_pageHistory.contains( page ) ) @@ -630,6 +630,7 @@ ViewManager::setPage( ViewPage* page, bool trackHistory ) updateView(); } + bool ViewManager::isNewPlaylistPageVisible() const { @@ -661,7 +662,7 @@ ViewManager::saveCurrentPlaylistSettings() { TomahawkSettings* s = TomahawkSettings::instance(); Tomahawk::playlist_ptr pl = playlistForInterface( currentPlaylistInterface() ); - + if ( !pl.isNull() ) { s->setShuffleState( pl->guid(), currentPlaylistInterface()->shuffled() ); s->setRepeatMode( pl->guid(), currentPlaylistInterface()->repeatMode() ); @@ -726,7 +727,7 @@ ViewManager::updateView() m_infobar->setCaption( currentPage()->title() ); m_infobar->setDescription( currentPage()->description() ); m_infobar->setPixmap( currentPage()->pixmap() ); - + // turn on shuffle/repeat mode for the new playlist view if specified in config loadCurrentPlaylistSettings(); } @@ -739,7 +740,7 @@ ViewManager::loadCurrentPlaylistSettings() if ( !pl.isNull() ) { currentPlaylistInterface()->setShuffled( s->shuffleState( pl->guid() )); currentPlaylistInterface()->setRepeatMode( s->repeatMode( pl->guid() )); - } else { + } else { Tomahawk::dynplaylist_ptr dynPl = dynamicPlaylistForInterface( currentPlaylistInterface() ); if ( !dynPl.isNull() ) { currentPlaylistInterface()->setShuffled( s->shuffleState( dynPl->guid() )); diff --git a/src/libtomahawk/widgets/newplaylistwidget.cpp b/src/libtomahawk/widgets/newplaylistwidget.cpp index 30481b96b..2bb826b49 100644 --- a/src/libtomahawk/widgets/newplaylistwidget.cpp +++ b/src/libtomahawk/widgets/newplaylistwidget.cpp @@ -125,11 +125,9 @@ NewPlaylistWidget::suggestionsFound() m_suggestionsModel = new PlaylistModel( ui->suggestionsView ); ui->suggestionsView->setPlaylistModel( m_suggestionsModel ); - QList ql; foreach( const Tomahawk::query_ptr& query, m_queries ) { m_suggestionsModel->append( query ); - ql.append( query ); } loader->deleteLater(); diff --git a/src/resolvers/qtscriptresolver.cpp b/src/resolvers/qtscriptresolver.cpp index 4fe9704dc..a069ab5cf 100644 --- a/src/resolvers/qtscriptresolver.cpp +++ b/src/resolvers/qtscriptresolver.cpp @@ -75,11 +75,24 @@ QtScriptResolver::resolve( const Tomahawk::query_ptr& query ) } // qDebug() << Q_FUNC_INFO << query->toString(); - QString eval = QString( "resolve( '%1', '%2', '%3', '%4' );" ) - .arg( query->id().replace( "'", "\\'" ) ) - .arg( query->artist().replace( "'", "\\'" ) ) - .arg( query->album().replace( "'", "\\'" ) ) - .arg( query->track().replace( "'", "\\'" ) ); + QString eval; + + if ( !query->isFullTextQuery() ) + { + eval = QString( "resolve( '%1', '%2', '%3', '%4' );" ) + .arg( query->id().replace( "'", "\\'" ) ) + .arg( query->artist().replace( "'", "\\'" ) ) + .arg( query->album().replace( "'", "\\'" ) ) + .arg( query->track().replace( "'", "\\'" ) ); + } + else + { + eval = QString( "resolve( '%1', '%2', '%3', '%4' );" ) + .arg( query->id().replace( "'", "\\'" ) ) + .arg( query->fullTextQuery().replace( "'", "\\'" ) ) + .arg( QString() ) + .arg( QString() ); + } QList< Tomahawk::result_ptr > results; diff --git a/src/resolvers/scriptresolver.cpp b/src/resolvers/scriptresolver.cpp index 76e44d1f7..c9f6b9f48 100644 --- a/src/resolvers/scriptresolver.cpp +++ b/src/resolvers/scriptresolver.cpp @@ -208,12 +208,22 @@ ScriptResolver::resolve( const Tomahawk::query_ptr& query ) { QVariantMap m; m.insert( "_msgtype", "rq" ); - m.insert( "artist", query->artist() ); - m.insert( "track", query->track() ); - m.insert( "qid", query->id() ); + + if ( query->isFullTextQuery() ) + { + m.insert( "fulltext", query->fullTextQuery() ); + m.insert( "artist", query->artist() ); + m.insert( "track", query->fullTextQuery() ); + m.insert( "qid", query->id() ); + } + else + { + m.insert( "artist", query->artist() ); + m.insert( "track", query->track() ); + m.insert( "qid", query->id() ); + } const QByteArray msg = m_serializer.serialize( QVariant( m ) ); -// qDebug() << "ASKING SCRIPT RESOLVER TO RESOLVE:" << msg; sendMsg( msg ); } diff --git a/src/tomahawkwindow.cpp b/src/tomahawkwindow.cpp index c83332f70..1011b270c 100644 --- a/src/tomahawkwindow.cpp +++ b/src/tomahawkwindow.cpp @@ -18,6 +18,7 @@ #include "tomahawkwindow.h" #include "ui_tomahawkwindow.h" +#include "ui_searchwidget.h" #include "config.h" @@ -28,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -50,6 +52,7 @@ #include "utils/widgetdragfilter.h" #include "utils/xspfloader.h" #include "widgets/newplaylistwidget.h" +#include "widgets/searchwidget.h" #include "widgets/playlisttypeselectordlg.h" #include "audiocontrols.h" @@ -74,6 +77,7 @@ using namespace Tomahawk; TomahawkWindow::TomahawkWindow( QWidget* parent ) : QMainWindow( parent ) , ui( new Ui::TomahawkWindow ) + , m_searchWidget( new Ui::SearchWidget ) , m_audioControls( new AudioControls( this ) ) , m_trayIcon( new TomahawkTrayIcon( this ) ) , m_sourcetree( 0 ) @@ -92,7 +96,9 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) connect( m_audioControls, SIGNAL( playPressed() ), pm, SLOT( onPlayClicked() ) ); connect( m_audioControls, SIGNAL( pausePressed() ), pm, SLOT( onPauseClicked() ) ); + m_searchBox = new QWidget(); ui->setupUi( this ); + m_searchWidget->setupUi( m_searchBox ); delete ui->sidebarWidget; delete ui->playlistWidget; @@ -186,6 +192,14 @@ TomahawkWindow::TomahawkWindow( QWidget* parent ) m_forwardAvailable = toolbar->addAction( QIcon( RESPATH "images/forward.png" ), tr( "Forward" ), ViewManager::instance(), SLOT( historyForward() ) ); m_forwardAvailable->setToolTip( tr( "Go forward one page" ) ); + m_searchWidget->searchEdit->setStyleSheet( "QLineEdit { border: 1px solid gray; border-radius: 6px; margin-right: 2px; }" ); +#ifdef Q_WS_MAC + ui->filterEdit->setAttribute( Qt::WA_MacShowFocusRect, 0 ); +#endif + + connect( m_searchWidget->searchEdit, SIGNAL( returnPressed() ), SLOT( onSearch() ) ); + toolbar->addWidget( m_searchBox ); + statusBar()->addPermanentWidget( m_audioControls, 1 ); // propagate sip menu @@ -488,14 +502,17 @@ TomahawkWindow::createPlaylist() PlaylistTypeSelectorDlg playlistSelectorDlg; int successfulReturn = playlistSelectorDlg.exec(); - if ( !playlistSelectorDlg.playlistTypeIsAuto() && successfulReturn ) { - + if ( !playlistSelectorDlg.playlistTypeIsAuto() && successfulReturn ) + { // only show if none is shown yet - if( !ViewManager::instance()->isNewPlaylistPageVisible() ) { + if ( !ViewManager::instance()->isNewPlaylistPageVisible() ) + { ViewManager::instance()->show( new NewPlaylistWidget() ); } - } else if ( playlistSelectorDlg.playlistTypeIsAuto() && successfulReturn ) { + } + else if ( playlistSelectorDlg.playlistTypeIsAuto() && successfulReturn ) + { // create Auto Playlist QString playlistName = playlistSelectorDlg.playlistName(); APP->mainWindow()->createAutomaticPlaylist( playlistName ); @@ -600,13 +617,23 @@ TomahawkWindow::checkForUpdates() } +void +TomahawkWindow::onSearch() +{ + ViewManager::instance()->show( new SearchWidget( m_searchWidget->searchEdit->text() ) ); + m_searchWidget->searchEdit->setText( QString() ); +} + + void TomahawkWindow::minimize() { if ( isMinimized() ) { showNormal(); - } else { + } + else + { showMinimized(); } } @@ -618,7 +645,9 @@ TomahawkWindow::maximize() if ( isMaximized() ) { showNormal(); - } else { + } + else + { showMaximized(); } } diff --git a/src/tomahawkwindow.h b/src/tomahawkwindow.h index e724f7313..a9799838a 100644 --- a/src/tomahawkwindow.h +++ b/src/tomahawkwindow.h @@ -38,6 +38,7 @@ class TomahawkTrayIcon; namespace Ui { class TomahawkWindow; + class SearchWidget; } class TomahawkWindow : public QMainWindow @@ -88,6 +89,8 @@ private slots: void onSipPluginAdded( SipPlugin* p ); void onSipPluginRemoved( SipPlugin* p ); + void onSearch(); + void minimize(); void maximize(); @@ -97,6 +100,8 @@ private: void setupSignals(); Ui::TomahawkWindow* ui; + Ui::SearchWidget* m_searchWidget; + QWidget* m_searchBox; AudioControls* m_audioControls; TomahawkTrayIcon* m_trayIcon; SourceTreeView* m_sourcetree;