opt:optimize the openLink method (#1853)
Some checks are pending
SonarCloud / Build and analyze (push) Waiting to run

* opt: optimize the resourcedownload logic


---------

Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
xiaoyifang 2024-10-23 21:29:28 +08:00 committed by GitHub
parent 426950fc10
commit 66a45f975e
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 42 additions and 103 deletions

View file

@ -181,13 +181,11 @@ sptr< WordSearchRequest > Class::stemmedMatch( wstring const & /*str*/,
unsigned /*minLength*/, unsigned /*minLength*/,
unsigned /*maxSuffixVariation*/, unsigned /*maxSuffixVariation*/,
unsigned long /*maxResults*/ ) unsigned long /*maxResults*/ )
{ {
return std::make_shared< WordSearchRequestInstant >(); return std::make_shared< WordSearchRequestInstant >();
} }
sptr< WordSearchRequest > Class::findHeadwordsForSynonym( wstring const & ) sptr< WordSearchRequest > Class::findHeadwordsForSynonym( wstring const & )
{ {
return std::make_shared< WordSearchRequestInstant >(); return std::make_shared< WordSearchRequestInstant >();
} }

View file

@ -1038,18 +1038,12 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const &
|| Utils::Url::isAudioUrl( url ) ) { || Utils::Url::isAudioUrl( url ) ) {
// Download it // Download it
// Clear any pending ones
resourceDownloadRequests.clear();
resourceDownloadUrl = url;
if ( Utils::Url::isWebAudioUrl( url ) ) { if ( Utils::Url::isWebAudioUrl( url ) ) {
sptr< Dictionary::DataRequest > req = std::make_shared< Dictionary::WebMultimediaDownload >( url, articleNetMgr ); sptr< Dictionary::DataRequest > req = std::make_shared< Dictionary::WebMultimediaDownload >( url, articleNetMgr );
resourceDownloadRequests.push_back( req ); connect( req.get(), &Dictionary::Request::finished, this, [ req, url, this ]() {
resourceDownloadFinished( req, url );
connect( req.get(), &Dictionary::Request::finished, this, &ArticleView::resourceDownloadFinished ); } );
} }
else { else {
// Normal resource download // Normal resource download
@ -1063,28 +1057,16 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref, QString const &
} }
else if ( req->isFinished() && req->dataSize() >= 0 ) { else if ( req->isFinished() && req->dataSize() >= 0 ) {
// Have data ready, handle it // Have data ready, handle it
resourceDownloadRequests.push_back( req ); resourceDownloadFinished( req, url );
resourceDownloadFinished();
return; return;
} }
else if ( !req->isFinished() ) { else if ( !req->isFinished() ) {
// Queue to be handled when done connect( req.get(), &Dictionary::Request::finished, this, [ req, url, this ]() {
resourceDownloadFinished( req, url );
resourceDownloadRequests.push_back( req ); } );
connect( req.get(), &Dictionary::Request::finished, this, &ArticleView::resourceDownloadFinished );
} }
} }
if ( resourceDownloadRequests.empty() ) // No requests were queued
{
qDebug() << tr( "The referenced resource doesn't exist." );
return;
}
else {
resourceDownloadFinished(); // Check any requests finished already
}
} }
else if ( url.scheme() == "gdprg" ) { else if ( url.scheme() == "gdprg" ) {
// Program. Run it. // Program. Run it.
@ -1754,83 +1736,49 @@ void ArticleView::contextMenuRequested( QPoint const & pos )
qDebug() << "title = " << r->title(); qDebug() << "title = " << r->title();
} }
void ArticleView::resourceDownloadFinished() void ArticleView::resourceDownloadFinished( const sptr< Dictionary::DataRequest > & req,
const QUrl & resourceDownloadUrl )
{ {
if ( resourceDownloadRequests.empty() ) { if ( !req->isFinished() ) {
return; // Stray signal return;
} }
if ( req->dataSize() >= 0 ) {
vector< char > const & data = req->getFullData();
// Find any finished resources if ( resourceDownloadUrl.scheme() == "gdau" || Utils::Url::isWebAudioUrl( resourceDownloadUrl ) ) {
for ( list< sptr< Dictionary::DataRequest > >::iterator i = resourceDownloadRequests.begin(); // Audio data
i != resourceDownloadRequests.end(); ) { audioPlayer->stop();
if ( ( *i )->isFinished() ) { connect( audioPlayer.data(),
if ( ( *i )->dataSize() >= 0 ) { &AudioPlayerInterface::error,
// Ok, got one finished, all others are irrelevant now this,
&ArticleView::audioPlayerError,
Qt::UniqueConnection );
QString errorMessage = audioPlayer->play( data.data(), data.size() );
if ( !errorMessage.isEmpty() ) {
QMessageBox::critical( this, "GoldenDict", tr( "Failed to play sound file: %1" ).arg( errorMessage ) );
}
}
else {
QString fileName;
vector< char > const & data = ( *i )->getFullData(); QTemporaryFile tmp( QDir::temp().filePath( "XXXXXX-" + resourceDownloadUrl.path().section( '/', -1 ) ), this );
if ( resourceDownloadUrl.scheme() == "gdau" || Utils::Url::isWebAudioUrl( resourceDownloadUrl ) ) {
// Audio data
audioPlayer->stop();
connect( audioPlayer.data(),
&AudioPlayerInterface::error,
this,
&ArticleView::audioPlayerError,
Qt::UniqueConnection );
QString errorMessage = audioPlayer->play( data.data(), data.size() );
if ( !errorMessage.isEmpty() ) {
QMessageBox::critical( this, "GoldenDict", tr( "Failed to play sound file: %1" ).arg( errorMessage ) );
}
}
else {
// Create a temporary file
// Remove the ones previously used, if any
cleanupTemp();
QString fileName;
{
QTemporaryFile tmp( QDir::temp().filePath( "XXXXXX-" + resourceDownloadUrl.path().section( '/', -1 ) ),
this );
if ( !tmp.open() || (size_t)tmp.write( &data.front(), data.size() ) != data.size() ) {
QMessageBox::critical( this, "GoldenDict", tr( "Failed to create temporary file." ) );
return;
}
tmp.setAutoRemove( false );
desktopOpenedTempFiles.insert( fileName = tmp.fileName() );
}
if ( !QDesktopServices::openUrl( QUrl::fromLocalFile( fileName ) ) ) {
QMessageBox::critical(
this,
"GoldenDict",
tr( "Failed to auto-open resource file, try opening manually: %1." ).arg( fileName ) );
}
}
// Ok, whatever it was, it's finished. Remove this and any other
// requests and finish.
resourceDownloadRequests.clear();
if ( !tmp.open() || (size_t)tmp.write( &data.front(), data.size() ) != data.size() ) {
QMessageBox::critical( this, "GoldenDict", tr( "Failed to create temporary file." ) );
return; return;
} }
else {
// This one had no data. Erase it. tmp.setAutoRemove( false );
resourceDownloadRequests.erase( i++ );
desktopOpenedTempFiles.insert( fileName = tmp.fileName() );
if ( !QDesktopServices::openUrl( QUrl::fromLocalFile( fileName ) ) ) {
QMessageBox::critical( this,
"GoldenDict",
tr( "Failed to auto-open resource file, try opening manually: %1." ).arg( fileName ) );
} }
} }
else { // Unfinished, wait. return;
break;
}
}
if ( resourceDownloadRequests.empty() ) {
// emit statusBarMessage(
// tr("WARNING: %1").arg(tr("The referenced resource failed to download.")),
// 10000, QPixmap(":/icons/error.svg"));
} }
} }

