mirror of
https://github.com/xiaoyifang/goldendict-ng.git
synced 2024-11-24 04:24:09 +00:00
Refactor resource downloading
This commit is contained in:
parent
67b6b6b91c
commit
747dc0aaaf
115
articleview.cc
115
articleview.cc
|
@ -1165,6 +1165,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
|
||||||
activeDicts = &allDictionaries;
|
activeDicts = &allDictionaries;
|
||||||
|
|
||||||
if ( activeDicts )
|
if ( activeDicts )
|
||||||
|
{
|
||||||
for( unsigned x = 0; x < activeDicts->size(); ++x )
|
for( unsigned x = 0; x < activeDicts->size(); ++x )
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -1173,24 +1174,10 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
|
||||||
(*activeDicts)[ x ]->getResource(
|
(*activeDicts)[ x ]->getResource(
|
||||||
url.path().mid( 1 ).toUtf8().data() );
|
url.path().mid( 1 ).toUtf8().data() );
|
||||||
|
|
||||||
if ( req->isFinished() && req->dataSize() >= 0 )
|
|
||||||
{
|
|
||||||
// A request was instantly finished with success.
|
|
||||||
// If we've managed to spawn some lingering requests already,
|
|
||||||
// erase them.
|
|
||||||
resourceDownloadRequests.clear();
|
|
||||||
|
|
||||||
// Handle the result
|
|
||||||
resourceDownloadRequests.push_back( req );
|
resourceDownloadRequests.push_back( req );
|
||||||
resourceDownloadFinished();
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if ( !req->isFinished() )
|
if ( !req->isFinished() )
|
||||||
{
|
{
|
||||||
resourceDownloadRequests.push_back( req );
|
|
||||||
|
|
||||||
connect( req.get(), SIGNAL( finished() ),
|
connect( req.get(), SIGNAL( finished() ),
|
||||||
this, SLOT( resourceDownloadFinished() ) );
|
this, SLOT( resourceDownloadFinished() ) );
|
||||||
}
|
}
|
||||||
|
@ -1203,6 +1190,7 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Normal resource download
|
// Normal resource download
|
||||||
|
@ -1314,14 +1302,14 @@ void ArticleView::openLink( QUrl const & url, QUrl const & ref,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
vector< ResourceToSaveHandler * > ArticleView::saveResource( const QUrl & url, const QString & fileName )
|
ResourceToSaveHandler * ArticleView::saveResource( const QUrl & url, const QString & fileName )
|
||||||
{
|
{
|
||||||
return saveResource( url, ui.definition->url(), fileName );
|
return saveResource( url, ui.definition->url(), fileName );
|
||||||
}
|
}
|
||||||
|
|
||||||
vector< ResourceToSaveHandler * > ArticleView::saveResource( const QUrl & url, const QUrl & ref, const QString & fileName )
|
ResourceToSaveHandler * ArticleView::saveResource( const QUrl & url, const QUrl & ref, const QString & fileName )
|
||||||
{
|
{
|
||||||
vector< ResourceToSaveHandler * > handlers;
|
ResourceToSaveHandler * handler = new ResourceToSaveHandler( this, fileName );
|
||||||
sptr< Dictionary::DataRequest > req;
|
sptr< Dictionary::DataRequest > req;
|
||||||
|
|
||||||
if( url.scheme() == "bres" || url.scheme() == "gico" || url.scheme() == "gdau" || url.scheme() == "gdvideo" )
|
if( url.scheme() == "bres" || url.scheme() == "gico" || url.scheme() == "gdau" || url.scheme() == "gdvideo" )
|
||||||
|
@ -1357,14 +1345,7 @@ vector< ResourceToSaveHandler * > ArticleView::saveResource( const QUrl & url, c
|
||||||
req = (*activeDicts)[ x ]->getResource(
|
req = (*activeDicts)[ x ]->getResource(
|
||||||
Qt4x5::Url::path( url ).mid( 1 ).toUtf8().data() );
|
Qt4x5::Url::path( url ).mid( 1 ).toUtf8().data() );
|
||||||
|
|
||||||
ResourceToSaveHandler * handler = new ResourceToSaveHandler( this, req, fileName, true );
|
handler->addRequest( req );
|
||||||
handlers.push_back( handler );
|
|
||||||
|
|
||||||
if( req.get()->isFinished() && req.get()->dataSize() > 0 )
|
|
||||||
{
|
|
||||||
// A request was instantly finished with success. Stop search.
|
|
||||||
return handlers;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
catch( std::exception & e )
|
catch( std::exception & e )
|
||||||
{
|
{
|
||||||
|
@ -1382,8 +1363,7 @@ vector< ResourceToSaveHandler * > ArticleView::saveResource( const QUrl & url, c
|
||||||
|
|
||||||
if( req.get() )
|
if( req.get() )
|
||||||
{
|
{
|
||||||
ResourceToSaveHandler * handler = new ResourceToSaveHandler( this, req, fileName );
|
handler->addRequest( req );
|
||||||
handlers.push_back( handler );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1391,18 +1371,20 @@ vector< ResourceToSaveHandler * > ArticleView::saveResource( const QUrl & url, c
|
||||||
{
|
{
|
||||||
req = new Dictionary::WebMultimediaDownload( url, articleNetMgr );
|
req = new Dictionary::WebMultimediaDownload( url, articleNetMgr );
|
||||||
|
|
||||||
ResourceToSaveHandler * handler = new ResourceToSaveHandler( this, req, fileName );
|
handler->addRequest( req );
|
||||||
handlers.push_back( handler );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( handlers.empty() ) // No requests were queued
|
if ( handler->isEmpty() ) // No requests were queued
|
||||||
{
|
{
|
||||||
emit statusBarMessage(
|
emit statusBarMessage(
|
||||||
tr( "ERROR: %1" ).arg( tr( "The referenced resource doesn't exist." ) ),
|
tr( "ERROR: %1" ).arg( tr( "The referenced resource doesn't exist." ) ),
|
||||||
10000, QPixmap( ":/icons/error.png" ) );
|
10000, QPixmap( ":/icons/error.png" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
return handlers;
|
// Check already finished downloads
|
||||||
|
handler->downloadFinished();
|
||||||
|
|
||||||
|
return handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ArticleView::updateMutedContents()
|
void ArticleView::updateMutedContents()
|
||||||
|
@ -1927,8 +1909,8 @@ void ArticleView::resourceDownloadFinished()
|
||||||
resourceDownloadRequests.erase( i++ );
|
resourceDownloadRequests.erase( i++ );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Unfinished, try the next one.
|
else // Unfinished, wait.
|
||||||
i++;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( resourceDownloadRequests.empty() )
|
if ( resourceDownloadRequests.empty() )
|
||||||
|
@ -2747,43 +2729,46 @@ QString ArticleView::wordAtPoint( int x, int y )
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ResourceToSaveHandler::ResourceToSaveHandler(
|
ResourceToSaveHandler::ResourceToSaveHandler(ArticleView * view, QString const & fileName ) :
|
||||||
ArticleView * view, sptr< Dictionary::DataRequest > req,
|
|
||||||
QString const & fileName, bool search ) :
|
|
||||||
QObject( view ),
|
QObject( view ),
|
||||||
req( req ),
|
|
||||||
fileName( fileName ),
|
fileName( fileName ),
|
||||||
search_req( search )
|
alreadyDone( false )
|
||||||
{
|
{
|
||||||
connect( this, SIGNAL( statusBarMessage( QString, int, QPixmap ) ),
|
connect( this, SIGNAL( statusBarMessage( QString, int, QPixmap ) ),
|
||||||
view, SIGNAL( statusBarMessage( QString, int, QPixmap ) ) );
|
view, SIGNAL( statusBarMessage( QString, int, QPixmap ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
// If DataRequest finsihed immediately, call our handler directly
|
void ResourceToSaveHandler::addRequest( sptr<Dictionary::DataRequest> req )
|
||||||
if ( req.get()->isFinished() )
|
{
|
||||||
|
if( !alreadyDone )
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod( this, "downloadFinished", Qt::QueuedConnection );
|
downloadRequests.push_back( req );
|
||||||
}
|
|
||||||
else
|
connect( req.get(), SIGNAL( finished() ),
|
||||||
{
|
this, SLOT( downloadFinished() ) );
|
||||||
connect( req.get(), SIGNAL( finished() ), this, SLOT( downloadFinished() ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ResourceToSaveHandler::downloadFinished()
|
void ResourceToSaveHandler::downloadFinished()
|
||||||
{
|
{
|
||||||
assert( req && req.get()->isFinished() );
|
if ( downloadRequests.empty() )
|
||||||
|
return; // Stray signal
|
||||||
|
|
||||||
QByteArray resourceData;
|
// Find any finished resources
|
||||||
|
for( list< sptr< Dictionary::DataRequest > >::iterator i =
|
||||||
if ( req.get()->dataSize() >= 0 )
|
downloadRequests.begin(); i != downloadRequests.end(); )
|
||||||
{
|
{
|
||||||
vector< char > const & data = req.get()->getFullData();
|
if ( (*i)->isFinished() )
|
||||||
|
{
|
||||||
|
if ( (*i)->dataSize() >= 0 && !alreadyDone )
|
||||||
|
{
|
||||||
|
QByteArray resourceData;
|
||||||
|
vector< char > const & data = (*i)->getFullData();
|
||||||
resourceData = QByteArray( data.data(), data.size() );
|
resourceData = QByteArray( data.data(), data.size() );
|
||||||
}
|
|
||||||
|
|
||||||
// Write data to file
|
// Write data to file
|
||||||
|
|
||||||
if ( !resourceData.isEmpty() && !fileName.isEmpty() )
|
if ( !fileName.isEmpty() )
|
||||||
{
|
{
|
||||||
QFileInfo fileInfo( fileName );
|
QFileInfo fileInfo( fileName );
|
||||||
QDir().mkpath( fileInfo.absoluteDir().absolutePath() );
|
QDir().mkpath( fileInfo.absoluteDir().absolutePath() );
|
||||||
|
@ -2802,16 +2787,32 @@ void ResourceToSaveHandler::downloadFinished()
|
||||||
10000, QPixmap( ":/icons/error.png" ) );
|
10000, QPixmap( ":/icons/error.png" ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
alreadyDone = true;
|
||||||
|
|
||||||
|
// Clear other requests
|
||||||
|
|
||||||
|
downloadRequests.clear();
|
||||||
|
break;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( !search_req )
|
// This one had no data. Erase it.
|
||||||
{
|
downloadRequests.erase( i++ );
|
||||||
emit statusBarMessage(
|
|
||||||
tr( "ERROR: %1" ).arg( tr( "The referenced resource failed to download." ) ),
|
|
||||||
10000, QPixmap( ":/icons/error.png" ) );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else // Unfinished, wait.
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( downloadRequests.empty() )
|
||||||
|
{
|
||||||
|
if( !alreadyDone )
|
||||||
|
{
|
||||||
|
emit statusBarMessage(
|
||||||
|
tr( "WARNING: %1" ).arg( tr( "The referenced resource failed to download." ) ),
|
||||||
|
10000, QPixmap( ":/icons/error.png" ) );
|
||||||
|
}
|
||||||
emit done();
|
emit done();
|
||||||
deleteLater();
|
deleteLater();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -177,8 +177,8 @@ public:
|
||||||
/// Returns the dictionary id of the currently active article in the view.
|
/// Returns the dictionary id of the currently active article in the view.
|
||||||
QString getActiveArticleId();
|
QString getActiveArticleId();
|
||||||
|
|
||||||
std::vector< ResourceToSaveHandler * > saveResource( const QUrl & url, const QString & fileName );
|
ResourceToSaveHandler * saveResource( const QUrl & url, const QString & fileName );
|
||||||
std::vector< ResourceToSaveHandler * > saveResource( const QUrl & url, const QUrl & ref, const QString & fileName );
|
ResourceToSaveHandler * saveResource( const QUrl & url, const QUrl & ref, const QString & fileName );
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
|
@ -365,20 +365,22 @@ class ResourceToSaveHandler: public QObject
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ResourceToSaveHandler( ArticleView * view, sptr< Dictionary::DataRequest > req,
|
explicit ResourceToSaveHandler( ArticleView * view, QString const & fileName );
|
||||||
QString const & fileName, bool search = false );
|
void addRequest( sptr< Dictionary::DataRequest > req );
|
||||||
|
bool isEmpty()
|
||||||
|
{ return downloadRequests.empty(); }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void done();
|
void done();
|
||||||
void statusBarMessage( QString const & message, int timeout = 0, QPixmap const & pixmap = QPixmap() );
|
void statusBarMessage( QString const & message, int timeout = 0, QPixmap const & pixmap = QPixmap() );
|
||||||
|
|
||||||
private slots:
|
public slots:
|
||||||
void downloadFinished();
|
void downloadFinished();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
sptr< Dictionary::DataRequest > req;
|
std::list< sptr< Dictionary::DataRequest > > downloadRequests;
|
||||||
QString fileName;
|
QString fileName;
|
||||||
bool search_req;
|
bool alreadyDone;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3362,13 +3362,11 @@ void MainWindow::on_saveArticle_triggered()
|
||||||
for ( vector< pair< QUrl, QString > >::const_iterator i = downloadResources.begin();
|
for ( vector< pair< QUrl, QString > >::const_iterator i = downloadResources.begin();
|
||||||
i != downloadResources.end(); i++ )
|
i != downloadResources.end(); i++ )
|
||||||
{
|
{
|
||||||
vector< ResourceToSaveHandler * > handlerss = view->saveResource( i->first, i->second );
|
ResourceToSaveHandler * handler = view->saveResource( i->first, i->second );
|
||||||
maxVal += handlerss.size();
|
if( !handler->isEmpty() )
|
||||||
|
|
||||||
for ( vector< ResourceToSaveHandler * >::iterator j = handlerss.begin();
|
|
||||||
j != handlerss.end(); j++ )
|
|
||||||
{
|
{
|
||||||
connect( *j, SIGNAL( done() ), progressDialog, SLOT( perform() ) );
|
maxVal += 1;
|
||||||
|
connect( handler, SIGNAL( done() ), progressDialog, SLOT( perform() ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue