forked from qt-creator/qt-creator
GenericHighlighter: Download dependent definitions
Change-Id: Idd3ce51316f2e2cc2270c8ed65fb419d9ef91b78 Reviewed-by: David Schulz <david.schulz@digia.com>
This commit is contained in:
committed by
Orgad Shaneh
parent
d3c6e59ae9
commit
e95ac00f75
@@ -88,8 +88,18 @@ void DefinitionDownloader::saveData(QNetworkReply *reply)
|
|||||||
const QString &fileName =
|
const QString &fileName =
|
||||||
urlPath.right(urlPath.length() - urlPath.lastIndexOf(QLatin1Char('/')) - 1);
|
urlPath.right(urlPath.length() - urlPath.lastIndexOf(QLatin1Char('/')) - 1);
|
||||||
Utils::FileSaver saver(m_localPath + fileName, QIODevice::Text);
|
Utils::FileSaver saver(m_localPath + fileName, QIODevice::Text);
|
||||||
saver.write(reply->readAll());
|
const QByteArray data = reply->readAll();
|
||||||
|
saver.write(data);
|
||||||
m_status = saver.finalize() ? Ok: WriteError;
|
m_status = saver.finalize() ? Ok: WriteError;
|
||||||
|
QString content = QString::fromUtf8(data);
|
||||||
|
QRegExp reference(QLatin1String("context\\s*=\\s*\"[^\"]*##([^\"]+)\""));
|
||||||
|
int index = -1;
|
||||||
|
forever {
|
||||||
|
index = reference.indexIn(content, index + 1);
|
||||||
|
if (index == -1)
|
||||||
|
break;
|
||||||
|
emit foundReferencedDefinition(reference.cap(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DefinitionDownloader::Status DefinitionDownloader::status() const
|
DefinitionDownloader::Status DefinitionDownloader::status() const
|
||||||
|
@@ -58,6 +58,9 @@ public:
|
|||||||
void run();
|
void run();
|
||||||
Status status() const;
|
Status status() const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void foundReferencedDefinition(const QString &name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QNetworkReply *getData(QNetworkAccessManager *manager) const;
|
QNetworkReply *getData(QNetworkAccessManager *manager) const;
|
||||||
void saveData(QNetworkReply *reply);
|
void saveData(QNetworkReply *reply);
|
||||||
|
@@ -76,22 +76,55 @@ const char kMimeType[] = "mimetype";
|
|||||||
const char kVersion[] = "version";
|
const char kVersion[] = "version";
|
||||||
const char kUrl[] = "url";
|
const char kUrl[] = "url";
|
||||||
|
|
||||||
|
class MultiDefinitionDownloader : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
MultiDefinitionDownloader(const QString &savePath, const QList<QString> &installedDefinitions) :
|
||||||
|
m_downloadPath(savePath),
|
||||||
|
m_installedDefinitions(installedDefinitions)
|
||||||
|
{
|
||||||
|
connect(&m_downloadWatcher, SIGNAL(finished()), this, SLOT(downloadDefinitionsFinished()));
|
||||||
|
}
|
||||||
|
|
||||||
|
~MultiDefinitionDownloader()
|
||||||
|
{
|
||||||
|
if (m_downloadWatcher.isRunning())
|
||||||
|
m_downloadWatcher.cancel();
|
||||||
|
}
|
||||||
|
|
||||||
|
void downloadDefinitions(const QList<QUrl> &urls);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void finished();
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void downloadReferencedDefinition(const QString &name);
|
||||||
|
void downloadDefinitionsFinished();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QFutureWatcher<void> m_downloadWatcher;
|
||||||
|
QList<DefinitionDownloader *> m_downloaders;
|
||||||
|
QList<QString> m_installedDefinitions;
|
||||||
|
QSet<QString> m_referencedDefinitions;
|
||||||
|
QString m_downloadPath;
|
||||||
|
};
|
||||||
|
|
||||||
Manager::Manager() :
|
Manager::Manager() :
|
||||||
m_isDownloadingDefinitionsSpec(false),
|
m_multiDownloader(0),
|
||||||
m_hasQueuedRegistration(false)
|
m_hasQueuedRegistration(false)
|
||||||
{
|
{
|
||||||
connect(&m_registeringWatcher, SIGNAL(finished()), this, SLOT(registerMimeTypesFinished()));
|
connect(&m_registeringWatcher, SIGNAL(finished()), this, SLOT(registerMimeTypesFinished()));
|
||||||
connect(&m_downloadWatcher, SIGNAL(finished()), this, SLOT(downloadDefinitionsFinished()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager::~Manager()
|
Manager::~Manager()
|
||||||
{
|
{
|
||||||
disconnect(&m_registeringWatcher);
|
disconnect(&m_registeringWatcher);
|
||||||
disconnect(&m_downloadWatcher);
|
disconnect(m_multiDownloader);
|
||||||
if (m_registeringWatcher.isRunning())
|
if (m_registeringWatcher.isRunning())
|
||||||
m_registeringWatcher.cancel();
|
m_registeringWatcher.cancel();
|
||||||
if (m_downloadWatcher.isRunning())
|
delete m_multiDownloader;
|
||||||
m_downloadWatcher.cancel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Manager *Manager::instance()
|
Manager *Manager::instance()
|
||||||
@@ -121,6 +154,11 @@ QString Manager::definitionIdByAnyMimeType(const QStringList &mimeTypes) const
|
|||||||
return definitionId;
|
return definitionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefinitionMetaDataPtr Manager::availableDefinitionByName(const QString &name) const
|
||||||
|
{
|
||||||
|
return m_availableDefinitions.value(name);
|
||||||
|
}
|
||||||
|
|
||||||
QSharedPointer<HighlightDefinition> Manager::definition(const QString &id)
|
QSharedPointer<HighlightDefinition> Manager::definition(const QString &id)
|
||||||
{
|
{
|
||||||
if (!id.isEmpty() && !m_definitions.contains(id)) {
|
if (!id.isEmpty() && !m_definitions.contains(id)) {
|
||||||
@@ -380,12 +418,12 @@ DefinitionMetaDataPtr Manager::parseMetadata(const QFileInfo &fileInfo)
|
|||||||
return metaData;
|
return metaData;
|
||||||
}
|
}
|
||||||
|
|
||||||
QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *device) const
|
QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *device)
|
||||||
{
|
{
|
||||||
static const QLatin1Char kSlash('/');
|
static const QLatin1Char kSlash('/');
|
||||||
static const QLatin1String kDefinition("Definition");
|
static const QLatin1String kDefinition("Definition");
|
||||||
|
|
||||||
QList<DefinitionMetaDataPtr> metaDataList;
|
m_availableDefinitions.clear();
|
||||||
QXmlStreamReader reader(device);
|
QXmlStreamReader reader(device);
|
||||||
while (!reader.atEnd() && !reader.hasError()) {
|
while (!reader.atEnd() && !reader.hasError()) {
|
||||||
if (reader.readNext() == QXmlStreamReader::StartElement &&
|
if (reader.readNext() == QXmlStreamReader::StartElement &&
|
||||||
@@ -401,12 +439,12 @@ QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *d
|
|||||||
if (slash != -1)
|
if (slash != -1)
|
||||||
metaData->fileName = url.right(url.length() - slash - 1);
|
metaData->fileName = url.right(url.length() - slash - 1);
|
||||||
|
|
||||||
metaDataList.append(metaData);
|
m_availableDefinitions.insert(metaData->name, metaData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
reader.clear();
|
reader.clear();
|
||||||
|
|
||||||
return metaDataList;
|
return m_availableDefinitions.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::downloadAvailableDefinitionsMetaData()
|
void Manager::downloadAvailableDefinitionsMetaData()
|
||||||
@@ -431,18 +469,28 @@ void Manager::downloadAvailableDefinitionsListFinished()
|
|||||||
|
|
||||||
void Manager::downloadDefinitions(const QList<QUrl> &urls, const QString &savePath)
|
void Manager::downloadDefinitions(const QList<QUrl> &urls, const QString &savePath)
|
||||||
{
|
{
|
||||||
m_downloaders.clear();
|
m_multiDownloader = new MultiDefinitionDownloader(savePath, m_register.m_idByName.keys());
|
||||||
foreach (const QUrl &url, urls)
|
connect(m_multiDownloader, SIGNAL(finished()), this, SLOT(downloadDefinitionsFinished()));
|
||||||
m_downloaders.append(new DefinitionDownloader(url, savePath));
|
m_multiDownloader->downloadDefinitions(urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiDefinitionDownloader::downloadDefinitions(const QList<QUrl> &urls)
|
||||||
|
{
|
||||||
|
m_downloaders.clear();
|
||||||
|
foreach (const QUrl &url, urls) {
|
||||||
|
DefinitionDownloader *downloader = new DefinitionDownloader(url, m_downloadPath);
|
||||||
|
connect(downloader, SIGNAL(foundReferencedDefinition(QString)),
|
||||||
|
this, SLOT(downloadReferencedDefinition(QString)));
|
||||||
|
m_downloaders.append(downloader);
|
||||||
|
}
|
||||||
|
|
||||||
m_isDownloadingDefinitionsSpec = true;
|
|
||||||
QFuture<void> future = QtConcurrent::map(m_downloaders, DownloaderStarter());
|
QFuture<void> future = QtConcurrent::map(m_downloaders, DownloaderStarter());
|
||||||
m_downloadWatcher.setFuture(future);
|
m_downloadWatcher.setFuture(future);
|
||||||
ProgressManager::addTask(future, tr("Downloading Highlighting Definitions"),
|
ProgressManager::addTask(future, tr("Downloading Highlighting Definitions"),
|
||||||
"TextEditor.Task.Download");
|
"TextEditor.Task.Download");
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::downloadDefinitionsFinished()
|
void MultiDefinitionDownloader::downloadDefinitionsFinished()
|
||||||
{
|
{
|
||||||
int errors = 0;
|
int errors = 0;
|
||||||
bool writeError = false;
|
bool writeError = false;
|
||||||
@@ -467,12 +515,37 @@ void Manager::downloadDefinitionsFinished()
|
|||||||
QMessageBox::critical(0, tr("Download Error"), text);
|
QMessageBox::critical(0, tr("Download Error"), text);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_isDownloadingDefinitionsSpec = false;
|
QList<QUrl> urls;
|
||||||
|
foreach (const QString &definition, m_referencedDefinitions) {
|
||||||
|
if (DefinitionMetaDataPtr metaData =
|
||||||
|
Manager::instance()->availableDefinitionByName(definition)) {
|
||||||
|
urls << metaData->url;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
m_referencedDefinitions.clear();
|
||||||
|
if (urls.isEmpty())
|
||||||
|
emit finished();
|
||||||
|
else
|
||||||
|
downloadDefinitions(urls);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::downloadDefinitionsFinished()
|
||||||
|
{
|
||||||
|
delete m_multiDownloader;
|
||||||
|
m_multiDownloader = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void MultiDefinitionDownloader::downloadReferencedDefinition(const QString &name)
|
||||||
|
{
|
||||||
|
if (m_installedDefinitions.contains(name))
|
||||||
|
return;
|
||||||
|
m_referencedDefinitions.insert(name);
|
||||||
|
m_installedDefinitions.append(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::isDownloadingDefinitions() const
|
bool Manager::isDownloadingDefinitions() const
|
||||||
{
|
{
|
||||||
return m_isDownloadingDefinitionsSpec;
|
return m_multiDownloader != 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::clear()
|
void Manager::clear()
|
||||||
|
@@ -56,6 +56,7 @@ namespace Internal {
|
|||||||
class HighlightDefinition;
|
class HighlightDefinition;
|
||||||
class DefinitionDownloader;
|
class DefinitionDownloader;
|
||||||
class ManagerProcessor;
|
class ManagerProcessor;
|
||||||
|
class MultiDefinitionDownloader;
|
||||||
|
|
||||||
// This is the generic highlighter manager. It is not thread-safe.
|
// This is the generic highlighter manager. It is not thread-safe.
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ public:
|
|||||||
QString definitionIdByName(const QString &name) const;
|
QString definitionIdByName(const QString &name) const;
|
||||||
QString definitionIdByMimeType(const QString &mimeType) const;
|
QString definitionIdByMimeType(const QString &mimeType) const;
|
||||||
QString definitionIdByAnyMimeType(const QStringList &mimeTypes) const;
|
QString definitionIdByAnyMimeType(const QStringList &mimeTypes) const;
|
||||||
|
DefinitionMetaDataPtr availableDefinitionByName(const QString &name) const;
|
||||||
|
|
||||||
bool isBuildingDefinition(const QString &id) const;
|
bool isBuildingDefinition(const QString &id) const;
|
||||||
QSharedPointer<HighlightDefinition> definition(const QString &id);
|
QSharedPointer<HighlightDefinition> definition(const QString &id);
|
||||||
@@ -96,13 +98,12 @@ private:
|
|||||||
|
|
||||||
void clear();
|
void clear();
|
||||||
|
|
||||||
bool m_isDownloadingDefinitionsSpec;
|
MultiDefinitionDownloader *m_multiDownloader;
|
||||||
QList<DefinitionDownloader *> m_downloaders;
|
QList<DefinitionMetaDataPtr> parseAvailableDefinitionsList(QIODevice *device);
|
||||||
QFutureWatcher<void> m_downloadWatcher;
|
|
||||||
QList<DefinitionMetaDataPtr> parseAvailableDefinitionsList(QIODevice *device) const;
|
|
||||||
|
|
||||||
QSet<QString> m_isBuildingDefinition;
|
QSet<QString> m_isBuildingDefinition;
|
||||||
QHash<QString, QSharedPointer<HighlightDefinition> > m_definitions;
|
QHash<QString, QSharedPointer<HighlightDefinition> > m_definitions;
|
||||||
|
QHash<QString, DefinitionMetaDataPtr> m_availableDefinitions;
|
||||||
|
|
||||||
struct RegisterData
|
struct RegisterData
|
||||||
{
|
{
|
||||||
|
Reference in New Issue
Block a user