changeset 210:a06afefe45ee

* Cancel when downloading file * Handle status codes (404 etc) * Add RemoteFile::isAvailable * Start on FileFinder for looking up files referred to in distant sessions
author Chris Cannam
date Wed, 10 Jan 2007 17:26:39 +0000 (2007-01-10)
parents 6576a208e8e7
children e2bbb58e6df6
files data/data.pro data/fileio/FileFinder.cpp data/fileio/FileFinder.h data/fileio/RemoteFile.cpp data/fileio/RemoteFile.h
diffstat 5 files changed, 187 insertions(+), 4 deletions(-) [+]
line wrap: on
line diff
--- a/data/data.pro	Wed Jan 10 12:27:55 2007 +0000
+++ b/data/data.pro	Wed Jan 10 17:26:39 2007 +0000
@@ -26,6 +26,7 @@
            fileio/CSVFileWriter.h \
            fileio/DataFileReader.h \
            fileio/DataFileReaderFactory.h \
+           fileio/FileFinder.h \
            fileio/FileReadThread.h \
            fileio/MatrixFile.h \
            fileio/MIDIFileReader.h \
@@ -60,6 +61,7 @@
            fileio/CSVFileReader.cpp \
            fileio/CSVFileWriter.cpp \
            fileio/DataFileReaderFactory.cpp \
+           fileio/FileFinder.cpp \
            fileio/FileReadThread.cpp \
            fileio/MatrixFile.cpp \
            fileio/MIDIFileReader.cpp \
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/fileio/FileFinder.cpp	Wed Jan 10 17:26:39 2007 +0000
@@ -0,0 +1,68 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2007 QMUL.
+    
+    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.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#include "FileFinder.h"
+#include "RemoteFile.h"
+
+#include <QFileInfo>
+#include <QMessageBox>
+#include <QFileDialog>
+
+
+FileFinder::FileFinder(QString location, QString lastKnownLocation) :
+    m_location(location),
+    m_lastKnownLocation(lastKnownLocation),
+    m_lastLocatedLocation("")
+{
+}
+
+FileFinder::~FileFinder()
+{
+}
+
+QString
+FileFinder::getLocation()
+{
+    if (QFileInfo(m_location).exists()) return m_location;
+
+    if (QMessageBox::question(0,
+                              QMessageBox::tr("Failed to open file"),
+                              QMessageBox::tr("Audio file \"%1\" could not be opened.\nLocate it?").arg(m_location),
+//!!!                                  QMessageBox::tr("File \"%1\" could not be opened.\nLocate it?").arg(location),
+                              QMessageBox::Ok,
+                              QMessageBox::Cancel) == QMessageBox::Ok) {
+
+        //!!! This uses QFileDialog::getOpenFileName, while other
+        //files are located using specially built file dialogs in
+        //MainWindow::getOpenFileName -- pull out MainWindow
+        //functions into another class?
+        QString path = QFileDialog::getOpenFileName
+            (0,
+             QFileDialog::tr("Locate file \"%1\"").arg(QFileInfo(m_location).fileName()), m_location,
+             QFileDialog::tr("All files (*.*)"));
+/*!!!
+                 QFileDialog::tr("Audio files (%1)\nAll files (*.*)")
+                 .arg(AudioFileReaderFactory::getKnownExtensions()));
+*/
+
+        if (path != "") {
+            return path;
+        }
+    }
+
+    return "";
+}
+
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/data/fileio/FileFinder.h	Wed Jan 10 17:26:39 2007 +0000
@@ -0,0 +1,48 @@
+/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*-  vi:set ts=8 sts=4 sw=4: */
+
+/*
+    Sonic Visualiser
+    An audio file viewer and annotation editor.
+    Centre for Digital Music, Queen Mary, University of London.
+    This file copyright 2007 QMUL.
+    
+    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.  See the file
+    COPYING included with this distribution for more information.
+*/
+
+#ifndef _FILE_FINDER_H_
+#define _FILE_FINDER_H_
+
+#include <QString>
+
+class FileFinder
+{
+public:
+    /**
+     * Find a file.
+     *
+     * "location" is what we know about where the file is supposed to
+     * be: it may be a relative path, an absolute path, a URL, or just
+     * a filename.
+     *
+     * "lastKnownLocation", if provided, is a path or URL of something
+     * that can be used as a reference point to locate it -- for
+     * example, the location of the session file that is referring to
+     * the file we're looking for.
+     */
+    FileFinder(QString location, QString lastKnownLocation = "");
+    virtual ~FileFinder();
+
+    QString getLocation();
+
+protected:
+    QString m_location;
+    QString m_lastKnownLocation;
+    QString m_lastLocatedLocation;
+};
+
+#endif
+
--- a/data/fileio/RemoteFile.cpp	Wed Jan 10 12:27:55 2007 +0000
+++ b/data/fileio/RemoteFile.cpp	Wed Jan 10 17:26:39 2007 +0000
@@ -23,6 +23,7 @@
 #include <QDir>
 #include <QApplication>
 #include <QProgressDialog>
+#include <QHttpResponseHeader>
 
 #include <iostream>
 
