Skip to content

Commit

Permalink
File downloader for identify dialog hyperlinks
Browse files Browse the repository at this point in the history
fixes #14703

Include C++ and Python tests
  • Loading branch information
elpaso committed Nov 9, 2016
1 parent db0e7d5 commit bdc2e24
Show file tree
Hide file tree
Showing 11 changed files with 815 additions and 0 deletions.
1 change: 1 addition & 0 deletions python/gui/gui.sip
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
%Include qgsfieldvalidator.sip
%Include qgsfiledropedit.sip
%Include qgsfilewidget.sip
%Include qgsfiledownloader.sip
%Include qgsfilterlineedit.sip
%Include qgsfocuswatcher.sip
%Include qgsformannotationitem.sip
Expand Down
64 changes: 64 additions & 0 deletions python/gui/qgsfiledownloader.sip
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/***************************************************************************
qgsfiledownloader.sip
--------------------------------------
Date : November 2016
Copyright : (C) 2016 by Alessandro Pasotti
Email : elpaso at itopen dot it
***************************************************************************
* *
* 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 2 of the License, or *
* (at your option) any later version. *
* *
***************************************************************************/

/** \ingroup gui
* QgsFileDownloader is a utility class for downloading files.
*
* To use this class, it is necessary to pass the URL and an output file name as
* arguments to the constructor, the download will start immediately.
* The download is asynchronous and depending on the guiNotificationsEnabled
* parameter accepted by the constructor (default = true) the class will
* show a progress dialog and report all errors in a QMessageBox::warning dialog.
* If the guiNotificationsEnabled parameter is set to false, the class can still
* be used through the signals and slots mechanism.
* The object will destroy itself when the request completes, errors or is canceled.
*/
class QgsFileDownloader : public QObject
{
%TypeHeaderCode
#include <qgsfiledownloader.h>
%End
public:
/**
* QgsFileDownloader
* @param url the download url
* @param outputFileName file name where the downloaded content will be stored
* @param guiNotificationsEnabled if false, the downloader will not display any progress bar or error message
*/
QgsFileDownloader(QUrl url, QString outputFileName, bool guiNotificationsEnabled = true);

signals:
/** Emitted when the download has completed successfully */
void downloadCompleted();
/** Emitted always when the downloader exits */
void downloadExited();
/** Emitted when the download was canceled by the user */
void downloadCanceled();
/** Emitted when an error makes the download fail */
void downloadError( QStringList errorMessages );
/** Emitted when data ready to be processed */
void downloadProgress(qint64 bytesReceived, qint64 bytesTotal);

public slots:
/**
* Called when a download is canceled by the user
* this slot aborts the download and deletes the object
*/
void onDownloadCanceled();

private:
~QgsFileDownloader();

};
56 changes: 56 additions & 0 deletions src/app/qgsidentifyresultsdialog.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
#include "qgswebview.h"
#include "qgswebframe.h"
#include "qgsstringutils.h"
#include "qgsfiledownloader.h"

#include <QCloseEvent>
#include <QLabel>
Expand All @@ -55,6 +56,11 @@
#include <QMessageBox>
#include <QComboBox>
#include <QTextDocument>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QFileDialog>
#include <QFileInfo>
#include <QRegExp>

//graph
#include <qwt_plot.h>
Expand All @@ -68,13 +74,63 @@ QgsIdentifyResultsWebView::QgsIdentifyResultsWebView( QWidget *parent ) : QgsWeb
setSizePolicy( QSizePolicy::MinimumExpanding, QSizePolicy::Minimum );
page()->setNetworkAccessManager( QgsNetworkAccessManager::instance() );
// page()->setLinkDelegationPolicy( QWebPage::DelegateAllLinks );
page()->setForwardUnsupportedContent( true );

This comment has been minimized.

Copy link
@3nids

3nids Nov 14, 2016

Member

While building, I get this error:

error: no member named 'setForwardUnsupportedContent' in 'QWebPage' page()->setForwardUnsupportedContent( true );

This comment has been minimized.

Copy link
@3nids

3nids Nov 14, 2016

Member

building WITH_QT_WEBKIT=OFF

This comment has been minimized.

Copy link
@elpaso

elpaso Nov 14, 2016

Author Contributor

Yes: missing the stub. I will add it.

This comment has been minimized.

Copy link
@elpaso

elpaso Nov 14, 2016

Author Contributor

@3nids would you mind testing this?

diff --git a/src/core/qgswebpage.h b/src/core/qgswebpage.h                                                                                                                      
index 57a1d5a..d9a9669 100644                                                                                                                                                   
--- a/src/core/qgswebpage.h                                                                                                                                                     
+++ b/src/core/qgswebpage.h                                                                                                                                                     
@@ -156,6 +156,11 @@ class CORE_EXPORT QWebPage : public QObject                                                                                                                
       tb->setOpenExternalLinks( linkDelegationPolicy != DontDelegateLinks );                                                                                                   
     }                                                                                                                                                                          
                                                                                                                                                                                
