Skip to content
Snippets Groups Projects
Commit 6c73fb8f authored by Leandro Melo's avatar Leandro Melo
Browse files

Improve user interface of manage definitions dialog.

Task-number: QTCREATORBUG-1886
parent 28247894
No related branches found
No related tags found
No related merge requests found
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#include <QtCore/QLatin1Char> #include <QtCore/QLatin1Char>
#include <QtCore/QEventLoop> #include <QtCore/QEventLoop>
#include <QtCore/QFile> #include <QtCore/QFile>
#include <QtCore/QScopedPointer>
#include <QtNetwork/QNetworkAccessManager> #include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkRequest> #include <QtNetwork/QNetworkRequest>
#include <QtNetwork/QNetworkReply> #include <QtNetwork/QNetworkReply>
...@@ -40,33 +41,31 @@ using namespace TextEditor; ...@@ -40,33 +41,31 @@ using namespace TextEditor;
using namespace Internal; using namespace Internal;
DefinitionDownloader::DefinitionDownloader(const QUrl &url, const QString &localPath) : DefinitionDownloader::DefinitionDownloader(const QUrl &url, const QString &localPath) :
m_url(url), m_localPath(localPath) m_url(url), m_localPath(localPath), m_status(Unknown)
{} {}
void DefinitionDownloader::start() void DefinitionDownloader::run()
{ {
QNetworkReply *reply;
QNetworkAccessManager manager; QNetworkAccessManager manager;
int currentAttempt = 0; int currentAttempt = 0;
const int maxAttempts = 5; const int maxAttempts = 5;
while (currentAttempt < maxAttempts) { while (currentAttempt < maxAttempts) {
reply = getData(&manager); QScopedPointer<QNetworkReply> reply(getData(&manager));
if (reply->error() != QNetworkReply::NoError) if (reply->error() != QNetworkReply::NoError) {
break; m_status = NetworkError;
return;
}
++currentAttempt; ++currentAttempt;
QVariant variant = reply->attribute(QNetworkRequest::RedirectionTargetAttribute); QVariant variant = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
if (variant.isValid() && currentAttempt < maxAttempts) { if (variant.isValid() && currentAttempt < maxAttempts) {
m_url = variant.toUrl(); m_url = variant.toUrl();
delete reply;
} else if (!variant.isValid()) { } else if (!variant.isValid()) {
saveData(reply); saveData(reply.data());
break; return;
} }
} }
delete reply;
} }
QNetworkReply *DefinitionDownloader::getData(QNetworkAccessManager *manager) const QNetworkReply *DefinitionDownloader::getData(QNetworkAccessManager *manager) const
...@@ -81,14 +80,20 @@ QNetworkReply *DefinitionDownloader::getData(QNetworkAccessManager *manager) con ...@@ -81,14 +80,20 @@ QNetworkReply *DefinitionDownloader::getData(QNetworkAccessManager *manager) con
return reply; return reply;
} }
void DefinitionDownloader::saveData(QNetworkReply *reply) const void DefinitionDownloader::saveData(QNetworkReply *reply)
{ {
const QString &urlPath = m_url.path(); const QString &urlPath = m_url.path();
const QString &fileName = const QString &fileName =
urlPath.right(urlPath.length() - urlPath.lastIndexOf(QLatin1Char('/')) - 1); urlPath.right(urlPath.length() - urlPath.lastIndexOf(QLatin1Char('/')) - 1);
QFile file(m_localPath + fileName); QFile file(m_localPath + fileName);
if (!file.open(QIODevice::Text | QIODevice::WriteOnly)) if (file.open(QIODevice::Text | QIODevice::WriteOnly)) {
return; file.write(reply->readAll());
file.write(reply->readAll()); file.close();
file.close(); m_status = Ok;
} else {
m_status = WriteError;
}
} }
DefinitionDownloader::Status DefinitionDownloader::status() const
{ return m_status; }
...@@ -48,25 +48,34 @@ class DefinitionDownloader : public QObject ...@@ -48,25 +48,34 @@ class DefinitionDownloader : public QObject
public: public:
DefinitionDownloader(const QUrl &url, const QString &localPath); DefinitionDownloader(const QUrl &url, const QString &localPath);
void start(); enum Status {
NetworkError,
WriteError,
Ok,
Unknown
};
void run();
Status status() const;
private: private:
QNetworkReply *getData(QNetworkAccessManager *manager) const; QNetworkReply *getData(QNetworkAccessManager *manager) const;
void saveData(QNetworkReply *reply) const; void saveData(QNetworkReply *reply);
QUrl m_url; QUrl m_url;
QString m_localPath; QString m_localPath;
Status m_status;
}; };
// Currently QtConcurrent::map does not support passing member functions for sequence of pointers // Currently QtConcurrent::map does not support passing member functions for sequence of pointers
// (only works for operator.*) which is the case for the downloaders held by the manager. Then the // (only works for operator.*) which is the case for the downloaders held by the manager. Then the
// reason for the following functor. If something is implemented (for example a type traits) to // reason for the following functor. If something is implemented (for example a type traits) to
// handle operator->* in QtConcurrent::map this functor will not be necessary since it would be // handle operator->* in QtConcurrent::map this functor will not be necessary since it would be
// possible to directly pass DefinitionDownloader::start. // possible to directly pass DefinitionDownloader::run.
struct DownloaderStarter struct DownloaderStarter
{ {
void operator()(DefinitionDownloader *downloader) void operator()(DefinitionDownloader *downloader)
{ downloader->start(); } { downloader->run(); }
}; };
} // namespace Internal } // namespace Internal
......
...@@ -58,6 +58,7 @@ ...@@ -58,6 +58,7 @@
#include <QtCore/QtConcurrentMap> #include <QtCore/QtConcurrentMap>
#include <QtCore/QUrl> #include <QtCore/QUrl>
#include <QtGui/QDesktopServices> #include <QtGui/QDesktopServices>
#include <QtGui/QMessageBox>
#include <QtXml/QXmlSimpleReader> #include <QtXml/QXmlSimpleReader>
#include <QtXml/QXmlInputSource> #include <QtXml/QXmlInputSource>
#include <QtXml/QXmlStreamReader> #include <QtXml/QXmlStreamReader>
...@@ -289,6 +290,14 @@ void Manager::downloadDefinitions(const QList<QUrl> &urls) ...@@ -289,6 +290,14 @@ void Manager::downloadDefinitions(const QList<QUrl> &urls)
TextEditorSettings::instance()->highlighterSettings().definitionFilesPath() + TextEditorSettings::instance()->highlighterSettings().definitionFilesPath() +
QLatin1Char('/'); QLatin1Char('/');
QDir saveDir(savePath);
if (!saveDir.exists()) {
QMessageBox::critical(0,
tr("Error"),
tr("Please make sure the destination directory exists."));
return;
}
m_downloaders.clear(); m_downloaders.clear();
foreach (const QUrl &url, urls) foreach (const QUrl &url, urls)
m_downloaders.append(new DefinitionDownloader(url, savePath)); m_downloaders.append(new DefinitionDownloader(url, savePath));
...@@ -303,8 +312,28 @@ void Manager::downloadDefinitions(const QList<QUrl> &urls) ...@@ -303,8 +312,28 @@ void Manager::downloadDefinitions(const QList<QUrl> &urls)
void Manager::downloadDefinitionsFinished() void Manager::downloadDefinitionsFinished()
{ {
foreach (DefinitionDownloader *downloader, m_downloaders) int errors = 0;
bool writeError = false;
foreach (DefinitionDownloader *downloader, m_downloaders) {
DefinitionDownloader::Status status = downloader->status();
if (status != DefinitionDownloader::Ok) {
++errors;
if (status == DefinitionDownloader::WriteError && !writeError)
writeError = true;
}
delete downloader; delete downloader;
}
if (errors > 0) {
QString text;
if (errors == m_downloaders.size())
text = tr("Error downloading selected definition(s).");
else
text = tr("Error downloading one or more definitions.");
if (writeError)
text.append(tr("\nPlease check the directory's access rights."));
QMessageBox::critical(0, tr("Download Error"), text);
}
registerMimeTypes(); registerMimeTypes();
m_downloadingDefinitions = false; m_downloadingDefinitions = false;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment