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 =
|
||||
urlPath.right(urlPath.length() - urlPath.lastIndexOf(QLatin1Char('/')) - 1);
|
||||
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;
|
||||
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
|
||||
|
@@ -58,6 +58,9 @@ public:
|
||||
void run();
|
||||
Status status() const;
|
||||
|
||||
signals:
|
||||
void foundReferencedDefinition(const QString &name);
|
||||
|
||||
private:
|
||||
QNetworkReply *getData(QNetworkAccessManager *manager) const;
|
||||
void saveData(QNetworkReply *reply);
|
||||
|
@@ -76,22 +76,55 @@ const char kMimeType[] = "mimetype";
|
||||
const char kVersion[] = "version";
|
||||
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() :
|
||||
m_isDownloadingDefinitionsSpec(false),
|
||||
m_multiDownloader(0),
|
||||
m_hasQueuedRegistration(false)
|
||||
{
|
||||
connect(&m_registeringWatcher, SIGNAL(finished()), this, SLOT(registerMimeTypesFinished()));
|
||||
connect(&m_downloadWatcher, SIGNAL(finished()), this, SLOT(downloadDefinitionsFinished()));
|
||||
}
|
||||
|
||||
Manager::~Manager()
|
||||
{
|
||||
disconnect(&m_registeringWatcher);
|
||||
disconnect(&m_downloadWatcher);
|
||||
disconnect(m_multiDownloader);
|
||||
if (m_registeringWatcher.isRunning())
|
||||
m_registeringWatcher.cancel();
|
||||
if (m_downloadWatcher.isRunning())
|
||||
m_downloadWatcher.cancel();
|
||||
delete m_multiDownloader;
|
||||
}
|
||||
|
||||
Manager *Manager::instance()
|
||||
@@ -121,6 +154,11 @@ QString Manager::definitionIdByAnyMimeType(const QStringList &mimeTypes) const
|
||||
return definitionId;
|
||||
}
|
||||
|
||||
DefinitionMetaDataPtr Manager::availableDefinitionByName(const QString &name) const
|
||||
{
|
||||
return m_availableDefinitions.value(name);
|
||||
}
|
||||
|
||||
QSharedPointer<HighlightDefinition> Manager::definition(const QString &id)
|
||||
{
|
||||
if (!id.isEmpty() && !m_definitions.contains(id)) {
|
||||
@@ -380,12 +418,12 @@ DefinitionMetaDataPtr Manager::parseMetadata(const QFileInfo &fileInfo)
|
||||
return metaData;
|
||||
}
|
||||
|
||||
QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *device) const
|
||||
QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *device)
|
||||
{
|
||||
static const QLatin1Char kSlash('/');
|
||||
static const QLatin1String kDefinition("Definition");
|
||||
|
||||
QList<DefinitionMetaDataPtr> metaDataList;
|
||||
m_availableDefinitions.clear();
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd() && !reader.hasError()) {
|
||||
if (reader.readNext() == QXmlStreamReader::StartElement &&
|
||||
@@ -401,12 +439,12 @@ QList<DefinitionMetaDataPtr> Manager::parseAvailableDefinitionsList(QIODevice *d
|
||||
if (slash != -1)
|
||||
metaData->fileName = url.right(url.length() - slash - 1);
|
||||
|
||||
metaDataList.append(metaData);
|
||||
m_availableDefinitions.insert(metaData->name, metaData);
|
||||
}
|
||||
}
|
||||
reader.clear();
|
||||
|
||||
return metaDataList;
|
||||
return m_availableDefinitions.values();
|
||||
}
|
||||
|
||||
void Manager::downloadAvailableDefinitionsMetaData()
|
||||
@@ -431,18 +469,28 @@ void Manager::downloadAvailableDefinitionsListFinished()
|
||||
|
||||
void Manager::downloadDefinitions(const QList<QUrl> &urls, const QString &savePath)
|
||||
{
|
||||
m_downloaders.clear();
|
||||
foreach (const QUrl &url, urls)
|
||||
m_downloaders.append(new DefinitionDownloader(url, savePath));
|
||||
m_multiDownloader = new MultiDefinitionDownloader(savePath, m_register.m_idByName.keys());
|
||||
connect(m_multiDownloader, SIGNAL(finished()), this, SLOT(downloadDefinitionsFinished()));
|
||||
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());
|
||||
m_downloadWatcher.setFuture(future);
|
||||
ProgressManager::addTask(future, tr("Downloading Highlighting Definitions"),
|
||||
"TextEditor.Task.Download");
|
||||
}
|
||||
|
||||
void Manager::downloadDefinitionsFinished()
|
||||
void MultiDefinitionDownloader::downloadDefinitionsFinished()
|
||||
{
|
||||
int errors = 0;
|
||||
bool writeError = false;
|
||||
@@ -467,12 +515,37 @@ void Manager::downloadDefinitionsFinished()
|
||||
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
|
||||
{
|
||||
return m_isDownloadingDefinitionsSpec;
|
||||
return m_multiDownloader != 0;
|
||||
}
|
||||
|
||||
void Manager::clear()
|
||||
|
@@ -56,6 +56,7 @@ namespace Internal {
|
||||
class HighlightDefinition;
|
||||
class DefinitionDownloader;
|
||||
class ManagerProcessor;
|
||||
class MultiDefinitionDownloader;
|
||||
|
||||
// This is the generic highlighter manager. It is not thread-safe.
|
||||
|
||||
@@ -69,6 +70,7 @@ public:
|
||||
QString definitionIdByName(const QString &name) const;
|
||||
QString definitionIdByMimeType(const QString &mimeType) const;
|
||||
QString definitionIdByAnyMimeType(const QStringList &mimeTypes) const;
|
||||
DefinitionMetaDataPtr availableDefinitionByName(const QString &name) const;
|
||||
|
||||
bool isBuildingDefinition(const QString &id) const;
|
||||
QSharedPointer<HighlightDefinition> definition(const QString &id);
|
||||
@@ -96,13 +98,12 @@ private:
|
||||
|
||||
void clear();
|
||||
|
||||
bool m_isDownloadingDefinitionsSpec;
|
||||
QList<DefinitionDownloader *> m_downloaders;
|
||||
QFutureWatcher<void> m_downloadWatcher;
|
||||
QList<DefinitionMetaDataPtr> parseAvailableDefinitionsList(QIODevice *device) const;
|
||||
MultiDefinitionDownloader *m_multiDownloader;
|
||||
QList<DefinitionMetaDataPtr> parseAvailableDefinitionsList(QIODevice *device);
|
||||
|
||||
QSet<QString> m_isBuildingDefinition;
|
||||
QHash<QString, QSharedPointer<HighlightDefinition> > m_definitions;
|
||||
QHash<QString, DefinitionMetaDataPtr> m_availableDefinitions;
|
||||
|
||||
struct RegisterData
|
||||
{
|
||||
|
Reference in New Issue
Block a user