View file

@ -52,13 +52,6 @@ class ArticleView: public QWidget
/// An action used to create Anki notes. /// An action used to create Anki notes.
QAction sendToAnkiAction{ tr( "&Create Anki note" ), this }; QAction sendToAnkiAction{ tr( "&Create Anki note" ), this };
/// Any resource we've decided to download off the dictionary gets stored here.
/// Full vector capacity is used for search requests, where we have to make
/// a multitude of requests.
std::list< sptr< Dictionary::DataRequest > > resourceDownloadRequests;
/// Url of the resourceDownloadRequests
QUrl resourceDownloadUrl;
/// For resources opened via desktop services /// For resources opened via desktop services
QSet< QString > desktopOpenedTempFiles; QSet< QString > desktopOpenedTempFiles;
@ -342,7 +335,7 @@ private slots:
return ( targetUrl.scheme() == "gdau" || Utils::Url::isAudioUrl( targetUrl ) ); return ( targetUrl.scheme() == "gdau" || Utils::Url::isAudioUrl( targetUrl ) );
} }
void resourceDownloadFinished(); void resourceDownloadFinished( const sptr< Dictionary::DataRequest > & req, const QUrl & resourceDownloadUrl );
/// We handle pasting by attempting to define the word in clipboard. /// We handle pasting by attempting to define the word in clipboard.
void pasteTriggered(); void pasteTriggered();