@@ -37,8 +38,10 @@
     m_http(0),
     m_localFile(0),
     m_ok(false),
+    m_lastStatus(0),
     m_done(false),
-    m_progressDialog(0)
+    m_progressDialog(0),
+    m_progressShowTimer(this)
 {
     if (!canHandleScheme(url)) {
         std::cerr << "RemoteFile::RemoteFile: ERROR: Unsupported scheme in URL \"" << url.toString().toStdString() << "\"" << std::endl;
@@ -58,6 +61,8 @@
         connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool)));
         connect(m_http, SIGNAL(dataReadProgress(int, int)),
                 this, SLOT(dataReadProgress(int, int)));
+        connect(m_http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
+                this, SLOT(responseHeaderReceived(const QHttpResponseHeader &)));
         m_http->get(url.path(), m_localFile);
         m_ok = true;
 
@@ -95,7 +100,12 @@
 
     if (m_ok) {
         m_progressDialog = new QProgressDialog(tr("Downloading %1...").arg(url.toString()), tr("Cancel"), 0, 100);
-        m_progressDialog->show();
+        m_progressDialog->hide();
+        connect(&m_progressShowTimer, SIGNAL(timeout()),
+                this, SLOT(showProgressDialog()));
+        connect(m_progressDialog, SIGNAL(canceled()), this, SLOT(cancelled()));
+        m_progressShowTimer.setSingleShot(true);
+        m_progressShowTimer.start(2000);
     }
 }
 
@@ -114,6 +124,15 @@
     return (scheme == "http" || scheme == "ftp");
 }
 
+bool
+RemoteFile::isAvailable()
+{
+    while (!m_done && m_lastStatus == 0) {
+        QApplication::processEvents();
+    }
+    return (m_lastStatus / 100 == 2);
+}
+
 void
 RemoteFile::wait()
 {
@@ -153,21 +172,47 @@
 }
 
 void
+RemoteFile::responseHeaderReceived(const QHttpResponseHeader &resp)
+{
+    m_lastStatus = resp.statusCode();
+    if (m_lastStatus / 100 >= 4) {
+        m_errorString = QString("%1 %2")
+            .arg(resp.statusCode()).arg(resp.reasonPhrase());
+    }
+}
+
+void
 RemoteFile::dataTransferProgress(qint64 done, qint64 total)
 {
     int percent = int((double(done) / double(total)) * 100.0 - 0.1);
     emit progress(percent);
 
     m_progressDialog->setValue(percent);
+    m_progressDialog->show();
+}
+
+void
+RemoteFile::cancelled()
+{
+    delete m_http;
+    m_http = 0;
+    delete m_ftp;
+    m_ftp = 0;
+    delete m_progressDialog;
+    m_progressDialog = 0;
+    delete m_localFile;
+    m_localFile = 0;
+    m_done = true;
+    m_ok = false;
+    m_errorString = tr("Download cancelled");
 }
 
 void
 RemoteFile::done(bool error)
 {
-    //!!! need to identify 404s etc in the return headers
-
     emit progress(100);
     m_ok = !error;
+
     if (error) {
         if (m_http) {
             m_errorString = m_http->errorString();
@@ -176,6 +221,10 @@
         }
     }
 
+    if (m_lastStatus / 100 >= 4) {
+        m_ok = false;
+    }
+
     delete m_localFile;
     m_localFile = 0;
 
@@ -195,6 +244,12 @@
     m_done = true;
 }
 
+void
+RemoteFile::showProgressDialog()
+{
+    if (m_progressDialog) m_progressDialog->show();
+}
+
 QString
 RemoteFile::createLocalFile(QUrl url)
 {
--- a/data/fileio/RemoteFile.h	Wed Jan 10 12:27:55 2007 +0000
+++ b/data/fileio/RemoteFile.h	Wed Jan 10 17:26:39 2007 +0000
@@ -19,11 +19,13 @@
 #include <QUrl>
 #include <QMutex>
 #include <QString>
+#include <QTimer>
 
 class QFtp;
 class QHttp;
 class QFile;
 class QProgressDialog;
+class QHttpResponseHeader;
 
 class RemoteFile : public QObject
 {
@@ -33,10 +35,13 @@
     RemoteFile(QUrl url);
     virtual ~RemoteFile();
 
+    bool isAvailable();
+
     void wait();
 
     bool isOK() const;
     bool isDone() const;
+
     QString getLocalFilename() const;
     QString getErrorString() const;
 
@@ -48,8 +53,11 @@
 
 protected slots:
     void dataReadProgress(int done, int total);
+    void responseHeaderReceived(const QHttpResponseHeader &resp);
     void dataTransferProgress(qint64 done, qint64 total);
     void done(bool error);
+    void showProgressDialog();
+    void cancelled();
 
 protected:
     QFtp *m_ftp;
@@ -58,8 +66,10 @@
     QString m_localFilename;
     QString m_errorString;
     bool m_ok;
+    int m_lastStatus;
     bool m_done;
     QProgressDialog *m_progressDialog;
+    QTimer m_progressShowTimer;
 
     QString createLocalFile(QUrl url);