Trouble understanding how to handle unsupportedContent() signal and actual saving of file



  • Hello!

    I made a little download test program to test unsupportedContent(QNetworkReply*) handling.

    The trouble for me is now how and where to handle the actual "Save File dialog" stuff ???

    This test code is for both normal file URL's like (http://download.winzip.com/winzip180.exe)
    and for dynamically generated files (has "Content-Disposition" header that has the filename to save in it)

    Any advise how to do this correctly and efficiently ?

    @class MainWindow : public QMainWindow
    {
    Q_OBJECT
    public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
    public slots:
    void slot_unsupportedContent(QNetworkReply * reply);
    void slot_downloadProgress(qint64 bytesReceived, qint64 bytesTotal);
    void slot_finished();
    private:
    Ui::MainWindow *ui;
    QString fileName;
    };

    #include <QMessageBox>
    #include <QDebug>
    #include <QFileInfo>
    #include <QFileDialog>
    #include <QDir>

    MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
    {
    ui->setupUi(this);

    this->ui->webView->page()->setForwardUnsupportedContent(true);
    connect(this->ui->webView->page(),SIGNAL(unsupportedContent(QNetworkReply*)),this,SLOT(slot_unsupportedContent(QNetworkReply*)));
    
    /* To test dynamically generated file download ("Content-Disposition" header)
     * Just give that page some YouTube URL (like https://www.youtube.com/watch?v=UtBysnK0CQM)
     * and continue so long untill you see the Download button and see what happens */
    
    this->ui->webView->load(QUrl("http://convert2mp3.net/en/index.php?p=home"));
    
    /* To test normal URL download, that is URL contains filename part */
    //this->ui->webView->load(QUrl("http://www.winzip.com/win/en/dprob.html"));
    

    }

    void
    MainWindow::slot_unsupportedContent(QNetworkReply * reply)
    {
    /* To see the download progress.
    * Downloading is actually in progress already in this point!
    * That is, reply is already downloading data */
    connect(reply,SIGNAL(downloadProgress(qint64,qint64)),this,SLOT(slot_downloadProgress(qint64,qint64)));

    /* To check the final download status, and if no error then save to disk.
     * But where should the user be asked the filename to save with
     * QFileDialog::getSaveFileName() ???
     *
     * If it's done here then the download could be finished already
     * (if very small file) and then slot_finished() called
     * before user even had chance to give filename to save!
     * (you can see the progressbar starting going immediately before savedialog)
     *
     * If it's done at the slot_finished() then with large files
     * user has to wait untill whole download complete before he/she
     * can give filename to save.
     *
     * Does this download have to do "twice" ? Once in here to get the
     * metadata from reply so that user can save with correct filename
     * and then at the end of this slot_unsupportedContent()
     * call download method or emit some signal to start download method ?
     * Sounds wastefull of bandwidth...
     *
     * Isn't there any way to postpone the actual coming of data from reply
     * object untill the metadata for filename has been gotted ??? */
    
    connect(reply,SIGNAL(finished()),this,SLOT(slot_finished()));
    
    /* Diagnostic purposes only. Especially to see if server sends
     * "Content-Disposition" header when it send dynamically (usually with php)
     * generated file */
    QList<QByteArray>   h = reply->rawHeaderList();
    foreach(QByteArray x,h) {
        qDebug() << x << "\t" << reply->rawHeader(x);
    }
    
    QString                 baseFileName;
    if(!reply->rawHeader("Content-Disposition").isEmpty()) {
        baseFileName = QString(reply->rawHeader("Content-Disposition")).replace(QRegular[removed]"(.*filename=)\"(.*)\""),"\\2");
    } else {
        baseFileName = reply->url().path().split("/").last();
    }
    fileName = QFileDialog::getSaveFileName(this, tr("Save File"), QDir::currentPath() + "/" + baseFileName);
    

    }

    void
    MainWindow::slot_downloadProgress(qint64 bytesReceived, qint64 bytesTotal)
    {
    this->ui->progressBar->setMaximum(bytesTotal);
    this->ui->progressBar->setValue(bytesReceived);
    }

    void
    MainWindow::slot_finished()
    {
    QNetworkReply* reply = qobject_cast<QNetworkReply*>(sender());

    if(reply)
    switch(reply->error()) {
        case    QNetworkReply::NoError:
        {
        qDebug() << "Download Finished!";
    
            QFile   file&#40;this->fileName&#41;;
            if(file.open(QIODevice::WriteOnly&#41;) {
                QByteArray data = reply->readAll();
               qDebug() << "Writted " <<  file.write(data) << " BYTES";
                file.close();
            }
        }
        break;
    }
    

    }

    @


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.