2011-03-03 18:29:20 +01:00
/* ============================================================
* QupZilla - WebKit based browser
* Copyright ( C ) 2010 - 2011 nowrep
*
* This program 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 .
*
* This program 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 this program . If not , see < http : //www.gnu.org/licenses/>.
* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = */
2011-03-02 16:57:41 +01:00
# include "downloaditem.h"
# include "ui_downloaditem.h"
2011-04-08 18:52:14 +02:00
# include "mainapplication.h"
# include "qupzilla.h"
# include "tabwidget.h"
# include "webpage.h"
2011-03-02 16:57:41 +01:00
2011-03-29 19:55:21 +02:00
//#define DOWNMANAGER_DEBUG
2011-03-24 22:31:38 +01:00
DownloadItem : : DownloadItem ( QListWidgetItem * item , QNetworkReply * reply , QString path , QString fileName , QPixmap fileIcon , bool openAfterFinishedDownload , QWidget * parent )
2011-03-02 16:57:41 +01:00
: QWidget ( parent )
, ui ( new Ui : : DownloadItem )
, m_item ( item )
, m_reply ( reply )
, m_path ( path )
, m_fileName ( fileName )
2011-04-08 18:52:14 +02:00
, m_downUrl ( reply - > url ( ) )
, m_downloadPage ( QUrl ( ) )
2011-03-02 16:57:41 +01:00
, m_downloading ( false )
2011-03-24 22:31:38 +01:00
, m_openAfterFinish ( openAfterFinishedDownload )
2011-03-02 16:57:41 +01:00
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ < < item < < reply < < path < < fileName ;
# endif
2011-03-02 16:57:41 +01:00
QString fullPath = path + fileName ;
if ( QFile : : exists ( fullPath ) )
QFile : : remove ( fullPath ) ;
m_outputFile . setFileName ( fullPath ) ;
ui - > setupUi ( this ) ;
2011-03-20 13:20:50 +01:00
# ifdef Q_WS_WIN
ui - > progressBar - > setStyleSheet ( " QProgressBar {border: 1px solid;} " ) ;
# endif
2011-03-02 16:57:41 +01:00
ui - > button - > setPixmap (
# ifdef Q_WS_X11
style ( ) - > standardIcon ( QStyle : : SP_BrowserStop ) . pixmap ( 20 , 20 )
# else
QIcon ( " :/icons/faenza/stop.png " ) . pixmap ( 20 , 20 )
# endif
) ;
ui - > fileName - > setText ( m_fileName ) ;
ui - > downloadInfo - > setText ( tr ( " Remaining time unavailable " ) ) ;
ui - > fileIcon - > setPixmap ( fileIcon ) ;
setContextMenuPolicy ( Qt : : CustomContextMenu ) ;
connect ( this , SIGNAL ( customContextMenuRequested ( QPoint ) ) , this , SLOT ( customContextMenuRequested ( QPoint ) ) ) ;
2011-03-29 19:55:21 +02:00
m_reply - > setParent ( this ) ;
2011-03-02 16:57:41 +01:00
connect ( m_reply , SIGNAL ( finished ( ) ) , this , SLOT ( finished ( ) ) ) ;
connect ( m_reply , SIGNAL ( readyRead ( ) ) , this , SLOT ( readyRead ( ) ) ) ;
connect ( m_reply , SIGNAL ( downloadProgress ( qint64 , qint64 ) ) , this , SLOT ( downloadProgress ( qint64 , qint64 ) ) ) ;
connect ( m_reply , SIGNAL ( error ( QNetworkReply : : NetworkError ) ) , this , SLOT ( error ( QNetworkReply : : NetworkError ) ) ) ;
2011-03-18 23:04:02 +01:00
connect ( m_reply , SIGNAL ( metaDataChanged ( ) ) , this , SLOT ( metaDataChanged ( ) ) ) ;
2011-03-02 16:57:41 +01:00
connect ( ui - > button , SIGNAL ( clicked ( QPoint ) ) , this , SLOT ( stop ( ) ) ) ;
m_downloading = true ;
m_downTimer . start ( ) ;
m_timer . start ( 1000 * 1 , this ) ;
readyRead ( ) ;
QTimer : : singleShot ( 500 , this , SLOT ( updateDownload ( ) ) ) ;
if ( m_reply - > error ( ) ! = QNetworkReply : : NoError ) {
stop ( ) ;
error ( m_reply - > error ( ) ) ;
}
show ( ) ;
2011-04-08 18:52:14 +02:00
//Get Download Page
QNetworkRequest request = m_reply - > request ( ) ;
QVariant v = request . attribute ( ( QNetworkRequest : : Attribute ) ( QNetworkRequest : : User + 100 ) ) ;
WebPage * webPage = ( WebPage * ) ( v . value < void * > ( ) ) ;
if ( webPage ) {
if ( ! webPage - > mainFrame ( ) - > url ( ) . isEmpty ( ) )
m_downloadPage = webPage - > mainFrame ( ) - > url ( ) ;
else if ( webPage - > history ( ) - > canGoBack ( ) )
m_downloadPage = webPage - > history ( ) - > backItem ( ) . url ( ) ;
2011-05-08 15:05:52 +02:00
else if ( webPage - > history ( ) - > count ( ) = = 0 )
webPage - > getView ( ) - > closeTab ( ) ;
2011-04-08 18:52:14 +02:00
}
2011-03-02 16:57:41 +01:00
}
2011-03-18 23:04:02 +01:00
void DownloadItem : : metaDataChanged ( )
{
2011-03-31 19:14:13 +02:00
// http://www.olympus.cz/consumer/images/XD-Picture_card_1GB_Hand_CROP(1).jpg
// << download this picture emits metaDataChanged signal, but image is downloaded correctly
2011-03-18 23:04:02 +01:00
QVariant locationHeader = m_reply - > header ( QNetworkRequest : : LocationHeader ) ;
2011-03-31 19:14:13 +02:00
if ( ! locationHeader . toUrl ( ) . isEmpty ( ) )
2011-04-08 18:52:14 +02:00
qWarning ( " DownloadManager: metaDataChanged << URL: %s " , qPrintable ( locationHeader . toString ( ) ) ) ;
2011-03-31 19:14:13 +02:00
// QMessageBox::information(m_item->listWidget()->parentWidget(), "Meta Data Changed", QString("Meta data changed feature unimplemented yet, sorry.\n URL: '%̈́'").arg(locationHeader.toUrl().toString()));
2011-03-18 23:04:02 +01:00
}
2011-03-02 16:57:41 +01:00
void DownloadItem : : finished ( )
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ < < m_reply ;
# endif
2011-03-02 16:57:41 +01:00
m_timer . stop ( ) ;
ui - > downloadInfo - > setText ( tr ( " Done - %1 " ) . arg ( m_reply - > url ( ) . host ( ) ) ) ;
ui - > progressBar - > hide ( ) ;
ui - > button - > hide ( ) ;
ui - > frame - > hide ( ) ;
m_outputFile . close ( ) ;
m_item - > setSizeHint ( sizeHint ( ) ) ;
# if QT_VERSION == 0x040700 // Workaround
ui - > button - > show ( ) ;
ui - > button - > hide ( ) ;
# endif
m_downloading = false ;
2011-03-24 22:31:38 +01:00
if ( m_openAfterFinish )
openFile ( ) ;
2011-04-24 22:40:35 +02:00
emit downloadFinished ( true ) ;
2011-03-02 16:57:41 +01:00
}
void DownloadItem : : downloadProgress ( qint64 received , qint64 total )
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ < < received < < total ;
# endif
2011-03-02 16:57:41 +01:00
qint64 currentValue = 0 ;
qint64 totalValue = 0 ;
if ( total > 0 ) {
currentValue = received * 100 / total ;
totalValue = 100 ;
}
ui - > progressBar - > setValue ( currentValue ) ;
ui - > progressBar - > setMaximum ( totalValue ) ;
m_currSpeed = received * 1000.0 / m_downTimer . elapsed ( ) ;
m_received = received ;
m_total = total ;
}
2011-03-17 17:03:04 +01:00
void DownloadItem : : timerEvent ( QTimerEvent * event )
2011-03-02 16:57:41 +01:00
{
if ( event - > timerId ( ) = = m_timer . timerId ( ) ) {
updateDownloadInfo ( m_currSpeed , m_received , m_total ) ;
} else
QWidget : : timerEvent ( event ) ;
}
int DownloadItem : : progress ( )
{
return ui - > progressBar - > value ( ) ;
}
bool DownloadItem : : isCancelled ( )
{
return ui - > downloadInfo - > text ( ) . startsWith ( tr ( " Cancelled " ) ) ;
}
QString DownloadItem : : remaingTimeToString ( QTime time )
{
if ( time < QTime ( 0 , 0 , 10 ) )
return tr ( " few seconds " ) ;
else if ( time < QTime ( 0 , 1 ) )
return time . toString ( " s " ) + " " + tr ( " seconds " ) ;
else if ( time < QTime ( 1 , 0 ) )
return time . toString ( " m " ) + " " + tr ( " minutes " ) ;
else
return time . toString ( " h " ) + " " + tr ( " hours " ) ;
}
QString DownloadItem : : currentSpeedToString ( double speed )
{
2011-04-21 13:28:07 +02:00
if ( speed < 0 )
return tr ( " Unknown speed " ) ;
speed / = 1024 ; // kB
if ( speed < 1000 )
return QString : : number ( speed , ' f ' , 0 ) + " kB/s " ;
speed / = 1024 ; //MB
if ( speed < 1000 )
return QString : : number ( speed , ' f ' , 2 ) + " MB/s " ;
speed / = 1024 ; //GB
return QString : : number ( speed , ' f ' , 2 ) + " GB/s " ;
2011-03-02 16:57:41 +01:00
}
2011-04-21 13:28:07 +02:00
QString DownloadItem : : fileSizeToString ( qint64 size )
2011-03-02 16:57:41 +01:00
{
2011-04-21 13:28:07 +02:00
if ( size < 0 )
return tr ( " Unknown size " ) ;
double _size = ( double ) size ;
_size / = 1024 ; //kB
if ( _size < 1000 )
return QString : : number ( _size , ' f ' , 0 ) + " kB " ;
_size / = 1024 ; //MB
if ( _size < 1000 )
return QString : : number ( _size , ' f ' , 1 ) + " MB " ;
_size / = 1024 ; //GB
return QString : : number ( _size , ' f ' , 2 ) + " GB " ;
2011-03-02 16:57:41 +01:00
}
void DownloadItem : : updateDownloadInfo ( double currSpeed , qint64 received , qint64 total )
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ < < currSpeed < < received < < total ;
# endif
2011-03-02 16:57:41 +01:00
// QString QString QString QString
// | m_remTime | |m_currSize| |m_fileSize| |m_speed|
// Remaining 26 minutes - 339MB of 693 MB (350kB/s)
int estimatedTime = ( ( total - received ) / 1024 ) / ( currSpeed / 1024 ) ;
QString speed = currentSpeedToString ( currSpeed ) ;
// We have QString speed now
QTime time ;
time = time . addSecs ( estimatedTime ) ;
QString remTime = remaingTimeToString ( time ) ;
m_remTime = time ;
QString currSize = fileSizeToString ( received ) ;
QString fileSize = fileSizeToString ( total ) ;
ui - > downloadInfo - > setText ( tr ( " Remaining %1 - %2 of %3 (%4) " ) . arg ( remTime , currSize , fileSize , speed ) ) ;
}
2011-03-29 19:55:21 +02:00
void DownloadItem : : stop ( bool askForDeleteFile )
2011-03-02 16:57:41 +01:00
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ ;
# endif
m_openAfterFinish = false ;
2011-03-02 16:57:41 +01:00
m_timer . stop ( ) ;
m_reply - > abort ( ) ;
QString outputfile = QFileInfo ( m_outputFile ) . absoluteFilePath ( ) ;
m_outputFile . close ( ) ;
ui - > downloadInfo - > setText ( tr ( " Cancelled - %1 " ) . arg ( m_reply - > url ( ) . host ( ) ) ) ;
ui - > progressBar - > hide ( ) ;
ui - > button - > hide ( ) ;
m_item - > setSizeHint ( sizeHint ( ) ) ;
# if QT_VERSION == 0x040700 // Workaround
ui - > button - > show ( ) ;
ui - > button - > hide ( ) ;
# endif
2011-03-29 19:55:21 +02:00
m_downloading = false ;
2011-03-02 16:57:41 +01:00
2011-04-24 22:40:35 +02:00
emit downloadFinished ( false ) ;
2011-03-29 19:55:21 +02:00
if ( askForDeleteFile ) {
QMessageBox : : StandardButton button = QMessageBox : : question ( m_item - > listWidget ( ) - > parentWidget ( ) , tr ( " Delete file " ) , tr ( " Do you want to also delete dowloaded file? " ) , QMessageBox : : Yes | QMessageBox : : No ) ;
if ( button ! = QMessageBox : : Yes )
return ;
}
2011-03-02 16:57:41 +01:00
QFile : : remove ( outputfile ) ;
}
2011-03-17 17:03:04 +01:00
void DownloadItem : : mouseDoubleClickEvent ( QMouseEvent * e )
2011-03-02 16:57:41 +01:00
{
openFile ( ) ;
e - > accept ( ) ;
}
void DownloadItem : : customContextMenuRequested ( QPoint pos )
{
QMenu menu ;
menu . addAction ( QIcon : : fromTheme ( " document-open " ) , tr ( " Open File " ) , this , SLOT ( openFile ( ) ) ) ;
menu . addAction ( tr ( " Open Folder " ) , this , SLOT ( openFolder ( ) ) ) ;
menu . addSeparator ( ) ;
2011-04-08 18:52:14 +02:00
menu . addAction ( tr ( " Go to Download Page " ) , this , SLOT ( goToDownloadPage ( ) ) ) - > setEnabled ( ! m_downloadPage . isEmpty ( ) ) ;
menu . addAction ( QIcon : : fromTheme ( " edit-copy " ) , tr ( " Copy Download Link " ) , this , SLOT ( copyDownloadLink ( ) ) ) ;
menu . addSeparator ( ) ;
2011-03-02 16:57:41 +01:00
menu . addAction (
# ifdef Q_WS_X11
style ( ) - > standardIcon ( QStyle : : SP_BrowserStop )
# else
QIcon ( " :/icons/faenza/stop.png " )
# endif
2011-04-08 18:52:14 +02:00
, tr ( " Cancel downloading " ) , this , SLOT ( stop ( ) ) ) - > setEnabled ( m_downloading ) ;
menu . addAction ( QIcon : : fromTheme ( " window-close " ) , tr ( " Clear " ) , this , SLOT ( clear ( ) ) ) - > setEnabled ( ! m_downloading ) ;
2011-03-02 16:57:41 +01:00
if ( m_downloading | | ui - > downloadInfo - > text ( ) . startsWith ( tr ( " Cancelled " ) ) | | ui - > downloadInfo - > text ( ) . startsWith ( tr ( " Error " ) ) )
menu . actions ( ) . at ( 0 ) - > setEnabled ( false ) ;
menu . exec ( mapToGlobal ( pos ) ) ;
}
2011-04-08 18:52:14 +02:00
void DownloadItem : : goToDownloadPage ( )
{
mApp - > getWindow ( ) - > tabWidget ( ) - > addView ( m_downloadPage , tr ( " New tab " ) , TabWidget : : NewSelectedTab ) ;
}
void DownloadItem : : copyDownloadLink ( )
{
qApp - > clipboard ( ) - > setText ( m_downUrl . toString ( ) ) ;
}
2011-03-02 16:57:41 +01:00
void DownloadItem : : clear ( )
{
emit deleteItem ( this ) ;
}
void DownloadItem : : openFile ( )
{
if ( m_downloading )
return ;
QFileInfo info ( m_path + m_fileName ) ;
if ( info . exists ( ) )
QDesktopServices : : openUrl ( QUrl : : fromLocalFile ( info . absoluteFilePath ( ) ) ) ;
else
2011-03-29 19:55:21 +02:00
QMessageBox : : warning ( m_item - > listWidget ( ) - > parentWidget ( ) , tr ( " Not found " ) , tr ( " Sorry, the file \n %1 \n was not found! " ) . arg ( info . absoluteFilePath ( ) ) ) ;
2011-03-02 16:57:41 +01:00
}
void DownloadItem : : openFolder ( )
{
QDesktopServices : : openUrl ( QUrl : : fromLocalFile ( m_path ) ) ;
}
void DownloadItem : : readyRead ( )
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ ;
# endif
2011-03-02 16:57:41 +01:00
if ( ! m_outputFile . isOpen ( ) & & ! m_outputFile . open ( QIODevice : : WriteOnly ) ) {
stop ( ) ;
ui - > downloadInfo - > setText ( tr ( " Error: Cannot write to file! " ) ) ;
return ;
}
m_outputFile . write ( m_reply - > readAll ( ) ) ;
}
void DownloadItem : : error ( QNetworkReply : : NetworkError error )
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ < < error ;
# endif
2011-03-02 16:57:41 +01:00
if ( error ! = QNetworkReply : : NoError )
ui - > downloadInfo - > setText ( tr ( " Error: " ) + m_reply - > errorString ( ) ) ;
}
void DownloadItem : : updateDownload ( )
{
2011-03-29 19:55:21 +02:00
# ifdef DOWNMANAGER_DEBUG
qDebug ( ) < < __FUNCTION__ ;
# endif
2011-03-02 16:57:41 +01:00
if ( ui - > progressBar - > maximum ( ) = = 0 & & m_outputFile . isOpen ( ) & & m_reply - > isFinished ( ) ) {
downloadProgress ( 0 , 0 ) ;
finished ( ) ;
}
}
DownloadItem : : ~ DownloadItem ( )
{
delete ui ;
delete m_item ;
}