+    void setForwardUnsupportedContent( bool value)                                                                                                                            
+    {                                                                                                                                                                          
+      Q_UNUSED( value );                                                                                                                                                       
+    }                                                                                                                                                                          
+                                                                                                                                                                               
     void setNetworkAccessManager( QNetworkAccessManager* networkAccessManager )                                                                                                
     {                                                                                                                                                                          
       Q_UNUSED( networkAccessManager );                                                                                                                                        

This comment has been minimized.

Copy link
@3nids

3nids Nov 14, 2016

Member

yep, it works

This comment has been minimized.

Copy link
@elpaso

elpaso Nov 15, 2016

Author Contributor

Fixed, thanks to @wonder-sk in 04e02af

page()->setLinkDelegationPolicy( QWebPage::DontDelegateLinks );
settings()->setAttribute( QWebSettings::LocalContentCanAccessRemoteUrls, true );
settings()->setAttribute( QWebSettings::JavascriptCanOpenWindows, true );
settings()->setAttribute( QWebSettings::PluginsEnabled, true );
#ifdef QGISDEBUG
settings()->setAttribute( QWebSettings::DeveloperExtrasEnabled, true );
#endif
connect( page(), SIGNAL( downloadRequested( QNetworkRequest ) ), this, SLOT( downloadRequested( QNetworkRequest ) ) );
connect( page(), SIGNAL( unsupportedContent( QNetworkReply* ) ), this, SLOT( unsupportedContent( QNetworkReply* ) ) );
}


void QgsIdentifyResultsWebView::downloadRequested( const QNetworkRequest &request )
{
qDebug() << "Download Requested: " << request.url();
handleDownload( request.url() );
}

void QgsIdentifyResultsWebView::unsupportedContent( QNetworkReply * reply )
{
qDebug() << "Unsupported Content: " << reply->url();
handleDownload( reply->url() );
}

void QgsIdentifyResultsWebView::handleDownload( QUrl url )
{
qDebug() << "Downloading: " << url;
if ( ! url.isValid() )
{
QMessageBox::warning( this, tr( "Invalid URL" ), tr( "The download URL is not valid: %1" ).arg( url.toString( ) ) );
}
else
{
const QString DOWNLOADER_LAST_DIR_KEY( "Qgis/fileDownloaderLastDir" );
QSettings settings;
// Try to get some information from the URL
QFileInfo info( url.toString( ) );
QString savePath = settings.value( DOWNLOADER_LAST_DIR_KEY ).toString( );
QString fileName = info.fileName().replace( QRegExp( "[^A-z0-9\\-_\\.]" ), "_" );
if ( ! savePath.isEmpty() && ! fileName.isEmpty( ) )
{
savePath = QDir::cleanPath( savePath + QDir::separator() + fileName );
}
QString targetFile = QFileDialog::getSaveFileName( this,
tr( "Save as" ),
savePath,
info.suffix( ).isEmpty() ? QString( ) : "*." + info.suffix( )
);
if ( ! targetFile.isEmpty() )
{
settings.setValue( DOWNLOADER_LAST_DIR_KEY, QFileInfo( targetFile ).dir().absolutePath( ) );
// Start the download
qDebug() << "Start the download: " << url;
new QgsFileDownloader( url, targetFile );
}
}
}

void QgsIdentifyResultsWebView::print()
Expand Down
7 changes: 7 additions & 0 deletions src/app/qgsidentifyresultsdialog.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@

#include <QWidget>
#include <QList>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QUrl>

class QCloseEvent;
class QTreeWidgetItem;
Expand All @@ -57,9 +60,13 @@ class APP_EXPORT QgsIdentifyResultsWebView : public QgsWebView
QSize sizeHint() const override;
public slots:
void print();
void downloadRequested( const QNetworkRequest &request );
void unsupportedContent( QNetworkReply *reply );
protected:
void contextMenuEvent( QContextMenuEvent* ) override;
QgsWebView *createWindow( QWebPage::WebWindowType type ) override;
private:
void handleDownload( QUrl url );
};

class APP_EXPORT QgsIdentifyResultsFeatureItem: public QTreeWidgetItem
Expand Down
3 changes: 3 additions & 0 deletions src/gui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ SET(QGIS_GUI_SRCS
qgsuserinputdockwidget.cpp
qgsvariableeditorwidget.cpp
qgsvertexmarker.cpp
qgsfiledownloader.cpp
)

IF (WITH_QTWEBKIT)
Expand Down Expand Up @@ -454,6 +455,7 @@ SET(QGIS_GUI_MOC_HDRS
qgsunitselectionwidget.h
qgsuserinputdockwidget.h
qgsvariableeditorwidget.h
qgsfiledownloader.h

raster/qgsmultibandcolorrendererwidget.h
raster/qgspalettedrendererwidget.h
Expand Down Expand Up @@ -648,6 +650,7 @@ SET(QGIS_GUI_HDRS
qgsuserinputdockwidget.h
qgsvectorlayertools.h
qgsvertexmarker.h
qgsfiledownloader.h

attributetable/qgsfeaturemodel.h

Expand Down
Loading

0 comments on commit bdc2e24

Please sign in to comment.