comparison data/fileio/RemoteFile.cpp @ 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
parents 8a3d68910b37
children e2bbb58e6df6
comparison
equal deleted inserted replaced
209:6576a208e8e7 210:a06afefe45ee
21 #include <QFtp> 21 #include <QFtp>
22 #include <QFileInfo> 22 #include <QFileInfo>
23 #include <QDir> 23 #include <QDir>
24 #include <QApplication> 24 #include <QApplication>
25 #include <QProgressDialog> 25 #include <QProgressDialog>
26 #include <QHttpResponseHeader>
26 27
27 #include <iostream> 28 #include <iostream>
28 29
29 int 30 int
30 RemoteFile::m_count = 0; 31 RemoteFile::m_count = 0;
35 RemoteFile::RemoteFile(QUrl url) : 36 RemoteFile::RemoteFile(QUrl url) :
36 m_ftp(0), 37 m_ftp(0),
37 m_http(0), 38 m_http(0),
38 m_localFile(0), 39 m_localFile(0),
39 m_ok(false), 40 m_ok(false),
41 m_lastStatus(0),
40 m_done(false), 42 m_done(false),
41 m_progressDialog(0) 43 m_progressDialog(0),
44 m_progressShowTimer(this)
42 { 45 {
43 if (!canHandleScheme(url)) { 46 if (!canHandleScheme(url)) {
44 std::cerr << "RemoteFile::RemoteFile: ERROR: Unsupported scheme in URL \"" << url.toString().toStdString() << "\"" << std::endl; 47 std::cerr << "RemoteFile::RemoteFile: ERROR: Unsupported scheme in URL \"" << url.toString().toStdString() << "\"" << std::endl;
45 return; 48 return;
46 } 49 }
56 59
57 m_http = new QHttp(url.host(), url.port(80)); 60 m_http = new QHttp(url.host(), url.port(80));
58 connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool))); 61 connect(m_http, SIGNAL(done(bool)), this, SLOT(done(bool)));
59 connect(m_http, SIGNAL(dataReadProgress(int, int)), 62 connect(m_http, SIGNAL(dataReadProgress(int, int)),
60 this, SLOT(dataReadProgress(int, int))); 63 this, SLOT(dataReadProgress(int, int)));
64 connect(m_http, SIGNAL(responseHeaderReceived(const QHttpResponseHeader &)),
65 this, SLOT(responseHeaderReceived(const QHttpResponseHeader &)));
61 m_http->get(url.path(), m_localFile); 66 m_http->get(url.path(), m_localFile);
62 m_ok = true; 67 m_ok = true;
63 68
64 } else if (scheme == "ftp") { 69 } else if (scheme == "ftp") {
65 70
93 m_ok = true; 98 m_ok = true;
94 } 99 }
95 100
96 if (m_ok) { 101 if (m_ok) {
97 m_progressDialog = new QProgressDialog(tr("Downloading %1...").arg(url.toString()), tr("Cancel"), 0, 100); 102 m_progressDialog = new QProgressDialog(tr("Downloading %1...").arg(url.toString()), tr("Cancel"), 0, 100);
98 m_progressDialog->show(); 103 m_progressDialog->hide();
104 connect(&m_progressShowTimer, SIGNAL(timeout()),
105 this, SLOT(showProgressDialog()));
106 connect(m_progressDialog, SIGNAL(canceled()), this, SLOT(cancelled()));
107 m_progressShowTimer.setSingleShot(true);
108 m_progressShowTimer.start(2000);
99 } 109 }
100 } 110 }
101 111
102 RemoteFile::~RemoteFile() 112 RemoteFile::~RemoteFile()
103 { 113 {
112 { 122 {
113 QString scheme = url.scheme().toLower(); 123 QString scheme = url.scheme().toLower();
114 return (scheme == "http" || scheme == "ftp"); 124 return (scheme == "http" || scheme == "ftp");
115 } 125 }
116 126
127 bool
128 RemoteFile::isAvailable()
129 {
130 while (!m_done && m_lastStatus == 0) {
131 QApplication::processEvents();
132 }
133 return (m_lastStatus / 100 == 2);
134 }
135
117 void 136 void
118 RemoteFile::wait() 137 RemoteFile::wait()
119 { 138 {
120 while (!m_done) { 139 while (!m_done) {
121 QApplication::processEvents(); 140 QApplication::processEvents();
151 { 170 {
152 dataTransferProgress(done, total); 171 dataTransferProgress(done, total);
153 } 172 }
154 173
155 void 174 void
175 RemoteFile::responseHeaderReceived(const QHttpResponseHeader &resp)
176 {
177 m_lastStatus = resp.statusCode();
178 if (m_lastStatus / 100 >= 4) {
179 m_errorString = QString("%1 %2")
180 .arg(resp.statusCode()).arg(resp.reasonPhrase());
181 }
182 }
183
184 void
156 RemoteFile::dataTransferProgress(qint64 done, qint64 total) 185 RemoteFile::dataTransferProgress(qint64 done, qint64 total)
157 { 186 {
158 int percent = int((double(done) / double(total)) * 100.0 - 0.1); 187 int percent = int((double(done) / double(total)) * 100.0 - 0.1);
159 emit progress(percent); 188 emit progress(percent);
160 189
161 m_progressDialog->setValue(percent); 190 m_progressDialog->setValue(percent);
191 m_progressDialog->show();
192 }
193
194 void
195 RemoteFile::cancelled()
196 {
197 delete m_http;
198 m_http = 0;
199 delete m_ftp;
200 m_ftp = 0;
201 delete m_progressDialog;
202 m_progressDialog = 0;
203 delete m_localFile;
204 m_localFile = 0;
205 m_done = true;
206 m_ok = false;
207 m_errorString = tr("Download cancelled");
162 } 208 }
163 209
164 void 210 void
165 RemoteFile::done(bool error) 211 RemoteFile::done(bool error)
166 { 212 {
167 //!!! need to identify 404s etc in the return headers
168
169 emit progress(100); 213 emit progress(100);
170 m_ok = !error; 214 m_ok = !error;
215
171 if (error) { 216 if (error) {
172 if (m_http) { 217 if (m_http) {
173 m_errorString = m_http->errorString(); 218 m_errorString = m_http->errorString();
174 } else if (m_ftp) { 219 } else if (m_ftp) {
175 m_errorString = m_ftp->errorString(); 220 m_errorString = m_ftp->errorString();
176 } 221 }
222 }
223
224 if (m_lastStatus / 100 >= 4) {
225 m_ok = false;
177 } 226 }
178 227
179 delete m_localFile; 228 delete m_localFile;
180 m_localFile = 0; 229 m_localFile = 0;
181 230
193 } 242 }
194 } 243 }
195 m_done = true; 244 m_done = true;
196 } 245 }
197 246
247 void
248 RemoteFile::showProgressDialog()
249 {
250 if (m_progressDialog) m_progressDialog->show();
251 }
252
198 QString 253 QString
199 RemoteFile::createLocalFile(QUrl url) 254 RemoteFile::createLocalFile(QUrl url)
200 { 255 {
201 //!!! should we actually put up dialogs for these errors? or propagate an exception? 256 //!!! should we actually put up dialogs for these errors? or propagate an exception?
202 257