forked from qt-creator/qt-creator
Generic highlighter: Interface for automatic download of available definitions. Refactorings and changes in related parts of the code.
This commit is contained in:
@@ -0,0 +1,94 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "definitiondownloader.h"
|
||||
|
||||
#include <QtCore/QLatin1Char>
|
||||
#include <QtCore/QEventLoop>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
using namespace TextEditor;
|
||||
using namespace Internal;
|
||||
|
||||
DefinitionDownloader::DefinitionDownloader(const QUrl &url, const QString &localPath) :
|
||||
m_url(url), m_localPath(localPath)
|
||||
{}
|
||||
|
||||
void DefinitionDownloader::start()
|
||||
{
|
||||
QNetworkReply *reply;
|
||||
QNetworkAccessManager manager;
|
||||
|
||||
int currentAttempt = 0;
|
||||
const int maxAttempts = 5;
|
||||
while (currentAttempt < maxAttempts) {
|
||||
reply = getData(&manager);
|
||||
if (reply->error() != QNetworkReply::NoError)
|
||||
break;
|
||||
|
||||
++currentAttempt;
|
||||
QVariant variant = reply->attribute(QNetworkRequest::RedirectionTargetAttribute);
|
||||
if (variant.isValid() && currentAttempt < maxAttempts) {
|
||||
m_url = variant.toUrl();
|
||||
delete reply;
|
||||
} else if (!variant.isValid()) {
|
||||
saveData(reply);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
delete reply;
|
||||
}
|
||||
|
||||
QNetworkReply *DefinitionDownloader::getData(QNetworkAccessManager *manager) const
|
||||
{
|
||||
QNetworkRequest request(m_url);
|
||||
QNetworkReply *reply = manager->get(request);
|
||||
|
||||
QEventLoop eventLoop;
|
||||
connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
|
||||
eventLoop.exec();
|
||||
|
||||
return reply;
|
||||
}
|
||||
|
||||
void DefinitionDownloader::saveData(QNetworkReply *reply) const
|
||||
{
|
||||
const QString &urlPath = m_url.path();
|
||||
const QString &fileName =
|
||||
urlPath.right(urlPath.length() - urlPath.lastIndexOf(QLatin1Char('/')) - 1);
|
||||
QFile file(m_localPath + fileName);
|
||||
if (!file.open(QIODevice::Text | QIODevice::WriteOnly))
|
||||
return;
|
||||
file.write(reply->readAll());
|
||||
file.close();
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef DEFINITIONDOWNLOADER_H
|
||||
#define DEFINITIONDOWNLOADER_H
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QNetworkReply;
|
||||
class QNetworkAccessManager;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace TextEditor {
|
||||
namespace Internal {
|
||||
|
||||
class DefinitionDownloader : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
DefinitionDownloader(const QUrl &url, const QString &localPath);
|
||||
|
||||
void start();
|
||||
|
||||
private:
|
||||
QNetworkReply *getData(QNetworkAccessManager *manager) const;
|
||||
void saveData(QNetworkReply *reply) const;
|
||||
|
||||
QUrl m_url;
|
||||
QString m_localPath;
|
||||
};
|
||||
|
||||
// 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
|
||||
// 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
|
||||
// possible to directly pass DefinitionDownloader::start.
|
||||
struct DownloaderStarter
|
||||
{
|
||||
void operator()(DefinitionDownloader *downloader)
|
||||
{ downloader->start(); }
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace TextEditor
|
||||
|
||||
#endif // DEFINITIONDOWNLOADER_H
|
@@ -437,6 +437,9 @@ void HighlightDefinitionHandler::processIncludeRules(const QSharedPointer<Contex
|
||||
|
||||
const QSharedPointer<HighlightDefinition> &externalDefinition =
|
||||
Manager::instance()->definition(id);
|
||||
if (externalDefinition.isNull())
|
||||
continue;
|
||||
|
||||
sourceContext = externalDefinition->initialContext();
|
||||
} else if (!sourceName.startsWith(kHash)) {
|
||||
sourceContext = m_definition->context(sourceName);
|
||||
@@ -444,6 +447,8 @@ void HighlightDefinitionHandler::processIncludeRules(const QSharedPointer<Contex
|
||||
// Recursion is done only for context direct rules. Child rules are not processed
|
||||
// because they cannot be include rules.
|
||||
processIncludeRules(sourceContext);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (instruction.replaceItemData()) {
|
||||
|
@@ -0,0 +1,72 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "highlightdefinitionmetadata.h"
|
||||
|
||||
using namespace TextEditor;
|
||||
using namespace Internal;
|
||||
|
||||
const QLatin1String HighlightDefinitionMetaData::kName("name");
|
||||
const QLatin1String HighlightDefinitionMetaData::kExtensions("extensions");
|
||||
const QLatin1String HighlightDefinitionMetaData::kMimeType("mimetype");
|
||||
const QLatin1String HighlightDefinitionMetaData::kVersion("version");
|
||||
const QLatin1String HighlightDefinitionMetaData::kUrl("url");
|
||||
|
||||
HighlightDefinitionMetaData::HighlightDefinitionMetaData()
|
||||
{}
|
||||
|
||||
void HighlightDefinitionMetaData::setName(const QString &name)
|
||||
{ m_name = name; }
|
||||
|
||||
const QString &HighlightDefinitionMetaData::name() const
|
||||
{ return m_name; }
|
||||
|
||||
void HighlightDefinitionMetaData::setVersion(const QString &version)
|
||||
{ m_version = version; }
|
||||
|
||||
const QString &HighlightDefinitionMetaData::version() const
|
||||
{ return m_version; }
|
||||
|
||||
void HighlightDefinitionMetaData::setPatterns(const QStringList &patterns)
|
||||
{ m_patterns = patterns; }
|
||||
|
||||
const QStringList &HighlightDefinitionMetaData::patterns() const
|
||||
{ return m_patterns; }
|
||||
|
||||
void HighlightDefinitionMetaData::setMimeTypes(const QStringList &mimeTypes)
|
||||
{ m_mimeTypes = mimeTypes; }
|
||||
|
||||
const QStringList &HighlightDefinitionMetaData::mimeTypes() const
|
||||
{ return m_mimeTypes; }
|
||||
|
||||
void HighlightDefinitionMetaData::setUrl(const QUrl &url)
|
||||
{ m_url = url; }
|
||||
|
||||
const QUrl &HighlightDefinitionMetaData::url() const
|
||||
{ return m_url; }
|
@@ -0,0 +1,78 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef HIGHLIGHTDEFINITIONMETADATA_H
|
||||
#define HIGHLIGHTDEFINITIONMETADATA_H
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QLatin1String>
|
||||
#include <QtCore/QStringList>
|
||||
#include <QtCore/QUrl>
|
||||
|
||||
namespace TextEditor {
|
||||
namespace Internal {
|
||||
|
||||
class HighlightDefinitionMetaData
|
||||
{
|
||||
public:
|
||||
HighlightDefinitionMetaData();
|
||||
|
||||
void setName(const QString &name);
|
||||
const QString &name() const;
|
||||
|
||||
void setVersion(const QString &version);
|
||||
const QString &version() const;
|
||||
|
||||
void setPatterns(const QStringList &patterns);
|
||||
const QStringList &patterns() const;
|
||||
|
||||
void setMimeTypes(const QStringList &mimeTypes);
|
||||
const QStringList &mimeTypes() const;
|
||||
|
||||
void setUrl(const QUrl &url);
|
||||
const QUrl &url() const;
|
||||
|
||||
static const QLatin1String kName;
|
||||
static const QLatin1String kExtensions;
|
||||
static const QLatin1String kMimeType;
|
||||
static const QLatin1String kVersion;
|
||||
static const QLatin1String kUrl;
|
||||
|
||||
private:
|
||||
QString m_name;
|
||||
QString m_version;
|
||||
QStringList m_patterns;
|
||||
QStringList m_mimeTypes;
|
||||
QUrl m_url;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace TextEditor
|
||||
|
||||
#endif // HIGHLIGHTDEFINITIONMETADATA_H
|
@@ -30,11 +30,14 @@
|
||||
#include "highlightersettingspage.h"
|
||||
#include "highlightersettings.h"
|
||||
#include "manager.h"
|
||||
#include "managedefinitionsdialog.h"
|
||||
#include "ui_highlightersettingspage.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
using namespace TextEditor;
|
||||
using namespace Internal;
|
||||
|
||||
@@ -102,8 +105,9 @@ QWidget *HighlighterSettingsPage::createPage(QWidget *parent)
|
||||
}
|
||||
|
||||
connect(m_d->m_page.resetButton, SIGNAL(clicked()), this, SLOT(resetDefinitionsLocation()));
|
||||
connect(m_d->m_page.downloadNoteLabel, SIGNAL(linkActivated(QString)),
|
||||
Manager::instance(), SLOT(openDefinitionsUrl(QString)));
|
||||
connect(m_d->m_page.manageDefinitionsButton, SIGNAL(clicked()),
|
||||
this, SLOT(requestAvailableDefinitionsMetaData()));
|
||||
connect(w, SIGNAL(destroyed()), this, SLOT(ignoreDownloadReply()));
|
||||
|
||||
return w;
|
||||
}
|
||||
@@ -152,6 +156,45 @@ void HighlighterSettingsPage::resetDefinitionsLocation()
|
||||
m_d->m_page.definitionFilesPath->setPath(findDefinitionsLocation());
|
||||
}
|
||||
|
||||
void HighlighterSettingsPage::requestAvailableDefinitionsMetaData()
|
||||
{
|
||||
m_d->m_page.manageDefinitionsButton->setEnabled(false);
|
||||
|
||||
Manager::instance()->downloadAvailableDefinitionsMetaData();
|
||||
connect(Manager::instance(),
|
||||
SIGNAL(definitionsMetaDataReady(QList<Internal::HighlightDefinitionMetaData>)),
|
||||
this,
|
||||
SLOT(manageDefinitions(QList<Internal::HighlightDefinitionMetaData>)),
|
||||
Qt::UniqueConnection);
|
||||
connect(Manager::instance(), SIGNAL(errorDownloadingDefinitionsMetaData()),
|
||||
this, SLOT(showError()), Qt::UniqueConnection);
|
||||
}
|
||||
|
||||
void HighlighterSettingsPage::ignoreDownloadReply()
|
||||
{
|
||||
disconnect(Manager::instance(),
|
||||
SIGNAL(definitionsMetaDataReady(QList<Internal::HighlightDefinitionMetaData>)),
|
||||
this,
|
||||
SLOT(manageDefinitions(QList<Internal::HighlightDefinitionMetaData>)));
|
||||
disconnect(Manager::instance(), SIGNAL(errorDownloadingDefinitionsMetaData()),
|
||||
this, SLOT(showError()));
|
||||
}
|
||||
|
||||
void HighlighterSettingsPage::manageDefinitions(const QList<HighlightDefinitionMetaData> &metaData)
|
||||
{
|
||||
ManageDefinitionsDialog dialog(metaData, m_d->m_page.manageDefinitionsButton->window());
|
||||
dialog.exec();
|
||||
m_d->m_page.manageDefinitionsButton->setEnabled(true);
|
||||
}
|
||||
|
||||
void HighlighterSettingsPage::showError()
|
||||
{
|
||||
QMessageBox::critical(m_d->m_page.manageDefinitionsButton->window(),
|
||||
tr("Error connecting to server."),
|
||||
tr("Not possible to retrieve data."));
|
||||
m_d->m_page.manageDefinitionsButton->setEnabled(true);
|
||||
}
|
||||
|
||||
bool HighlighterSettingsPage::settingsChanged() const
|
||||
{
|
||||
if (m_d->m_settings.definitionFilesPath() != m_d->m_page.definitionFilesPath->path())
|
||||
|
@@ -32,8 +32,16 @@
|
||||
|
||||
#include "texteditoroptionspage.h"
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
template <class> class QList;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace TextEditor {
|
||||
|
||||
namespace Internal {
|
||||
class HighlightDefinitionMetaData;
|
||||
}
|
||||
|
||||
class HighlighterSettings;
|
||||
|
||||
class HighlighterSettingsPage : public TextEditorOptionsPage
|
||||
@@ -58,6 +66,10 @@ signals:
|
||||
|
||||
private slots:
|
||||
void resetDefinitionsLocation();
|
||||
void requestAvailableDefinitionsMetaData();
|
||||
void manageDefinitions(const QList<Internal::HighlightDefinitionMetaData> &metaData);
|
||||
void showError();
|
||||
void ignoreDownloadReply();
|
||||
|
||||
private:
|
||||
void settingsFromUI();
|
||||
|
@@ -21,33 +21,20 @@
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="downloadNoteLabel">
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Definitions can be downloaded from the </span><a href="http://kate-editor.org/downloads/syntax_highlighting"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">Kate Text Editor</span></a><span style=" font-size:8pt;"> website and stored at the location below.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::TextBrowserInteraction</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QLabel" name="locationLabel">
|
||||
<property name="text">
|
||||
<string>Location:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Utils::PathChooser" name="definitionFilesPath" native="true"/>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QLabel" name="locationLabel">
|
||||
<property name="text">
|
||||
<string>Location:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Utils::PathChooser" name="definitionFilesPath" native="true"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QToolButton" name="resetButton">
|
||||
@@ -65,6 +52,59 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="definitionsInfolabel">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Preferred">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'MS Shell Dlg 2'; font-size:8.25pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-size:8pt;">Highlight definitions are available from the </span><a href="http://kate-editor.org/downloads/syntax_highlighting?kateversion=3.2"><span style=" font-size:8pt; text-decoration: underline; color:#0000ff;">Kate Text Editor</span></a><span style=" font-size:8pt;"> website. Qt Creator can download a list of available definitions and then install the selected ones.</span></p></body></html></string>
|
||||
</property>
|
||||
<property name="textFormat">
|
||||
<enum>Qt::RichText</enum>
|
||||
</property>
|
||||
<property name="alignment">
|
||||
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<widget class="QPushButton" name="manageDefinitionsButton">
|
||||
<property name="text">
|
||||
<string>Manage Definitions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>328</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -77,7 +117,7 @@ p, li { white-space: pre-wrap; }
|
||||
<item>
|
||||
<widget class="QCheckBox" name="alertWhenNoDefinition">
|
||||
<property name="text">
|
||||
<string>Alert when a highlight definition is not found.</string>
|
||||
<string>Alert when a highlight definition is not found</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
@@ -125,6 +165,12 @@ p, li { white-space: pre-wrap; }
|
||||
</slots>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>resetButton</tabstop>
|
||||
<tabstop>manageDefinitionsButton</tabstop>
|
||||
<tabstop>alertWhenNoDefinition</tabstop>
|
||||
<tabstop>ignoreEdit</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../coreplugin/core.qrc"/>
|
||||
</resources>
|
||||
|
@@ -0,0 +1,121 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#include "managedefinitionsdialog.h"
|
||||
#include "manager.h"
|
||||
|
||||
#include <QtCore>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QIODevice>
|
||||
#include <QtCore/QXmlStreamReader>
|
||||
#include <QtCore/QXmlStreamAttributes>
|
||||
#include <QtCore/QFuture>
|
||||
#include <QtCore/QFutureWatcher>
|
||||
#include <QtCore/QtConcurrentMap>
|
||||
#include <QtGui/QMessageBox>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
using namespace TextEditor;
|
||||
using namespace Internal;
|
||||
|
||||
ManageDefinitionsDialog::ManageDefinitionsDialog(
|
||||
const QList<HighlightDefinitionMetaData> &metaDataList, QWidget *parent) :
|
||||
m_definitionsMetaData(metaDataList), QDialog(parent)
|
||||
{
|
||||
ui.setupUi(this);
|
||||
ui.definitionsTable->setHorizontalHeaderLabels(
|
||||
QStringList() << tr("Definition Name") << tr("Installed") << tr("Available"));
|
||||
ui.definitionsTable->horizontalHeader()->setResizeMode(0, QHeaderView::Stretch);
|
||||
|
||||
setWindowTitle(tr("Manage Definitions"));
|
||||
|
||||
populateDefinitionsWidget();
|
||||
|
||||
connect(ui.downloadButton, SIGNAL(clicked()), this, SLOT(downloadDefinitions()));
|
||||
}
|
||||
|
||||
void ManageDefinitionsDialog::populateDefinitionsWidget()
|
||||
{
|
||||
const int size = m_definitionsMetaData.size();
|
||||
ui.definitionsTable->setRowCount(size);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
const HighlightDefinitionMetaData &downloadData = m_definitionsMetaData.at(i);
|
||||
|
||||
QString installedVersion;
|
||||
const QString &id = Manager::instance()->definitionIdByName(downloadData.name());
|
||||
const QSharedPointer<HighlightDefinitionMetaData> &metaData =
|
||||
Manager::instance()->definitionMetaData(id);
|
||||
if (!metaData.isNull())
|
||||
installedVersion = metaData->version();
|
||||
|
||||
for (int j = 0; j < 3; ++j) {
|
||||
QTableWidgetItem *item = new QTableWidgetItem;
|
||||
if (j == 0)
|
||||
item->setText(downloadData.name());
|
||||
else if (j == 1) {
|
||||
item->setText(installedVersion);
|
||||
item->setTextAlignment(Qt::AlignCenter);
|
||||
} else if (j == 2) {
|
||||
item->setText(downloadData.version());
|
||||
item->setTextAlignment(Qt::AlignCenter);
|
||||
}
|
||||
ui.definitionsTable->setItem(i, j, item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ManageDefinitionsDialog::downloadDefinitions()
|
||||
{
|
||||
if (Manager::instance()->isDownloadingDefinitions()) {
|
||||
QMessageBox::information(
|
||||
this,
|
||||
tr("Download Information"),
|
||||
tr("There is already one download in progress. Please wait until it is finished."));
|
||||
return;
|
||||
}
|
||||
|
||||
QList<QUrl> urls;
|
||||
foreach (const QModelIndex &index, ui.definitionsTable->selectionModel()->selectedRows())
|
||||
urls.append(m_definitionsMetaData.at(index.row()).url());
|
||||
Manager::instance()->downloadDefinitions(urls);
|
||||
close();
|
||||
}
|
||||
|
||||
void ManageDefinitionsDialog::changeEvent(QEvent *e)
|
||||
{
|
||||
QDialog::changeEvent(e);
|
||||
switch (e->type()) {
|
||||
case QEvent::LanguageChange:
|
||||
ui.retranslateUi(this);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** This file is part of Qt Creator
|
||||
**
|
||||
** Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
|
||||
**
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** Commercial Usage
|
||||
**
|
||||
** Licensees holding valid Qt Commercial licenses may use this file in
|
||||
** accordance with the Qt Commercial License Agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and Nokia.
|
||||
**
|
||||
** GNU Lesser General Public License Usage
|
||||
**
|
||||
** Alternatively, this file may be used under the terms of the GNU Lesser
|
||||
** General Public License version 2.1 as published by the Free Software
|
||||
** Foundation and appearing in the file LICENSE.LGPL included in the
|
||||
** packaging of this file. Please review the following information to
|
||||
** ensure the GNU Lesser General Public License version 2.1 requirements
|
||||
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
||||
**
|
||||
** If you are unsure which license is appropriate for your use, please
|
||||
** contact the sales department at http://qt.nokia.com/contact.
|
||||
**
|
||||
**************************************************************************/
|
||||
|
||||
#ifndef MANAGEDEFINITIONSDIALOG_H
|
||||
#define MANAGEDEFINITIONSDIALOG_H
|
||||
|
||||
#include "ui_managedefinitionsdialog.h"
|
||||
#include "highlightdefinitionmetadata.h"
|
||||
|
||||
#include <QtCore/QList>
|
||||
|
||||
namespace TextEditor {
|
||||
namespace Internal {
|
||||
|
||||
class ManageDefinitionsDialog : public QDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit ManageDefinitionsDialog(const QList<HighlightDefinitionMetaData> &metaDataList,
|
||||
QWidget *parent = 0);
|
||||
|
||||
protected:
|
||||
void changeEvent(QEvent *e);
|
||||
|
||||
private slots:
|
||||
void downloadDefinitions();
|
||||
|
||||
private:
|
||||
void populateDefinitionsWidget();
|
||||
|
||||
QList<HighlightDefinitionMetaData> m_definitionsMetaData;
|
||||
Ui::ManageDefinitionsDialog ui;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace TextEditor
|
||||
|
||||
#endif // MANAGEDEFINITIONSDIALOG_H
|
@@ -0,0 +1,117 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>ManageDefinitionsDialog</class>
|
||||
<widget class="QDialog" name="ManageDefinitionsDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>447</width>
|
||||
<height>315</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>Dialog</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="definitionsGroupBox">
|
||||
<property name="title">
|
||||
<string>Available Definitions</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QTableWidget" name="definitionsTable">
|
||||
<property name="alternatingRowColors">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior">
|
||||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
<property name="columnCount">
|
||||
<number>3</number>
|
||||
</property>
|
||||
<attribute name="verticalHeaderVisible">
|
||||
<bool>false</bool>
|
||||
</attribute>
|
||||
<attribute name="verticalHeaderDefaultSectionSize">
|
||||
<number>20</number>
|
||||
</attribute>
|
||||
<column/>
|
||||
<column/>
|
||||
<column/>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="downloadButton">
|
||||
<property name="text">
|
||||
<string>Download Selected Definitions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>188</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>298</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="closeButton">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>closeButton</sender>
|
||||
<signal>clicked()</signal>
|
||||
<receiver>ManageDefinitionsDialog</receiver>
|
||||
<slot>close()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>381</x>
|
||||
<y>294</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>306</x>
|
||||
<y>298</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
@@ -31,14 +31,16 @@
|
||||
#include "highlightdefinition.h"
|
||||
#include "highlightdefinitionhandler.h"
|
||||
#include "highlighterexception.h"
|
||||
#include "definitiondownloader.h"
|
||||
#include "highlightersettings.h"
|
||||
#include "plaintexteditorfactory.h"
|
||||
#include "texteditorconstants.h"
|
||||
#include "texteditorplugin.h"
|
||||
#include "texteditorsettings.h"
|
||||
#include "plaintexteditorfactory.h"
|
||||
#include "highlightersettings.h"
|
||||
#include "texteditorconstants.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
#include <qtconcurrent/QtConcurrentTools>
|
||||
|
||||
#include <QtCore/QtAlgorithms>
|
||||
@@ -50,22 +52,27 @@
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QDir>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QRegExp>
|
||||
#include <QtCore/QFuture>
|
||||
#include <QtCore/QtConcurrentRun>
|
||||
#include <QtCore/QtConcurrentMap>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtGui/QDesktopServices>
|
||||
#include <QtXml/QXmlSimpleReader>
|
||||
#include <QtXml/QXmlInputSource>
|
||||
#include <QtXml/QXmlStreamReader>
|
||||
#include <QtXml/QXmlStreamAttributes>
|
||||
#include <QtNetwork/QNetworkRequest>
|
||||
#include <QtNetwork/QNetworkReply>
|
||||
|
||||
using namespace TextEditor;
|
||||
using namespace Internal;
|
||||
|
||||
Manager::Manager()
|
||||
{}
|
||||
Manager::Manager() : m_downloadingDefinitions(false)
|
||||
{
|
||||
connect(&m_mimeTypeWatcher, SIGNAL(resultReadyAt(int)), this, SLOT(registerMimeType(int)));
|
||||
connect(&m_downloadWatcher, SIGNAL(finished()), this, SLOT(downloadDefinitionsFinished()));
|
||||
}
|
||||
|
||||
Manager::~Manager()
|
||||
{}
|
||||
@@ -80,19 +87,7 @@ QString Manager::definitionIdByName(const QString &name) const
|
||||
{ return m_idByName.value(name); }
|
||||
|
||||
QString Manager::definitionIdByMimeType(const QString &mimeType) const
|
||||
{
|
||||
if (m_idByMimeType.count(mimeType) > 1) {
|
||||
QStringList candidateIds;
|
||||
QMultiHash<QString, QString>::const_iterator it = m_idByMimeType.find(mimeType);
|
||||
QMultiHash<QString, QString>::const_iterator endIt = m_idByMimeType.end();
|
||||
for (; it != endIt && it.key() == mimeType; ++it)
|
||||
candidateIds.append(it.value());
|
||||
|
||||
qSort(candidateIds.begin(), candidateIds.end(), m_priorityComp);
|
||||
return candidateIds.last();
|
||||
}
|
||||
return m_idByMimeType.value(mimeType);
|
||||
}
|
||||
{ return m_idByMimeType.value(mimeType); }
|
||||
|
||||
QString Manager::definitionIdByAnyMimeType(const QStringList &mimeTypes) const
|
||||
{
|
||||
@@ -105,31 +100,37 @@ QString Manager::definitionIdByAnyMimeType(const QStringList &mimeTypes) const
|
||||
return definitionId;
|
||||
}
|
||||
|
||||
const QSharedPointer<HighlightDefinition> &Manager::definition(const QString &id)
|
||||
QSharedPointer<HighlightDefinition> Manager::definition(const QString &id)
|
||||
{
|
||||
if (!m_definitions.contains(id)) {
|
||||
m_isBuilding.insert(id);
|
||||
|
||||
if (!id.isEmpty() && !m_definitions.contains(id)) {
|
||||
QFile definitionFile(id);
|
||||
if (!definitionFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
throw HighlighterException();
|
||||
QXmlInputSource source(&definitionFile);
|
||||
return QSharedPointer<HighlightDefinition>();
|
||||
|
||||
QSharedPointer<HighlightDefinition> definition(new HighlightDefinition);
|
||||
HighlightDefinitionHandler handler(definition);
|
||||
|
||||
QXmlInputSource source(&definitionFile);
|
||||
QXmlSimpleReader reader;
|
||||
reader.setContentHandler(&handler);
|
||||
reader.parse(source);
|
||||
m_isBuilding.insert(id);
|
||||
try {
|
||||
reader.parse(source);
|
||||
} catch (HighlighterException &) {
|
||||
definition.clear();
|
||||
}
|
||||
m_isBuilding.remove(id);
|
||||
definitionFile.close();
|
||||
|
||||
m_definitions.insert(id, definition);
|
||||
definitionFile.close();
|
||||
m_isBuilding.remove(id);
|
||||
}
|
||||
|
||||
return *m_definitions.constFind(id);
|
||||
return m_definitions.value(id);
|
||||
}
|
||||
|
||||
QSharedPointer<HighlightDefinitionMetaData> Manager::definitionMetaData(const QString &id) const
|
||||
{ return m_definitionsMetaData.value(id); }
|
||||
|
||||
bool Manager::isBuildingDefinition(const QString &id) const
|
||||
{ return m_isBuilding.contains(id); }
|
||||
|
||||
@@ -138,9 +139,7 @@ void Manager::registerMimeTypes()
|
||||
clear();
|
||||
QFuture<Core::MimeType> future =
|
||||
QtConcurrent::run(&Manager::gatherDefinitionsMimeTypes, this);
|
||||
m_watcher.setFuture(future);
|
||||
|
||||
connect(&m_watcher, SIGNAL(resultReadyAt(int)), this, SLOT(registerMimeType(int)));
|
||||
m_mimeTypeWatcher.setFuture(future);
|
||||
}
|
||||
|
||||
void Manager::gatherDefinitionsMimeTypes(QFutureInterface<Core::MimeType> &future)
|
||||
@@ -153,10 +152,13 @@ void Manager::gatherDefinitionsMimeTypes(QFutureInterface<Core::MimeType> &futur
|
||||
|
||||
const QFileInfoList &filesInfo = definitionsDir.entryInfoList();
|
||||
foreach (const QFileInfo &fileInfo, filesInfo) {
|
||||
QString comment;
|
||||
QStringList mimeTypes;
|
||||
QStringList patterns;
|
||||
parseDefinitionMetadata(fileInfo, &comment, &mimeTypes, &patterns);
|
||||
const QSharedPointer<HighlightDefinitionMetaData> &metaData = parseMetadata(fileInfo);
|
||||
if (metaData.isNull())
|
||||
continue;
|
||||
|
||||
const QString &id = fileInfo.absoluteFilePath();
|
||||
m_idByName.insert(metaData->name(), id);
|
||||
m_definitionsMetaData.insert(id, metaData);
|
||||
|
||||
// A definition can specify multiple MIME types and file extensions/patterns. However, each
|
||||
// thing is done with a single string. Then, there is no direct way to tell which patterns
|
||||
@@ -165,19 +167,20 @@ void Manager::gatherDefinitionsMimeTypes(QFutureInterface<Core::MimeType> &futur
|
||||
|
||||
static const QStringList textPlain(QLatin1String("text/plain"));
|
||||
|
||||
QList<QRegExp> expressions;
|
||||
foreach (const QString &type, mimeTypes) {
|
||||
QList<QRegExp> patterns;
|
||||
foreach (const QString &type, metaData->mimeTypes()) {
|
||||
m_idByMimeType.insert(type, id);
|
||||
Core::MimeType mimeType = Core::ICore::instance()->mimeDatabase()->findByType(type);
|
||||
if (mimeType.isNull()) {
|
||||
if (expressions.isEmpty()) {
|
||||
foreach (const QString &pattern, patterns)
|
||||
expressions.append(QRegExp(pattern, Qt::CaseSensitive, QRegExp::Wildcard));
|
||||
if (patterns.isEmpty()) {
|
||||
foreach (const QString &pattern, metaData->patterns())
|
||||
patterns.append(QRegExp(pattern, Qt::CaseSensitive, QRegExp::Wildcard));
|
||||
}
|
||||
|
||||
mimeType.setType(type);
|
||||
mimeType.setSubClassesOf(textPlain);
|
||||
mimeType.setComment(comment);
|
||||
mimeType.setGlobPatterns(expressions);
|
||||
mimeType.setComment(metaData->name());
|
||||
mimeType.setGlobPatterns(patterns);
|
||||
|
||||
future.reportResult(mimeType);
|
||||
}
|
||||
@@ -187,76 +190,129 @@ void Manager::gatherDefinitionsMimeTypes(QFutureInterface<Core::MimeType> &futur
|
||||
|
||||
void Manager::registerMimeType(int index) const
|
||||
{
|
||||
const Core::MimeType &mimeType = m_watcher.resultAt(index);
|
||||
Core::ICore::instance()->mimeDatabase()->addMimeType(mimeType);
|
||||
const Core::MimeType &mimeType = m_mimeTypeWatcher.resultAt(index);
|
||||
TextEditorPlugin::instance()->editorFactory()->addMimeType(mimeType.type());
|
||||
Core::ICore::instance()->mimeDatabase()->addMimeType(mimeType);
|
||||
}
|
||||
|
||||
void Manager::parseDefinitionMetadata(const QFileInfo &fileInfo,
|
||||
QString *comment,
|
||||
QStringList *mimeTypes,
|
||||
QStringList *patterns)
|
||||
QSharedPointer<HighlightDefinitionMetaData> Manager::parseMetadata(const QFileInfo &fileInfo)
|
||||
{
|
||||
static const QLatin1Char kSemiColon(';');
|
||||
static const QLatin1Char kSlash('/');
|
||||
static const QLatin1String kLanguage("language");
|
||||
static const QLatin1String kName("name");
|
||||
static const QLatin1String kExtensions("extensions");
|
||||
static const QLatin1String kMimeType("mimetype");
|
||||
static const QLatin1String kPriority("priority");
|
||||
static const QLatin1String kArtificial("artificial");
|
||||
|
||||
const QString &id = fileInfo.absoluteFilePath();
|
||||
|
||||
QFile definitionFile(id);
|
||||
QFile definitionFile(fileInfo.absoluteFilePath());
|
||||
if (!definitionFile.open(QIODevice::ReadOnly | QIODevice::Text))
|
||||
return;
|
||||
return QSharedPointer<HighlightDefinitionMetaData>();
|
||||
|
||||
QSharedPointer<HighlightDefinitionMetaData> metaData(new HighlightDefinitionMetaData);
|
||||
|
||||
QXmlStreamReader reader(&definitionFile);
|
||||
while (!reader.atEnd() && !reader.hasError()) {
|
||||
if (reader.readNext() == QXmlStreamReader::StartElement &&
|
||||
reader.name() == kLanguage) {
|
||||
const QXmlStreamAttributes &attr = reader.attributes();
|
||||
const QXmlStreamAttributes &atts = reader.attributes();
|
||||
|
||||
*comment = attr.value(kName).toString();
|
||||
m_idByName.insert(*comment, id);
|
||||
metaData->setName(atts.value(HighlightDefinitionMetaData::kName).toString());
|
||||
metaData->setVersion(atts.value(HighlightDefinitionMetaData::kVersion).toString());
|
||||
metaData->setPatterns(atts.value(HighlightDefinitionMetaData::kExtensions).
|
||||
toString().split(kSemiColon, QString::SkipEmptyParts));
|
||||
|
||||
*patterns = attr.value(kExtensions).toString().split(kSemiColon,
|
||||
QString::SkipEmptyParts);
|
||||
|
||||
*mimeTypes = attr.value(kMimeType).toString().split(kSemiColon,
|
||||
QString::SkipEmptyParts);
|
||||
if (mimeTypes->isEmpty()) {
|
||||
QStringList mimeTypes = atts.value(HighlightDefinitionMetaData::kMimeType).
|
||||
toString().split(kSemiColon, QString::SkipEmptyParts);
|
||||
if (mimeTypes.isEmpty()) {
|
||||
// There are definitions which do not specify a MIME type, but specify file
|
||||
// patterns. Creating an artificial MIME type is a workaround.
|
||||
QString artificialType(kArtificial);
|
||||
artificialType.append(kSlash).append(*comment);
|
||||
m_idByMimeType.insert(artificialType, id);
|
||||
mimeTypes->append(artificialType);
|
||||
} else {
|
||||
foreach (const QString &type, *mimeTypes)
|
||||
m_idByMimeType.insert(type, id);
|
||||
artificialType.append(kSlash).append(metaData->name());
|
||||
mimeTypes.append(artificialType);
|
||||
}
|
||||
|
||||
// The priority below should not be confused with the priority used when matching files
|
||||
// to MIME types. Kate uses this when there are definitions which share equal
|
||||
// extensions/patterns. Here it is for choosing a highlight definition if there are
|
||||
// multiple ones associated with the same MIME type (should not happen in general).
|
||||
m_priorityComp.m_priorityById.insert(id, attr.value(kPriority).toString().toInt());
|
||||
metaData->setMimeTypes(mimeTypes);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
reader.clear();
|
||||
definitionFile.close();
|
||||
|
||||
return metaData;
|
||||
}
|
||||
|
||||
void Manager::clear()
|
||||
QList<HighlightDefinitionMetaData> Manager::parseAvailableDefinitionsList(QIODevice *device) const
|
||||
{
|
||||
m_priorityComp.m_priorityById.clear();
|
||||
m_idByName.clear();
|
||||
m_idByMimeType.clear();
|
||||
m_definitions.clear();
|
||||
static const QLatin1String kDefinition("Definition");
|
||||
|
||||
QList<HighlightDefinitionMetaData> metaDataList;
|
||||
QXmlStreamReader reader(device);
|
||||
while (!reader.atEnd() && !reader.hasError()) {
|
||||
if (reader.readNext() == QXmlStreamReader::StartElement &&
|
||||
reader.name() == kDefinition) {
|
||||
const QXmlStreamAttributes &atts = reader.attributes();
|
||||
|
||||
HighlightDefinitionMetaData metaData;
|
||||
metaData.setName(atts.value(HighlightDefinitionMetaData::kName).toString());
|
||||
metaData.setUrl(QUrl(atts.value(HighlightDefinitionMetaData::kUrl).toString()));
|
||||
metaData.setVersion(atts.value(HighlightDefinitionMetaData::kVersion).toString());
|
||||
|
||||
metaDataList.append(metaData);
|
||||
}
|
||||
}
|
||||
reader.clear();
|
||||
|
||||
return metaDataList;
|
||||
}
|
||||
|
||||
void Manager::downloadAvailableDefinitionsMetaData()
|
||||
{
|
||||
QUrl url(QLatin1String("http://www.kate-editor.org/syntax/update-3.2.xml"));
|
||||
QNetworkRequest request(url);
|
||||
// Currently this takes a couple of seconds on Windows 7: QTBUG-10106.
|
||||
QNetworkReply *reply = m_networkManager.get(request);
|
||||
connect(reply, SIGNAL(finished()), this, SLOT(downloadAvailableDefinitionsListFinished()));
|
||||
}
|
||||
|
||||
void Manager::downloadAvailableDefinitionsListFinished()
|
||||
{
|
||||
if (QNetworkReply *reply = qobject_cast<QNetworkReply *>(sender())) {
|
||||
if (reply->error() == QNetworkReply::NoError)
|
||||
emit definitionsMetaDataReady(parseAvailableDefinitionsList(reply));
|
||||
else
|
||||
emit errorDownloadingDefinitionsMetaData();
|
||||
reply->deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::downloadDefinitions(const QList<QUrl> &urls)
|
||||
{
|
||||
const QString &savePath =
|
||||
TextEditorSettings::instance()->highlighterSettings().definitionFilesPath() +
|
||||
QLatin1Char('/');
|
||||
|
||||
m_downloaders.clear();
|
||||
foreach (const QUrl &url, urls)
|
||||
m_downloaders.append(new DefinitionDownloader(url, savePath));
|
||||
|
||||
m_downloadingDefinitions = true;
|
||||
QFuture<void> future = QtConcurrent::map(m_downloaders, DownloaderStarter());
|
||||
m_downloadWatcher.setFuture(future);
|
||||
Core::ICore::instance()->progressManager()->addTask(future,
|
||||
tr("Downloading definitions"),
|
||||
Constants::TASK_DOWNLOAD);
|
||||
}
|
||||
|
||||
void Manager::downloadDefinitionsFinished()
|
||||
{
|
||||
foreach (DefinitionDownloader *downloader, m_downloaders)
|
||||
delete downloader;
|
||||
|
||||
registerMimeTypes();
|
||||
m_downloadingDefinitions = false;
|
||||
}
|
||||
|
||||
bool Manager::isDownloadingDefinitions() const
|
||||
{
|
||||
return m_downloadingDefinitions;
|
||||
}
|
||||
|
||||
void Manager::showGenericHighlighterOptions() const
|
||||
@@ -265,7 +321,10 @@ void Manager::showGenericHighlighterOptions() const
|
||||
Constants::TEXT_EDITOR_HIGHLIGHTER_SETTINGS);
|
||||
}
|
||||
|
||||
void Manager::openDefinitionsUrl(const QString &location) const
|
||||
void Manager::clear()
|
||||
{
|
||||
QDesktopServices::openUrl(QUrl(location));
|
||||
m_idByName.clear();
|
||||
m_idByMimeType.clear();
|
||||
m_definitions.clear();
|
||||
m_definitionsMetaData.clear();
|
||||
}
|
||||
|
@@ -30,19 +30,23 @@
|
||||
#ifndef MANAGER_H
|
||||
#define MANAGER_H
|
||||
|
||||
#include "highlightdefinitionmetadata.h"
|
||||
|
||||
#include <coreplugin/mimedatabase.h>
|
||||
|
||||
#include <QtCore/QString>
|
||||
#include <QtCore/QHash>
|
||||
#include <QtCore/QMultiHash>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QList>
|
||||
#include <QtCore/QSharedPointer>
|
||||
#include <QtCore/QFutureWatcher>
|
||||
#include <QtNetwork/QNetworkAccessManager>
|
||||
|
||||
QT_BEGIN_NAMESPACE
|
||||
class QFileInfo;
|
||||
class QStringList;
|
||||
class QDir;
|
||||
class QIODevice;
|
||||
template <class> class QFutureInterface;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
@@ -50,6 +54,7 @@ namespace TextEditor {
|
||||
namespace Internal {
|
||||
|
||||
class HighlightDefinition;
|
||||
class DefinitionDownloader;
|
||||
|
||||
class Manager : public QObject
|
||||
{
|
||||
@@ -61,43 +66,50 @@ public:
|
||||
QString definitionIdByName(const QString &name) const;
|
||||
QString definitionIdByMimeType(const QString &mimeType) const;
|
||||
QString definitionIdByAnyMimeType(const QStringList &mimeTypes) const;
|
||||
|
||||
bool isBuildingDefinition(const QString &id) const;
|
||||
const QSharedPointer<HighlightDefinition> &definition(const QString &id);
|
||||
|
||||
QSharedPointer<HighlightDefinition> definition(const QString &id);
|
||||
QSharedPointer<HighlightDefinitionMetaData> definitionMetaData(const QString &id) const;
|
||||
|
||||
void downloadAvailableDefinitionsMetaData();
|
||||
void downloadDefinitions(const QList<QUrl> &urls);
|
||||
bool isDownloadingDefinitions() const;
|
||||
|
||||
public slots:
|
||||
void registerMimeTypes();
|
||||
void showGenericHighlighterOptions() const;
|
||||
void openDefinitionsUrl(const QString &location) const;
|
||||
|
||||
private slots:
|
||||
void registerMimeType(int index) const;
|
||||
void downloadAvailableDefinitionsListFinished();
|
||||
void downloadDefinitionsFinished();
|
||||
|
||||
private:
|
||||
Manager();
|
||||
Q_DISABLE_COPY(Manager)
|
||||
|
||||
void clear();
|
||||
void gatherDefinitionsMimeTypes(QFutureInterface<Core::MimeType> &future);
|
||||
void parseDefinitionMetadata(const QFileInfo &fileInfo,
|
||||
QString *comment,
|
||||
QStringList *mimeTypes,
|
||||
QStringList *patterns);
|
||||
|
||||
struct PriorityCompare
|
||||
{
|
||||
bool operator()(const QString &a, const QString &b) const
|
||||
{ return m_priorityById.value(a) < m_priorityById.value(b); }
|
||||
|
||||
QHash<QString, int> m_priorityById;
|
||||
};
|
||||
PriorityCompare m_priorityComp;
|
||||
|
||||
QFutureWatcher<Core::MimeType> m_watcher;
|
||||
QSharedPointer<HighlightDefinitionMetaData> parseMetadata(const QFileInfo &fileInfo);
|
||||
QList<HighlightDefinitionMetaData> parseAvailableDefinitionsList(QIODevice *device) const;
|
||||
void clear();
|
||||
|
||||
QHash<QString, QString> m_idByName;
|
||||
QMultiHash<QString, QString> m_idByMimeType;
|
||||
QHash<QString, QString> m_idByMimeType;
|
||||
QHash<QString, QSharedPointer<HighlightDefinition> > m_definitions;
|
||||
QHash<QString, QSharedPointer<HighlightDefinitionMetaData> > m_definitionsMetaData;
|
||||
QSet<QString> m_isBuilding;
|
||||
|
||||
QList<DefinitionDownloader *> m_downloaders;
|
||||
bool m_downloadingDefinitions;
|
||||
QNetworkAccessManager m_networkManager;
|
||||
|
||||
QFutureWatcher<void> m_downloadWatcher;
|
||||
QFutureWatcher<Core::MimeType> m_mimeTypeWatcher;
|
||||
|
||||
signals:
|
||||
void definitionsMetaDataReady(const QList<Internal::HighlightDefinitionMetaData>&);
|
||||
void errorDownloadingDefinitionsMetaData();
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
@@ -173,10 +173,9 @@ void PlainTextEditor::configure(const Core::MimeType &mimeType)
|
||||
definitionId = findDefinitionId(mimeType, true);
|
||||
|
||||
if (!definitionId.isEmpty()) {
|
||||
try {
|
||||
const QSharedPointer<HighlightDefinition> &definition =
|
||||
Manager::instance()->definition(definitionId);
|
||||
|
||||
const QSharedPointer<HighlightDefinition> &definition =
|
||||
Manager::instance()->definition(definitionId);
|
||||
if (!definition.isNull()) {
|
||||
Highlighter *highlighter = new Highlighter(definition->initialContext());
|
||||
baseTextDocument()->setSyntaxHighlighter(highlighter);
|
||||
|
||||
@@ -188,7 +187,6 @@ void PlainTextEditor::configure(const Core::MimeType &mimeType)
|
||||
setFontSettings(TextEditorSettings::instance()->fontSettings());
|
||||
|
||||
m_isMissingSyntaxDefinition = false;
|
||||
} catch (const HighlighterException &) {
|
||||
}
|
||||
} else if (file()) {
|
||||
const QString &fileName = file()->fileName();
|
||||
|
@@ -1,7 +1,7 @@
|
||||
TEMPLATE = lib
|
||||
TARGET = TextEditor
|
||||
DEFINES += TEXTEDITOR_LIBRARY
|
||||
QT += xml
|
||||
QT += xml network
|
||||
include(../../qtcreatorplugin.pri)
|
||||
include(texteditor_dependencies.pri)
|
||||
INCLUDEPATH += generichighlighter
|
||||
@@ -55,7 +55,10 @@ SOURCES += texteditorplugin.cpp \
|
||||
generichighlighter/manager.cpp \
|
||||
generichighlighter/highlightdefinitionhandler.cpp \
|
||||
generichighlighter/highlightersettingspage.cpp \
|
||||
generichighlighter/highlightersettings.cpp
|
||||
generichighlighter/highlightersettings.cpp \
|
||||
generichighlighter/managedefinitionsdialog.cpp \
|
||||
generichighlighter/highlightdefinitionmetadata.cpp \
|
||||
generichighlighter/definitiondownloader.cpp
|
||||
|
||||
HEADERS += texteditorplugin.h \
|
||||
textfilewizard.h \
|
||||
@@ -113,13 +116,17 @@ HEADERS += texteditorplugin.h \
|
||||
generichighlighter/manager.h \
|
||||
generichighlighter/highlightdefinitionhandler.h \
|
||||
generichighlighter/highlightersettingspage.h \
|
||||
generichighlighter/highlightersettings.h
|
||||
generichighlighter/highlightersettings.h \
|
||||
generichighlighter/managedefinitionsdialog.h \
|
||||
generichighlighter/highlightdefinitionmetadata.h \
|
||||
generichighlighter/definitiondownloader.h
|
||||
|
||||
|
||||
FORMS += behaviorsettingspage.ui \
|
||||
displaysettingspage.ui \
|
||||
fontsettingspage.ui \
|
||||
colorschemeedit.ui \
|
||||
generichighlighter/highlightersettingspage.ui
|
||||
generichighlighter/highlightersettingspage.ui \
|
||||
generichighlighter/managedefinitionsdialog.ui
|
||||
RESOURCES += texteditor.qrc
|
||||
OTHER_FILES += TextEditor.pluginspec TextEditor.mimetypes.xml
|
||||
|
@@ -88,7 +88,7 @@ const char * const GOTO_PREVIOUS_WORD_WITH_SELECTION = "TextEditor.GotoPreviousW
|
||||
const char * const GOTO_NEXT_WORD_WITH_SELECTION = "TextEditor.GotoNextWordWithSelection";
|
||||
const char * const C_TEXTEDITOR_MIMETYPE_TEXT = "text/plain";
|
||||
const char * const INFO_SYNTAX_DEFINITION = "TextEditor.InfoSyntaxDefinition";
|
||||
|
||||
const char * const TASK_DOWNLOAD = "TextEditor.Task.Download";
|
||||
|
||||
// Text color and style categories
|
||||
const char * const C_TEXT = "Text";
|
||||
|
Reference in New Issue
Block a user