2011-03-03 18:29:20 +01:00
/* ============================================================
* QupZilla - WebKit based browser
2016-02-15 09:58:14 +01:00
* Copyright ( C ) 2010 - 2016 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 "downloadmanager.h"
# include "ui_downloadmanager.h"
2014-02-19 22:07:21 +01:00
# include "browserwindow.h"
2012-01-21 23:19:38 +01:00
# include "mainapplication.h"
2011-03-02 16:57:41 +01:00
# include "downloadoptionsdialog.h"
# include "downloaditem.h"
# include "ecwin7.h"
2011-03-20 17:42:56 +01:00
# include "networkmanager.h"
2011-04-07 18:00:26 +02:00
# include "qtwin.h"
2011-04-24 22:40:35 +02:00
# include "desktopnotificationsfactory.h"
2013-01-22 19:04:22 +01:00
# include "qztools.h"
2011-09-23 15:40:14 +02:00
# include "webpage.h"
2015-05-24 19:22:32 +02:00
# include "webview.h"
2012-01-11 21:58:25 +01:00
# include "settings.h"
2015-10-04 20:59:29 +02:00
# include "datapaths.h"
2011-03-02 16:57:41 +01:00
2013-02-15 12:29:13 +01:00
# include <QMessageBox>
2012-02-29 18:33:50 +01:00
# include <QCloseEvent>
# include <QDir>
2014-12-21 20:53:33 +01:00
# include <QShortcut>
2015-05-24 19:22:32 +02:00
# include <QStandardPaths>
# include <QWebEngineHistory>
# include <QWebEngineDownloadItem>
2012-02-29 18:33:50 +01:00
2011-10-30 16:32:36 +01:00
DownloadManager : : DownloadManager ( QWidget * parent )
: QWidget ( parent )
, ui ( new Ui : : DownloadManager )
, m_isClosing ( false )
2014-02-01 19:21:49 +01:00
, m_lastDownloadOption ( NoOption )
2011-03-02 16:57:41 +01:00
{
2011-05-25 14:26:36 +02:00
setWindowFlags ( windowFlags ( ) ^ Qt : : WindowMaximizeButtonHint ) ;
2011-03-02 16:57:41 +01:00
ui - > setupUi ( this ) ;
2012-09-03 22:48:52 +02:00
# ifdef Q_OS_WIN
2011-11-06 17:01:23 +01:00
if ( QtWin : : isCompositionEnabled ( ) ) {
2011-04-07 18:00:26 +02:00
QtWin : : extendFrameIntoClientArea ( this ) ;
2011-11-06 17:01:23 +01:00
}
2011-04-07 18:00:26 +02:00
# endif
2011-03-02 16:57:41 +01:00
ui - > clearButton - > setIcon ( QIcon : : fromTheme ( " edit-clear " ) ) ;
2013-01-22 19:04:22 +01:00
QzTools : : centerWidgetOnScreen ( this ) ;
2011-03-02 16:57:41 +01:00
connect ( ui - > clearButton , SIGNAL ( clicked ( ) ) , this , SLOT ( clearList ( ) ) ) ;
2014-12-21 20:53:33 +01:00
QShortcut * clearShortcut = new QShortcut ( QKeySequence ( " CTRL+L " ) , this ) ;
connect ( clearShortcut , SIGNAL ( activated ( ) ) , this , SLOT ( clearList ( ) ) ) ;
2011-05-25 14:26:36 +02:00
loadSettings ( ) ;
2013-07-12 11:43:13 +02:00
QzTools : : setWmClass ( " Download Manager " , this ) ;
2012-01-28 12:02:37 +01:00
# ifdef W7TASKBAR
2011-11-06 17:01:23 +01:00
if ( QtWin : : isRunningWindows7 ( ) ) {
2013-01-19 23:22:30 +01:00
win7 . init ( QtWin : : hwndOfWidget ( this ) ) ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
# endif
}
2011-05-25 14:26:36 +02:00
void DownloadManager : : loadSettings ( )
{
2012-01-11 21:58:25 +01:00
Settings settings ;
2011-05-25 14:26:36 +02:00
settings . beginGroup ( " DownloadManager " ) ;
2012-09-02 11:42:41 +02:00
m_downloadPath = settings . value ( " defaultDownloadPath " , QString ( ) ) . toString ( ) ;
2012-09-04 12:42:45 +02:00
m_lastDownloadPath = settings . value ( " lastDownloadPath " , QDir : : homePath ( ) . append ( QLatin1Char ( ' / ' ) ) ) . toString ( ) ;
2011-10-30 16:32:36 +01:00
m_closeOnFinish = settings . value ( " CloseManagerOnFinish " , false ) . toBool ( ) ;
2012-04-05 10:27:35 +02:00
m_useNativeDialog = settings . value ( " useNativeDialog " , DEFAULT_DOWNLOAD_USE_NATIVE_DIALOG ) . toBool ( ) ;
2012-01-28 15:37:11 +01:00
m_useExternalManager = settings . value ( " UseExternalManager " , false ) . toBool ( ) ;
2012-09-02 11:42:41 +02:00
m_externalExecutable = settings . value ( " ExternalManagerExecutable " , QString ( ) ) . toString ( ) ;
m_externalArguments = settings . value ( " ExternalManagerArguments " , QString ( ) ) . toString ( ) ;
2011-05-25 14:26:36 +02:00
settings . endGroup ( ) ;
2013-02-15 15:35:23 +01:00
if ( ! m_externalArguments . contains ( QLatin1String ( " %d " ) ) ) {
m_externalArguments . append ( QLatin1String ( " %d " ) ) ;
}
2011-05-25 14:26:36 +02:00
}
2011-10-18 14:30:17 +02:00
void DownloadManager : : show ( )
{
2015-10-04 21:12:53 +02:00
m_timer . start ( 500 , this ) ;
2011-10-18 14:30:17 +02:00
QWidget : : show ( ) ;
2013-06-11 09:08:26 +02:00
raise ( ) ;
activateWindow ( ) ;
2011-10-18 14:30:17 +02:00
}
2011-11-06 17:01:23 +01:00
void DownloadManager : : resizeEvent ( QResizeEvent * e )
2011-05-25 14:26:36 +02:00
{
QWidget : : resizeEvent ( e ) ;
emit resized ( size ( ) ) ;
}
2012-04-20 14:49:16 +02:00
void DownloadManager : : keyPressEvent ( QKeyEvent * e )
{
2014-12-20 15:58:25 +01:00
if ( e - > key ( ) = = Qt : : Key_Escape
| | ( e - > key ( ) = = Qt : : Key_W & & e - > modifiers ( ) = = Qt : : ControlModifier ) ) {
2012-04-20 14:49:16 +02:00
close ( ) ;
}
QWidget : : keyPressEvent ( e ) ;
}
2012-01-28 15:37:11 +01:00
void DownloadManager : : startExternalManager ( const QUrl & url )
{
2013-02-15 15:35:23 +01:00
QString arguments = m_externalArguments ;
arguments . replace ( QLatin1String ( " %d " ) , url . toEncoded ( ) ) ;
QzTools : : startExternalProcess ( m_externalExecutable , arguments ) ;
2012-08-14 11:52:06 +02:00
m_lastDownloadOption = ExternalManager ;
2012-01-28 15:37:11 +01:00
}
2012-01-28 12:02:37 +01:00
# ifdef W7TASKBAR
2013-01-19 23:22:30 +01:00
bool DownloadManager : : nativeEvent ( const QByteArray & eventType , void * _message , long * result )
{
Q_UNUSED ( eventType )
MSG * message = static_cast < MSG * > ( _message ) ;
2011-03-02 16:57:41 +01:00
return win7 . winEvent ( message , result ) ;
}
# endif
2012-04-20 14:49:16 +02:00
void DownloadManager : : timerEvent ( QTimerEvent * e )
2011-03-02 16:57:41 +01:00
{
2013-02-26 12:56:11 +01:00
QVector < QTime > remTimes ;
QVector < int > progresses ;
QVector < double > speeds ;
2011-03-02 16:57:41 +01:00
2012-04-20 14:49:16 +02:00
if ( e - > timerId ( ) = = m_timer . timerId ( ) ) {
2011-03-02 16:57:41 +01:00
if ( ! ui - > list - > count ( ) ) {
ui - > speedLabel - > clear ( ) ;
setWindowTitle ( tr ( " Download Manager " ) ) ;
return ;
}
for ( int i = 0 ; i < ui - > list - > count ( ) ; i + + ) {
DownloadItem * downItem = qobject_cast < DownloadItem * > ( ui - > list - > itemWidget ( ui - > list - > item ( i ) ) ) ;
2011-11-06 17:01:23 +01:00
if ( ! downItem | | ( downItem & & downItem - > isCancelled ( ) ) | | ! downItem - > isDownloading ( ) ) {
2011-03-02 16:57:41 +01:00
continue ;
2011-11-06 17:01:23 +01:00
}
2011-04-24 22:40:35 +02:00
progresses . append ( downItem - > progress ( ) ) ;
2011-03-02 16:57:41 +01:00
remTimes . append ( downItem - > remainingTime ( ) ) ;
speeds . append ( downItem - > currentSpeed ( ) ) ;
}
2011-11-06 17:01:23 +01:00
if ( remTimes . isEmpty ( ) ) {
2011-03-02 16:57:41 +01:00
return ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
QTime remaining ;
2013-03-06 09:05:41 +01:00
foreach ( const QTime & time , remTimes ) {
2011-11-06 17:01:23 +01:00
if ( time > remaining ) {
2011-03-02 16:57:41 +01:00
remaining = time ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
}
int progress = 0 ;
2013-03-06 09:05:41 +01:00
foreach ( int prog , progresses ) {
progress + = prog ;
}
2011-03-02 16:57:41 +01:00
progress = progress / progresses . count ( ) ;
double speed = 0.00 ;
2013-03-06 09:05:41 +01:00
foreach ( double spee , speeds ) {
speed + = spee ;
}
2011-03-02 16:57:41 +01:00
2011-11-06 17:01:23 +01:00
ui - > speedLabel - > setText ( tr ( " %1% of %2 files (%3) %4 remaining " ) . arg ( QString : : number ( progress ) , QString : : number ( progresses . count ( ) ) ,
DownloadItem : : currentSpeedToString ( speed ) ,
DownloadItem : : remaingTimeToString ( remaining ) ) ) ;
2013-05-05 12:41:12 +02:00
setWindowTitle ( tr ( " %1% - Download Manager " ) . arg ( progress ) ) ;
2012-01-28 12:02:37 +01:00
# ifdef W7TASKBAR
2011-05-01 22:07:57 +02:00
if ( QtWin : : isRunningWindows7 ( ) ) {
win7 . setProgressValue ( progress , 100 ) ;
win7 . setProgressState ( win7 . Normal ) ;
}
2011-03-02 16:57:41 +01:00
# endif
2011-11-06 17:01:23 +01:00
}
2016-04-08 11:05:42 +02:00
QWidget : : timerEvent ( e ) ;
2011-03-02 16:57:41 +01:00
}
void DownloadManager : : clearList ( )
{
QList < DownloadItem * > items ;
for ( int i = 0 ; i < ui - > list - > count ( ) ; i + + ) {
DownloadItem * downItem = qobject_cast < DownloadItem * > ( ui - > list - > itemWidget ( ui - > list - > item ( i ) ) ) ;
2011-11-06 17:01:23 +01:00
if ( ! downItem ) {
2011-03-02 16:57:41 +01:00
continue ;
2011-11-06 17:01:23 +01:00
}
if ( downItem - > isDownloading ( ) ) {
2011-03-02 16:57:41 +01:00
continue ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
items . append ( downItem ) ;
}
qDeleteAll ( items ) ;
}
2015-05-24 19:22:32 +02:00
void DownloadManager : : download ( QWebEngineDownloadItem * downloadItem )
2011-03-02 16:57:41 +01:00
{
2015-10-04 20:59:29 +02:00
QString downloadPath ;
bool openFile = false ;
QString fileName = QFileInfo ( downloadItem - > path ( ) ) . fileName ( ) ;
2015-12-16 23:32:29 +01:00
fileName = QUrl : : fromPercentEncoding ( fileName . toUtf8 ( ) ) ;
2015-10-04 20:59:29 +02:00
2016-05-31 18:39:43 +02:00
if ( m_useExternalManager ) {
startExternalManager ( downloadItem - > url ( ) ) ;
} else if ( m_downloadPath . isEmpty ( ) ) {
2016-09-18 12:09:38 +02:00
enum Result { Open = 1 , Save = 2 , ExternalManager = 3 , Unknown = 0 } ;
Result result = Unknown ;
if ( fileName . endsWith ( QL1S ( " .mhtml " ) ) ) {
// Save Page action
result = Save ;
} else {
// Ask what to do
DownloadOptionsDialog optionsDialog ( fileName , downloadItem - > url ( ) , mApp - > activeWindow ( ) ) ;
optionsDialog . showExternalManagerOption ( m_useExternalManager ) ;
optionsDialog . setLastDownloadOption ( m_lastDownloadOption ) ;
result = Result ( optionsDialog . exec ( ) ) ;
}
2015-10-04 20:59:29 +02:00
2016-09-18 12:09:38 +02:00
switch ( result ) {
case Open :
2015-10-04 20:59:29 +02:00
openFile = true ;
downloadPath = QzTools : : ensureUniqueFilename ( DataPaths : : path ( DataPaths : : Temp ) + QLatin1Char ( ' / ' ) + fileName ) ;
m_lastDownloadOption = OpenFile ;
break ;
2016-09-18 12:09:38 +02:00
case Save :
2016-05-27 21:31:20 +02:00
downloadPath = QFileDialog : : getSaveFileName ( mApp - > activeWindow ( ) , tr ( " Save file as... " ) , m_lastDownloadPath + QLatin1Char ( ' / ' ) + fileName ) ;
2016-05-27 20:37:08 +02:00
if ( ! downloadPath . isEmpty ( ) ) {
m_lastDownloadPath = QFileInfo ( downloadPath ) . absolutePath ( ) ;
2016-05-27 21:31:20 +02:00
Settings ( ) . setValue ( QSL ( " DownloadManager/lastDownloadPath " ) , m_lastDownloadPath ) ;
2016-05-27 20:37:08 +02:00
m_lastDownloadOption = SaveFile ;
}
2015-10-04 20:59:29 +02:00
break ;
2016-09-18 12:09:38 +02:00
case ExternalManager :
2015-10-04 20:59:29 +02:00
startExternalManager ( downloadItem - > url ( ) ) ;
// fallthrough
default :
downloadItem - > cancel ( ) ;
return ;
}
} else {
downloadPath = QzTools : : ensureUniqueFilename ( m_downloadPath + QL1C ( ' / ' ) + fileName ) ;
}
if ( downloadPath . isEmpty ( ) ) {
2015-05-24 19:22:32 +02:00
downloadItem - > cancel ( ) ;
2012-01-21 20:27:45 +01:00
return ;
}
2015-05-24 19:22:32 +02:00
// Set download path and accept
2015-10-04 20:59:29 +02:00
downloadItem - > setPath ( downloadPath ) ;
2015-05-24 19:22:32 +02:00
downloadItem - > accept ( ) ;
2011-09-30 19:22:50 +02:00
2015-05-24 19:22:32 +02:00
// Create download item
QListWidgetItem * listItem = new QListWidgetItem ( ui - > list ) ;
2015-12-17 00:45:09 +01:00
DownloadItem * downItem = new DownloadItem ( listItem , downloadItem , QFileInfo ( downloadPath ) . absolutePath ( ) , QFileInfo ( downloadPath ) . fileName ( ) , openFile , this ) ;
2015-10-04 20:23:54 +02:00
connect ( downItem , SIGNAL ( deleteItem ( DownloadItem * ) ) , this , SLOT ( deleteItem ( DownloadItem * ) ) ) ;
connect ( downItem , SIGNAL ( downloadFinished ( bool ) ) , this , SLOT ( downloadFinished ( bool ) ) ) ;
2015-05-24 19:22:32 +02:00
ui - > list - > setItemWidget ( listItem , downItem ) ;
listItem - > setSizeHint ( downItem - > sizeHint ( ) ) ;
2012-02-04 18:45:59 +01:00
downItem - > show ( ) ;
2011-09-30 19:22:50 +02:00
2011-03-02 16:57:41 +01:00
show ( ) ;
2011-10-21 23:26:34 +02:00
raise ( ) ;
2011-03-02 16:57:41 +01:00
activateWindow ( ) ;
}
2011-04-24 22:40:35 +02:00
void DownloadManager : : downloadFinished ( bool success )
{
bool downloadingAllFilesFinished = true ;
for ( int i = 0 ; i < ui - > list - > count ( ) ; i + + ) {
DownloadItem * downItem = qobject_cast < DownloadItem * > ( ui - > list - > itemWidget ( ui - > list - > item ( i ) ) ) ;
2011-11-06 17:01:23 +01:00
if ( ! downItem | | ( downItem & & downItem - > isCancelled ( ) ) | | ! downItem - > isDownloading ( ) ) {
2011-04-24 22:40:35 +02:00
continue ;
2011-11-06 17:01:23 +01:00
}
2011-04-24 22:40:35 +02:00
downloadingAllFilesFinished = false ;
}
if ( downloadingAllFilesFinished ) {
2011-04-29 17:47:55 +02:00
if ( success & & qApp - > activeWindow ( ) ! = this ) {
2014-03-24 16:08:33 +01:00
mApp - > desktopNotifications ( ) - > showNotification ( QIcon : : fromTheme ( QSL ( " download " ) , QIcon ( " :icons/notifications/download.png " ) ) . pixmap ( 48 ) , tr ( " Download Finished " ) , tr ( " All files have been successfully downloaded. " ) ) ;
2011-10-30 16:32:36 +01:00
if ( ! m_closeOnFinish ) {
raise ( ) ;
activateWindow ( ) ;
}
2011-04-29 17:47:55 +02:00
}
2011-04-24 22:40:35 +02:00
ui - > speedLabel - > clear ( ) ;
setWindowTitle ( tr ( " Download Manager " ) ) ;
2012-01-28 12:02:37 +01:00
# ifdef W7TASKBAR
2011-05-01 22:07:57 +02:00
if ( QtWin : : isRunningWindows7 ( ) ) {
2011-05-06 12:58:07 +02:00
win7 . setProgressValue ( 0 , 100 ) ;
win7 . setProgressState ( win7 . NoProgress ) ;
2011-05-01 22:07:57 +02:00
}
2011-04-24 22:40:35 +02:00
# endif
2011-11-06 17:01:23 +01:00
if ( m_closeOnFinish ) {
2011-10-30 16:32:36 +01:00
close ( ) ;
2011-11-06 17:01:23 +01:00
}
2011-04-24 22:40:35 +02:00
}
}
2011-03-17 17:03:04 +01:00
void DownloadManager : : deleteItem ( DownloadItem * item )
2011-03-02 16:57:41 +01:00
{
2011-11-06 17:01:23 +01:00
if ( item & & ! item - > isDownloading ( ) ) {
2011-03-02 16:57:41 +01:00
delete item ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
}
bool DownloadManager : : canClose ( )
{
2011-11-06 17:01:23 +01:00
if ( m_isClosing ) {
2011-03-02 16:57:41 +01:00
return true ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
bool isDownloading = false ;
for ( int i = 0 ; i < ui - > list - > count ( ) ; i + + ) {
DownloadItem * downItem = qobject_cast < DownloadItem * > ( ui - > list - > itemWidget ( ui - > list - > item ( i ) ) ) ;
2011-11-06 17:01:23 +01:00
if ( ! downItem ) {
2011-03-02 16:57:41 +01:00
continue ;
2011-11-06 17:01:23 +01:00
}
2011-03-02 16:57:41 +01:00
if ( downItem - > isDownloading ( ) ) {
isDownloading = true ;
break ;
}
}
return ! isDownloading ;
}
2012-08-14 11:52:06 +02:00
bool DownloadManager : : useExternalManager ( ) const
{
return m_useExternalManager ;
}
2011-03-17 17:03:04 +01:00
void DownloadManager : : closeEvent ( QCloseEvent * e )
2011-03-02 16:57:41 +01:00
{
2011-03-05 13:16:13 +01:00
if ( mApp - > windowCount ( ) = = 0 ) { // No main windows -> we are going to quit
2011-11-06 17:01:23 +01:00
if ( ! canClose ( ) ) {
2011-03-02 16:57:41 +01:00
QMessageBox : : StandardButton button = QMessageBox : : warning ( this , tr ( " Warning " ) ,
2016-02-15 09:58:14 +01:00
tr ( " Are you sure you want to quit? All uncompleted downloads will be cancelled! " ) , QMessageBox : : Yes | QMessageBox : : No ) ;
2011-03-02 16:57:41 +01:00
if ( button ! = QMessageBox : : Yes ) {
e - > ignore ( ) ;
return ;
}
m_isClosing = true ;
}
2011-03-04 13:59:07 +01:00
mApp - > quitApplication ( ) ;
2011-03-02 16:57:41 +01:00
}
e - > accept ( ) ;
}
DownloadManager : : ~ DownloadManager ( )
{
delete ui ;
}
2015-01-27 11:01:52 +01:00