forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.6'
Conflicts: src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp Change-Id: I4c619efd7c1060ffd759df44a03a111269d3478d
This commit is contained in:
@@ -1180,7 +1180,7 @@ void PropertiesView::MView::onClassMembersStatusChanged(bool valid)
|
||||
if (valid)
|
||||
m_classMembersStatusLabel->clear();
|
||||
else
|
||||
m_classMembersStatusLabel->setText(tr("<font color=red>Invalid syntax.</font>"));
|
||||
m_classMembersStatusLabel->setText("<font color=red>" + tr("Invalid syntax.") + "</font>");
|
||||
}
|
||||
|
||||
void PropertiesView::MView::onParseClassMembers()
|
||||
|
@@ -866,10 +866,10 @@ TreeItem *TreeItem::reverseFindAnyChild(const std::function<bool (TreeItem *)> &
|
||||
{
|
||||
auto end = m_children.rend();
|
||||
for (auto it = m_children.rbegin(); it != end; ++it) {
|
||||
if (pred(*it))
|
||||
return *it;
|
||||
if (TreeItem *found = (*it)->reverseFindAnyChild(pred))
|
||||
return found;
|
||||
if (pred(*it))
|
||||
return *it;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@@ -82,7 +82,8 @@ public:
|
||||
void forSelectedChildren(const std::function<bool(TreeItem *)> &pred) const;
|
||||
void forAllChildren(const std::function<void(TreeItem *)> &pred) const;
|
||||
TreeItem *findAnyChild(const std::function<bool(TreeItem *)> &pred) const;
|
||||
// like findAnyChild() but processes children from bottom to top
|
||||
// like findAnyChild() but processes children in exact reverse order
|
||||
// (bottom to top, most inner children first)
|
||||
TreeItem *reverseFindAnyChild(const std::function<bool(TreeItem *)> &pred) const;
|
||||
|
||||
// Levels are 1-based: Child at Level 1 is an immediate child.
|
||||
|
@@ -405,7 +405,7 @@ void ClangEditorDocumentProcessor::updateProjectPartAndTranslationUnitForEditor(
|
||||
const CppTools::ProjectPart::Ptr projectPart = m_parser->projectPartInfo().projectPart;
|
||||
|
||||
if (isProjectPartLoadedOrIsFallback(projectPart)) {
|
||||
registerTranslationUnitForEditor(projectPart.data());
|
||||
registerTranslationUnitForEditor(*projectPart.data());
|
||||
|
||||
m_projectPart = projectPart;
|
||||
m_isProjectFile = m_parser->projectPartInfo().hints
|
||||
@@ -421,7 +421,132 @@ void ClangEditorDocumentProcessor::onParserFinished()
|
||||
updateProjectPartAndTranslationUnitForEditor();
|
||||
}
|
||||
|
||||
void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart)
|
||||
namespace {
|
||||
// TODO: Can we marry this with CompilerOptionsBuilder?
|
||||
class FileOptionsBuilder
|
||||
{
|
||||
public:
|
||||
FileOptionsBuilder(const QString &filePath, CppTools::ProjectPart &projectPart)
|
||||
: m_filePath(filePath)
|
||||
, m_projectPart(projectPart)
|
||||
{
|
||||
addLanguageOptions();
|
||||
addDiagnosticOptions();
|
||||
addGlobalOptions();
|
||||
addPrecompiledHeaderOptions();
|
||||
}
|
||||
|
||||
const QStringList &options() const { return m_options; }
|
||||
|
||||
private:
|
||||
void addLanguageOptions()
|
||||
{
|
||||
// Determine file kind with respect to ambiguous headers.
|
||||
CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(m_filePath);
|
||||
if (fileKind == CppTools::ProjectFile::AmbiguousHeader) {
|
||||
fileKind = m_projectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion
|
||||
? CppTools::ProjectFile::CHeader
|
||||
: CppTools::ProjectFile::CXXHeader;
|
||||
}
|
||||
|
||||
CppTools::CompilerOptionsBuilder builder(m_projectPart);
|
||||
builder.addLanguageOption(fileKind);
|
||||
|
||||
m_options.append(builder.options());
|
||||
}
|
||||
|
||||
void addDiagnosticOptions()
|
||||
{
|
||||
if (m_projectPart.project) {
|
||||
ClangProjectSettings projectSettings(m_projectPart.project);
|
||||
if (!projectSettings.useGlobalConfig()) {
|
||||
const Core::Id warningConfigId = projectSettings.warningConfigId();
|
||||
const CppTools::ClangDiagnosticConfigsModel configsModel(
|
||||
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
|
||||
if (configsModel.hasConfigWithId(warningConfigId)) {
|
||||
m_options.append(
|
||||
configsModel.configWithId(warningConfigId).commandLineWarnings());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_options.append(
|
||||
CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings());
|
||||
}
|
||||
|
||||
void addXclangArg(const QString &argName, const QString &argValue = QString())
|
||||
{
|
||||
m_options.append("-Xclang");
|
||||
m_options.append(argName);
|
||||
if (!argValue.isEmpty()) {
|
||||
m_options.append("-Xclang");
|
||||
m_options.append(argValue);
|
||||
}
|
||||
}
|
||||
|
||||
void addTidyOptions()
|
||||
{
|
||||
const QString tidyChecks = CppTools::codeModelSettings()->tidyChecks();
|
||||
if (tidyChecks.isEmpty())
|
||||
return;
|
||||
|
||||
addXclangArg("-add-plugin", "clang-tidy");
|
||||
addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + tidyChecks + "'");
|
||||
}
|
||||
|
||||
void addClazyOptions()
|
||||
{
|
||||
const QString clazyChecks = CppTools::codeModelSettings()->clazyChecks();
|
||||
if (clazyChecks.isEmpty())
|
||||
return;
|
||||
|
||||
addXclangArg("-add-plugin", "clang-lazy");
|
||||
addXclangArg("-plugin-arg-clang-lazy", clazyChecks);
|
||||
|
||||
// NOTE: we already use -isystem for all include paths to make libclang skip diagnostics for
|
||||
// all of them. That means that ignore-included-files will not change anything unless we decide
|
||||
// to return the original -I prefix for some include paths.
|
||||
addXclangArg("-plugin-arg-clang-lazy", "ignore-included-files");
|
||||
}
|
||||
|
||||
void addGlobalOptions()
|
||||
{
|
||||
if (!m_projectPart.project)
|
||||
m_options.append(ClangProjectSettings::globalCommandLineOptions());
|
||||
else
|
||||
m_options.append(ClangProjectSettings{m_projectPart.project}.commandLineOptions());
|
||||
|
||||
addTidyOptions();
|
||||
addClazyOptions();
|
||||
}
|
||||
|
||||
void addPrecompiledHeaderOptions()
|
||||
{
|
||||
using namespace CppTools;
|
||||
|
||||
if (getPchUsage() == CompilerOptionsBuilder::PchUsage::None)
|
||||
return;
|
||||
|
||||
if (m_projectPart.precompiledHeaders.contains(m_filePath))
|
||||
return;
|
||||
|
||||
CompilerOptionsBuilder builder(m_projectPart);
|
||||
builder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::Use);
|
||||
|
||||
m_options.append(builder.options());
|
||||
}
|
||||
|
||||
private:
|
||||
const QString &m_filePath;
|
||||
const CppTools::ProjectPart &m_projectPart;
|
||||
|
||||
QStringList m_options;
|
||||
};
|
||||
} // namespace
|
||||
|
||||
void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(
|
||||
CppTools::ProjectPart &projectPart)
|
||||
{
|
||||
// On registration we send the document content immediately as an unsaved
|
||||
// file, because
|
||||
@@ -433,12 +558,13 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(CppTools::Pr
|
||||
// like on Windows.
|
||||
|
||||
if (m_projectPart) {
|
||||
if (projectPart->id() == m_projectPart->id())
|
||||
if (projectPart.id() == m_projectPart->id())
|
||||
return;
|
||||
}
|
||||
|
||||
const FileOptionsBuilder fileOptions(filePath(), projectPart);
|
||||
m_communicator.registerTranslationUnitsForEditor(
|
||||
{fileContainerWithArgumentsAndDocumentContent(projectPart)});
|
||||
{fileContainerWithOptionsAndDocumentContent(projectPart, fileOptions.options())});
|
||||
ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision());
|
||||
}
|
||||
|
||||
@@ -503,137 +629,12 @@ ClangBackEnd::FileContainer ClangEditorDocumentProcessor::simpleFileContainer(
|
||||
Utf8String::fromByteArray(codecName));
|
||||
}
|
||||
|
||||
static CppTools::ProjectPart projectPartForLanguageOption(CppTools::ProjectPart *projectPart)
|
||||
ClangBackEnd::FileContainer ClangEditorDocumentProcessor::fileContainerWithOptionsAndDocumentContent(
|
||||
CppTools::ProjectPart &projectPart, const QStringList &fileOptions) const
|
||||
{
|
||||
if (projectPart)
|
||||
return *projectPart;
|
||||
return *CppTools::CppModelManager::instance()->fallbackProjectPart().data();
|
||||
}
|
||||
|
||||
static QStringList languageOptions(const QString &filePath, CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
const auto theProjectPart = projectPartForLanguageOption(projectPart);
|
||||
|
||||
// Determine file kind with respect to ambiguous headers.
|
||||
CppTools::ProjectFile::Kind fileKind = CppTools::ProjectFile::classify(filePath);
|
||||
if (fileKind == CppTools::ProjectFile::AmbiguousHeader) {
|
||||
fileKind = theProjectPart.languageVersion <= CppTools::ProjectPart::LatestCVersion
|
||||
? CppTools::ProjectFile::CHeader
|
||||
: CppTools::ProjectFile::CXXHeader;
|
||||
}
|
||||
|
||||
CppTools::CompilerOptionsBuilder builder(theProjectPart);
|
||||
builder.addLanguageOption(fileKind);
|
||||
|
||||
return builder.options();
|
||||
}
|
||||
|
||||
static QStringList warningOptions(CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
if (projectPart && projectPart->project) {
|
||||
ClangProjectSettings projectSettings(projectPart->project);
|
||||
if (!projectSettings.useGlobalConfig()) {
|
||||
const Core::Id warningConfigId = projectSettings.warningConfigId();
|
||||
const CppTools::ClangDiagnosticConfigsModel configsModel(
|
||||
CppTools::codeModelSettings()->clangCustomDiagnosticConfigs());
|
||||
if (configsModel.hasConfigWithId(warningConfigId))
|
||||
return configsModel.configWithId(warningConfigId).commandLineWarnings();
|
||||
}
|
||||
}
|
||||
|
||||
return CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings();
|
||||
}
|
||||
|
||||
static void addXclangArg(QStringList &list, const QString &argName,
|
||||
const QString &argValue = QString())
|
||||
{
|
||||
list.append("-Xclang");
|
||||
list.append(argName);
|
||||
if (!argValue.isEmpty()) {
|
||||
list.append("-Xclang");
|
||||
list.append(argValue);
|
||||
}
|
||||
}
|
||||
|
||||
static QStringList tidyCommandLine()
|
||||
{
|
||||
const QString tidyChecks = CppTools::codeModelSettings()->tidyChecks();
|
||||
|
||||
if (tidyChecks.isEmpty())
|
||||
return QStringList();
|
||||
|
||||
QStringList result;
|
||||
addXclangArg(result, "-add-plugin", "clang-tidy");
|
||||
addXclangArg(result, "-plugin-arg-clang-tidy", "-checks='-*" + tidyChecks + "'");
|
||||
return result;
|
||||
}
|
||||
|
||||
static QStringList clazyCommandLine()
|
||||
{
|
||||
const QString clazyChecks = CppTools::codeModelSettings()->clazyChecks();
|
||||
|
||||
if (clazyChecks.isEmpty())
|
||||
return QStringList();
|
||||
|
||||
QStringList result;
|
||||
addXclangArg(result, "-add-plugin", "clang-lazy");
|
||||
addXclangArg(result, "-plugin-arg-clang-lazy", clazyChecks);
|
||||
|
||||
// NOTE: we already use -isystem for all include paths to make libclang skip diagnostics for
|
||||
// all of them. That means that ignore-included-files will not change anything unless we decide
|
||||
// to return the original -I prefix for some include paths.
|
||||
addXclangArg(result, "-plugin-arg-clang-lazy", "ignore-included-files");
|
||||
return result;
|
||||
}
|
||||
|
||||
static QStringList commandLineOptions(CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
QStringList result;
|
||||
if (!projectPart || !projectPart->project)
|
||||
result.append(ClangProjectSettings::globalCommandLineOptions());
|
||||
else
|
||||
result.append(ClangProjectSettings{projectPart->project}.commandLineOptions());
|
||||
result.append(tidyCommandLine());
|
||||
result.append(clazyCommandLine());
|
||||
return result;
|
||||
}
|
||||
|
||||
static QStringList precompiledHeaderOptions(
|
||||
const QString& filePath,
|
||||
CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
using namespace CppTools;
|
||||
|
||||
if (CppTools::getPchUsage() == CompilerOptionsBuilder::PchUsage::None)
|
||||
return QStringList();
|
||||
|
||||
if (projectPart->precompiledHeaders.contains(filePath))
|
||||
return QStringList();
|
||||
|
||||
const CppTools::ProjectPart theProjectPart = projectPartForLanguageOption(projectPart);
|
||||
CppTools::CompilerOptionsBuilder builder(theProjectPart);
|
||||
builder.addPrecompiledHeaderOptions(CompilerOptionsBuilder::PchUsage::Use);
|
||||
|
||||
return builder.options();
|
||||
}
|
||||
|
||||
static QStringList fileArguments(const QString &filePath, CppTools::ProjectPart *projectPart)
|
||||
{
|
||||
return languageOptions(filePath, projectPart)
|
||||
+ warningOptions(projectPart)
|
||||
+ commandLineOptions(projectPart)
|
||||
+ precompiledHeaderOptions(filePath, projectPart);
|
||||
}
|
||||
|
||||
ClangBackEnd::FileContainer
|
||||
ClangEditorDocumentProcessor::fileContainerWithArgumentsAndDocumentContent(
|
||||
CppTools::ProjectPart *projectPart) const
|
||||
{
|
||||
const QStringList theFileArguments = fileArguments(filePath(), projectPart);
|
||||
|
||||
return ClangBackEnd::FileContainer(filePath(),
|
||||
projectPart->id(),
|
||||
Utf8StringVector(theFileArguments),
|
||||
projectPart.id(),
|
||||
Utf8StringVector(fileOptions),
|
||||
textDocument()->toPlainText(),
|
||||
true,
|
||||
revision());
|
||||
|
@@ -104,14 +104,14 @@ public:
|
||||
private:
|
||||
void onParserFinished();
|
||||
void updateProjectPartAndTranslationUnitForEditor();
|
||||
void registerTranslationUnitForEditor(CppTools::ProjectPart *projectPart);
|
||||
void registerTranslationUnitForEditor(CppTools::ProjectPart &projectPart);
|
||||
void updateTranslationUnitIfProjectPartExists();
|
||||
void requestDocumentAnnotations(const QString &projectpartId);
|
||||
HeaderErrorDiagnosticWidgetCreator creatorForHeaderErrorDiagnosticWidget(
|
||||
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic);
|
||||
ClangBackEnd::FileContainer simpleFileContainer(const QByteArray &codecName = QByteArray()) const;
|
||||
ClangBackEnd::FileContainer fileContainerWithArgumentsAndDocumentContent(
|
||||
CppTools::ProjectPart *projectPart) const;
|
||||
ClangBackEnd::FileContainer fileContainerWithOptionsAndDocumentContent(
|
||||
CppTools::ProjectPart &projectPart, const QStringList &fileOptions) const;
|
||||
ClangBackEnd::FileContainer fileContainerWithDocumentContent(const QString &projectpartId) const;
|
||||
|
||||
private:
|
||||
|
@@ -39,9 +39,10 @@ VersionSelector::VersionSelector(const QString &fileName, const QString &message
|
||||
{
|
||||
ui->setupUi(this);
|
||||
ui->headerLabel->setText(ui->headerLabel->text().arg(fileName));
|
||||
ui->loadedText->setHtml(tr("<html><head/><body><p><b>Note: You will not be able to check in "
|
||||
"this file without merging the changes (not supported by the "
|
||||
"plugin)</b></p></body></html>"));
|
||||
ui->loadedText->setHtml("<html><head/><body><p><b>"
|
||||
+ tr("Note: You will not be able to check in this file without merging "
|
||||
"the changes (not supported by the plugin)")
|
||||
+ "</b></p></body></html>");
|
||||
m_stream = new QTextStream(message.toLocal8Bit(), QIODevice::ReadOnly | QIODevice::Text);
|
||||
QString line;
|
||||
while (!m_stream->atEnd() && !line.contains(QLatin1String("1) Loaded version")))
|
||||
|
@@ -450,9 +450,9 @@ KitInformation::ItemList CMakeGeneratorKitInformation::toUserOutput(const Kit *k
|
||||
} else {
|
||||
message = tr("Generator: %1<br>Extra generator: %2").arg(info.generator).arg(info.extraGenerator);
|
||||
if (!info.platform.isEmpty())
|
||||
message += tr("<br>Platform: %1").arg(info.platform);
|
||||
message += "<br/>" + tr("Platform: %1").arg(info.platform);
|
||||
if (!info.toolset.isEmpty())
|
||||
message += tr("<br>Toolset: %1").arg(info.toolset);
|
||||
message += "<br/>" + tr("Toolset: %1").arg(info.toolset);
|
||||
}
|
||||
return ItemList() << qMakePair(tr("CMake Generator"), message);
|
||||
}
|
||||
|
@@ -115,7 +115,7 @@ void CMakeTargetNode::setTargetInformation(const QList<Utils::FileName> &artifac
|
||||
m_tooltip += QCoreApplication::translate("CMakeTargetNode", "No build artifacts");
|
||||
} else {
|
||||
const QStringList tmp = Utils::transform(artifacts, &Utils::FileName::toUserOutput);
|
||||
m_tooltip += QCoreApplication::translate("CMakeTargetNode", "Build artifacts:<br>")
|
||||
m_tooltip += QCoreApplication::translate("CMakeTargetNode", "Build artifacts:") + "<br>"
|
||||
+ tmp.join("<br>");
|
||||
}
|
||||
}
|
||||
|
@@ -53,10 +53,12 @@ namespace Core {
|
||||
struct HelpManagerPrivate
|
||||
{
|
||||
HelpManagerPrivate() :
|
||||
m_needsSetup(true), m_helpEngine(0), m_collectionWatcher(0)
|
||||
m_needsSetup(true), m_helpEngine(nullptr), m_collectionWatcher(nullptr)
|
||||
{}
|
||||
|
||||
QStringList documentationFromInstaller();
|
||||
~HelpManagerPrivate();
|
||||
|
||||
const QStringList documentationFromInstaller();
|
||||
void readSettings();
|
||||
void writeSettings();
|
||||
void cleanUpDocumentation();
|
||||
@@ -73,8 +75,8 @@ struct HelpManagerPrivate
|
||||
QSet<QString> m_userRegisteredFiles;
|
||||
};
|
||||
|
||||
static HelpManager *m_instance = 0;
|
||||
static HelpManagerPrivate *d;
|
||||
static HelpManager *m_instance = nullptr;
|
||||
static HelpManagerPrivate *d = nullptr;
|
||||
|
||||
static const char linksForKeyQuery[] = "SELECT d.Title, f.Name, e.Name, "
|
||||
"d.Name, a.Anchor FROM IndexTable a, FileNameTable d, FolderTable e, "
|
||||
@@ -102,11 +104,8 @@ HelpManager::HelpManager(QObject *parent) :
|
||||
|
||||
HelpManager::~HelpManager()
|
||||
{
|
||||
d->writeSettings();
|
||||
delete d->m_helpEngine;
|
||||
d->m_helpEngine = 0;
|
||||
m_instance = 0;
|
||||
delete d;
|
||||
m_instance = nullptr;
|
||||
}
|
||||
|
||||
HelpManager *HelpManager::instance()
|
||||
@@ -124,13 +123,13 @@ QString HelpManager::collectionFilePath()
|
||||
void HelpManager::registerDocumentation(const QStringList &files)
|
||||
{
|
||||
if (d->m_needsSetup) {
|
||||
foreach (const QString &filePath, files)
|
||||
for (const QString &filePath : files)
|
||||
d->m_filesToRegister.insert(filePath);
|
||||
return;
|
||||
}
|
||||
|
||||
bool docsChanged = false;
|
||||
foreach (const QString &file, files) {
|
||||
for (const QString &file : files) {
|
||||
const QString &nameSpace = d->m_helpEngine->namespaceName(file);
|
||||
if (nameSpace.isEmpty())
|
||||
continue;
|
||||
@@ -162,13 +161,13 @@ void HelpManager::registerDocumentation(const QStringList &files)
|
||||
void HelpManager::unregisterDocumentation(const QStringList &nameSpaces)
|
||||
{
|
||||
if (d->m_needsSetup) {
|
||||
foreach (const QString &name, nameSpaces)
|
||||
for (const QString &name : nameSpaces)
|
||||
d->m_nameSpacesToUnregister.insert(name);
|
||||
return;
|
||||
}
|
||||
|
||||
bool docsChanged = false;
|
||||
foreach (const QString &nameSpace, nameSpaces) {
|
||||
for (const QString &nameSpace : nameSpaces) {
|
||||
const QString filePath = d->m_helpEngine->documentationFileName(nameSpace);
|
||||
if (d->m_helpEngine->unregisterDocumentation(nameSpace)) {
|
||||
docsChanged = true;
|
||||
@@ -185,7 +184,7 @@ void HelpManager::unregisterDocumentation(const QStringList &nameSpaces)
|
||||
|
||||
void HelpManager::registerUserDocumentation(const QStringList &filePaths)
|
||||
{
|
||||
foreach (const QString &filePath, filePaths)
|
||||
for (const QString &filePath : filePaths)
|
||||
d->m_userRegisteredFiles.insert(filePath);
|
||||
registerDocumentation(filePaths);
|
||||
}
|
||||
@@ -219,7 +218,7 @@ QMap<QString, QUrl> HelpManager::linksForKeyword(const QString &key)
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
|
||||
if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) {
|
||||
const QStringList ®isteredDocs = d->m_helpEngine->registeredDocumentations();
|
||||
foreach (const QString &nameSpace, registeredDocs) {
|
||||
for (const QString &nameSpace : registeredDocs) {
|
||||
db.setDatabaseName(d->m_helpEngine->documentationFileName(nameSpace));
|
||||
if (db.open()) {
|
||||
QSqlQuery query = QSqlQuery(db);
|
||||
@@ -308,7 +307,7 @@ HelpManager::Filters HelpManager::filters()
|
||||
|
||||
Filters filters;
|
||||
const QStringList &customFilters = d->m_helpEngine->customFilters();
|
||||
foreach (const QString &filter, customFilters)
|
||||
for (const QString &filter : customFilters)
|
||||
filters.insert(filter, d->m_helpEngine->filterAttributes(filter));
|
||||
return filters;
|
||||
}
|
||||
@@ -325,7 +324,7 @@ HelpManager::Filters HelpManager::fixedFilters()
|
||||
QSqlDatabase db = QSqlDatabase::addDatabase(sqlite, name);
|
||||
if (db.driver() && db.driver()->lastError().type() == QSqlError::NoError) {
|
||||
const QStringList ®isteredDocs = d->m_helpEngine->registeredDocumentations();
|
||||
foreach (const QString &nameSpace, registeredDocs) {
|
||||
for (const QString &nameSpace : registeredDocs) {
|
||||
db.setDatabaseName(d->m_helpEngine->documentationFileName(nameSpace));
|
||||
if (db.open()) {
|
||||
QSqlQuery query = QSqlQuery(db);
|
||||
@@ -382,7 +381,7 @@ void HelpManager::setupHelpManager()
|
||||
d->m_helpEngine = new QHelpEngineCore(collectionFilePath(), m_instance);
|
||||
d->m_helpEngine->setupData();
|
||||
|
||||
foreach (const QString &filePath, d->documentationFromInstaller())
|
||||
for (const QString &filePath : d->documentationFromInstaller())
|
||||
d->m_filesToRegister.insert(filePath);
|
||||
|
||||
d->cleanUpDocumentation();
|
||||
@@ -409,7 +408,7 @@ void HelpManagerPrivate::cleanUpDocumentation()
|
||||
// mark documentation for removal for which there is no documentation file anymore
|
||||
// mark documentation for removal that is neither user registered, nor marked for registration
|
||||
const QStringList ®isteredDocs = m_helpEngine->registeredDocumentations();
|
||||
foreach (const QString &nameSpace, registeredDocs) {
|
||||
for (const QString &nameSpace : registeredDocs) {
|
||||
const QString filePath = m_helpEngine->documentationFileName(nameSpace);
|
||||
if (!QFileInfo::exists(filePath)
|
||||
|| (!m_filesToRegister.contains(filePath)
|
||||
@@ -419,24 +418,30 @@ void HelpManagerPrivate::cleanUpDocumentation()
|
||||
}
|
||||
}
|
||||
|
||||
QStringList HelpManagerPrivate::documentationFromInstaller()
|
||||
HelpManagerPrivate::~HelpManagerPrivate()
|
||||
{
|
||||
writeSettings();
|
||||
delete m_helpEngine;
|
||||
m_helpEngine = nullptr;
|
||||
}
|
||||
|
||||
const QStringList HelpManagerPrivate::documentationFromInstaller()
|
||||
{
|
||||
QSettings *installSettings = ICore::settings();
|
||||
QStringList documentationPaths = installSettings->value(QLatin1String("Help/InstalledDocumentation"))
|
||||
const QStringList documentationPaths = installSettings->value(QLatin1String("Help/InstalledDocumentation"))
|
||||
.toStringList();
|
||||
QStringList documentationFiles;
|
||||
foreach (const QString &path, documentationPaths) {
|
||||
for (const QString &path : documentationPaths) {
|
||||
QFileInfo pathInfo(path);
|
||||
if (pathInfo.isFile() && pathInfo.isReadable()) {
|
||||
documentationFiles << pathInfo.absoluteFilePath();
|
||||
} else if (pathInfo.isDir()) {
|
||||
QDir dir(path);
|
||||
foreach (const QFileInfo &fileInfo, dir.entryInfoList(QStringList(QLatin1String("*.qch")),
|
||||
QDir::Files | QDir::Readable)) {
|
||||
const QFileInfoList files(QDir(path).entryInfoList(QStringList(QLatin1String("*.qch")),
|
||||
QDir::Files | QDir::Readable));
|
||||
for (const QFileInfo &fileInfo : files)
|
||||
documentationFiles << fileInfo.absoluteFilePath();
|
||||
}
|
||||
}
|
||||
}
|
||||
return documentationFiles;
|
||||
}
|
||||
|
||||
|
@@ -99,7 +99,7 @@ signals:
|
||||
void helpRequested(const QUrl &url, Core::HelpManager::HelpViewerLocation location);
|
||||
|
||||
private:
|
||||
explicit HelpManager(QObject *parent = 0);
|
||||
explicit HelpManager(QObject *parent = nullptr);
|
||||
~HelpManager();
|
||||
|
||||
static void setupHelpManager();
|
||||
|
@@ -286,7 +286,8 @@ void KdePasteProtocol::paste(const QString &text, Protocol::ContentType ct, int
|
||||
QString details = tr("Pasting to KDE paster needs authentication.<br/>"
|
||||
"Enter your KDE Identity credentials to continue.");
|
||||
if (m_loginFailed)
|
||||
details.prepend(tr("<span style='background-color:LightYellow;color:red'>Login failed</span><br/><br/>"));
|
||||
details.prepend("<span style='background-color:LightYellow;color:red'>"
|
||||
+ tr("Login failed") + "</span><br/><br/>");
|
||||
|
||||
AuthenticationDialog authDialog(details, Core::ICore::dialogParent());
|
||||
authDialog.setWindowTitle("Authenticate for KDE paster");
|
||||
|
@@ -447,9 +447,9 @@ BreakpointDialog::BreakpointDialog(Breakpoint b, QWidget *parent)
|
||||
m_labelUseFullPath->setToolTip(pathToolTip);
|
||||
|
||||
const QString moduleToolTip =
|
||||
tr("<p>Specifying the module (base name of the library or executable) "
|
||||
"<p>" + tr("Specifying the module (base name of the library or executable) "
|
||||
"for function or file type breakpoints can significantly speed up "
|
||||
"debugger startup times (CDB, LLDB).");
|
||||
"debugger startup times (CDB, LLDB).") + "</p>";
|
||||
m_lineEditModule = new QLineEdit(groupBoxAdvanced);
|
||||
m_lineEditModule->setToolTip(moduleToolTip);
|
||||
m_labelModule = new QLabel(tr("&Module:"), groupBoxAdvanced);
|
||||
@@ -457,8 +457,8 @@ BreakpointDialog::BreakpointDialog(Breakpoint b, QWidget *parent)
|
||||
m_labelModule->setToolTip(moduleToolTip);
|
||||
|
||||
const QString commandsToolTip =
|
||||
tr("<p>Debugger commands to be executed when the breakpoint is hit. "
|
||||
"This feature is only available for GDB.");
|
||||
"<p>" + tr("Debugger commands to be executed when the breakpoint is hit. "
|
||||
"This feature is only available for GDB.") + "</p>";
|
||||
m_textEditCommands = new SmallTextEdit(groupBoxAdvanced);
|
||||
m_textEditCommands->setToolTip(commandsToolTip);
|
||||
m_labelCommands = new QLabel(tr("&Commands:"), groupBoxAdvanced);
|
||||
|
@@ -320,10 +320,11 @@ QWidget *LocalsAndExpressionsOptionsPage::widget()
|
||||
|
||||
auto groupBoxCustomDumperCommands = new QGroupBox(debuggingHelperGroupBox);
|
||||
groupBoxCustomDumperCommands->setTitle(tr("Debugging Helper Customization"));
|
||||
groupBoxCustomDumperCommands->setToolTip(tr(
|
||||
"<html><head/><body><p>Python commands entered here will be executed after built-in "
|
||||
"debugging helpers have been loaded and fully initialized. You can load additional "
|
||||
"debugging helpers or modify existing ones here.</p></body></html>"));
|
||||
groupBoxCustomDumperCommands->setToolTip("<html><head/><body><p>"
|
||||
+ tr("Python commands entered here will be executed after built-in "
|
||||
"debugging helpers have been loaded and fully initialized. You can "
|
||||
"load additional debugging helpers or modify existing ones here.")
|
||||
+ "</p></body></html>");
|
||||
|
||||
auto textEditCustomDumperCommands = new QTextEdit(groupBoxCustomDumperCommands);
|
||||
textEditCustomDumperCommands->setAcceptRichText(false);
|
||||
|
@@ -401,10 +401,11 @@ void DebuggerItemConfigWidget::load(const DebuggerItem *item)
|
||||
const bool is64bit = is64BitWindowsSystem();
|
||||
const QString versionString = is64bit ? tr("64-bit version") : tr("32-bit version");
|
||||
//: Label text for path configuration. %2 is "x-bit version".
|
||||
text = tr("<html><body><p>Specify the path to the "
|
||||
text = "<html><body><p>"
|
||||
+ tr("Specify the path to the "
|
||||
"<a href=\"%1\">Windows Console Debugger executable</a>"
|
||||
" (%2) here.</p>""</body></html>").
|
||||
arg(QLatin1String(debuggingToolsWikiLinkC), versionString);
|
||||
" (%2) here.").arg(QLatin1String(debuggingToolsWikiLinkC), versionString)
|
||||
+ "</p></body></html>";
|
||||
versionCommand = QLatin1String("-version");
|
||||
} else {
|
||||
versionCommand = QLatin1String("--version");
|
||||
|
@@ -218,7 +218,8 @@ void ActionHandler::createActions()
|
||||
registerCommand(Constants::ACTION_ADD_CANVAS_DIAGRAM, nullptr, Core::Context(), true, tr("Add Canvas Diagram"));
|
||||
d->synchronizeBrowserAction = registerCommand(
|
||||
Constants::ACTION_SYNC_BROWSER, nullptr, Core::Context(), true,
|
||||
tr("Synchronize Browser and Diagram<br><i><small>Press&Hold for options</small></i>"))->action();
|
||||
tr("Synchronize Browser and Diagram") + "<br><i><small>"
|
||||
+ tr("Press && Hold for options") + "</small></i>")->action();
|
||||
d->synchronizeBrowserAction->setIcon(Utils::Icons::LINK.icon());
|
||||
d->synchronizeBrowserAction->setCheckable(true);
|
||||
|
||||
|
@@ -344,7 +344,7 @@ bool UpdateIncludeDependenciesVisitor::haveDependency(const qmt::MObject *source
|
||||
aToB = qmt::MDependency::BToA;
|
||||
bToA = qmt::MDependency::AToB;
|
||||
}
|
||||
foreach (const qmt::Handle<qmt::MRelation> &handle, source->relations()) {
|
||||
for (const qmt::Handle<qmt::MRelation> &handle : source->relations()) {
|
||||
if (auto dependency = dynamic_cast<qmt::MDependency *>(handle.target())) {
|
||||
if (dependency->source() == source->uid()
|
||||
&& dependency->target() == target->uid()
|
||||
|
@@ -215,7 +215,7 @@ ModelIndexer::DiagramsCollectorVisitor::DiagramsCollectorVisitor(IndexedModel *i
|
||||
|
||||
void ModelIndexer::DiagramsCollectorVisitor::visitMObject(const qmt::MObject *object)
|
||||
{
|
||||
foreach (const qmt::Handle<qmt::MObject> &child, object->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &child : object->children()) {
|
||||
if (child.hasTarget())
|
||||
child.target()->accept(this);
|
||||
}
|
||||
|
@@ -205,7 +205,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore
|
||||
qmt::MPackage *package = roots.takeFirst();
|
||||
|
||||
// append all sub-packages of the same level as next root packages
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
if (auto childPackage = dynamic_cast<qmt::MPackage *>(handle.target()))
|
||||
roots.append(childPackage);
|
||||
@@ -219,7 +219,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore
|
||||
QString relativeSearchId = qmt::NameController::calcElementNameSearchId(
|
||||
relativeElements.at(relativeIndex));
|
||||
found = false;
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
if (auto childPackage = dynamic_cast<qmt::MPackage *>(handle.target())) {
|
||||
if (qmt::NameController::calcElementNameSearchId(childPackage->name()) == relativeSearchId) {
|
||||
@@ -241,7 +241,7 @@ qmt::MDiagram *PxNodeController::findDiagramForExplorerNode(const ProjectExplore
|
||||
if (diagram)
|
||||
return diagram;
|
||||
// find first diagram within deepest package
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
if (auto diagram = dynamic_cast<qmt::MDiagram *>(handle.target()))
|
||||
return diagram;
|
||||
|
@@ -120,7 +120,7 @@ qmt::MPackage *PxNodeUtilities::createBestMatchingPackagePath(
|
||||
roots.takeFirst();
|
||||
|
||||
// append all sub-packages of the same level as next root packages
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
if (auto childPackage = dynamic_cast<qmt::MPackage *>(handle.target())) {
|
||||
// only accept root packages in the same path as the suggested parent package
|
||||
@@ -139,7 +139,7 @@ qmt::MPackage *PxNodeUtilities::createBestMatchingPackagePath(
|
||||
QString relativeSearchId = qmt::NameController::calcElementNameSearchId(
|
||||
relativeElements.at(relativeIndex));
|
||||
found = false;
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
if (auto childPackage = dynamic_cast<qmt::MPackage *>(handle.target())) {
|
||||
if (qmt::NameController::calcElementNameSearchId(childPackage->name()) == relativeSearchId) {
|
||||
@@ -198,7 +198,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement
|
||||
qmt::MPackage *package = roots.takeFirst();
|
||||
|
||||
// append all sub-packages of the same level as next root packages
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
if (auto childPackage = dynamic_cast<qmt::MPackage *>(handle.target()))
|
||||
roots.append(childPackage);
|
||||
@@ -212,7 +212,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement
|
||||
QString relativeSearchId = qmt::NameController::calcElementNameSearchId(
|
||||
relativeElements.at(relativeIndex));
|
||||
found = false;
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
if (auto childPackage = dynamic_cast<qmt::MPackage *>(handle.target())) {
|
||||
if (qmt::NameController::calcElementNameSearchId(childPackage->name()) == relativeSearchId) {
|
||||
@@ -230,7 +230,7 @@ qmt::MObject *PxNodeUtilities::findSameObject(const QStringList &relativeElement
|
||||
QMT_CHECK(relativeIndex >= relativeElements.size());
|
||||
// chain was found so check for given object within deepest package
|
||||
QString objectSearchId = qmt::NameController::calcElementNameSearchId(object->name());
|
||||
foreach (const qmt::Handle<qmt::MObject> &handle, package->children()) {
|
||||
for (const qmt::Handle<qmt::MObject> &handle : package->children()) {
|
||||
if (handle.hasTarget()) {
|
||||
qmt::MObject *target = handle.target();
|
||||
if (typeid(*target) == typeid(*object)
|
||||
|
@@ -73,7 +73,7 @@ const char QBS_RC_PREFIX[] = "Qbs.RunConfiguration:";
|
||||
|
||||
static QString rcNameSeparator() { return QLatin1String("---Qbs.RC.NameSeparator---"); }
|
||||
|
||||
static QString usingLibraryPathsKey() { return "Qbs.RunConfiguration.UsingLibraryPaths"; }
|
||||
static QString usingLibraryPathsKey() { return QString("Qbs.RunConfiguration.UsingLibraryPaths"); }
|
||||
|
||||
const qbs::ProductData findProduct(const qbs::ProjectData &pro, const QString &uniqeName)
|
||||
{
|
||||
|
@@ -29,32 +29,38 @@
|
||||
|
||||
#include <theme.h>
|
||||
|
||||
#include <itemlibrarymodel.h>
|
||||
#include <itemlibraryimageprovider.h>
|
||||
#include <itemlibraryinfo.h>
|
||||
#include <metainfo.h>
|
||||
#include <model.h>
|
||||
#include <rewritingexception.h>
|
||||
#include <qmldesignerplugin.h>
|
||||
|
||||
#include <utils/flowlayout.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/stylehelper.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include "itemlibrarymodel.h"
|
||||
#include "itemlibraryimageprovider.h"
|
||||
#include <model.h>
|
||||
#include <metainfo.h>
|
||||
#include "rewritingexception.h"
|
||||
|
||||
#include <QApplication>
|
||||
#include <QDrag>
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemModel>
|
||||
#include <QStackedWidget>
|
||||
#include <QGridLayout>
|
||||
#include <QTabBar>
|
||||
#include <QImageReader>
|
||||
#include <QMenu>
|
||||
#include <QMimeData>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QMenu>
|
||||
#include <QApplication>
|
||||
#include <QTimer>
|
||||
#include <QShortcut>
|
||||
#include <QStackedWidget>
|
||||
#include <QTabBar>
|
||||
#include <QTimer>
|
||||
#include <QToolButton>
|
||||
#include <QWheelEvent>
|
||||
#include <QQmlContext>
|
||||
#include <QQuickItem>
|
||||
|
||||
@@ -69,6 +75,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
m_itemIconSize(24, 24),
|
||||
m_itemViewQuickWidget(new QQuickWidget),
|
||||
m_resourcesView(new ItemLibraryResourceView(this)),
|
||||
m_importTagsWidget(new QWidget(this)),
|
||||
m_filterFlag(QtBasic)
|
||||
{
|
||||
m_compressionTimer.setInterval(200);
|
||||
@@ -126,7 +133,6 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
lineEditLayout->addItem(new QSpacerItem(5, 5, QSizePolicy::Fixed, QSizePolicy::Fixed), 1, 2);
|
||||
connect(m_filterLineEdit.data(), &Utils::FancyLineEdit::filterChanged, this, &ItemLibraryWidget::setSearchFilter);
|
||||
|
||||
|
||||
m_stackedWidget = new QStackedWidget(this);
|
||||
m_stackedWidget->addWidget(m_itemViewQuickWidget.data());
|
||||
m_stackedWidget->addWidget(m_resourcesView.data());
|
||||
@@ -141,7 +147,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
layout->addWidget(tabBar, 0, 0, 1, 1);
|
||||
layout->addWidget(spacer, 1, 0);
|
||||
layout->addWidget(lineEditFrame, 2, 0, 1, 1);
|
||||
layout->addWidget(m_stackedWidget.data(), 3, 0, 1, 1);
|
||||
layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1);
|
||||
layout->addWidget(m_stackedWidget.data(), 4, 0, 1, 1);
|
||||
|
||||
setSearchFilter(QString());
|
||||
|
||||
@@ -154,6 +161,9 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
|
||||
|
||||
connect(&m_compressionTimer, &QTimer::timeout, this, &ItemLibraryWidget::updateModel);
|
||||
|
||||
auto *flowLayout = new Utils::FlowLayout(m_importTagsWidget.data());
|
||||
flowLayout->setMargin(4);
|
||||
|
||||
// init the first load of the QML UI elements
|
||||
reloadQmlSource();
|
||||
}
|
||||
@@ -175,12 +185,8 @@ void ItemLibraryWidget::setItemLibraryInfo(ItemLibraryInfo *itemLibraryInfo)
|
||||
|
||||
void ItemLibraryWidget::updateImports()
|
||||
{
|
||||
if (m_model) {
|
||||
QStringList imports;
|
||||
foreach (const Import &import, m_model->imports())
|
||||
if (import.isLibraryImport())
|
||||
imports << import.url();
|
||||
}
|
||||
if (m_model)
|
||||
setupImportTagWidget();
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::setImportsWidget(QWidget *importsWidget)
|
||||
@@ -223,10 +229,16 @@ void ItemLibraryWidget::setModel(Model *model)
|
||||
|
||||
void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index)
|
||||
{
|
||||
if (index == 2)
|
||||
if (index == 2) {
|
||||
m_filterLineEdit->setVisible(false);
|
||||
else
|
||||
m_importTagsWidget->setVisible(true);
|
||||
} if (index == 1) {
|
||||
m_filterLineEdit->setVisible(true);
|
||||
m_importTagsWidget->setVisible(false);
|
||||
} else {
|
||||
m_filterLineEdit->setVisible(true);
|
||||
m_importTagsWidget->setVisible(true);
|
||||
}
|
||||
|
||||
m_stackedWidget->setCurrentIndex(index);
|
||||
}
|
||||
@@ -249,6 +261,38 @@ void ItemLibraryWidget::reloadQmlSource()
|
||||
m_itemViewQuickWidget->setSource(QUrl::fromLocalFile(itemLibraryQmlFilePath));
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::setupImportTagWidget()
|
||||
{
|
||||
QTC_ASSERT(m_model, return);
|
||||
|
||||
const QStringList imports = m_model->metaInfo().itemLibraryInfo()->showTagsForImports();
|
||||
|
||||
qDeleteAll(m_importTagsWidget->findChildren<QWidget*>("", Qt::FindDirectChildrenOnly));
|
||||
|
||||
auto *flowLayout = m_importTagsWidget->layout();
|
||||
|
||||
auto createButton = [this](const QString &import) {
|
||||
auto button = new QToolButton(m_importTagsWidget.data());
|
||||
auto font = button->font();
|
||||
font.setPixelSize(9);
|
||||
button->setFont(font);
|
||||
button->setIcon(Utils::Icons::PLUS.icon());
|
||||
button->setText(import);
|
||||
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
|
||||
connect(button, &QToolButton::clicked, this, [this, import]() {
|
||||
addPossibleImport(import);
|
||||
});
|
||||
return button;
|
||||
};
|
||||
|
||||
for (const QString &importPath : imports) {
|
||||
const Import import = Import::createLibraryImport(importPath);
|
||||
if (!m_model->hasImport(import, true, true)
|
||||
&& m_model->isImportPossible(import, true, true))
|
||||
flowLayout->addWidget(createButton(importPath));
|
||||
}
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::updateModel()
|
||||
{
|
||||
m_itemLibraryModel->update(m_itemLibraryInfo.data(), m_model.data());
|
||||
@@ -293,8 +337,7 @@ void ItemLibraryWidget::startDragAndDrop(QQuickItem *mouseArea, QVariant itemLib
|
||||
|
||||
void ItemLibraryWidget::removeImport(const QString &name)
|
||||
{
|
||||
if (!m_model)
|
||||
return;
|
||||
QTC_ASSERT(m_model, return);
|
||||
|
||||
QList<Import> toBeRemovedImportList;
|
||||
foreach (const Import &import, m_model->imports())
|
||||
@@ -306,9 +349,21 @@ void ItemLibraryWidget::removeImport(const QString &name)
|
||||
|
||||
void ItemLibraryWidget::addImport(const QString &name, const QString &version)
|
||||
{
|
||||
if (!m_model)
|
||||
return;
|
||||
QTC_ASSERT(m_model, return);
|
||||
m_model->changeImports({Import::createLibraryImport(name, version)}, {});
|
||||
}
|
||||
|
||||
void ItemLibraryWidget::addPossibleImport(const QString &name)
|
||||
{
|
||||
QTC_ASSERT(m_model, return);
|
||||
const Import import = m_model->highestPossibleImport(name);
|
||||
try {
|
||||
m_model->changeImports({Import::createLibraryImport(name, import.version())}, {});
|
||||
}
|
||||
catch (const RewritingException &e) {
|
||||
e.showException();
|
||||
}
|
||||
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -86,18 +86,17 @@ public:
|
||||
|
||||
Q_INVOKABLE void startDragAndDrop(QQuickItem *mouseArea, QVariant itemLibId);
|
||||
|
||||
protected:
|
||||
void removeImport(const QString &name);
|
||||
void addImport(const QString &name, const QString &version);
|
||||
|
||||
signals:
|
||||
void itemActivated(const QString& itemName);
|
||||
|
||||
private:
|
||||
void setCurrentIndexOfStackedWidget(int index);
|
||||
void reloadQmlSource();
|
||||
void setupImportTagWidget();
|
||||
void removeImport(const QString &name);
|
||||
void addImport(const QString &name, const QString &version);
|
||||
void addPossibleImport(const QString &name);
|
||||
|
||||
private:
|
||||
QTimer m_compressionTimer;
|
||||
QSize m_itemIconSize;
|
||||
|
||||
@@ -111,6 +110,8 @@ private:
|
||||
QPointer<Utils::FancyLineEdit> m_filterLineEdit;
|
||||
QScopedPointer<QQuickWidget> m_itemViewQuickWidget;
|
||||
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
|
||||
QScopedPointer<QWidget> m_importTagsWidget;
|
||||
|
||||
QShortcut *m_qmlSourceUpdateShortcut;
|
||||
|
||||
QPointer<Model> m_model;
|
||||
|
@@ -106,6 +106,12 @@ public:
|
||||
bool containsEntry(const ItemLibraryEntry &entry);
|
||||
void clearEntries();
|
||||
|
||||
QStringList blacklistImports() const;
|
||||
QStringList showTagsForImports() const;
|
||||
|
||||
void addBlacklistImports(const QStringList &list);
|
||||
void addShowTagsForImports(const QStringList &list);
|
||||
|
||||
signals:
|
||||
void entriesChanged();
|
||||
|
||||
@@ -116,6 +122,9 @@ private: // functions
|
||||
private: // variables
|
||||
QHash<QString, ItemLibraryEntry> m_nameToEntryHash;
|
||||
QPointer<ItemLibraryInfo> m_baseInfo;
|
||||
|
||||
QStringList m_blacklistImports;
|
||||
QStringList m_showTagsForImports;
|
||||
};
|
||||
|
||||
} // namespace QmlDesigner
|
||||
|
@@ -66,6 +66,7 @@ private:
|
||||
ParsingDocument,
|
||||
ParsingMetaInfo,
|
||||
ParsingType,
|
||||
ParsingImports,
|
||||
ParsingItemLibrary,
|
||||
ParsingHints,
|
||||
ParsingProperty,
|
||||
@@ -81,6 +82,7 @@ private:
|
||||
ParserSate readQmlSourceElement(const QString &name);
|
||||
|
||||
void readTypeProperty(const QString &name, const QVariant &value);
|
||||
void readImportsProperty(const QString &name, const QVariant &value);
|
||||
void readItemLibraryEntryProperty(const QString &name, const QVariant &value);
|
||||
void readPropertyProperty(const QString &name, const QVariant &value);
|
||||
void readQmlSourceProperty(const QString &name, const QVariant &value);
|
||||
|
@@ -99,8 +99,10 @@ public:
|
||||
void setPossibleImports(const QList<Import> &possibleImports);
|
||||
void setUsedImports(const QList<Import> &usedImports);
|
||||
bool hasImport(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false);
|
||||
bool isImportPossible(const Import &import, bool ignoreAlias = true, bool allowHigherVersion = false);
|
||||
QString pathForImport(const Import &import);
|
||||
QStringList importPaths() const;
|
||||
Import highestPossibleImport(const QString &importPath);
|
||||
|
||||
RewriterView *rewriterView() const;
|
||||
void setRewriterView(RewriterView *rewriterView);
|
||||
|
@@ -337,6 +337,32 @@ void ItemLibraryInfo::clearEntries()
|
||||
emit entriesChanged();
|
||||
}
|
||||
|
||||
QStringList ItemLibraryInfo::blacklistImports() const
|
||||
{
|
||||
auto list = m_blacklistImports;
|
||||
if (m_baseInfo)
|
||||
list.append(m_baseInfo->m_blacklistImports);
|
||||
return list;
|
||||
}
|
||||
|
||||
QStringList ItemLibraryInfo::showTagsForImports() const
|
||||
{
|
||||
auto list = m_showTagsForImports;
|
||||
if (m_baseInfo)
|
||||
list.append(m_baseInfo->m_showTagsForImports);
|
||||
return list;
|
||||
}
|
||||
|
||||
void ItemLibraryInfo::addBlacklistImports(const QStringList &list)
|
||||
{
|
||||
m_blacklistImports.append(list);
|
||||
}
|
||||
|
||||
void ItemLibraryInfo::addShowTagsForImports(const QStringList &list)
|
||||
{
|
||||
m_showTagsForImports.append(list);
|
||||
}
|
||||
|
||||
void ItemLibraryInfo::setBaseInfo(ItemLibraryInfo *baseInfo)
|
||||
{
|
||||
m_baseInfo = baseInfo;
|
||||
|
@@ -40,6 +40,7 @@ enum {
|
||||
|
||||
const QString rootElementName = QStringLiteral("MetaInfo");
|
||||
const QString typeElementName = QStringLiteral("Type");
|
||||
const QString importsElementName = QStringLiteral("Imports");
|
||||
const QString ItemLibraryEntryElementName = QStringLiteral("ItemLibraryEntry");
|
||||
const QString HintsElementName = QStringLiteral("Hints");
|
||||
const QString QmlSourceElementName = QStringLiteral("QmlSource");
|
||||
@@ -106,6 +107,7 @@ void MetaInfoReader::elementEnd()
|
||||
switch (parserState()) {
|
||||
case ParsingMetaInfo: setParserState(Finished); break;
|
||||
case ParsingType: setParserState(ParsingMetaInfo); break;
|
||||
case ParsingImports: setParserState(ParsingMetaInfo); break;
|
||||
case ParsingItemLibrary: keepCurrentItemLibraryEntry(); setParserState((ParsingType)); break;
|
||||
case ParsingHints: setParserState(ParsingType); break;
|
||||
case ParsingProperty: insertProperty(); setParserState(ParsingItemLibrary); break;
|
||||
@@ -123,6 +125,7 @@ void MetaInfoReader::propertyDefinition(const QString &name, const QVariant &val
|
||||
{
|
||||
switch (parserState()) {
|
||||
case ParsingType: readTypeProperty(name, value); break;
|
||||
case ParsingImports: readImportsProperty(name, value); break;
|
||||
case ParsingItemLibrary: readItemLibraryEntryProperty(name, value); break;
|
||||
case ParsingProperty: readPropertyProperty(name, value); break;
|
||||
case ParsingQmlSource: readQmlSourceProperty(name, value); break;
|
||||
@@ -156,6 +159,8 @@ MetaInfoReader::ParserSate MetaInfoReader::readMetaInfoRootElement(const QString
|
||||
m_currentIcon.clear();
|
||||
m_currentHints.clear();
|
||||
return ParsingType;
|
||||
} else if (name == importsElementName) {
|
||||
return ParsingImports;
|
||||
} else {
|
||||
addErrorInvalidType(name);
|
||||
return Error;
|
||||
@@ -207,6 +212,20 @@ MetaInfoReader::ParserSate MetaInfoReader::readQmlSourceElement(const QString &n
|
||||
return Error;
|
||||
}
|
||||
|
||||
void MetaInfoReader::readImportsProperty(const QString &name, const QVariant &value)
|
||||
{
|
||||
const auto values = value.toStringList();
|
||||
|
||||
if (name == "blacklistImports" && !values.isEmpty()) {
|
||||
m_metaInfo.itemLibraryInfo()->addBlacklistImports(values);
|
||||
} else if (name == "showTagsForImports" && !values.isEmpty()) {
|
||||
m_metaInfo.itemLibraryInfo()->addShowTagsForImports(values);
|
||||
} else {
|
||||
addError(tr("Unknown property for Imports %1").arg(name), currentSourceLocation());
|
||||
setParserState(Error);
|
||||
}
|
||||
}
|
||||
|
||||
void MetaInfoReader::readTypeProperty(const QString &name, const QVariant &value)
|
||||
{
|
||||
if (name == QLatin1String("name")) {
|
||||
|
@@ -1874,6 +1874,8 @@ void Model::setUsedImports(const QList<Import> &usedImports)
|
||||
|
||||
static bool compareVersions(const QString &version1, const QString &version2, bool allowHigherVersion)
|
||||
{
|
||||
if (version2.isEmpty())
|
||||
return true;
|
||||
if (version1 == version2)
|
||||
return true;
|
||||
if (!allowHigherVersion)
|
||||
@@ -1921,6 +1923,26 @@ bool Model::hasImport(const Import &import, bool ignoreAlias, bool allowHigherVe
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Model::isImportPossible(const Import &import, bool ignoreAlias, bool allowHigherVersion)
|
||||
{
|
||||
if (imports().contains(import))
|
||||
return true;
|
||||
if (!ignoreAlias)
|
||||
return false;
|
||||
|
||||
const auto importList = possibleImports();
|
||||
|
||||
for (const Import &possibleImport : importList) {
|
||||
if (possibleImport.isFileImport() && import.isFileImport())
|
||||
if (possibleImport.file() == import.file())
|
||||
return true;
|
||||
if (possibleImport.isLibraryImport() && import.isLibraryImport())
|
||||
if (possibleImport.url() == import.url() && compareVersions(possibleImport.version(), import.version(), allowHigherVersion))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QString Model::pathForImport(const Import &import)
|
||||
{
|
||||
if (!rewriterView())
|
||||
@@ -1944,6 +1966,20 @@ QStringList Model::importPaths() const
|
||||
return importPathList;
|
||||
}
|
||||
|
||||
Import Model::highestPossibleImport(const QString &importPath)
|
||||
{
|
||||
Import candidate;
|
||||
|
||||
for (const Import &import : possibleImports()) {
|
||||
if (import.url() == importPath) {
|
||||
if (candidate.isEmpty() || compareVersions(import.version(), candidate.version(), true))
|
||||
candidate = import;
|
||||
}
|
||||
}
|
||||
|
||||
return candidate;
|
||||
}
|
||||
|
||||
RewriterView *Model::rewriterView() const
|
||||
{
|
||||
return d->rewriterView();
|
||||
|
@@ -29,16 +29,18 @@
|
||||
#include "modelnodepositionstorage.h"
|
||||
#include "abstractproperty.h"
|
||||
#include "bindingproperty.h"
|
||||
#include "enumeration.h"
|
||||
#include "filemanager/firstdefinitionfinder.h"
|
||||
#include "filemanager/objectlengthcalculator.h"
|
||||
#include "filemanager/qmlrefactoring.h"
|
||||
#include "itemlibraryinfo.h"
|
||||
#include "metainfo.h"
|
||||
#include "nodemetainfo.h"
|
||||
#include "nodeproperty.h"
|
||||
#include "signalhandlerproperty.h"
|
||||
#include "propertyparser.h"
|
||||
#include "rewriterview.h"
|
||||
#include "variantproperty.h"
|
||||
#include "signalhandlerproperty.h"
|
||||
#include "nodemetainfo.h"
|
||||
#include "enumeration.h"
|
||||
|
||||
#include <qmljs/qmljsevaluate.h>
|
||||
#include <qmljs/qmljslink.h>
|
||||
@@ -790,7 +792,20 @@ static bool isLatestImportVersion(const ImportKey &importKey, const QHash<QStrin
|
||||
&& filteredPossibleImportKeys.value(importKey.path()).minorVersion < importKey.minorVersion);
|
||||
}
|
||||
|
||||
static bool isBlacklistImport(const ImportKey &importKey)
|
||||
static bool filterByMetaInfo(const ImportKey &importKey, Model *model)
|
||||
{
|
||||
if (model) {
|
||||
for (const QString &filter : model->metaInfo().itemLibraryInfo()->blacklistImports()) {
|
||||
if (importKey.libraryQualifiedPath().contains(filter))
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isBlacklistImport(const ImportKey &importKey, Model *model)
|
||||
{
|
||||
const QString &importPathFirst = importKey.splitPath.constFirst();
|
||||
const QString &importPathLast = importKey.splitPath.constLast();
|
||||
@@ -799,6 +814,7 @@ static bool isBlacklistImport(const ImportKey &importKey)
|
||||
|| importPathFirst == QStringLiteral("QtQml")
|
||||
|| (importPathFirst == QStringLiteral("QtQuick") && importPathLast == QStringLiteral("PrivateWidgets"))
|
||||
|| importPathLast == QStringLiteral("Private")
|
||||
|| importPathLast == QStringLiteral("private")
|
||||
|| importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Particles") //Unsupported
|
||||
|| importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Dialogs") //Unsupported
|
||||
|| importKey.libraryQualifiedPath() == QStringLiteral("QtQuick.Controls.Styles") //Unsupported
|
||||
@@ -813,14 +829,16 @@ static bool isBlacklistImport(const ImportKey &importKey)
|
||||
|| importKey.libraryQualifiedPath() == QStringLiteral("QtBluetooth")
|
||||
|| importKey.libraryQualifiedPath() == QStringLiteral("Enginio")
|
||||
|
||||
|| (importKey.splitPath.count() == 1 && importPathFirst == QStringLiteral("QtQuick")); // Don't show Quick X.X imports
|
||||
// Don't show Quick X.X imports
|
||||
|| (importKey.splitPath.count() == 1 && importPathFirst == QStringLiteral("QtQuick"))
|
||||
|| filterByMetaInfo(importKey, model);
|
||||
}
|
||||
|
||||
static QHash<QString, ImportKey> filterPossibleImportKeys(const QSet<ImportKey> &possibleImportKeys)
|
||||
static QHash<QString, ImportKey> filterPossibleImportKeys(const QSet<ImportKey> &possibleImportKeys, Model *model)
|
||||
{
|
||||
QHash<QString, ImportKey> filteredPossibleImportKeys;
|
||||
foreach (const ImportKey &importKey, possibleImportKeys) {
|
||||
if (isLatestImportVersion(importKey, filteredPossibleImportKeys) && !isBlacklistImport(importKey))
|
||||
if (isLatestImportVersion(importKey, filteredPossibleImportKeys) && !isBlacklistImport(importKey, model))
|
||||
filteredPossibleImportKeys.insert(importKey.path(), importKey);
|
||||
}
|
||||
|
||||
@@ -868,7 +886,8 @@ static QList<QmlDesigner::Import> generatePossibleLibraryImports(const QHash<QSt
|
||||
|
||||
void TextToModelMerger::setupPossibleImports(const QmlJS::Snapshot &snapshot, const QmlJS::ViewerContext &viewContext)
|
||||
{
|
||||
QHash<QString, ImportKey> filteredPossibleImportKeys = filterPossibleImportKeys(snapshot.importDependencies()->libraryImports(viewContext));
|
||||
QHash<QString, ImportKey> filteredPossibleImportKeys =
|
||||
filterPossibleImportKeys(snapshot.importDependencies()->libraryImports(viewContext), m_rewriterView->model());
|
||||
|
||||
removeUsedImports(filteredPossibleImportKeys, m_scopeChain->context()->imports(m_document.data())->all());
|
||||
|
||||
|
Reference in New Issue
Block a user