2018-08-09 18:10:03 +02:00
/*
* Strawberry Music Player
* This code was part of Clementine ( GlobalSearch )
* Copyright 2012 , David Sansome < me @ davidsansome . com >
2021-03-20 21:14:47 +01:00
* Copyright 2018 - 2021 , Jonas Kvinge < jonas @ jkvinge . net >
2018-08-09 18:10:03 +02:00
*
* Strawberry 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 .
*
* Strawberry 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 Strawberry . If not , see < http : //www.gnu.org/licenses/>.
*
*/
# include "config.h"
2020-04-20 18:03:18 +02:00
# include <memory>
2020-04-13 06:30:40 +02:00
# include <utility>
2018-08-09 18:10:03 +02:00
# include <QtGlobal>
2020-04-13 06:30:40 +02:00
# include <QObject>
# include <QAbstractItemModel>
# include <QStandardItemModel>
# include <QItemSelectionModel>
# include <QSortFilterProxyModel>
# include <QApplication>
2018-08-09 18:10:03 +02:00
# include <QWidget>
# include <QTimer>
2020-04-20 18:03:18 +02:00
# include <QPair>
2018-08-09 18:10:03 +02:00
# include <QList>
2020-04-13 06:30:40 +02:00
# include <QMap>
# include <QVariant>
2018-08-09 18:10:03 +02:00
# include <QString>
2020-04-13 06:30:40 +02:00
# include <QStringList>
2020-07-18 04:05:07 +02:00
# include <QRegularExpression>
2020-04-13 06:30:40 +02:00
# include <QUrl>
# include <QImage>
2018-08-09 18:10:03 +02:00
# include <QPixmap>
2021-07-11 01:43:52 +02:00
# include <QPixmapCache>
2020-04-13 06:30:40 +02:00
# include <QPainter>
2018-08-09 18:10:03 +02:00
# include <QPalette>
# include <QColor>
# include <QFont>
2020-04-13 06:30:40 +02:00
# include <QSize>
2018-08-09 18:10:03 +02:00
# include <QStandardItem>
2019-05-27 21:10:37 +02:00
# include <QMenu>
2018-08-09 18:10:03 +02:00
# include <QAction>
2020-04-13 06:30:40 +02:00
# include <QActionGroup>
2019-05-27 21:10:37 +02:00
# include <QSettings>
2020-04-13 06:30:40 +02:00
# include <QStackedWidget>
# include <QLabel>
# include <QProgressBar>
# include <QRadioButton>
# include <QScrollArea>
# include <QToolButton>
# include <QEvent>
# include <QTimerEvent>
# include <QKeyEvent>
# include <QContextMenuEvent>
# include <QShowEvent>
# include <QHideEvent>
# include <QtGlobal>
2018-08-09 18:10:03 +02:00
# include "core/application.h"
# include "core/mimedata.h"
# include "core/iconloader.h"
2020-04-13 06:30:40 +02:00
# include "core/song.h"
2020-04-20 18:03:18 +02:00
# include "core/logging.h"
2018-08-09 18:10:03 +02:00
# include "collection/collectionfilterwidget.h"
# include "collection/collectionmodel.h"
# include "collection/groupbydialog.h"
2020-04-13 06:30:40 +02:00
# include "covermanager/albumcoverloader.h"
2020-04-20 18:03:18 +02:00
# include "covermanager/albumcoverloaderoptions.h"
# include "covermanager/albumcoverloaderresult.h"
2020-04-13 06:30:40 +02:00
# include "internetsongmimedata.h"
# include "internetservice.h"
2018-10-17 21:18:39 +02:00
# include "internetsearchitemdelegate.h"
# include "internetsearchmodel.h"
# include "internetsearchsortmodel.h"
# include "internetsearchview.h"
# include "ui_internetsearchview.h"
2020-06-28 18:36:48 +02:00
# include "settings/appearancesettingspage.h"
2018-08-09 18:10:03 +02:00
2018-10-17 21:18:39 +02:00
const int InternetSearchView : : kSwapModelsTimeoutMsec = 250 ;
2020-04-13 06:30:40 +02:00
const int InternetSearchView : : kDelayedSearchTimeoutMs = 200 ;
const int InternetSearchView : : kArtHeight = 32 ;
2018-08-09 18:10:03 +02:00
2019-05-27 21:10:37 +02:00
InternetSearchView : : InternetSearchView ( QWidget * parent )
2018-08-09 18:10:03 +02:00
: QWidget ( parent ) ,
2019-05-27 21:10:37 +02:00
app_ ( nullptr ) ,
2020-04-13 06:30:40 +02:00
service_ ( nullptr ) ,
2018-10-17 21:18:39 +02:00
ui_ ( new Ui_InternetSearchView ) ,
2018-08-09 18:10:03 +02:00
context_menu_ ( nullptr ) ,
2020-04-13 06:30:40 +02:00
group_by_actions_ ( nullptr ) ,
2019-05-27 21:10:37 +02:00
front_model_ ( nullptr ) ,
back_model_ ( nullptr ) ,
current_model_ ( nullptr ) ,
2018-10-17 21:18:39 +02:00
front_proxy_ ( new InternetSearchSortModel ( this ) ) ,
back_proxy_ ( new InternetSearchSortModel ( this ) ) ,
2018-08-09 18:10:03 +02:00
current_proxy_ ( front_proxy_ ) ,
swap_models_timer_ ( new QTimer ( this ) ) ,
2020-04-20 18:03:18 +02:00
use_pretty_covers_ ( true ) ,
2020-04-13 06:30:40 +02:00
search_type_ ( InternetSearchView : : SearchType_Artists ) ,
search_error_ ( false ) ,
last_search_id_ ( 0 ) ,
2020-04-20 18:03:18 +02:00
searches_next_id_ ( 1 ) {
2018-08-09 18:10:03 +02:00
ui_ - > setupUi ( this ) ;
2019-05-27 21:10:37 +02:00
2018-08-09 18:10:03 +02:00
ui_ - > search - > installEventFilter ( this ) ;
ui_ - > results_stack - > installEventFilter ( this ) ;
ui_ - > settings - > setIcon ( IconLoader : : Load ( " configure " ) ) ;
// Set the appearance of the results list
2018-10-17 21:18:39 +02:00
ui_ - > results - > setItemDelegate ( new InternetSearchItemDelegate ( this ) ) ;
2018-08-09 18:10:03 +02:00
ui_ - > results - > setAttribute ( Qt : : WA_MacShowFocusRect , false ) ;
ui_ - > results - > setStyleSheet ( " QTreeView::item{padding-top:1px;} " ) ;
// Show the help page initially
ui_ - > results_stack - > setCurrentWidget ( ui_ - > help_page ) ;
ui_ - > help_frame - > setBackgroundRole ( QPalette : : Base ) ;
// Set the colour of the help text to the disabled window text colour
QPalette help_palette = ui_ - > label_helptext - > palette ( ) ;
const QColor help_color = help_palette . color ( QPalette : : Disabled , QPalette : : WindowText ) ;
help_palette . setColor ( QPalette : : Normal , QPalette : : WindowText , help_color ) ;
help_palette . setColor ( QPalette : : Inactive , QPalette : : WindowText , help_color ) ;
ui_ - > label_helptext - > setPalette ( help_palette ) ;
// Make it bold
QFont help_font = ui_ - > label_helptext - > font ( ) ;
help_font . setBold ( true ) ;
ui_ - > label_helptext - > setFont ( help_font ) ;
2020-04-13 06:30:40 +02:00
// Hide progressbar
ui_ - > progressbar - > hide ( ) ;
ui_ - > progressbar - > reset ( ) ;
cover_loader_options_ . desired_height_ = kArtHeight ;
cover_loader_options_ . pad_output_image_ = true ;
cover_loader_options_ . scale_output_image_ = true ;
2019-05-27 21:10:37 +02:00
}
InternetSearchView : : ~ InternetSearchView ( ) { delete ui_ ; }
2020-04-13 06:30:40 +02:00
void InternetSearchView : : Init ( Application * app , InternetService * service ) {
2019-05-27 21:10:37 +02:00
app_ = app ;
2020-04-13 06:30:40 +02:00
service_ = service ;
2019-05-27 21:10:37 +02:00
2020-04-13 06:30:40 +02:00
front_model_ = new InternetSearchModel ( service , this ) ;
back_model_ = new InternetSearchModel ( service , this ) ;
2019-05-27 21:10:37 +02:00
front_proxy_ = new InternetSearchSortModel ( this ) ;
back_proxy_ = new InternetSearchSortModel ( this ) ;
front_model_ - > set_proxy ( front_proxy_ ) ;
back_model_ - > set_proxy ( back_proxy_ ) ;
current_model_ = front_model_ ;
current_proxy_ = front_proxy_ ;
2020-04-20 18:03:18 +02:00
2018-08-09 18:10:03 +02:00
// Set up the sorting proxy model
front_proxy_ - > setSourceModel ( front_model_ ) ;
front_proxy_ - > setDynamicSortFilter ( true ) ;
front_proxy_ - > sort ( 0 ) ;
back_proxy_ - > setSourceModel ( back_model_ ) ;
back_proxy_ - > setDynamicSortFilter ( true ) ;
back_proxy_ - > sort ( 0 ) ;
// Add actions to the settings menu
group_by_actions_ = CollectionFilterWidget : : CreateGroupByActions ( this ) ;
QMenu * settings_menu = new QMenu ( this ) ;
settings_menu - > addActions ( group_by_actions_ - > actions ( ) ) ;
settings_menu - > addSeparator ( ) ;
2021-01-26 16:48:04 +01:00
settings_menu - > addAction ( IconLoader : : Load ( " configure " ) , tr ( " Configure %1... " ) . arg ( Song : : TextForSource ( service_ - > source ( ) ) ) , this , & InternetSearchView : : OpenSettingsDialog ) ;
2018-08-09 18:10:03 +02:00
ui_ - > settings - > setMenu ( settings_menu ) ;
2019-05-27 21:10:37 +02:00
swap_models_timer_ - > setSingleShot ( true ) ;
swap_models_timer_ - > setInterval ( kSwapModelsTimeoutMsec ) ;
2021-01-26 16:48:04 +01:00
QObject : : connect ( swap_models_timer_ , & QTimer : : timeout , this , & InternetSearchView : : SwapModels ) ;
2019-05-27 21:10:37 +02:00
2021-01-26 16:48:04 +01:00
QObject : : connect ( ui_ - > radiobutton_search_artists , & QRadioButton : : clicked , this , & InternetSearchView : : SearchArtistsClicked ) ;
QObject : : connect ( ui_ - > radiobutton_search_albums , & QRadioButton : : clicked , this , & InternetSearchView : : SearchAlbumsClicked ) ;
QObject : : connect ( ui_ - > radiobutton_search_songs , & QRadioButton : : clicked , this , & InternetSearchView : : SearchSongsClicked ) ;
QObject : : connect ( group_by_actions_ , & QActionGroup : : triggered , this , & InternetSearchView : : GroupByClicked ) ;
QObject : : connect ( group_by_actions_ , & QActionGroup : : triggered , this , & InternetSearchView : : GroupByClicked ) ;
2018-08-09 18:10:03 +02:00
2021-01-26 16:48:04 +01:00
QObject : : connect ( ui_ - > search , & QSearchField : : textChanged , this , & InternetSearchView : : TextEdited ) ;
QObject : : connect ( ui_ - > results , & AutoExpandingTreeView : : AddToPlaylistSignal , this , & InternetSearchView : : AddToPlaylist ) ;
QObject : : connect ( ui_ - > results , & AutoExpandingTreeView : : FocusOnFilterSignal , this , & InternetSearchView : : FocusOnFilter ) ;
2019-05-27 21:10:37 +02:00
2021-01-26 16:48:04 +01:00
QObject : : connect ( service_ , & InternetService : : SearchUpdateStatus , this , & InternetSearchView : : UpdateStatus ) ;
QObject : : connect ( service_ , & InternetService : : SearchProgressSetMaximum , this , & InternetSearchView : : ProgressSetMaximum ) ;
QObject : : connect ( service_ , & InternetService : : SearchUpdateProgress , this , & InternetSearchView : : UpdateProgress ) ;
QObject : : connect ( service_ , & InternetService : : SearchResults , this , & InternetSearchView : : SearchDone ) ;
2018-09-06 17:39:26 +02:00
2021-01-26 16:48:04 +01:00
QObject : : connect ( app_ , & Application : : SettingsChanged , this , & InternetSearchView : : ReloadSettings ) ;
QObject : : connect ( app_ - > album_cover_loader ( ) , & AlbumCoverLoader : : AlbumCoverLoaded , this , & InternetSearchView : : AlbumCoverLoaded ) ;
2018-08-09 18:10:03 +02:00
2022-01-10 22:51:27 +01:00
QObject : : connect ( ui_ - > settings , & QToolButton : : clicked , ui_ - > settings , & QToolButton : : showMenu ) ;
2018-08-09 18:10:03 +02:00
ReloadSettings ( ) ;
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : ReloadSettings ( ) {
2018-08-09 18:10:03 +02:00
QSettings s ;
// Collection settings
2020-04-13 06:30:40 +02:00
s . beginGroup ( service_ - > settings_group ( ) ) ;
2020-04-20 18:03:18 +02:00
use_pretty_covers_ = s . value ( " pretty_covers " , true ) . toBool ( ) ;
front_model_ - > set_use_pretty_covers ( use_pretty_covers_ ) ;
back_model_ - > set_use_pretty_covers ( use_pretty_covers_ ) ;
2018-08-09 18:10:03 +02:00
2018-10-17 21:18:39 +02:00
// Internet search settings
2018-08-09 18:10:03 +02:00
2021-10-11 22:28:28 +02:00
search_type_ = InternetSearchView : : SearchType ( s . value ( " type " , static_cast < int > ( InternetSearchView : : SearchType_Artists ) ) . toInt ( ) ) ;
2019-02-12 21:58:03 +01:00
switch ( search_type_ ) {
2020-04-13 06:30:40 +02:00
case InternetSearchView : : SearchType_Artists :
2019-02-12 21:58:03 +01:00
ui_ - > radiobutton_search_artists - > setChecked ( true ) ;
2018-08-09 18:10:03 +02:00
break ;
2020-04-13 06:30:40 +02:00
case InternetSearchView : : SearchType_Albums :
2019-02-12 21:58:03 +01:00
ui_ - > radiobutton_search_albums - > setChecked ( true ) ;
break ;
2020-04-13 06:30:40 +02:00
case InternetSearchView : : SearchType_Songs :
2019-02-12 21:58:03 +01:00
ui_ - > radiobutton_search_songs - > setChecked ( true ) ;
2018-08-09 18:10:03 +02:00
break ;
}
2020-09-12 00:32:50 +02:00
int group_by_version = s . value ( " search_group_by_version " , 0 ) . toInt ( ) ;
if ( group_by_version = = 1 & & s . contains ( " search_group_by1 " ) & & s . contains ( " search_group_by2 " ) & & s . contains ( " search_group_by3 " ) ) {
SetGroupBy ( CollectionModel : : Grouping (
2021-10-11 22:28:28 +02:00
CollectionModel : : GroupBy ( s . value ( " search_group_by1 " , static_cast < int > ( CollectionModel : : GroupBy_AlbumArtist ) ) . toInt ( ) ) ,
CollectionModel : : GroupBy ( s . value ( " search_group_by2 " , static_cast < int > ( CollectionModel : : GroupBy_AlbumDisc ) ) . toInt ( ) ) ,
CollectionModel : : GroupBy ( s . value ( " search_group_by3 " , static_cast < int > ( CollectionModel : : GroupBy_None ) ) . toInt ( ) ) ) ) ;
2020-09-12 00:32:50 +02:00
}
else {
SetGroupBy ( CollectionModel : : Grouping ( CollectionModel : : GroupBy ( CollectionModel : : GroupBy_AlbumArtist ) , CollectionModel : : GroupBy ( CollectionModel : : GroupBy_AlbumDisc ) , CollectionModel : : GroupBy ( CollectionModel : : GroupBy_None ) ) ) ;
}
2018-08-09 18:10:03 +02:00
s . endGroup ( ) ;
2020-06-28 18:36:48 +02:00
s . beginGroup ( AppearanceSettingsPage : : kSettingsGroup ) ;
int iconsize = s . value ( AppearanceSettingsPage : : kIconSizeConfigureButtons , 20 ) . toInt ( ) ;
s . endGroup ( ) ;
2021-04-10 09:56:59 +02:00
2020-06-28 18:36:48 +02:00
ui_ - > settings - > setIconSize ( QSize ( iconsize , iconsize ) ) ;
2020-06-29 01:09:02 +02:00
ui_ - > search - > setIconSize ( iconsize ) ;
2020-06-28 18:36:48 +02:00
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : showEvent ( QShowEvent * e ) {
QWidget : : showEvent ( e ) ;
2021-04-10 09:56:59 +02:00
# ifndef Q_OS_MACOS
2020-04-13 06:30:40 +02:00
FocusSearchField ( ) ;
2021-04-10 09:56:59 +02:00
# endif
2020-04-13 06:30:40 +02:00
}
bool InternetSearchView : : eventFilter ( QObject * object , QEvent * e ) {
if ( object = = ui_ - > search & & e - > type ( ) = = QEvent : : KeyRelease ) {
if ( SearchKeyEvent ( static_cast < QKeyEvent * > ( e ) ) ) {
return true ;
}
}
else if ( object = = ui_ - > results_stack & & e - > type ( ) = = QEvent : : ContextMenu ) {
if ( ResultsContextMenuEvent ( static_cast < QContextMenuEvent * > ( e ) ) ) {
return true ;
}
}
return QWidget : : eventFilter ( object , e ) ;
}
bool InternetSearchView : : SearchKeyEvent ( QKeyEvent * e ) {
switch ( e - > key ( ) ) {
case Qt : : Key_Up :
ui_ - > results - > UpAndFocus ( ) ;
break ;
case Qt : : Key_Down :
ui_ - > results - > DownAndFocus ( ) ;
break ;
case Qt : : Key_Escape :
ui_ - > search - > clear ( ) ;
break ;
case Qt : : Key_Return :
TextEdited ( ui_ - > search - > text ( ) ) ;
break ;
default :
return false ;
}
e - > accept ( ) ;
return true ;
}
bool InternetSearchView : : ResultsContextMenuEvent ( QContextMenuEvent * e ) {
2021-07-11 01:52:21 +02:00
if ( ! context_menu_ ) {
context_menu_ = new QMenu ( this ) ;
2021-07-11 02:27:26 +02:00
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " media-playback-start " ) , tr ( " Append to current playlist " ) , this , & InternetSearchView : : AddSelectedToPlaylist ) ;
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " media-playback-start " ) , tr ( " Replace current playlist " ) , this , & InternetSearchView : : LoadSelected ) ;
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " document-new " ) , tr ( " Open in new playlist " ) , this , & InternetSearchView : : OpenSelectedInNewPlaylist ) ;
2020-04-13 06:30:40 +02:00
2021-07-11 01:52:21 +02:00
context_menu_ - > addSeparator ( ) ;
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " go-next " ) , tr ( " Queue track " ) , this , & InternetSearchView : : AddSelectedToPlaylistEnqueue ) ;
2020-04-13 06:30:40 +02:00
2021-07-11 01:52:21 +02:00
context_menu_ - > addSeparator ( ) ;
2020-04-13 06:30:40 +02:00
2021-07-11 01:52:21 +02:00
if ( service_ - > artists_collection_model ( ) | | service_ - > albums_collection_model ( ) | | service_ - > songs_collection_model ( ) ) {
if ( service_ - > artists_collection_model ( ) ) {
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " folder-new " ) , tr ( " Add to artists " ) , this , & InternetSearchView : : AddArtists ) ;
}
if ( service_ - > albums_collection_model ( ) ) {
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " folder-new " ) , tr ( " Add to albums " ) , this , & InternetSearchView : : AddAlbums ) ;
}
if ( service_ - > songs_collection_model ( ) ) {
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " folder-new " ) , tr ( " Add to songs " ) , this , & InternetSearchView : : AddSongs ) ;
}
context_menu_ - > addSeparator ( ) ;
2020-04-13 06:30:40 +02:00
}
2021-07-11 01:52:21 +02:00
if ( ui_ - > results - > selectionModel ( ) & & ui_ - > results - > selectionModel ( ) - > selectedRows ( ) . length ( ) = = 1 ) {
context_actions_ < < context_menu_ - > addAction ( IconLoader : : Load ( " search " ) , tr ( " Search for this " ) , this , & InternetSearchView : : SearchForThis ) ;
2020-04-13 06:30:40 +02:00
}
2021-07-11 01:52:21 +02:00
context_menu_ - > addSeparator ( ) ;
context_menu_ - > addMenu ( tr ( " Group by " ) ) - > addActions ( group_by_actions_ - > actions ( ) ) ;
2020-04-13 06:30:40 +02:00
2021-07-11 01:52:21 +02:00
context_menu_ - > addAction ( IconLoader : : Load ( " configure " ) , tr ( " Configure %1... " ) . arg ( Song : : TextForSource ( service_ - > source ( ) ) ) , this , & InternetSearchView : : OpenSettingsDialog ) ;
2020-04-13 06:30:40 +02:00
2021-07-11 01:52:21 +02:00
}
2020-04-13 06:30:40 +02:00
const bool enable_context_actions = ui_ - > results - > selectionModel ( ) & & ui_ - > results - > selectionModel ( ) - > hasSelection ( ) ;
for ( QAction * action : context_actions_ ) {
action - > setEnabled ( enable_context_actions ) ;
}
context_menu_ - > popup ( e - > globalPos ( ) ) ;
return true ;
}
void InternetSearchView : : timerEvent ( QTimerEvent * e ) {
QMap < int , DelayedSearch > : : iterator it = delayed_searches_ . find ( e - > timerId ( ) ) ;
if ( it ! = delayed_searches_ . end ( ) ) {
SearchAsync ( it . value ( ) . id_ , it . value ( ) . query_ , it . value ( ) . type_ ) ;
2021-06-20 19:04:08 +02:00
delayed_searches_ . erase ( it ) ; // clazy:exclude=strict-iterators
2020-04-13 06:30:40 +02:00
return ;
}
QObject : : timerEvent ( e ) ;
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : StartSearch ( const QString & query ) {
2018-08-09 18:10:03 +02:00
ui_ - > search - > setText ( query ) ;
TextEdited ( query ) ;
// Swap models immediately
swap_models_timer_ - > stop ( ) ;
SwapModels ( ) ;
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : TextEdited ( const QString & text ) {
2018-08-09 18:10:03 +02:00
const QString trimmed ( text . trimmed ( ) ) ;
2020-04-13 06:30:40 +02:00
search_error_ = false ;
2020-04-20 18:03:18 +02:00
cover_loader_tasks_ . clear ( ) ;
2018-08-09 18:10:03 +02:00
// Add results to the back model, switch models after some delay.
back_model_ - > Clear ( ) ;
current_model_ = back_model_ ;
current_proxy_ = back_proxy_ ;
swap_models_timer_ - > start ( ) ;
// Cancel the last search (if any) and start the new one.
2020-04-13 06:30:40 +02:00
CancelSearch ( last_search_id_ ) ;
2018-08-09 18:10:03 +02:00
// If text query is empty, don't start a new search
if ( trimmed . isEmpty ( ) ) {
last_search_id_ = - 1 ;
2020-04-20 18:03:18 +02:00
ui_ - > label_helptext - > setText ( tr ( " Enter search terms above to find music " ) ) ;
2018-09-06 17:39:26 +02:00
ui_ - > label_status - > clear ( ) ;
ui_ - > progressbar - > hide ( ) ;
ui_ - > progressbar - > reset ( ) ;
2018-08-09 18:10:03 +02:00
}
else {
2018-09-06 17:39:26 +02:00
ui_ - > progressbar - > reset ( ) ;
2020-04-13 06:30:40 +02:00
last_search_id_ = SearchAsync ( trimmed , search_type_ ) ;
2018-08-09 18:10:03 +02:00
}
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : SwapModels ( ) {
2018-08-09 18:10:03 +02:00
2020-04-20 18:03:18 +02:00
cover_loader_tasks_ . clear ( ) ;
2018-08-09 18:10:03 +02:00
std : : swap ( front_model_ , back_model_ ) ;
std : : swap ( front_proxy_ , back_proxy_ ) ;
ui_ - > results - > setModel ( front_proxy_ ) ;
2020-04-13 06:30:40 +02:00
if ( ui_ - > search - > text ( ) . trimmed ( ) . isEmpty ( ) | | search_error_ ) {
2018-08-09 18:10:03 +02:00
ui_ - > results_stack - > setCurrentWidget ( ui_ - > help_page ) ;
}
else {
ui_ - > results_stack - > setCurrentWidget ( ui_ - > results_page ) ;
}
}
2020-04-13 06:30:40 +02:00
QStringList InternetSearchView : : TokenizeQuery ( const QString & query ) {
2018-09-10 21:58:57 +02:00
2020-07-18 04:05:07 +02:00
QStringList tokens ( query . split ( QRegularExpression ( " \\ s+ " ) ) ) ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
for ( QStringList : : iterator it = tokens . begin ( ) ; it ! = tokens . end ( ) ; + + it ) {
( * it ) . remove ( ' ( ' ) ;
( * it ) . remove ( ' ) ' ) ;
( * it ) . remove ( ' " ' ) ;
2018-08-09 18:10:03 +02:00
2021-10-30 02:21:29 +02:00
const qint64 colon = ( * it ) . indexOf ( " : " ) ;
2020-04-13 06:30:40 +02:00
if ( colon ! = - 1 ) {
( * it ) . remove ( 0 , colon + 1 ) ;
}
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
return tokens ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
}
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
bool InternetSearchView : : Matches ( const QStringList & tokens , const QString & string ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
for ( const QString & token : tokens ) {
if ( ! string . contains ( token , Qt : : CaseInsensitive ) ) {
return false ;
}
}
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
return true ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
int InternetSearchView : : SearchAsync ( const QString & query , const SearchType type ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
const int id = searches_next_id_ + + ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
int timer_id = startTimer ( kDelayedSearchTimeoutMs ) ;
delayed_searches_ [ timer_id ] . id_ = id ;
delayed_searches_ [ timer_id ] . query_ = query ;
delayed_searches_ [ timer_id ] . type_ = type ;
return id ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : SearchAsync ( const int id , const QString & query , const SearchType type ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
const int service_id = service_ - > Search ( query , type ) ;
pending_searches_ [ service_id ] = PendingState ( id , TokenizeQuery ( query ) ) ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
}
2021-09-19 15:41:36 +02:00
void InternetSearchView : : SearchDone ( const int service_id , const SongMap & songs , const QString & error ) {
2020-04-13 06:30:40 +02:00
if ( ! pending_searches_ . contains ( service_id ) ) return ;
// Map back to the original id.
const PendingState state = pending_searches_ . take ( service_id ) ;
const int search_id = state . orig_id_ ;
if ( songs . isEmpty ( ) ) {
SearchError ( search_id , error ) ;
return ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
ResultList results ;
2021-06-20 19:04:08 +02:00
results . reserve ( songs . count ( ) ) ;
2020-04-13 06:30:40 +02:00
for ( const Song & song : songs ) {
Result result ;
result . metadata_ = song ;
results < < result ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
// Load cached pixmaps into the results
2021-08-23 21:21:08 +02:00
for ( InternetSearchView : : ResultList : : iterator it = results . begin ( ) ; it ! = results . end ( ) ; + + it ) {
2020-04-13 06:30:40 +02:00
it - > pixmap_cache_key_ = PixmapCacheKey ( * it ) ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
AddResults ( search_id , results ) ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : CancelSearch ( const int id ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
QMap < int , DelayedSearch > : : iterator it ;
for ( it = delayed_searches_ . begin ( ) ; it ! = delayed_searches_ . end ( ) ; + + it ) {
if ( it . value ( ) . id_ = = id ) {
killTimer ( it . key ( ) ) ;
2021-06-20 19:04:08 +02:00
delayed_searches_ . erase ( it ) ; // clazy:exclude=strict-iterators
2020-04-13 06:30:40 +02:00
return ;
2018-08-09 18:10:03 +02:00
}
}
2020-04-13 06:30:40 +02:00
service_ - > CancelSearch ( ) ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : AddResults ( const int id , const InternetSearchView : : ResultList & results ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
if ( id ! = last_search_id_ | | results . isEmpty ( ) ) return ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
ui_ - > label_status - > clear ( ) ;
ui_ - > progressbar - > reset ( ) ;
ui_ - > progressbar - > hide ( ) ;
current_model_ - > AddResults ( results ) ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
}
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
void InternetSearchView : : SearchError ( const int id , const QString & error ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
if ( id ! = last_search_id_ ) return ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
search_error_ = true ;
ui_ - > label_helptext - > setText ( error ) ;
ui_ - > label_status - > clear ( ) ;
ui_ - > progressbar - > reset ( ) ;
ui_ - > progressbar - > hide ( ) ;
ui_ - > results_stack - > setCurrentWidget ( ui_ - > help_page ) ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : UpdateStatus ( const int service_id , const QString & text ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
if ( ! pending_searches_ . contains ( service_id ) ) return ;
const PendingState state = pending_searches_ [ service_id ] ;
const int search_id = state . orig_id_ ;
if ( search_id ! = last_search_id_ ) return ;
ui_ - > progressbar - > show ( ) ;
ui_ - > label_status - > setText ( text ) ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
}
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
void InternetSearchView : : ProgressSetMaximum ( const int service_id , const int max ) {
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
if ( ! pending_searches_ . contains ( service_id ) ) return ;
const PendingState state = pending_searches_ [ service_id ] ;
const int search_id = state . orig_id_ ;
if ( search_id ! = last_search_id_ ) return ;
ui_ - > progressbar - > setMaximum ( max ) ;
2019-06-07 20:23:05 +02:00
2020-04-13 06:30:40 +02:00
}
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
void InternetSearchView : : UpdateProgress ( const int service_id , const int progress ) {
2018-10-20 22:33:23 +02:00
2020-04-13 06:30:40 +02:00
if ( ! pending_searches_ . contains ( service_id ) ) return ;
const PendingState state = pending_searches_ [ service_id ] ;
const int search_id = state . orig_id_ ;
if ( search_id ! = last_search_id_ ) return ;
ui_ - > progressbar - > setValue ( progress ) ;
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
}
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
MimeData * InternetSearchView : : SelectedMimeData ( ) {
if ( ! ui_ - > results - > selectionModel ( ) ) return nullptr ;
// Get all selected model indexes
QModelIndexList indexes = ui_ - > results - > selectionModel ( ) - > selectedRows ( ) ;
if ( indexes . isEmpty ( ) ) {
// There's nothing selected - take the first thing in the model that isn't a divider.
2021-08-23 21:21:08 +02:00
for ( int i = 0 ; i < front_proxy_ - > rowCount ( ) ; + + i ) {
2021-01-26 16:48:04 +01:00
QModelIndex idx = front_proxy_ - > index ( i , 0 ) ;
if ( ! idx . data ( CollectionModel : : Role_IsDivider ) . toBool ( ) ) {
2021-06-20 19:04:08 +02:00
indexes < < idx ; // clazy:exclude=reserve-candidates
2021-01-26 16:48:04 +01:00
ui_ - > results - > setCurrentIndex ( idx ) ;
2020-04-13 06:30:40 +02:00
break ;
}
}
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
// Still got nothing? Give up.
if ( indexes . isEmpty ( ) ) {
return nullptr ;
}
2018-08-09 18:10:03 +02:00
2020-04-13 06:30:40 +02:00
// Get items for these indexes
QList < QStandardItem * > items ;
2021-01-26 16:48:04 +01:00
for ( const QModelIndex & idx : indexes ) {
2021-06-20 19:04:08 +02:00
items < < ( front_model_ - > itemFromIndex ( front_proxy_ - > mapToSource ( idx ) ) ) ; // clazy:exclude=reserve-candidates
2020-04-13 06:30:40 +02:00
}
// Get a MimeData for these items
return front_model_ - > LoadTracks ( front_model_ - > GetChildResults ( items ) ) ;
2018-08-09 18:10:03 +02:00
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : AddSelectedToPlaylist ( ) {
2018-08-09 18:10:03 +02:00
emit AddToPlaylist ( SelectedMimeData ( ) ) ;
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : LoadSelected ( ) {
2020-04-13 06:30:40 +02:00
2020-04-23 21:08:28 +02:00
MimeData * mimedata = SelectedMimeData ( ) ;
if ( ! mimedata ) return ;
2018-08-09 18:10:03 +02:00
2020-04-23 21:08:28 +02:00
mimedata - > clear_first_ = true ;
emit AddToPlaylist ( mimedata ) ;
2020-04-13 06:30:40 +02:00
2018-08-09 18:10:03 +02:00
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : AddSelectedToPlaylistEnqueue ( ) {
2020-04-13 06:30:40 +02:00
2020-04-23 21:08:28 +02:00
MimeData * mimedata = SelectedMimeData ( ) ;
if ( ! mimedata ) return ;
2018-08-09 18:10:03 +02:00
2020-04-23 21:08:28 +02:00
mimedata - > enqueue_now_ = true ;
emit AddToPlaylist ( mimedata ) ;
2020-04-13 06:30:40 +02:00
2018-08-09 18:10:03 +02:00
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : OpenSelectedInNewPlaylist ( ) {
2020-04-13 06:30:40 +02:00
2020-04-23 21:08:28 +02:00
MimeData * mimedata = SelectedMimeData ( ) ;
if ( ! mimedata ) return ;
2018-08-09 18:10:03 +02:00
2020-04-23 21:08:28 +02:00
mimedata - > open_in_new_playlist_ = true ;
emit AddToPlaylist ( mimedata ) ;
2020-04-13 06:30:40 +02:00
2018-08-09 18:10:03 +02:00
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : SearchForThis ( ) {
2018-08-09 18:10:03 +02:00
StartSearch ( ui_ - > results - > selectionModel ( ) - > selectedRows ( ) . first ( ) . data ( ) . toString ( ) ) ;
}
2021-09-27 21:42:30 +02:00
bool InternetSearchView : : SearchFieldHasFocus ( ) const {
return ui_ - > search - > hasFocus ( ) ;
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : FocusSearchField ( ) {
2020-04-13 06:30:40 +02:00
2018-08-09 18:10:03 +02:00
ui_ - > search - > setFocus ( ) ;
ui_ - > search - > selectAll ( ) ;
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : FocusOnFilter ( QKeyEvent * e ) {
2018-08-09 18:10:03 +02:00
ui_ - > search - > setFocus ( ) ;
2020-04-13 06:30:40 +02:00
QApplication : : sendEvent ( ui_ - > search , e ) ;
2018-08-09 18:10:03 +02:00
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : OpenSettingsDialog ( ) {
2020-04-13 06:30:40 +02:00
app_ - > OpenSettingsDialogAtPage ( service_ - > settings_page ( ) ) ;
2018-08-09 18:10:03 +02:00
}
2018-10-17 21:18:39 +02:00
void InternetSearchView : : GroupByClicked ( QAction * action ) {
2018-08-09 18:10:03 +02:00
if ( action - > property ( " group_by " ) . isNull ( ) ) {
if ( ! group_by_dialog_ ) {
2021-06-21 15:40:25 +02:00
group_by_dialog_ = std : : make_unique < GroupByDialog > ( ) ;
2021-01-26 16:48:04 +01:00
QObject : : connect ( group_by_dialog_ . get ( ) , & GroupByDialog : : Accepted , this , & InternetSearchView : : SetGroupBy ) ;
2018-08-09 18:10:03 +02:00
}
group_by_dialog_ - > show ( ) ;
return ;
}
SetGroupBy ( action - > property ( " group_by " ) . value < CollectionModel : : Grouping > ( ) ) ;
}
2021-06-20 19:04:08 +02:00
void InternetSearchView : : SetGroupBy ( const CollectionModel : : Grouping g ) {
2018-08-09 18:10:03 +02:00
// Clear requests: changing "group by" on the models will cause all the items to be removed/added again,
// so all the QModelIndex here will become invalid. New requests will be created for those
2019-07-07 21:14:24 +02:00
// songs when they will be displayed again anyway (when InternetSearchItemDelegate::paint will call LazyLoadAlbumCover)
2020-04-20 18:03:18 +02:00
cover_loader_tasks_ . clear ( ) ;
2018-08-09 18:10:03 +02:00
// Update the models
front_model_ - > SetGroupBy ( g , true ) ;
back_model_ - > SetGroupBy ( g , false ) ;
// Save the setting
QSettings s ;
2020-04-13 06:30:40 +02:00
s . beginGroup ( service_ - > settings_group ( ) ) ;
2020-09-12 00:32:50 +02:00
s . setValue ( " search_group_by_version " , 1 ) ;
2021-10-11 22:28:28 +02:00
s . setValue ( " search_group_by1 " , static_cast < int > ( g . first ) ) ;
s . setValue ( " search_group_by2 " , static_cast < int > ( g . second ) ) ;
s . setValue ( " search_group_by3 " , static_cast < int > ( g . third ) ) ;
2018-08-09 18:10:03 +02:00
s . endGroup ( ) ;
// Make sure the correct action is checked.
for ( QAction * action : group_by_actions_ - > actions ( ) ) {
if ( action - > property ( " group_by " ) . isNull ( ) ) continue ;
if ( g = = action - > property ( " group_by " ) . value < CollectionModel : : Grouping > ( ) ) {
action - > setChecked ( true ) ;
return ;
}
}
// Check the advanced action
2021-03-21 04:47:11 +01:00
QList < QAction * > actions = group_by_actions_ - > actions ( ) ;
actions . last ( ) - > setChecked ( true ) ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : SearchArtistsClicked ( const bool ) {
SetSearchType ( InternetSearchView : : SearchType_Artists ) ;
2019-02-12 21:58:03 +01:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : SearchAlbumsClicked ( const bool ) {
SetSearchType ( InternetSearchView : : SearchType_Albums ) ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : SearchSongsClicked ( const bool ) {
SetSearchType ( InternetSearchView : : SearchType_Songs ) ;
2018-08-09 18:10:03 +02:00
}
2020-04-13 06:30:40 +02:00
void InternetSearchView : : SetSearchType ( const InternetSearchView : : SearchType type ) {
2019-02-12 21:58:03 +01:00
search_type_ = type ;
2020-04-20 18:03:18 +02:00
2018-08-09 18:10:03 +02:00
QSettings s ;
2020-04-13 06:30:40 +02:00
s . beginGroup ( service_ - > settings_group ( ) ) ;
2021-10-11 22:28:28 +02:00
s . setValue ( " type " , static_cast < int > ( search_type_ ) ) ;
2018-08-09 18:10:03 +02:00
s . endGroup ( ) ;
2020-04-20 18:03:18 +02:00
2018-08-09 18:10:03 +02:00
TextEdited ( ui_ - > search - > text ( ) ) ;
2019-06-20 16:33:28 +02:00
2018-09-06 17:39:26 +02:00
}
2019-06-07 20:23:05 +02:00
void InternetSearchView : : AddArtists ( ) {
2020-04-23 21:08:28 +02:00
MimeData * mimedata = SelectedMimeData ( ) ;
if ( ! mimedata ) return ;
if ( const InternetSongMimeData * internet_song_data = qobject_cast < const InternetSongMimeData * > ( mimedata ) ) {
2021-09-19 15:41:36 +02:00
emit AddArtistsSignal ( internet_song_data - > songs . values ( ) ) ;
2019-06-07 20:23:05 +02:00
}
}
void InternetSearchView : : AddAlbums ( ) {
2020-04-23 21:08:28 +02:00
MimeData * mimedata = SelectedMimeData ( ) ;
if ( ! mimedata ) return ;
if ( const InternetSongMimeData * internet_song_data = qobject_cast < const InternetSongMimeData * > ( mimedata ) ) {
2021-09-19 15:41:36 +02:00
emit AddAlbumsSignal ( internet_song_data - > songs . values ( ) ) ;
2019-06-07 20:23:05 +02:00
}
}
void InternetSearchView : : AddSongs ( ) {
2020-04-23 21:08:28 +02:00
MimeData * mimedata = SelectedMimeData ( ) ;
if ( ! mimedata ) return ;
if ( const InternetSongMimeData * internet_song_data = qobject_cast < const InternetSongMimeData * > ( mimedata ) ) {
2019-06-07 20:23:05 +02:00
emit AddSongsSignal ( internet_song_data - > songs ) ;
}
}
2020-04-13 06:30:40 +02:00
QString InternetSearchView : : PixmapCacheKey ( const InternetSearchView : : Result & result ) const {
2020-04-20 18:03:18 +02:00
if ( result . metadata_ . art_automatic_is_valid ( ) ) {
return Song : : TextForSource ( service_ - > source ( ) ) + " / " + result . metadata_ . art_automatic ( ) . toString ( ) ;
}
else if ( ! result . metadata_ . effective_albumartist ( ) . isEmpty ( ) & & ! result . metadata_ . album ( ) . isEmpty ( ) ) {
return Song : : TextForSource ( service_ - > source ( ) ) + " / " + result . metadata_ . effective_albumartist ( ) + " / " + result . metadata_ . album ( ) ;
}
else {
return Song : : TextForSource ( service_ - > source ( ) ) + " / " + result . metadata_ . url ( ) . toString ( ) ;
}
2020-04-13 06:30:40 +02:00
}
bool InternetSearchView : : FindCachedPixmap ( const InternetSearchView : : Result & result , QPixmap * pixmap ) const {
2021-07-11 01:43:52 +02:00
return QPixmapCache : : find ( result . pixmap_cache_key_ , pixmap ) ;
2020-04-13 06:30:40 +02:00
}
void InternetSearchView : : LazyLoadAlbumCover ( const QModelIndex & proxy_index ) {
if ( ! proxy_index . isValid ( ) | | proxy_index . model ( ) ! = front_proxy_ ) {
return ;
}
2020-04-20 18:03:18 +02:00
const QModelIndex source_index = front_proxy_ - > mapToSource ( proxy_index ) ;
if ( ! source_index . isValid ( ) ) {
return ;
}
2020-04-13 06:30:40 +02:00
// Already loading art for this item?
2020-04-20 18:03:18 +02:00
if ( source_index . data ( InternetSearchModel : : Role_LazyLoadingArt ) . isValid ( ) ) {
2020-04-13 06:30:40 +02:00
return ;
}
// Should we even load art at all?
2020-04-20 18:03:18 +02:00
if ( ! use_pretty_covers_ ) {
2020-04-13 06:30:40 +02:00
return ;
}
// Is this an album?
const CollectionModel : : GroupBy container_type = CollectionModel : : GroupBy ( proxy_index . data ( CollectionModel : : Role_ContainerType ) . toInt ( ) ) ;
2020-09-10 22:09:24 +02:00
if ( ! CollectionModel : : IsAlbumGroupBy ( container_type ) ) return ;
2020-04-13 06:30:40 +02:00
// Mark the item as loading art
2020-04-20 18:03:18 +02:00
QStandardItem * item_album = front_model_ - > itemFromIndex ( source_index ) ;
if ( ! item_album ) {
return ;
}
item_album - > setData ( true , InternetSearchModel : : Role_LazyLoadingArt ) ;
2020-04-13 06:30:40 +02:00
// Walk down the item's children until we find a track
2020-04-20 18:03:18 +02:00
QStandardItem * item_song = item_album ;
2021-06-22 13:54:58 +02:00
while ( item_song - > rowCount ( ) > 0 ) {
2020-04-20 18:03:18 +02:00
item_song = item_song - > child ( 0 ) ;
2020-04-13 06:30:40 +02:00
}
// Get the track's Result
2020-04-20 18:03:18 +02:00
const InternetSearchView : : Result result = item_song - > data ( InternetSearchModel : : Role_Result ) . value < InternetSearchView : : Result > ( ) ;
2020-04-13 06:30:40 +02:00
2020-04-20 18:03:18 +02:00
QPixmap cached_pixmap ;
2021-07-11 01:43:52 +02:00
if ( QPixmapCache : : find ( result . pixmap_cache_key_ , & cached_pixmap ) ) {
2020-04-20 18:03:18 +02:00
item_album - > setData ( cached_pixmap , Qt : : DecorationRole ) ;
}
else {
quint64 loader_id = app_ - > album_cover_loader ( ) - > LoadImageAsync ( cover_loader_options_ , result . metadata_ ) ;
cover_loader_tasks_ [ loader_id ] = qMakePair ( source_index , result . pixmap_cache_key_ ) ;
2020-04-13 06:30:40 +02:00
}
}
2020-04-20 18:03:18 +02:00
void InternetSearchView : : AlbumCoverLoaded ( const quint64 id , const AlbumCoverLoaderResult & albumcover_result ) {
2020-04-13 06:30:40 +02:00
2021-02-26 21:03:51 +01:00
if ( ! cover_loader_tasks_ . contains ( id ) ) return ;
2020-04-23 21:08:28 +02:00
2020-04-20 18:03:18 +02:00
QPair < QModelIndex , QString > cover_loader_task = cover_loader_tasks_ . take ( id ) ;
QModelIndex idx = cover_loader_task . first ;
QString key = cover_loader_task . second ;
2020-04-13 06:30:40 +02:00
2021-02-26 21:03:51 +01:00
if ( albumcover_result . success & & ! albumcover_result . image_scaled . isNull ( ) ) {
QPixmap pixmap = QPixmap : : fromImage ( albumcover_result . image_scaled ) ;
if ( ! pixmap . isNull ( ) ) {
2021-07-11 01:43:52 +02:00
QPixmapCache : : insert ( key , pixmap ) ;
2021-02-26 21:03:51 +01:00
}
if ( idx . isValid ( ) ) {
QStandardItem * item = front_model_ - > itemFromIndex ( idx ) ;
if ( item ) {
item - > setData ( albumcover_result . image_scaled , Qt : : DecorationRole ) ;
}
2020-04-20 18:03:18 +02:00
}
}
2020-04-13 06:30:40 +02:00
}