2011-03-03 18:29:20 +01:00
/* ============================================================
* QupZilla - WebKit based browser
2012-01-01 15:29:55 +01:00
* Copyright ( C ) 2010 - 2012 David Rosca < nowrep @ gmail . com >
2011-03-03 18:29:20 +01:00
*
* 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-05-25 14:26:36 +02:00
# include "downloadmanager.h"
2011-09-30 21:44:18 +02:00
# include "iconprovider.h"
2011-12-29 22:28:04 +01:00
# include "networkmanager.h"
2012-08-23 15:40:10 +02:00
# include "globalfunctions.h"
2011-03-02 16:57:41 +01:00
2012-02-29 18:33:50 +01:00
# include <QMenu>
# include <QClipboard>
# include <QListWidgetItem>
# include <QMouseEvent>
# include <QTimer>
# include <QFileInfo>
# include <QMessageBox>
# include <QDesktopServices>
2012-08-18 02:35:54 +02:00
# include <QProcess>
2012-02-29 18:33:50 +01:00
2011-03-29 19:55:21 +02:00
//#define DOWNMANAGER_DEBUG
2011-10-07 15:37:49 +02:00
DownloadItem : : DownloadItem ( QListWidgetItem * item , QNetworkReply * reply , const QString & path , const QString & fileName , const QPixmap & fileIcon , QTime * timer , bool openAfterFinishedDownload , const QUrl & downloadPage , DownloadManager * manager )
2011-09-30 19:22:50 +02:00
: QWidget ( )
, ui ( new Ui : : DownloadItem )
, m_item ( item )
, m_reply ( reply )
, m_path ( path )
, m_fileName ( fileName )
, m_downTimer ( timer )
, m_downUrl ( reply - > url ( ) )
, m_downloadPage ( downloadPage )
, m_downloading ( false )
, m_openAfterFinish ( openAfterFinishedDownload )
2011-11-04 22:34:45 +01:00
, m_downloadStopped ( false )
2012-03-08 12:48:23 +01:00
, m_received ( 0 )
, m_total ( 0 )
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-10-12 22:28:41 +02:00
QString fullPath = path + fileName ;
2011-11-06 17:01:23 +01:00
if ( QFile : : exists ( fullPath ) ) {
2011-03-02 16:57:41 +01:00
QFile : : remove ( fullPath ) ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
m_outputFile . setFileName ( fullPath ) ;
ui - > setupUi ( this ) ;
2011-05-25 14:26:36 +02:00
setMaximumWidth ( 525 ) ;
2011-09-30 21:44:18 +02:00
2012-04-22 20:51:28 +02:00
ui - > button - > setPixmap ( qIconProvider - > standardIcon ( QStyle : : SP_BrowserStop ) . pixmap ( 20 , 20 ) ) ;
2011-03-02 16:57:41 +01:00
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-12-29 22:28:04 +01:00
connect ( ui - > button , SIGNAL ( clicked ( QPoint ) ) , this , SLOT ( stop ( ) ) ) ;
connect ( manager , SIGNAL ( resized ( QSize ) ) , this , SLOT ( parentResized ( QSize ) ) ) ;
startDownloading ( ) ;
}
2012-03-08 12:48:23 +01:00
void DownloadItem : : setTotalSize ( qint64 total )
{
if ( total > 0 ) {
m_total = total ;
}
}
2011-12-29 22:28:04 +01:00
void DownloadItem : : startDownloading ( )
{
QUrl locationHeader = m_reply - > header ( QNetworkRequest : : LocationHeader ) . toUrl ( ) ;
if ( locationHeader . isValid ( ) ) {
2012-01-28 12:02:37 +01:00
m_reply - > abort ( ) ;
2011-12-29 22:28:04 +01:00
m_reply - > deleteLater ( ) ;
m_reply = mApp - > networkManager ( ) - > get ( QNetworkRequest ( locationHeader ) ) ;
}
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
m_downloading = true ;
2011-10-12 22:28:41 +02:00
m_timer . start ( 1000 , this ) ;
2011-03-02 16:57:41 +01:00
readyRead ( ) ;
2011-11-04 22:34:45 +01:00
QTimer : : singleShot ( 200 , this , SLOT ( updateDownload ( ) ) ) ;
2011-03-02 16:57:41 +01:00
if ( m_reply - > error ( ) ! = QNetworkReply : : NoError ) {
2011-11-04 22:34:45 +01:00
stop ( false ) ;
2011-03-02 16:57:41 +01:00
error ( m_reply - > error ( ) ) ;
}
}
2011-05-25 14:26:36 +02:00
void DownloadItem : : parentResized ( const QSize & size )
{
2011-11-06 17:01:23 +01:00
if ( size . width ( ) < 200 ) {
2011-05-25 14:26:36 +02:00
return ;
2011-11-06 17:01:23 +01:00
}
2011-05-25 14:26:36 +02:00
setMaximumWidth ( size . width ( ) ) ;
}
2011-03-18 23:04:02 +01:00
void DownloadItem : : metaDataChanged ( )
{
2011-12-29 22:28:04 +01:00
QUrl locationHeader = m_reply - > header ( QNetworkRequest : : LocationHeader ) . toUrl ( ) ;
if ( locationHeader . isValid ( ) ) {
m_reply - > close ( ) ;
m_reply - > deleteLater ( ) ;
2011-03-31 19:14:13 +02:00
2011-12-29 22:28:04 +01:00
m_reply = mApp - > networkManager ( ) - > get ( QNetworkRequest ( locationHeader ) ) ;
startDownloading ( ) ;
2011-11-06 17:01:23 +01:00
}
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 ( ) ;
2012-03-16 23:28:23 +01:00
m_reply - > deleteLater ( ) ;
2011-03-02 16:57:41 +01:00
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
2011-11-06 17:01:23 +01:00
if ( m_openAfterFinish ) {
2011-03-24 22:31:38 +01:00
openFile ( ) ;
2011-11-06 17:01:23 +01:00
}
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 ) ;
2011-05-10 21:25:31 +02:00
m_currSpeed = received * 1000.0 / m_downTimer - > elapsed ( ) ;
2011-03-02 16:57:41 +01:00
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 ) ;
2011-11-06 17:01:23 +01:00
}
else {
2011-03-02 16:57:41 +01:00
QWidget : : timerEvent ( event ) ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
}
int DownloadItem : : progress ( )
{
return ui - > progressBar - > value ( ) ;
}
bool DownloadItem : : isCancelled ( )
{
return ui - > downloadInfo - > text ( ) . startsWith ( tr ( " Cancelled " ) ) ;
}
QString DownloadItem : : remaingTimeToString ( QTime time )
{
2011-11-06 17:01:23 +01:00
if ( time < QTime ( 0 , 0 , 10 ) ) {
2011-03-02 16:57:41 +01:00
return tr ( " few seconds " ) ;
2011-11-06 17:01:23 +01:00
}
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 " ) ;
}
2011-03-02 16:57:41 +01:00
}
QString DownloadItem : : currentSpeedToString ( double speed )
{
2011-11-06 17:01:23 +01:00
if ( speed < 0 ) {
2011-04-21 13:28:07 +02:00
return tr ( " Unknown speed " ) ;
2011-11-06 17:01:23 +01:00
}
2011-04-21 13:28:07 +02:00
speed / = 1024 ; // kB
2011-11-06 17:01:23 +01:00
if ( speed < 1000 ) {
return QString : : number ( speed , ' f ' , 0 ) + " kB/s " ;
}
2011-04-21 13:28:07 +02:00
speed / = 1024 ; //MB
2011-11-06 17:01:23 +01:00
if ( speed < 1000 ) {
return QString : : number ( speed , ' f ' , 2 ) + " MB/s " ;
}
2011-04-21 13:28:07 +02:00
speed / = 1024 ; //GB
2011-11-06 17:01:23 +01:00
return QString : : number ( speed , ' f ' , 2 ) + " GB/s " ;
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)
2011-11-06 17:01:23 +01:00
int estimatedTime = ( ( total - received ) / 1024 ) / ( currSpeed / 1024 ) ;
2011-03-02 16:57:41 +01:00
QString speed = currentSpeedToString ( currSpeed ) ;
// We have QString speed now
QTime time ;
time = time . addSecs ( estimatedTime ) ;
QString remTime = remaingTimeToString ( time ) ;
m_remTime = time ;
2012-08-23 15:40:10 +02:00
QString currSize = qz_fileSizeToString ( received ) ;
QString fileSize = qz_fileSizeToString ( total ) ;
2011-03-02 16:57:41 +01:00
2011-11-06 17:01:23 +01:00
if ( fileSize = = tr ( " Unknown size " ) ) {
2011-10-02 17:39:59 +02:00
ui - > downloadInfo - > setText ( tr ( " %2 - unknown size (%3) " ) . arg ( currSize , speed ) ) ;
2011-11-06 17:01:23 +01:00
}
else {
2011-09-15 21:19:47 +02:00
ui - > downloadInfo - > setText ( tr ( " Remaining %1 - %2 of %3 (%4) " ) . arg ( remTime , currSize , fileSize , speed ) ) ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
}
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
2011-11-04 22:34:45 +01:00
2011-11-06 17:01:23 +01:00
if ( m_downloadStopped ) {
2011-11-04 22:34:45 +01:00
return ;
2011-11-06 17:01:23 +01:00
}
2011-11-04 22:34:45 +01:00
m_downloadStopped = true ;
2011-03-29 19:55:21 +02:00
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 ) ;
2011-11-06 17:01:23 +01:00
if ( button = = QMessageBox : : Yes ) {
2011-11-04 22:34:45 +01:00
QFile : : remove ( outputfile ) ;
2011-11-06 17:01:23 +01:00
}
2011-03-29 19:55:21 +02:00
}
2011-03-02 16:57:41 +01:00
}
2011-03-17 17:03:04 +01:00
void DownloadItem : : mouseDoubleClickEvent ( QMouseEvent * e )
2011-03-02 16:57:41 +01:00
{
openFile ( ) ;
e - > accept ( ) ;
}
2011-05-25 14:26:36 +02:00
void DownloadItem : : customContextMenuRequested ( const QPoint & pos )
2011-03-02 16:57:41 +01:00
{
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 ( ) ;
2012-04-22 20:51:28 +02:00
menu . addAction ( qIconProvider - > standardIcon ( QStyle : : SP_BrowserStop ) , tr ( " Cancel downloading " ) , this , SLOT ( stop ( ) ) ) - > setEnabled ( m_downloading ) ;
2012-07-20 20:30:57 +02:00
menu . addAction ( QIcon : : fromTheme ( " list-remove " ) , tr ( " Remove " ) , this , SLOT ( clear ( ) ) ) - > setEnabled ( ! m_downloading ) ;
2011-03-02 16:57:41 +01:00
2011-11-06 17:01:23 +01:00
if ( m_downloading | | ui - > downloadInfo - > text ( ) . startsWith ( tr ( " Cancelled " ) ) | | ui - > downloadInfo - > text ( ) . startsWith ( tr ( " Error " ) ) ) {
2011-03-02 16:57:41 +01:00
menu . actions ( ) . at ( 0 ) - > setEnabled ( false ) ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
menu . exec ( mapToGlobal ( pos ) ) ;
}
2011-04-08 18:52:14 +02:00
void DownloadItem : : goToDownloadPage ( )
{
2012-01-18 18:36:10 +01:00
QupZilla * qz = mApp - > getWindow ( ) ;
if ( qz ) {
2012-01-21 23:19:38 +01:00
qz - > tabWidget ( ) - > addView ( m_downloadPage , Qz : : NT_SelectedTab ) ;
2012-01-18 18:36:10 +01:00
}
else {
2012-01-21 23:19:38 +01:00
mApp - > makeNewWindow ( Qz : : BW_NewWindow , m_downloadPage ) ;
2012-01-18 18:36:10 +01:00
}
2011-04-08 18:52:14 +02:00
}
void DownloadItem : : copyDownloadLink ( )
{
2012-01-21 23:19:38 +01:00
QApplication : : clipboard ( ) - > setText ( m_downUrl . toString ( ) ) ;
2011-04-08 18:52:14 +02:00
}
2011-03-02 16:57:41 +01:00
void DownloadItem : : clear ( )
{
emit deleteItem ( this ) ;
}
void DownloadItem : : openFile ( )
{
2011-11-06 17:01:23 +01:00
if ( m_downloading ) {
2011-03-02 16:57:41 +01:00
return ;
2011-11-06 17:01:23 +01:00
}
QFileInfo info ( m_path + m_fileName ) ;
if ( info . exists ( ) ) {
2011-03-02 16:57:41 +01:00
QDesktopServices : : openUrl ( QUrl : : fromLocalFile ( info . absoluteFilePath ( ) ) ) ;
2011-11-06 17:01:23 +01:00
}
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-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
}
void DownloadItem : : openFolder ( )
{
2012-09-03 22:48:52 +02:00
# ifdef Q_OS_WIN
2013-01-17 14:19:19 +01:00
if ( m_fileName . endsWith ( " " ) ) {
// explorer.exe don't support filenames that end with SPACE
QDesktopServices : : openUrl ( QUrl : : fromLocalFile ( m_path ) ) ;
}
else {
QString winFileName = m_path + m_fileName ;
winFileName . replace ( QLatin1Char ( ' / ' ) , " \\ " ) ;
2013-01-21 22:11:31 +01:00
QString shExArg = " /e,/select, \" " + winFileName + " \" " ;
2013-01-17 14:19:19 +01:00
ShellExecute ( NULL , NULL , TEXT ( " explorer.exe " ) , shExArg . toStdWString ( ) . c_str ( ) , NULL , SW_SHOW ) ;
}
2012-08-18 02:35:54 +02:00
# else
2011-03-02 16:57:41 +01:00
QDesktopServices : : openUrl ( QUrl : : fromLocalFile ( m_path ) ) ;
2012-08-18 02:35:54 +02:00
# endif
2011-03-02 16:57:41 +01:00
}
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 ) ) {
2011-11-04 22:34:45 +01:00
stop ( false ) ;
2011-03-02 16:57:41 +01:00
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-11-06 17:01:23 +01:00
if ( error ! = QNetworkReply : : NoError ) {
2011-11-04 22:34:45 +01:00
ui - > downloadInfo - > setText ( tr ( " Error: " ) + m_reply - > errorString ( ) ) ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
}
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 ( ) ) {
2011-11-06 17:01:23 +01:00
downloadProgress ( 0 , 0 ) ;
2011-03-02 16:57:41 +01:00
finished ( ) ;
}
}
DownloadItem : : ~ DownloadItem ( )
{
delete ui ;
delete m_item ;
2011-05-10 21:25:31 +02:00
delete m_downTimer ;
2011-03-02 16:57:41 +01:00
}