2015-09-08 17:05:59 +02:00
# include "./downloadinteraction.h"
# include "./settings.h"
2015-04-22 19:32:04 +02:00
2015-09-08 17:05:59 +02:00
# include "../network/download.h"
# include "../network/permissionstatus.h"
2015-04-22 19:32:04 +02:00
# include <qtutilities/enterpassworddialog/enterpassworddialog.h>
# include <QMessageBox>
# include <QFileDialog>
# include <QPushButton>
2016-02-08 21:21:46 +01:00
# include <QStringBuilder>
2015-04-22 19:32:04 +02:00
using namespace Network ;
namespace QtGui {
DownloadInteraction : : DownloadInteraction ( QObject * parent ) :
QObject ( parent ) ,
m_parentWidget ( nullptr )
{ }
DownloadInteraction : : DownloadInteraction ( QWidget * parent ) :
QObject ( parent ) ,
m_parentWidget ( parent )
{ }
void DownloadInteraction : : connectDownload ( Download * download )
{
connect ( download , & Download : : outputDeviceRequired , this , static_cast < void ( DownloadInteraction : : * ) ( Download * , size_t ) > ( & DownloadInteraction : : downloadRequiresOutputDevice ) ) ;
connect ( download , & Download : : overwriteingPermissionRequired , this , & DownloadInteraction : : downloadRequriesOverwritePermission ) ;
connect ( download , & Download : : appendingPermissionRequired , this , & DownloadInteraction : : downloadRequriesAppendingPermission ) ;
connect ( download , & Download : : redirectionPermissonRequired , this , & DownloadInteraction : : downloadRequiresRedirectionPermission ) ;
connect ( download , & Download : : authenticationRequired , this , & DownloadInteraction : : downloadRequiresAuthentication ) ;
connect ( download , & Download : : sslErrors , this , & DownloadInteraction : : downloadHasSslErrors ) ;
}
void DownloadInteraction : : disconnectDownload ( Download * download )
{
download - > disconnect ( this ) ;
}
void DownloadInteraction : : downloadRequiresOutputDevice ( Download * download , size_t optionIndex )
{
downloadRequiresOutputDevice ( download , optionIndex , false ) ;
}
void DownloadInteraction : : downloadRequiresOutputDevice ( Download * download , size_t optionIndex , bool forceFileDialog )
{
QString fileName = download - > suitableFilename ( ) ;
// use default directory and the "suitable file name" to determine the target path
2016-04-04 14:51:51 +02:00
if ( TargetPage : : determineTargetFileWithoutAsking ( ) // if correspondent option is set
2015-04-22 19:32:04 +02:00
& & ! forceFileDialog // and the caller don't wants to force the file dialog
2016-04-04 14:51:51 +02:00
& & ( TargetPage : : targetDirectory ( ) . isEmpty ( ) | | QDir ( TargetPage : : targetDirectory ( ) ) . exists ( ) ) // and the default directory exists or is empty
2015-04-22 19:32:04 +02:00
& & ! fileName . isEmpty ( ) ) { // and the file name is not empty
2016-04-04 14:51:51 +02:00
download - > provideOutputDevice ( optionIndex , new QFile ( TargetPage : : targetDirectory ( ) % QChar ( ' / ' ) % fileName ) , true ) ;
2015-04-22 19:32:04 +02:00
} else { // aks the user for the target path otherwise
QFileDialog * dlg = new QFileDialog ( m_parentWidget ) ;
2016-02-08 21:21:46 +01:00
# ifndef Q_OS_WIN
// the native dialog can only be shown modal under Windows
2015-04-22 19:32:04 +02:00
dlg - > setModal ( false ) ;
2016-02-08 21:21:46 +01:00
# endif
2015-04-22 19:32:04 +02:00
dlg - > setFileMode ( QFileDialog : : AnyFile ) ;
dlg - > setAcceptMode ( QFileDialog : : AcceptSave ) ;
2016-04-04 14:51:51 +02:00
dlg - > setDirectory ( TargetPage : : targetDirectory ( ) ) ;
2015-04-22 19:32:04 +02:00
dlg - > selectFile ( fileName ) ;
dlg - > setOption ( QFileDialog : : DontConfirmOverwrite , true ) ;
if ( ! download - > title ( ) . isEmpty ( ) ) {
dlg - > setWindowTitle ( tr ( " Where to save »%1«? " ) . arg ( download - > title ( ) ) ) ;
}
connect ( dlg , & QFileDialog : : finished , [ download , optionIndex , dlg ] ( int result ) {
if ( result = = QFileDialog : : Accepted & & dlg - > selectedFiles ( ) . size ( ) = = 1 ) {
2016-02-08 21:21:46 +01:00
download - > provideOutputDevice ( optionIndex , new QFile ( dlg - > selectedFiles ( ) . front ( ) ) , true ) ;
2015-04-22 19:32:04 +02:00
} else {
download - > provideOutputDevice ( optionIndex , nullptr ) ;
}
dlg - > deleteLater ( ) ;
} ) ;
dlg - > show ( ) ;
}
}
void DownloadInteraction : : downloadRequriesOverwritePermission ( Download * download , size_t optionIndex , const QString & file )
{
2016-04-04 14:51:51 +02:00
if ( TargetPage : : overwriteWithoutAsking ( ) ) {
2015-04-22 19:32:04 +02:00
download - > setOverwritePermission ( optionIndex , PermissionStatus : : Allowed ) ;
} else {
QString message = tr ( " <p>The output file <i>%1</i> already exists.</p><p>Do you want to overwrite the existing file?</p> " ) . arg ( file ) ;
QMessageBox * dlg = new QMessageBox ( m_parentWidget ) ;
dlg - > setModal ( false ) ;
dlg - > setTextFormat ( Qt : : RichText ) ;
dlg - > setText ( message ) ;
dlg - > setIcon ( QMessageBox : : Warning ) ;
QPushButton * overwriteButton = dlg - > addButton ( tr ( " Overwrite (only this time) " ) , QMessageBox : : YesRole ) ;
QPushButton * overwriteAlwaysButton = dlg - > addButton ( tr ( " Overwrite (always) " ) , QMessageBox : : YesRole ) ;
QPushButton * selectOtherButton = dlg - > addButton ( tr ( " Select other download target " ) , QMessageBox : : ActionRole ) ;
QPushButton * abortButton = dlg - > addButton ( tr ( " Abort " ) , QMessageBox : : NoRole ) ;
dlg - > setEscapeButton ( abortButton ) ;
// show warning message
connect ( dlg , & QMessageBox : : finished , [ download , optionIndex , dlg , overwriteButton , overwriteAlwaysButton , selectOtherButton , abortButton , this ] ( int ) {
if ( dlg - > clickedButton ( ) = = overwriteAlwaysButton ) {
// set dontAskBeforeOverwriting to true if the user clicked yes to all
2016-04-04 14:51:51 +02:00
TargetPage : : overwriteWithoutAsking ( ) = true ;
2015-04-22 19:32:04 +02:00
}
if ( dlg - > clickedButton ( ) = = overwriteButton | | dlg - > clickedButton ( ) = = overwriteAlwaysButton ) {
download - > setOverwritePermission ( optionIndex , PermissionStatus : : Allowed ) ;
} else if ( dlg - > clickedButton ( ) = = selectOtherButton ) {
downloadRequiresOutputDevice ( download , optionIndex , true ) ;
} else {
download - > setOverwritePermission ( optionIndex , PermissionStatus : : Refused ) ;
}
dlg - > deleteLater ( ) ;
} ) ;
dlg - > show ( ) ;
}
}
void DownloadInteraction : : downloadRequriesAppendingPermission ( Download * download , size_t optionIndex , const QString & file , quint64 offset , quint64 fileSize )
{
2016-04-04 14:51:51 +02:00
if ( TargetPage : : overwriteWithoutAsking ( ) ) {
2015-04-22 19:32:04 +02:00
download - > setAppendPermission ( optionIndex , PermissionStatus : : Allowed ) ;
} else {
QString message = tr ( " <p>The output file <i>%1</i> already exists. The downloader assumes it contains previously downloaded data.</p><p>Do you want to <b>append</b> the received data to the existing file?</p> " ) . arg ( file ) ;
if ( offset ! = fileSize ) {
message . append ( tr ( " <p><b>The current download offset (%1) does not match the size of the existing file (%2).</b></p> " ) . arg ( offset ) . arg ( fileSize ) ) ;
}
QMessageBox * dlg = new QMessageBox ( m_parentWidget ) ;
dlg - > setModal ( false ) ;
dlg - > setTextFormat ( Qt : : RichText ) ;
dlg - > setText ( message ) ;
dlg - > setIcon ( QMessageBox : : Warning ) ;
QPushButton * appendButton = dlg - > addButton ( tr ( " Append " ) , QMessageBox : : YesRole ) ;
QPushButton * abortButton = dlg - > addButton ( tr ( " Abort " ) , QMessageBox : : NoRole ) ;
dlg - > setEscapeButton ( abortButton ) ;
// show warning message
connect ( dlg , & QMessageBox : : finished , [ download , optionIndex , dlg , appendButton , abortButton , this ] ( int ) {
if ( dlg - > clickedButton ( ) = = appendButton ) {
download - > setAppendPermission ( optionIndex , PermissionStatus : : Allowed ) ;
} else {
download - > setAppendPermission ( optionIndex , PermissionStatus : : Refused ) ;
}
dlg - > deleteLater ( ) ;
} ) ;
dlg - > show ( ) ;
}
}
void DownloadInteraction : : downloadRequiresRedirectionPermission ( Download * download , size_t optionIndex )
{
2016-04-04 14:51:51 +02:00
if ( MiscPage : : redirectWithoutAsking ( ) ) {
2015-04-22 19:32:04 +02:00
download - > setRedirectPermission ( optionIndex , PermissionStatus : : Allowed ) ;
} else {
const QUrl & originalUrl = download - > downloadUrl ( download - > options ( ) . at ( optionIndex ) . redirectionOf ( ) ) ;
const QUrl & newUrl = download - > downloadUrl ( optionIndex ) ;
2016-03-10 22:17:30 +01:00
QString message = tr ( " <p>Do you want to redirect form <i>%1</i> to <i>%2</i>?</p><p>The redirection URL will be added to the options so you can it select later, too.</p> " ) . arg (
2015-04-22 19:32:04 +02:00
originalUrl . toString ( ) ,
newUrl . toString ( ) ) ;
QMessageBox * dlg = new QMessageBox ( m_parentWidget ) ;
dlg - > setModal ( false ) ;
dlg - > setTextFormat ( Qt : : RichText ) ;
dlg - > setText ( message ) ;
dlg - > setIcon ( QMessageBox : : Question ) ;
dlg - > setStandardButtons ( QMessageBox : : Yes | QMessageBox : : YesToAll | QMessageBox : : No ) ;
connect ( dlg , & QMessageBox : : finished , [ download , optionIndex , dlg , this ] ( int result ) {
switch ( result ) {
case QMessageBox : : YesToAll :
2016-04-04 14:51:51 +02:00
MiscPage : : redirectWithoutAsking ( ) = true ;
2015-04-22 19:32:04 +02:00
download - > setRedirectPermission ( optionIndex , PermissionStatus : : AlwaysAllowed ) ;
break ;
case QMessageBox : : Yes :
download - > setRedirectPermission ( optionIndex , PermissionStatus : : Allowed ) ;
break ;
default :
download - > setRedirectPermission ( optionIndex , PermissionStatus : : Refused ) ;
}
dlg - > deleteLater ( ) ;
} ) ;
connect ( download , & Download : : destroyed , dlg , & QMessageBox : : deleteLater ) ;
dlg - > show ( ) ;
}
}
void DownloadInteraction : : downloadRequiresAuthentication ( Download * download , size_t optionIndex , const QString & realm )
{
Dialogs : : EnterPasswordDialog * dlg = new Dialogs : : EnterPasswordDialog ( m_parentWidget ) ;
QString downloadName = download - > downloadUrl ( ) . isEmpty ( ) ? download - > id ( ) : download - > downloadUrl ( ) . toString ( ) ;
dlg - > setModal ( false ) ;
dlg - > setPromptForUserName ( true ) ;
dlg - > setPasswordRequired ( true ) ;
dlg - > setInstruction ( tr ( " <p>Enter authentication credentials for the download <i>%1</i>.</p> " ) . arg ( downloadName ) ) ;
if ( ! realm . isEmpty ( ) ) {
dlg - > setDescription ( tr ( " Realm: %1 " ) . arg ( realm ) ) ;
}
connect ( dlg , & Dialogs : : EnterPasswordDialog : : accepted , [ download , optionIndex , dlg ] {
download - > provideAuthenticationCredentials ( optionIndex , AuthenticationCredentials ( dlg - > userName ( ) , dlg - > password ( ) ) ) ;
dlg - > deleteLater ( ) ;
} ) ;
connect ( download , & Download : : destroyed , dlg , & QMessageBox : : deleteLater ) ;
dlg - > adjustSize ( ) ;
dlg - > show ( ) ;
}
void DownloadInteraction : : downloadHasSslErrors ( Download * download , size_t optionIndex , const QList < QSslError > & sslErrors )
{
QString downloadName = download - > downloadUrl ( ) . isEmpty ( ) ? download - > id ( ) : download - > downloadUrl ( ) . toString ( ) ;
2016-04-09 00:52:21 +02:00
QString details ;
2015-04-22 19:32:04 +02:00
foreach ( const QSslError & error , sslErrors ) {
2016-04-09 00:52:21 +02:00
if ( ! details . isEmpty ( ) ) {
details . append ( QStringLiteral ( " \n \n " ) ) ;
}
details . append ( error . errorString ( ) ) ;
2015-04-22 19:32:04 +02:00
if ( ! error . certificate ( ) . isNull ( ) ) {
2016-04-09 00:52:21 +02:00
details . append ( QChar ( ' \n ' ) ) ;
details . append ( error . certificate ( ) . toText ( ) ) ;
2015-04-22 19:32:04 +02:00
}
}
QMessageBox * dlg = new QMessageBox ( m_parentWidget ) ;
dlg - > setModal ( false ) ;
2016-04-09 00:52:21 +02:00
dlg - > setWindowTitle ( tr ( " SSL errors occured " ) % QStringLiteral ( " - " ) % QCoreApplication : : applicationName ( ) ) ;
2015-04-22 19:32:04 +02:00
dlg - > setTextFormat ( Qt : : RichText ) ;
2016-04-09 00:52:21 +02:00
dlg - > setText ( tr ( " The download <i>%1</i> has SSL errors. " ) . arg ( downloadName ) ) ;
dlg - > setInformativeText ( tr ( " Do you want to ignore the SSL errors for this download? " ) ) ;
dlg - > setDetailedText ( details ) ;
2015-04-22 19:32:04 +02:00
dlg - > setIcon ( QMessageBox : : Warning ) ;
dlg - > setStandardButtons ( QMessageBox : : Yes | QMessageBox : : No ) ;
connect ( dlg , & QMessageBox : : finished , [ download , optionIndex , dlg ] ( int result ) {
switch ( result ) {
case QMessageBox : : Yes :
download - > setIgnoreSslErrorsPermission ( optionIndex , PermissionStatus : : Allowed ) ;
break ;
default :
download - > setIgnoreSslErrorsPermission ( optionIndex , PermissionStatus : : Refused ) ;
}
dlg - > deleteLater ( ) ;
} ) ;
connect ( download , & Download : : destroyed , dlg , & QMessageBox : : deleteLater ) ;
dlg - > show ( ) ;
}
}