Merge remote-tracking branch 'origin/4.6'

Conflicts:
	share/qtcreator/qml-type-descriptions/qmlproject.qmltypes
	src/plugins/clangcodemodel/clangeditordocumentprocessor.cpp

Change-Id: I35fb652f29a98a798be7c8b4b4c2e581eb175fb6
This commit is contained in:
Eike Ziller
2018-02-01 09:58:36 +01:00
138 changed files with 1554 additions and 781 deletions

View File

@@ -31,6 +31,7 @@
#include <cpptools/cppmodelmanager.h>
#include <projectexplorer/session.h>
#include <utils/algorithm.h>
#include <utils/asconst.h>
#include <utils/qtcassert.h>
namespace Autotest {
@@ -122,35 +123,67 @@ TestConfiguration *GTestTreeItem::debugConfiguration() const
return config;
}
QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
struct TestCases
{
QStringList filters;
int testSetCount = 0;
QSet<QString> internalTargets;
};
static void collectTestInfo(const GTestTreeItem *item,
QHash<QString, TestCases> &testCasesForProFile,
bool ignoreCheckState)
{
QTC_ASSERT(item, return);
if (item->type() == TestTreeItem::GroupNode) {
for (int row = 0, count = item->childCount(); row < count; ++row) {
auto child = static_cast<const GTestTreeItem *>(item->childItem(row));
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
}
return;
}
const int childCount = item->childCount();
QTC_ASSERT(childCount != 0, return);
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
if (ignoreCheckState || item->checked() == Qt::Checked) {
const QString &projectFile = item->childItem(0)->proFile();
testCasesForProFile[projectFile].filters.append(
gtestFilter(item->state()).arg(item->name()).arg('*'));
testCasesForProFile[projectFile].testSetCount += childCount - 1;
testCasesForProFile[projectFile].internalTargets.unite(item->internalTargets());
} else if (item->checked() == Qt::PartiallyChecked) {
for (int childRow = 0; childRow < childCount; ++childRow) {
const TestTreeItem *child = item->childItem(childRow);
QTC_ASSERT(child->type() == TestTreeItem::TestFunctionOrSet, continue);
if (child->checked() == Qt::Checked) {
testCasesForProFile[child->proFile()].filters.append(
gtestFilter(item->state()).arg(item->name()).arg(child->name()));
testCasesForProFile[child->proFile()].internalTargets.unite(
child->internalTargets());
}
}
}
}
QList<TestConfiguration *> GTestTreeItem::getTestConfigurations(bool ignoreCheckState) const
{
QList<TestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
QHash<QString, int> proFilesWithTestSets;
QHash<QString, QSet<QString> > proFilesWithInternalTargets;
QHash<QString, TestCases> testCasesForProFile;
for (int row = 0, count = childCount(); row < count; ++row) {
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
const int grandChildCount = child->childCount();
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
const TestTreeItem *grandChild = child->childItem(grandChildRow);
const QString &key = grandChild->proFile();
proFilesWithTestSets.insert(key, proFilesWithTestSets[key] + 1);
proFilesWithInternalTargets[key].unite(grandChild->internalTargets());
}
auto child = static_cast<const GTestTreeItem *>(childItem(row));
collectTestInfo(child, testCasesForProFile, ignoreCheckState);
}
QHash<QString, int>::ConstIterator it = proFilesWithTestSets.begin();
QHash<QString, int>::ConstIterator end = proFilesWithTestSets.end();
for ( ; it != end; ++it) {
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
for (const QString &target : internalTargets) {
for (auto it = testCasesForProFile.begin(), end = testCasesForProFile.end(); it != end; ++it) {
for (const QString &target : Utils::asConst(it.value().internalTargets)) {
GTestConfiguration *tc = new GTestConfiguration;
tc->setTestCaseCount(it.value());
if (!ignoreCheckState)
tc->setTestCases(it.value().filters);
tc->setTestCaseCount(tc->testCaseCount() + it.value().testSetCount);
tc->setProjectFile(it.key());
tc->setProject(project);
tc->setInternalTarget(target);
@@ -161,69 +194,14 @@ QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
return result;
}
struct TestCases
QList<TestConfiguration *> GTestTreeItem::getAllTestConfigurations() const
{
QStringList filters;
int additionalTestCaseCount = 0;
};
return getTestConfigurations(true);
}
QList<TestConfiguration *> GTestTreeItem::getSelectedTestConfigurations() const
{
QList<TestConfiguration *> result;
ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject();
if (!project || type() != Root)
return result;
QHash<QString, TestCases> proFilesWithCheckedTestSets;
QHash<QString, QSet<QString> > proFilesWithInternalTargets;
for (int row = 0, count = childCount(); row < count; ++row) {
const GTestTreeItem *child = static_cast<const GTestTreeItem *>(childItem(row));
const int grandChildCount = child->childCount();
QTC_ASSERT(grandChildCount != 0, continue);
switch (child->checked()) {
case Qt::Unchecked:
continue;
case Qt::Checked: {
auto &testCases = proFilesWithCheckedTestSets[child->childItem(0)->proFile()];
testCases.filters.append(gtestFilter(child->state()).arg(child->name()).arg('*'));
testCases.additionalTestCaseCount += grandChildCount - 1;
proFilesWithInternalTargets[child->childItem(0)->proFile()].unite(
child->internalTargets());
break;
}
case Qt::PartiallyChecked: {
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
const TestTreeItem *grandChild = child->childItem(grandChildRow);
if (grandChild->checked() == Qt::Checked) {
proFilesWithCheckedTestSets[grandChild->proFile()].filters.append(
gtestFilter(child->state()).arg(child->name()).arg(grandChild->name()));
proFilesWithInternalTargets[grandChild->proFile()].unite(
grandChild->internalTargets());
}
}
break;
}
}
}
QHash<QString, TestCases>::ConstIterator it = proFilesWithCheckedTestSets.begin();
QHash<QString, TestCases>::ConstIterator end = proFilesWithCheckedTestSets.end();
for ( ; it != end; ++it) {
const QSet<QString> &internalTargets = proFilesWithInternalTargets[it.key()];
for (const QString &target : internalTargets) {
GTestConfiguration *tc = new GTestConfiguration;
tc->setTestCases(it.value().filters);
tc->setTestCaseCount(tc->testCaseCount() + it.value().additionalTestCaseCount);
tc->setProjectFile(it.key());
tc->setProject(project);
tc->setInternalTarget(target);
result << tc;
}
}
return result;
return getTestConfigurations(false);
}
TestTreeItem *GTestTreeItem::find(const TestParseResult *result)

View File

@@ -71,6 +71,7 @@ public:
private:
bool modifyTestSetContent(const GTestParseResult *result);
QList<TestConfiguration *> getTestConfigurations(bool ignoreCheckState) const;
GTestTreeItem::TestStates m_state;
};

View File

@@ -38,7 +38,7 @@ QtTestTreeItem::QtTestTreeItem(const QString &name, const QString &filePath, Tes
: TestTreeItem(name, filePath, type)
{
if (type == TestDataTag)
setChecked(Qt::Checked);
setData(0, Qt::Checked, Qt::CheckStateRole);
}
QVariant QtTestTreeItem::data(int column, int role) const
@@ -139,6 +139,53 @@ TestConfiguration *QtTestTreeItem::testConfiguration() const
return config;
}
static void fillTestConfigurationsFromCheckState(const TestTreeItem *item,
QList<TestConfiguration *> &testConfigurations)
{
QTC_ASSERT(item, return);
if (item->type() == TestTreeItem::GroupNode) {
for (int row = 0, count = item->childCount(); row < count; ++row)
fillTestConfigurationsFromCheckState(item->childItem(row), testConfigurations);
return;
}
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
QtTestConfiguration *testConfig = nullptr;
switch (item->checked()) {
case Qt::Unchecked:
return;
case Qt::Checked:
testConfig = static_cast<QtTestConfiguration *>(item->testConfiguration());
QTC_ASSERT(testConfig, return);
testConfigurations << testConfig;
return;
case Qt::PartiallyChecked:
default:
int grandChildCount = item->childCount();
QStringList testCases;
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
const TestTreeItem *grandChild = item->childItem(grandChildRow);
if (grandChild->checked() == Qt::Checked) {
testCases << grandChild->name();
} else if (grandChild->checked() == Qt::PartiallyChecked) {
const int dtCount = grandChild->childCount();
const QString funcName = grandChild->name();
for (int dtRow = 0; dtRow < dtCount; ++dtRow) {
const TestTreeItem *dataTag = grandChild->childItem(dtRow);
if (dataTag->checked() == Qt::Checked)
testCases << funcName + ':' + dataTag->name();
}
}
}
testConfig = new QtTestConfiguration();
testConfig->setTestCases(testCases);
testConfig->setProjectFile(item->proFile());
testConfig->setProject(ProjectExplorer::SessionManager::startupProject());
testConfig->setInternalTargets(item->internalTargets());
testConfigurations << testConfig;
}
}
TestConfiguration *QtTestTreeItem::debugConfiguration() const
{
QtTestConfiguration *config = static_cast<QtTestConfiguration *>(testConfiguration());
@@ -157,13 +204,19 @@ QList<TestConfiguration *> QtTestTreeItem::getAllTestConfigurations() const
for (int row = 0, count = childCount(); row < count; ++row) {
const TestTreeItem *child = childItem(row);
TestConfiguration *tc = new QtTestConfiguration();
tc->setTestCaseCount(child->childCount());
tc->setProjectFile(child->proFile());
tc->setProject(project);
tc->setInternalTargets(child->internalTargets());
result << tc;
TestConfiguration *tc = nullptr;
if (child->type() == TestCase) {
tc = child->testConfiguration();
QTC_ASSERT(tc, continue);
result << tc;
} else if (child->type() == GroupNode) {
const int groupChildCount = child->childCount();
for (int groupChildRow = 0; groupChildRow < groupChildCount; ++groupChildRow) {
tc = child->childItem(groupChildRow)->testConfiguration();
QTC_ASSERT(tc, continue);
result << tc;
}
}
}
return result;
}
@@ -175,49 +228,8 @@ QList<TestConfiguration *> QtTestTreeItem::getSelectedTestConfigurations() const
if (!project || type() != Root)
return result;
QtTestConfiguration *testConfiguration = nullptr;
for (int row = 0, count = childCount(); row < count; ++row) {
const TestTreeItem *child = childItem(row);
switch (child->checked()) {
case Qt::Unchecked:
continue;
case Qt::Checked:
testConfiguration = new QtTestConfiguration();
testConfiguration->setTestCaseCount(child->childCount());
testConfiguration->setProjectFile(child->proFile());
testConfiguration->setProject(project);
testConfiguration->setInternalTargets(child->internalTargets());
result << testConfiguration;
continue;
case Qt::PartiallyChecked:
default:
int grandChildCount = child->childCount();
QStringList testCases;
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
const TestTreeItem *grandChild = child->childItem(grandChildRow);
if (grandChild->checked() == Qt::Checked) {
testCases << grandChild->name();
} else if (grandChild->checked() == Qt::PartiallyChecked) {
const int dtCount = grandChild->childCount();
const QString funcName = grandChild->name();
for (int dtRow = 0; dtRow < dtCount; ++dtRow) {
const TestTreeItem *dataTag = grandChild->childItem(dtRow);
if (dataTag->checked() == Qt::Checked)
testCases << funcName + ':' + dataTag->name();
}
}
}
testConfiguration = new QtTestConfiguration();
testConfiguration->setTestCases(testCases);
testConfiguration->setProjectFile(child->proFile());
testConfiguration->setProject(project);
testConfiguration->setInternalTargets(child->internalTargets());
result << testConfiguration;
}
}
for (int row = 0, count = childCount(); row < count; ++row)
fillTestConfigurationsFromCheckState(childItem(row), result);
return result;
}

View File

@@ -153,6 +153,43 @@ TestConfiguration *QuickTestTreeItem::testConfiguration() const
return config;
}
static void testConfigurationFromCheckState(const TestTreeItem *item,
QHash<QString, QuickTestConfiguration *> &foundProFiles)
{
QTC_ASSERT(item, return);
if (item->type() == TestTreeItem::GroupNode) {
for (int row = 0, count = item->childCount(); row < count; ++row)
testConfigurationFromCheckState(item->childItem(row), foundProFiles);
return;
}
QTC_ASSERT(item->type() == TestTreeItem::TestCase, return);
QuickTestConfiguration *tc = nullptr;
if (item->checked() == Qt::Unchecked)
return;
QStringList testFunctions;
const int childCount = item->childCount();
for (int childRow = 0; childRow < childCount; ++childRow) {
const TestTreeItem *child = item->childItem(childRow);
if (child->checked() != Qt::Checked || child->type() != TestTreeItem::TestFunctionOrSet)
continue;
testFunctions << item->name() + "::" + child->name();
}
if (foundProFiles.contains(item->proFile())) {
tc = foundProFiles[item->proFile()];
QStringList oldFunctions(tc->testCases());
oldFunctions << testFunctions;
tc->setTestCases(oldFunctions);
} else {
tc = new QuickTestConfiguration;
tc->setTestCases(testFunctions);
tc->setProjectFile(item->proFile());
tc->setProject(ProjectExplorer::SessionManager::startupProject());
tc->setInternalTargets(item->internalTargets());
foundProFiles.insert(item->proFile(), tc);
}
}
TestConfiguration *QuickTestTreeItem::debugConfiguration() const
{
QuickTestConfiguration *config = static_cast<QuickTestConfiguration *>(testConfiguration());
@@ -161,6 +198,17 @@ TestConfiguration *QuickTestTreeItem::debugConfiguration() const
return config;
}
struct Tests {
int testCount = 0;
QSet<QString> internalTargets;
};
static void addTestsForItem(Tests &tests, const TestTreeItem *item)
{
tests.testCount += item->childCount();
tests.internalTargets = item->internalTargets();
}
QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
{
QList<TestConfiguration *> result;
@@ -169,8 +217,7 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
if (!project || type() != Root)
return result;
QHash<QString, int> foundProFiles;
QHash<QString, QSet<QString> > proFilesWithTargets;
QHash<QString, Tests> testsForProfile;
for (int row = 0, count = childCount(); row < count; ++row) {
const TestTreeItem *child = childItem(row);
// unnamed Quick Tests must be handled separately
@@ -178,25 +225,29 @@ QList<TestConfiguration *> QuickTestTreeItem::getAllTestConfigurations() const
for (int childRow = 0, ccount = child->childCount(); childRow < ccount; ++ childRow) {
const TestTreeItem *grandChild = child->childItem(childRow);
const QString &proFile = grandChild->proFile();
foundProFiles.insert(proFile, foundProFiles[proFile] + 1);
proFilesWithTargets.insert(proFile, grandChild->internalTargets());
++(testsForProfile[proFile].testCount);
testsForProfile[proFile].internalTargets = grandChild->internalTargets();
}
continue;
}
// named Quick Test
const QString &proFile = child->proFile();
foundProFiles.insert(proFile, foundProFiles[proFile] + child->childCount());
proFilesWithTargets.insert(proFile, child->internalTargets());
if (child->type() == TestCase) {
addTestsForItem(testsForProfile[child->proFile()], child);
} else if (child->type() == GroupNode) {
const int groupCount = child->childCount();
for (int groupRow = 0; groupRow < groupCount; ++groupRow) {
const TestTreeItem *grandChild = child->childItem(groupRow);
addTestsForItem(testsForProfile[grandChild->proFile()], grandChild);
}
}
}
// create TestConfiguration for each project file
QHash<QString, int>::ConstIterator it = foundProFiles.begin();
QHash<QString, int>::ConstIterator end = foundProFiles.end();
for ( ; it != end; ++it) {
for (auto it = testsForProfile.begin(), end = testsForProfile.end(); it != end; ++it) {
QuickTestConfiguration *tc = new QuickTestConfiguration;
tc->setTestCaseCount(it.value());
tc->setTestCaseCount(it.value().testCount);
tc->setProjectFile(it.key());
tc->setProject(project);
tc->setInternalTargets(proFilesWithTargets[it.key()]);
tc->setInternalTargets(it.value().internalTargets);
result << tc;
}
return result;
@@ -209,7 +260,6 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
if (!project || type() != Root)
return result;
QuickTestConfiguration *tc = nullptr;
QHash<QString, QuickTestConfiguration *> foundProFiles;
for (int row = 0, count = childCount(); row < count; ++row) {
@@ -219,39 +269,10 @@ QList<TestConfiguration *> QuickTestTreeItem::getSelectedTestConfigurations() co
continue;
// named Quick Tests
switch (child->checked()) {
case Qt::Unchecked:
continue;
case Qt::Checked:
case Qt::PartiallyChecked:
default:
QStringList testFunctions;
int grandChildCount = child->childCount();
for (int grandChildRow = 0; grandChildRow < grandChildCount; ++grandChildRow) {
const TestTreeItem *grandChild = child->childItem(grandChildRow);
if (grandChild->checked() != Qt::Checked || grandChild->type() != TestFunctionOrSet)
continue;
testFunctions << child->name() + "::" + grandChild->name();
}
if (foundProFiles.contains(child->proFile())) {
tc = foundProFiles[child->proFile()];
QStringList oldFunctions(tc->testCases());
oldFunctions << testFunctions;
tc->setTestCases(oldFunctions);
} else {
tc = new QuickTestConfiguration;
tc->setTestCases(testFunctions);
tc->setProjectFile(child->proFile());
tc->setProject(project);
tc->setInternalTargets(child->internalTargets());
foundProFiles.insert(child->proFile(), tc);
}
break;
}
testConfigurationFromCheckState(child, foundProFiles);
}
QHash<QString, QuickTestConfiguration *>::ConstIterator it = foundProFiles.begin();
QHash<QString, QuickTestConfiguration *>::ConstIterator end = foundProFiles.end();
for ( ; it != end; ++it) {
for (auto it = foundProFiles.begin(), end = foundProFiles.end(); it != end; ++it) {
QuickTestConfiguration *config = it.value();
if (!config->unnamedOnly())
result << config;
@@ -327,6 +348,12 @@ bool QuickTestTreeItem::isGroupNodeFor(const TestTreeItem *other) const
return TestTreeItem::isGroupNodeFor(other);
}
bool QuickTestTreeItem::removeOnSweepIfEmpty() const
{
return TestTreeItem::removeOnSweepIfEmpty()
|| (type() == TestCase && name().isEmpty()); // remove pseudo item '<unnamed>'
}
TestTreeItem *QuickTestTreeItem::createParentGroupNode() const
{
if (filePath().isEmpty() || name().isEmpty())

View File

@@ -48,6 +48,7 @@ public:
bool modify(const TestParseResult *result) override;
bool lessThan(const TestTreeItem *other, SortMode mode) const override;
bool isGroupNodeFor(const TestTreeItem *other) const override;
bool removeOnSweepIfEmpty() const override;
TestTreeItem *createParentGroupNode() const override;
QSet<QString> internalTargets() const override;
private:

View File

@@ -55,13 +55,11 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
{
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
painter->save();
QFontMetrics fm(opt.font);
QBrush background;
QColor foreground;
const QAbstractItemView *view = qobject_cast<const QAbstractItemView *>(opt.widget);
const bool selected = opt.state & QStyle::State_Selected;
if (selected) {
@@ -71,10 +69,14 @@ void TestResultDelegate::paint(QPainter *painter, const QStyleOptionViewItem &op
background = opt.palette.window().color();
foreground = opt.palette.text().color();
}
auto resultFilterModel = qobject_cast<const TestResultFilterModel *>(index.model());
if (!resultFilterModel)
return;
painter->save();
painter->fillRect(opt.rect, background);
painter->setPen(foreground);
TestResultFilterModel *resultFilterModel = static_cast<TestResultFilterModel *>(view->model());
LayoutPositions positions(opt, resultFilterModel);
const TestResult *testResult = resultFilterModel->testResult(index);
QTC_ASSERT(testResult, painter->restore();return);

View File

@@ -56,7 +56,7 @@ private:
class LayoutPositions
{
public:
LayoutPositions(QStyleOptionViewItem &options, TestResultFilterModel *filterModel)
LayoutPositions(QStyleOptionViewItem &options, const TestResultFilterModel *filterModel)
: m_totalWidth(options.rect.width()),
m_top(options.rect.top()),
m_bottom(options.rect.bottom())

View File

@@ -106,9 +106,9 @@ QVariant TestTreeItem::data(int /*column*/, int role) const
bool TestTreeItem::setData(int /*column*/, const QVariant &data, int role)
{
if (role == Qt::CheckStateRole) {
Qt::CheckState old = checked();
setChecked((Qt::CheckState)data.toInt());
return checked() != old;
Qt::CheckState old = m_checked;
m_checked = (Qt::CheckState)data.toInt();
return m_checked != old;
}
return false;
}
@@ -168,34 +168,6 @@ bool TestTreeItem::modifyLineAndColumn(const TestParseResult *result)
return hasBeenModified;
}
void TestTreeItem::setChecked(const Qt::CheckState checkState)
{
switch (m_type) {
case TestDataTag: {
m_checked = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
if (auto parent = parentItem())
parent->revalidateCheckState();
break;
}
case Root:
case GroupNode:
case TestFunctionOrSet:
case TestCase: {
Qt::CheckState usedState = (checkState == Qt::Unchecked ? Qt::Unchecked : Qt::Checked);
for (int row = 0, count = childCount(); row < count; ++row)
childItem(row)->setChecked(usedState);
m_checked = usedState;
if (m_type != Root) {
if (auto parent = parentItem())
parent->revalidateCheckState();
}
break;
}
default:
return;
}
}
Qt::CheckState TestTreeItem::checked() const
{
switch (m_type) {
@@ -327,41 +299,6 @@ QSet<QString> TestTreeItem::internalTargets() const
return targets;
}
void TestTreeItem::revalidateCheckState()
{
const Type ttiType = type();
if (ttiType != TestCase && ttiType != TestFunctionOrSet && ttiType != Root && ttiType != GroupNode)
return;
if (childCount() == 0) // can this happen? (we're calling revalidateCS() on parentItem()
return;
bool foundChecked = false;
bool foundUnchecked = false;
bool foundPartiallyChecked = false;
for (int row = 0, count = childCount(); row < count; ++row) {
TestTreeItem *child = childItem(row);
switch (child->type()) {
case TestDataFunction:
case TestSpecialFunction:
continue;
default:
break;
}
foundChecked |= (child->checked() == Qt::Checked);
foundUnchecked |= (child->checked() == Qt::Unchecked);
foundPartiallyChecked |= (child->checked() == Qt::PartiallyChecked);
if (foundPartiallyChecked || (foundChecked && foundUnchecked)) {
m_checked = Qt::PartiallyChecked;
if (ttiType == TestFunctionOrSet || ttiType == TestCase || ttiType == GroupNode)
parentItem()->revalidateCheckState();
return;
}
}
m_checked = (foundUnchecked ? Qt::Unchecked : Qt::Checked);
if (ttiType == TestFunctionOrSet || ttiType == TestCase || ttiType == GroupNode)
parentItem()->revalidateCheckState();
}
inline bool TestTreeItem::modifyFilePath(const QString &filePath)
{
if (m_filePath != filePath) {

View File

@@ -89,12 +89,12 @@ public:
unsigned column() const { return m_column; }
QString proFile() const { return m_proFile; }
void setProFile(const QString &proFile) { m_proFile = proFile; }
virtual void setChecked(const Qt::CheckState checked);
virtual Qt::CheckState checked() const;
Type type() const { return m_type; }
void markForRemoval(bool mark);
void markForRemovalRecursively(bool mark);
virtual void markForRemovalRecursively(const QString &filePath);
virtual bool removeOnSweepIfEmpty() const { return m_type == GroupNode; }
bool markedForRemoval() const { return m_status == MarkedForRemoval; }
bool newlyAdded() const { return m_status == NewlyAdded; }
TestTreeItem *parentItem() const;
@@ -123,7 +123,6 @@ protected:
const QString &file);
private:
void revalidateCheckState();
bool modifyFilePath(const QString &filePath);
bool modifyName(const QString &name);
@@ -143,7 +142,7 @@ private:
QString m_proFile;
Status m_status = NewlyAdded;
friend class TestTreeModel; // grant access to (private) revalidateCheckState()
friend class TestTreeModel; // grant access to (protected) findChildBy()
};
class TestCodeLocationAndType

View File

@@ -108,21 +108,18 @@ bool TestTreeModel::setData(const QModelIndex &index, const QVariant &value, int
if (item && item->setData(index.column(), value, role)) {
emit dataChanged(index, index);
if (role == Qt::CheckStateRole) {
switch (item->type()) {
case TestTreeItem::Root:
case TestTreeItem::GroupNode:
case TestTreeItem::TestCase:
if (item->childCount() > 0)
emit dataChanged(index.child(0, 0), index.child(item->childCount() - 1, 0));
break;
case TestTreeItem::TestFunctionOrSet:
emit dataChanged(index.parent(), index.parent());
break;
default: // avoid warning regarding unhandled enum member
break;
Qt::CheckState checked = item->checked();
if (item->hasChildren() && checked != Qt::PartiallyChecked) {
// handle the new checkstate for children as well...
for (Utils::TreeItem *child : *item) {
const QModelIndex &idx = indexForItem(child);
setData(idx, checked ? Qt::Checked : Qt::Unchecked, Qt::CheckStateRole);
}
}
if (item->parent() != rootItem() && item->parentItem()->checked() != checked)
revalidateCheckState(item->parentItem()); // handle parent too
return true;
}
return true;
}
return false;
}
@@ -254,10 +251,14 @@ bool TestTreeModel::sweepChildren(TestTreeItem *item)
if (child->type() != TestTreeItem::Root && child->markedForRemoval()) {
destroyItem(child);
item->revalidateCheckState();
revalidateCheckState(item);
hasChanged = true;
} else if (child->hasChildren()) {
hasChanged |= sweepChildren(child);
if (!child->hasChildren() && child->removeOnSweepIfEmpty()) {
destroyItem(child);
revalidateCheckState(item);
}
} else {
hasChanged |= child->newlyAdded();
}
@@ -281,6 +282,50 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b
}
}
parentNode->appendChild(item);
if (item->checked() != parentNode->checked())
revalidateCheckState(parentNode);
}
void TestTreeModel::revalidateCheckState(TestTreeItem *item)
{
QTC_ASSERT(item, return);
const TestTreeItem::Type type = item->type();
if (type == TestTreeItem::TestSpecialFunction || type == TestTreeItem::TestDataFunction
|| type == TestTreeItem::TestDataTag) {
return;
}
const Qt::CheckState oldState = (Qt::CheckState)item->data(0, Qt::CheckStateRole).toInt();
Qt::CheckState newState = Qt::Checked;
bool foundChecked = false;
bool foundUnchecked = false;
bool foundPartiallyChecked = false;
for (int row = 0, count = item->childCount(); row < count; ++row) {
TestTreeItem *child = item->childItem(row);
switch (child->type()) {
case TestTreeItem::TestDataFunction:
case TestTreeItem::TestSpecialFunction:
continue;
default:
break;
}
foundChecked |= (child->checked() == Qt::Checked);
foundUnchecked |= (child->checked() == Qt::Unchecked);
foundPartiallyChecked |= (child->checked() == Qt::PartiallyChecked);
if (foundPartiallyChecked || (foundChecked && foundUnchecked)) {
newState = Qt::PartiallyChecked;
break;
}
}
if (newState != Qt::PartiallyChecked)
newState = foundUnchecked ? Qt::Unchecked : Qt::Checked;
if (oldState != newState) {
item->setData(0, newState, Qt::CheckStateRole);
emit dataChanged(item->index(), item->index());
if (item->parent() != rootItem() && item->parentItem()->checked() != newState)
revalidateCheckState(item->parentItem());
}
}
void TestTreeModel::onParseResultReady(const TestParseResultPtr result)
@@ -321,12 +366,6 @@ void TestTreeModel::handleParseResult(const TestParseResult *result, TestTreeIte
QTC_ASSERT(newItem, return);
insertItemInParent(newItem, parentNode, groupingEnabled);
// new items are checked by default - revalidation of parents might be necessary
if (parentNode->checked() != Qt::Checked) {
parentNode->revalidateCheckState();
const QModelIndex &idx = indexForItem(parentNode);
emit dataChanged(idx, idx);
}
}
void TestTreeModel::removeAllTestItems()
@@ -335,7 +374,7 @@ void TestTreeModel::removeAllTestItems()
item->removeChildren();
TestTreeItem *testTreeItem = static_cast<TestTreeItem *>(item);
if (testTreeItem->checked() == Qt::PartiallyChecked)
testTreeItem->setChecked(Qt::Checked);
testTreeItem->setData(0, Qt::Checked, Qt::CheckStateRole);
}
emit testTreeModelChanged();
}

View File

@@ -87,8 +87,8 @@ private:
void removeTestRootNodes();
void removeFiles(const QStringList &files);
bool sweepChildren(TestTreeItem *item);
static void insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
void insertItemInParent(TestTreeItem *item, TestTreeItem *root, bool groupingEnabled);
void revalidateCheckState(TestTreeItem *item);
explicit TestTreeModel(QObject *parent = 0);
void setupParsingConnections();

View File

@@ -45,6 +45,13 @@ TestTreeView::TestTreeView(QWidget *parent)
Core::ICore::addContextObject(m_context);
}
static void changeCheckStateAll(const Qt::CheckState checkState)
{
TestTreeModel *model = TestTreeModel::instance();
for (int row = 0, count = model->rowCount(); row < count; ++row)
model->setData(model->index(row, 0), checkState, Qt::CheckStateRole);
}
void TestTreeView::selectAll()
{
changeCheckStateAll(Qt::Checked);
@@ -55,40 +62,5 @@ void TestTreeView::deselectAll()
changeCheckStateAll(Qt::Unchecked);
}
// this avoids the re-evaluation of parent nodes when modifying the child nodes (setData())
void TestTreeView::changeCheckStateAll(const Qt::CheckState checkState)
{
const TestTreeModel *model = TestTreeModel::instance();
for (int rootRow = 0; rootRow < model->rowCount(rootIndex()); ++rootRow) {
QModelIndex currentRootIndex = model->index(rootRow, 0, rootIndex());
if (!currentRootIndex.isValid())
return;
int count = model->rowCount(currentRootIndex);
QModelIndex last;
for (int classesRow = 0; classesRow < count; ++classesRow) {
const QModelIndex classesIndex = model->index(classesRow, 0, currentRootIndex);
int funcCount = model->rowCount(classesIndex);
TestTreeItem *item = static_cast<TestTreeItem *>(classesIndex.internalPointer());
if (item) {
item->setChecked(checkState);
if (!item->childCount())
last = classesIndex;
}
for (int functionRow = 0; functionRow < funcCount; ++functionRow) {
last = model->index(functionRow, 0, classesIndex);
TestTreeItem *item = static_cast<TestTreeItem *>(last.internalPointer());
if (item)
item->setChecked(checkState);
}
}
if (count == 0) {
if (auto item = static_cast<TestTreeItem *>(currentRootIndex.internalPointer()))
item->setChecked(checkState);
}
emit dataChanged(currentRootIndex, last);
}
}
} // namespace Internal
} // namespace Autotest

View File

@@ -45,7 +45,6 @@ public:
void deselectAll();
private:
void changeCheckStateAll(const Qt::CheckState checkState);
Core::IContext *m_context;
};

View File

@@ -368,26 +368,23 @@ QFuture<CppTools::CursorInfo> BackendCommunicator::requestReferences(
const FileContainer &fileContainer,
quint32 line,
quint32 column,
QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses)
{
const RequestReferencesMessage message(fileContainer, line, column);
m_sender->requestReferences(message);
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument,
localUses);
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), localUses);
}
QFuture<CppTools::CursorInfo> BackendCommunicator::requestLocalReferences(
const FileContainer &fileContainer,
quint32 line,
quint32 column,
QTextDocument *textDocument)
quint32 column)
{
const RequestReferencesMessage message(fileContainer, line, column, true);
m_sender->requestReferences(message);
return m_receiver.addExpectedReferencesMessage(message.ticketNumber(), textDocument);
return m_receiver.addExpectedReferencesMessage(message.ticketNumber());
}
QFuture<CppTools::ToolTipInfo> BackendCommunicator::requestToolTip(

View File

@@ -75,13 +75,11 @@ public:
const FileContainer &fileContainer,
quint32 line,
quint32 column,
QTextDocument *textDocument,
const LocalUseMap &localUses);
QFuture<CppTools::CursorInfo> requestLocalReferences(
const FileContainer &fileContainer,
quint32 line,
quint32 column,
QTextDocument *textDocument);
quint32 column);
QFuture<CppTools::ToolTipInfo> requestToolTip(const FileContainer &fileContainer,
quint32 line,
quint32 column);

View File

@@ -101,16 +101,14 @@ void BackendReceiver::deleteProcessorsOfEditorWidget(TextEditor::TextEditorWidge
QFuture<CppTools::CursorInfo> BackendReceiver::addExpectedReferencesMessage(
quint64 ticket,
QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses)
{
QTC_CHECK(textDocument);
QTC_CHECK(!m_referencesTable.contains(ticket));
QFutureInterface<CppTools::CursorInfo> futureInterface;
futureInterface.reportStarted();
const ReferencesEntry entry{futureInterface, textDocument, localUses};
const ReferencesEntry entry{futureInterface, localUses};
m_referencesTable.insert(ticket, entry);
return futureInterface.future();
@@ -221,24 +219,17 @@ void BackendReceiver::documentAnnotationsChanged(const DocumentAnnotationsChange
}
static
CppTools::CursorInfo::Range toCursorInfoRange(const QTextDocument &textDocument,
const SourceRangeContainer &sourceRange)
CppTools::CursorInfo::Range toCursorInfoRange(const SourceRangeContainer &sourceRange)
{
const SourceLocationContainer start = sourceRange.start();
const SourceLocationContainer end = sourceRange.end();
const unsigned length = end.column() - start.column();
const QTextBlock block = textDocument.findBlockByNumber(static_cast<int>(start.line()) - 1);
const int shift = ClangCodeModel::Utils::extraUtf8CharsShift(block.text(),
static_cast<int>(start.column()));
const uint column = start.column() - static_cast<uint>(shift);
return CppTools::CursorInfo::Range(start.line(), column, length);
return CppTools::CursorInfo::Range(start.line(), start.column(), length);
}
static
CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses,
CppTools::CursorInfo toCursorInfo(const CppTools::SemanticInfo::LocalUseMap &localUses,
const ReferencesMessage &message)
{
CppTools::CursorInfo result;
@@ -246,7 +237,7 @@ CppTools::CursorInfo toCursorInfo(const QTextDocument &textDocument,
result.areUseRangesForLocalVariable = message.isLocalVariable();
for (const SourceRangeContainer &reference : references)
result.useRanges.append(toCursorInfoRange(textDocument, reference));
result.useRanges.append(toCursorInfoRange(reference));
result.useRanges.reserve(references.size());
result.localUses = localUses;
@@ -284,8 +275,7 @@ void BackendReceiver::references(const ReferencesMessage &message)
if (futureInterface.isCanceled())
return; // Editor document closed or a new request was issued making this result outdated.
QTC_ASSERT(entry.textDocument, return);
futureInterface.reportResult(toCursorInfo(*entry.textDocument, entry.localUses, message));
futureInterface.reportResult(toCursorInfo(entry.localUses, message));
futureInterface.reportFinished();
}

View File

@@ -56,7 +56,6 @@ public:
QFuture<CppTools::CursorInfo>
addExpectedReferencesMessage(quint64 ticket,
QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses
= CppTools::SemanticInfo::LocalUseMap());
QFuture<CppTools::SymbolInfo> addExpectedRequestFollowSymbolMessage(quint64 ticket);
@@ -82,13 +81,10 @@ private:
struct ReferencesEntry {
ReferencesEntry() = default;
ReferencesEntry(QFutureInterface<CppTools::CursorInfo> futureInterface,
QTextDocument *textDocument,
const CppTools::SemanticInfo::LocalUseMap &localUses)
: futureInterface(futureInterface)
, textDocument(textDocument)
, localUses(localUses) {}
QFutureInterface<CppTools::CursorInfo> futureInterface;
QPointer<QTextDocument> textDocument;
CppTools::SemanticInfo::LocalUseMap localUses;
};
QHash<quint64, ReferencesEntry> m_referencesTable;

View File

@@ -559,7 +559,8 @@ ClangCompletionAssistProcessor::extractLineColumn(int position)
int line = -1, column = -1;
::Utils::Text::convertPosition(m_interface->textDocument(), position, &line, &column);
const QTextBlock block = m_interface->textDocument()->findBlock(position);
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column) + 1;
const QString stringOnTheLeft = block.text().left(column);
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
return {line, column};
}

View File

@@ -64,8 +64,7 @@ int positionInText(QTextDocument *textDocument,
{
auto textBlock = textDocument->findBlockByNumber(
static_cast<int>(sourceLocationContainer.line()) - 1);
int column = static_cast<int>(sourceLocationContainer.column()) - 1;
column -= ClangCodeModel::Utils::extraUtf8CharsShift(textBlock.text(), column);
const int column = static_cast<int>(sourceLocationContainer.column()) - 1;
return textBlock.position() + column;
}

View File

@@ -29,6 +29,7 @@
#include "clangdiagnostictooltipwidget.h"
#include "clangfixitoperation.h"
#include "clangfixitoperationsextractor.h"
#include "clangmodelmanagersupport.h"
#include "clangtokeninfosreporter.h"
#include "clangprojectsettings.h"
#include "clangutils.h"
@@ -66,6 +67,12 @@
namespace ClangCodeModel {
namespace Internal {
static ClangProjectSettings &getProjectSettings(ProjectExplorer::Project *project)
{
QTC_CHECK(project);
return ModelManagerSupportClang::instance()->projectSettings(project);
}
ClangEditorDocumentProcessor::ClangEditorDocumentProcessor(
BackendCommunicator &communicator,
TextEditor::TextDocument *document)
@@ -174,6 +181,11 @@ void ClangEditorDocumentProcessor::clearProjectPart()
m_projectPart.clear();
}
Core::Id ClangEditorDocumentProcessor::diagnosticConfigId() const
{
return m_diagnosticConfigId;
}
void ClangEditorDocumentProcessor::updateCodeWarnings(
const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
@@ -331,20 +343,19 @@ ClangEditorDocumentProcessor::cursorInfo(const CppTools::CursorInfoParams &param
{
int line, column;
convertPosition(params.textCursor, &line, &column);
++column; // for 1-based columns
if (!isCursorOnIdentifier(params.textCursor))
return defaultCursorInfoFuture();
const QTextBlock block = params.textCursor.document()->findBlockByNumber(line - 1);
column += ClangCodeModel::Utils::extraUtf8CharsShift(block.text(), column);
const QString stringOnTheLeft = block.text().left(column);
column = stringOnTheLeft.toUtf8().size() + 1; // '+ 1' is for 1-based columns
const CppTools::SemanticInfo::LocalUseMap localUses
= CppTools::BuiltinCursorInfo::findLocalUses(params.semanticInfo.doc, line, column);
return m_communicator.requestReferences(simpleFileContainer(),
static_cast<quint32>(line),
static_cast<quint32>(column),
textDocument(),
localUses);
}
@@ -361,8 +372,7 @@ QFuture<CppTools::CursorInfo> ClangEditorDocumentProcessor::requestLocalReferenc
return m_communicator.requestLocalReferences(simpleFileContainer(),
static_cast<quint32>(line),
static_cast<quint32>(column),
textDocument());
static_cast<quint32>(column));
}
QFuture<CppTools::SymbolInfo>
@@ -437,6 +447,7 @@ public:
}
const QStringList &options() const { return m_options; }
const Core::Id &diagnosticConfigId() const { return m_diagnosticConfigId; }
private:
void addLanguageOptions()
@@ -458,21 +469,28 @@ private:
void addDiagnosticOptions()
{
if (m_projectPart.project) {
ClangProjectSettings projectSettings(m_projectPart.project);
ClangProjectSettings &projectSettings = getProjectSettings(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());
addDiagnosticOptionsForConfig(configsModel.configWithId(warningConfigId));
return;
}
}
}
m_options.append(
CppTools::codeModelSettings()->clangDiagnosticConfig().commandLineWarnings());
addDiagnosticOptionsForConfig(CppTools::codeModelSettings()->clangDiagnosticConfig());
}
void addDiagnosticOptionsForConfig(const CppTools::ClangDiagnosticConfig &diagnosticConfig)
{
m_diagnosticConfigId = diagnosticConfig.id();
m_options.append(diagnosticConfig.clangOptions());
addClangTidyOptions(diagnosticConfig.clangTidyChecks());
addClazyOptions(diagnosticConfig.clazyChecks());
}
void addXclangArg(const QString &argName, const QString &argValue = QString())
@@ -485,24 +503,22 @@ private:
}
}
void addTidyOptions()
void addClangTidyOptions(const QString &checks)
{
const QString tidyChecks = CppTools::codeModelSettings()->tidyChecks();
if (tidyChecks.isEmpty())
if (checks.isEmpty())
return;
addXclangArg("-add-plugin", "clang-tidy");
addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + tidyChecks + "'");
addXclangArg("-plugin-arg-clang-tidy", "-checks='-*" + checks + "'");
}
void addClazyOptions()
void addClazyOptions(const QString &checks)
{
const QString clazyChecks = CppTools::codeModelSettings()->clazyChecks();
if (clazyChecks.isEmpty())
if (checks.isEmpty())
return;
addXclangArg("-add-plugin", "clang-lazy");
addXclangArg("-plugin-arg-clang-lazy", clazyChecks);
addXclangArg("-plugin-arg-clang-lazy", checks);
// 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
@@ -515,10 +531,7 @@ private:
if (!m_projectPart.project)
m_options.append(ClangProjectSettings::globalCommandLineOptions());
else
m_options.append(ClangProjectSettings{m_projectPart.project}.commandLineOptions());
addTidyOptions();
addClazyOptions();
m_options.append(getProjectSettings(m_projectPart.project).commandLineOptions());
}
void addPrecompiledHeaderOptions()
@@ -541,6 +554,7 @@ private:
const QString &m_filePath;
const CppTools::ProjectPart &m_projectPart;
Core::Id m_diagnosticConfigId;
QStringList m_options;
};
} // namespace
@@ -563,6 +577,7 @@ void ClangEditorDocumentProcessor::registerTranslationUnitForEditor(
}
const FileOptionsBuilder fileOptions(filePath(), projectPart);
m_diagnosticConfigId = fileOptions.diagnosticConfigId();
m_communicator.registerTranslationUnitsForEditor(
{fileContainerWithOptionsAndDocumentContent(projectPart, fileOptions.options())});
ClangCodeModel::Utils::setLastSentDocumentRevision(filePath(), revision());

View File

@@ -28,6 +28,7 @@
#include "clangdiagnosticmanager.h"
#include "clangeditordocumentparser.h"
#include <coreplugin/id.h>
#include <cpptools/builtineditordocumentprocessor.h>
#include <cpptools/semantichighlighter.h>
@@ -67,6 +68,8 @@ public:
CppTools::ProjectPart::Ptr projectPart() const;
void clearProjectPart();
Core::Id diagnosticConfigId() const;
void updateCodeWarnings(const QVector<ClangBackEnd::DiagnosticContainer> &diagnostics,
const ClangBackEnd::DiagnosticContainer &firstHeaderErrorDiagnostic,
uint documentRevision);
@@ -120,6 +123,7 @@ private:
BackendCommunicator &m_communicator;
QSharedPointer<ClangEditorDocumentParser> m_parser;
CppTools::ProjectPart::Ptr m_projectPart;
Core::Id m_diagnosticConfigId;
bool m_isProjectFile = false;
QFutureWatcher<void> m_parserWatcher;
QTimer m_updateTranslationUnitTimer;

View File

@@ -133,7 +133,10 @@ void ClangHoverHandler::identifyMatch(TextEditorWidget *editorWidget,
m_reportPriority = report;
m_futureWatcher.reset(new QFutureWatcher<CppTools::ToolTipInfo>());
QObject::connect(m_futureWatcher.data(), &QFutureWatcherBase::finished, [this]() {
processToolTipInfo(m_futureWatcher->result());
if (m_futureWatcher->isCanceled())
m_reportPriority(Priority_None);
else
processToolTipInfo(m_futureWatcher->result());
});
m_futureWatcher->setFuture(future);
return;

View File

@@ -30,22 +30,27 @@
#include "clangutils.h"
#include "clangfollowsymbol.h"
#include "clanghoverhandler.h"
#include "clangprojectsettings.h"
#include "clangrefactoringengine.h"
#include "clangcurrentdocumentfilter.h"
#include <coreplugin/editormanager/editormanager.h>
#include <cpptools/cppcodemodelsettings.h>
#include <cpptools/cppfollowsymbolundercursor.h>
#include <cpptools/cppmodelmanager.h>
#include <cpptools/cpptoolsreuse.h>
#include <cpptools/editordocumenthandle.h>
#include <cpptools/projectinfo.h>
#include <texteditor/quickfix.h>
#include <projectexplorer/project.h>
#include <projectexplorer/session.h>
#include <clangsupport/cmbregisterprojectsforeditormessage.h>
#include <clangsupport/filecontainer.h>
#include <clangsupport/projectpartcontainer.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
#include <QCoreApplication>
@@ -100,11 +105,22 @@ ModelManagerSupportClang::ModelManagerSupportClang()
connect(modelManager, &CppTools::CppModelManager::projectPartsRemoved,
this, &ModelManagerSupportClang::onProjectPartsRemoved);
auto *sessionManager = ProjectExplorer::SessionManager::instance();
connect(sessionManager, &ProjectExplorer::SessionManager::projectAdded,
this, &ModelManagerSupportClang::onProjectAdded);
connect(sessionManager, &ProjectExplorer::SessionManager::aboutToRemoveProject,
this, &ModelManagerSupportClang::onAboutToRemoveProject);
CppTools::CppCodeModelSettings *settings = CppTools::codeModelSettings().data();
connect(settings, &CppTools::CppCodeModelSettings::clangDiagnosticConfigsInvalidated,
this, &ModelManagerSupportClang::onDiagnosticConfigsInvalidated);
m_communicator.registerFallbackProjectPart();
}
ModelManagerSupportClang::~ModelManagerSupportClang()
{
QTC_CHECK(m_projectSettings.isEmpty());
m_instance = 0;
}
@@ -336,6 +352,52 @@ void ModelManagerSupportClang::onTextMarkContextMenuRequested(TextEditor::TextEd
}
}
using ClangEditorDocumentProcessors = QVector<ClangEditorDocumentProcessor *>;
static ClangEditorDocumentProcessors clangProcessors()
{
ClangEditorDocumentProcessors result;
foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments())
result.append(qobject_cast<ClangEditorDocumentProcessor *>(editorDocument->processor()));
return result;
}
static ClangEditorDocumentProcessors
clangProcessorsWithProject(const ProjectExplorer::Project *project)
{
return ::Utils::filtered(clangProcessors(), [project](ClangEditorDocumentProcessor *p) {
return p->hasProjectPart() && p->projectPart()->project == project;
});
}
static void updateProcessors(const ClangEditorDocumentProcessors &processors)
{
CppTools::CppModelManager *modelManager = cppModelManager();
for (ClangEditorDocumentProcessor *processor : processors)
modelManager->cppEditorDocument(processor->filePath())->resetProcessor();
modelManager->updateCppEditorDocuments(/*projectsUpdated=*/ false);
}
void ModelManagerSupportClang::onProjectAdded(ProjectExplorer::Project *project)
{
QTC_ASSERT(!m_projectSettings.value(project), return);
auto *settings = new Internal::ClangProjectSettings(project);
connect(settings, &Internal::ClangProjectSettings::changed, [project]() {
updateProcessors(clangProcessorsWithProject(project));
});
m_projectSettings.insert(project, settings);
}
void ModelManagerSupportClang::onAboutToRemoveProject(ProjectExplorer::Project *project)
{
ClangProjectSettings * const settings = m_projectSettings.value(project);
QTC_ASSERT(settings, return);
m_projectSettings.remove(project);
delete settings;
}
void ModelManagerSupportClang::onProjectPartsUpdated(ProjectExplorer::Project *project)
{
QTC_ASSERT(project, return);
@@ -355,21 +417,25 @@ void ModelManagerSupportClang::onProjectPartsRemoved(const QStringList &projectP
}
}
static QVector<ClangEditorDocumentProcessor *>
static ClangEditorDocumentProcessors clangProcessorsWithDiagnosticConfig(
const QVector<Core::Id> &configIds)
{
return ::Utils::filtered(clangProcessors(), [configIds](ClangEditorDocumentProcessor *p) {
return configIds.contains(p->diagnosticConfigId());
});
}
void ModelManagerSupportClang::onDiagnosticConfigsInvalidated(const QVector<Core::Id> &configIds)
{
updateProcessors(clangProcessorsWithDiagnosticConfig(configIds));
}
static ClangEditorDocumentProcessors
clangProcessorsWithProjectParts(const QStringList &projectPartIds)
{
QVector<ClangEditorDocumentProcessor *> result;
foreach (auto *editorDocument, cppModelManager()->cppEditorDocuments()) {
auto *processor = editorDocument->processor();
auto *clangProcessor = qobject_cast<ClangEditorDocumentProcessor *>(processor);
if (clangProcessor && clangProcessor->hasProjectPart()) {
if (projectPartIds.contains(clangProcessor->projectPart()->id()))
result.append(clangProcessor);
}
}
return result;
return ::Utils::filtered(clangProcessors(), [projectPartIds](ClangEditorDocumentProcessor *p) {
return p->hasProjectPart() && projectPartIds.contains(p->projectPart()->id());
});
}
void ModelManagerSupportClang::unregisterTranslationUnitsWithProjectParts(
@@ -398,6 +464,12 @@ QString ModelManagerSupportClang::dummyUiHeaderOnDiskPath(const QString &filePat
return m_uiHeaderOnDiskManager.mapPath(filePath);
}
ClangProjectSettings &ModelManagerSupportClang::projectSettings(
ProjectExplorer::Project *project) const
{
return *m_projectSettings.value(project);
}
QString ModelManagerSupportClang::dummyUiHeaderOnDiskDirPath() const
{
return m_uiHeaderOnDiskManager.directoryPath();

View File

@@ -40,7 +40,10 @@ class QMenu;
class QWidget;
QT_END_NAMESPACE
namespace Core { class IDocument; }
namespace Core {
class IDocument;
class Id;
} // namespace Core
namespace TextEditor { class TextEditorWidget; }
namespace CppTools {
class FollowSymbolInterface;
@@ -50,6 +53,8 @@ class RefactoringEngineInterface;
namespace ClangCodeModel {
namespace Internal {
class ClangProjectSettings;
class ModelManagerSupportClang:
public QObject,
public CppTools::ModelManagerSupport
@@ -71,6 +76,8 @@ public:
QString dummyUiHeaderOnDiskDirPath() const;
QString dummyUiHeaderOnDiskPath(const QString &filePath) const;
ClangProjectSettings &projectSettings(ProjectExplorer::Project *project) const;
static ModelManagerSupportClang *instance();
private:
@@ -93,9 +100,14 @@ private:
int lineNumber,
QMenu *menu);
void onProjectAdded(ProjectExplorer::Project *project);
void onAboutToRemoveProject(ProjectExplorer::Project *project);
void onProjectPartsUpdated(ProjectExplorer::Project *project);
void onProjectPartsRemoved(const QStringList &projectPartIds);
void onDiagnosticConfigsInvalidated(const QVector<Core::Id> &configIds);
void unregisterTranslationUnitsWithProjectParts(const QStringList &projectPartIds);
void connectTextDocumentToTranslationUnit(TextEditor::TextDocument *textDocument);
@@ -111,6 +123,8 @@ private:
ClangCompletionAssistProvider m_completionAssistProvider;
std::unique_ptr<CppTools::FollowSymbolInterface> m_followSymbol;
std::unique_ptr<CppTools::RefactoringEngineInterface> m_refactoringEngine;
QHash<ProjectExplorer::Project *, ClangProjectSettings *> m_projectSettings;
};
class ModelManagerSupportProviderClang : public CppTools::ModelManagerSupportProvider

View File

@@ -42,6 +42,25 @@ static QString warningConfigIdKey()
static QString customCommandLineKey()
{ return QLatin1String("ClangCodeModel.CustomCommandLineKey"); }
static bool useGlobalConfigFromSettings(ProjectExplorer::Project *project)
{
const QVariant useGlobalConfigVariant = project->namedSettings(useGlobalConfigKey());
return useGlobalConfigVariant.isValid() ? useGlobalConfigVariant.toBool() : true;
}
static Core::Id warningConfigIdFromSettings(ProjectExplorer::Project *project)
{
return Core::Id::fromSetting(project->namedSettings(warningConfigIdKey()));
}
static QStringList customCommandLineFromSettings(ProjectExplorer::Project *project)
{
QStringList options = project->namedSettings(customCommandLineKey()).toStringList();
if (options.empty())
options = ClangProjectSettings::globalCommandLineOptions();
return options;
}
ClangProjectSettings::ClangProjectSettings(ProjectExplorer::Project *project)
: m_project(project)
{
@@ -88,23 +107,27 @@ void ClangProjectSettings::setCommandLineOptions(const QStringList &options)
void ClangProjectSettings::load()
{
const QVariant useGlobalConfigVariant = m_project->namedSettings(useGlobalConfigKey());
const bool useGlobalConfig = useGlobalConfigVariant.isValid()
? useGlobalConfigVariant.toBool()
: true;
setUseGlobalConfig(useGlobalConfig);
setWarningConfigId(Core::Id::fromSetting(m_project->namedSettings(warningConfigIdKey())));
m_customCommandLineOptions = m_project->namedSettings(customCommandLineKey()).toStringList();
if (m_customCommandLineOptions.empty())
m_customCommandLineOptions = globalCommandLineOptions();
setUseGlobalConfig(useGlobalConfigFromSettings(m_project));
setWarningConfigId(warningConfigIdFromSettings(m_project));
m_customCommandLineOptions = customCommandLineFromSettings(m_project);
}
void ClangProjectSettings::store()
{
bool settingsChanged = false;
if (useGlobalConfig() != useGlobalConfigFromSettings(m_project))
settingsChanged = true;
if (warningConfigId() != warningConfigIdFromSettings(m_project))
settingsChanged = true;
if (commandLineOptions() != customCommandLineFromSettings(m_project))
settingsChanged = true;
m_project->setNamedSettings(useGlobalConfigKey(), useGlobalConfig());
m_project->setNamedSettings(warningConfigIdKey(), warningConfigId().toSetting());
m_project->setNamedSettings(customCommandLineKey(), m_customCommandLineOptions);
if (settingsChanged)
emit changed();
}
QStringList ClangProjectSettings::globalCommandLineOptions()

View File

@@ -59,6 +59,9 @@ public:
static QStringList globalCommandLineOptions();
signals:
void changed();
private:
ProjectExplorer::Project *m_project;
bool m_useGlobalConfig = true;

View File

@@ -25,6 +25,7 @@
#include "clangprojectsettingswidget.h"
#include "clangmodelmanagersupport.h"
#include "clangprojectsettings.h"
#include <coreplugin/icore.h>
@@ -52,7 +53,7 @@ static Core::Id configIdForProject(ClangProjectSettings &projectSettings)
}
ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project *project)
: m_projectSettings(project)
: m_projectSettings(ModelManagerSupportClang::instance()->projectSettings(project))
{
m_ui.setupUi(this);
@@ -76,6 +77,8 @@ ClangProjectSettingsWidget::ClangProjectSettingsWidget(ProjectExplorer::Project
connect(m_ui.clangSettings,
static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged),
this, &ClangProjectSettingsWidget::onClangSettingsChanged);
connect(project, &ProjectExplorer::Project::aboutToSaveSettings,
this, &ClangProjectSettingsWidget::onAboutToSaveProjectSettings);
m_ui.diagnosticConfigurationGroupBox->layout()->addWidget(m_diagnosticConfigWidget);
}
@@ -86,7 +89,6 @@ void ClangProjectSettingsWidget::onCurrentWarningConfigChanged(const Core::Id &c
if (m_projectSettings.useGlobalConfig())
return;
m_projectSettings.setWarningConfigId(currentConfigId);
m_projectSettings.store();
}
void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
@@ -97,7 +99,6 @@ void ClangProjectSettingsWidget::onCustomWarningConfigsChanged(
const QSharedPointer<CppTools::CppCodeModelSettings> codeModelSettings
= CppTools::codeModelSettings();
codeModelSettings->setClangCustomDiagnosticConfigs(customConfigs);
codeModelSettings->toSettings(Core::ICore::settings());
connectToCppCodeModelSettingsChanged();
}
@@ -115,16 +116,19 @@ void ClangProjectSettingsWidget::onDelayedTemplateParseClicked(bool checked)
options.removeAll(QLatin1String{ClangProjectSettings::NoDelayedTemplateParsing});
options.append(extraFlag);
m_projectSettings.setCommandLineOptions(options);
m_projectSettings.store();
}
void ClangProjectSettingsWidget::onClangSettingsChanged(int index)
{
m_projectSettings.setUseGlobalConfig(index == 0 ? true : false);
m_projectSettings.store();
syncOtherWidgetsToComboBox();
}
void ClangProjectSettingsWidget::onAboutToSaveProjectSettings()
{
CppTools::codeModelSettings()->toSettings(Core::ICore::settings());
}
void ClangProjectSettingsWidget::syncOtherWidgetsToComboBox()
{
const QStringList options = m_projectSettings.commandLineOptions();

View File

@@ -51,6 +51,7 @@ private:
void onCustomWarningConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
void onDelayedTemplateParseClicked(bool);
void onClangSettingsChanged(int index);
void onAboutToSaveProjectSettings();
void refreshDiagnosticConfigsWidgetFromSettings();
void connectToCppCodeModelSettingsChanged();
void disconnectFromCppCodeModelSettingsChanged();
@@ -58,7 +59,7 @@ private:
private:
Ui::ClangProjectSettingsWidget m_ui;
ClangProjectSettings m_projectSettings;
ClangProjectSettings &m_projectSettings;
QPointer<CppTools::ClangDiagnosticConfigsWidget> m_diagnosticConfigWidget;
};

View File

@@ -190,31 +190,5 @@ void setLastSentDocumentRevision(const QString &filePath, uint revision)
document->sendTracker().setLastSentRevision(int(revision));
}
// CLANG-UPGRADE-CHECK: Workaround still needed?
// Remove once clang reports correct columns for lines with multi-byte utf8.
int extraUtf8CharsShift(const QString &str, int column)
{
int shift = 0;
const QByteArray byteArray = str.toUtf8();
for (int i = 0; i < qMin(str.length(), column); ++i) {
const uchar firstByte = static_cast<uchar>(byteArray.at(i));
// Skip different amount of bytes depending on value
if (firstByte < 0xC0) {
continue;
} else if (firstByte < 0xE0) {
++shift;
++i;
} else if (firstByte < 0xF0) {
shift += 2;
i += 2;
} else {
shift += 3;
i += 3;
}
}
return shift;
}
} // namespace Utils
} // namespace Clang

View File

@@ -47,7 +47,5 @@ CppTools::ProjectPart::Ptr projectPartForFileBasedOnProcessor(const QString &fil
bool isProjectPartLoaded(const CppTools::ProjectPart::Ptr projectPart);
QString projectPartIdForFile(const QString &filePath);
int extraUtf8CharsShift(const QString &str, int column);
} // namespace Utils
} // namespace Clang

View File

@@ -460,7 +460,6 @@ int ServerModeReader::calculateProgress(const int minRange, const int min, const
void ServerModeReader::extractCodeModelData(const QVariantMap &data)
{
const QVariantList configs = data.value("configurations").toList();
QTC_CHECK(configs.count() == 1); // FIXME: Support several configurations!
for (const QVariant &c : configs) {
const QVariantMap &cData = c.toMap();
extractConfigurationData(cData);
@@ -842,6 +841,11 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot,
{
QList<FileNode *> toList;
QSet<Utils::FileName> alreadyListed;
// Files already added by other configurations:
targetRoot->forEachGenericNode([&alreadyListed](const Node *n) {
alreadyListed.insert(n->filePath());
});
for (const FileGroup *f : fileGroups) {
const QList<FileName> newSources = Utils::filtered(f->sources, [&alreadyListed](const Utils::FileName &fn) {
const int count = alreadyListed.count();

View File

@@ -93,6 +93,8 @@ public:
virtual QFuture<SymbolInfo> requestFollowSymbol(int line, int column) = 0;
virtual QFuture<ToolTipInfo> toolTipInfo(const QByteArray &codecName, int line, int column);
QString filePath() const { return m_filePath; }
public:
using HeaderErrorDiagnosticWidgetCreator = std::function<QWidget*()>;
@@ -117,7 +119,6 @@ protected:
BaseEditorDocumentParser::UpdateParams updateParams);
// Convenience
QString filePath() const { return m_filePath; }
unsigned revision() const { return static_cast<unsigned>(m_textDocument->revision()); }
QTextDocument *textDocument() const { return m_textDocument; }

View File

@@ -47,14 +47,14 @@ void ClangDiagnosticConfig::setDisplayName(const QString &displayName)
m_displayName = displayName;
}
QStringList ClangDiagnosticConfig::commandLineWarnings() const
QStringList ClangDiagnosticConfig::clangOptions() const
{
return m_commandLineWarnings;
return m_clangOptions;
}
void ClangDiagnosticConfig::setCommandLineWarnings(const QStringList &warnings)
void ClangDiagnosticConfig::setClangOptions(const QStringList &options)
{
m_commandLineWarnings = warnings;
m_clangOptions = options;
}
bool ClangDiagnosticConfig::isReadOnly() const
@@ -71,8 +71,35 @@ bool ClangDiagnosticConfig::operator==(const ClangDiagnosticConfig &other) const
{
return m_id == other.m_id
&& m_displayName == other.m_displayName
&& m_commandLineWarnings == other.m_commandLineWarnings
&& m_clangOptions == other.m_clangOptions
&& m_clangTidyChecks == other.m_clangTidyChecks
&& m_clazyChecks == other.m_clazyChecks
&& m_isReadOnly == other.m_isReadOnly;
}
bool ClangDiagnosticConfig::operator!=(const ClangDiagnosticConfig &other) const
{
return !(*this == other);
}
QString ClangDiagnosticConfig::clangTidyChecks() const
{
return m_clangTidyChecks;
}
void ClangDiagnosticConfig::setClangTidyChecks(const QString &checks)
{
m_clangTidyChecks = checks;
}
QString ClangDiagnosticConfig::clazyChecks() const
{
return m_clazyChecks;
}
void ClangDiagnosticConfig::setClazyChecks(const QString &checks)
{
m_clazyChecks = checks;
}
} // namespace CppTools

View File

@@ -43,18 +43,27 @@ public:
QString displayName() const;
void setDisplayName(const QString &displayName);
QStringList commandLineWarnings() const;
void setCommandLineWarnings(const QStringList &commandLineWarnings);
QStringList clangOptions() const;
void setClangOptions(const QStringList &options);
QString clangTidyChecks() const;
void setClangTidyChecks(const QString &checks);
QString clazyChecks() const;
void setClazyChecks(const QString &checks);
bool isReadOnly() const;
void setIsReadOnly(bool isReadOnly);
bool operator==(const ClangDiagnosticConfig &other) const;
bool operator!=(const ClangDiagnosticConfig &other) const;
private:
Core::Id m_id;
QString m_displayName;
QStringList m_commandLineWarnings;
QStringList m_clangOptions;
QString m_clangTidyChecks;
QString m_clazyChecks;
bool m_isReadOnly = false;
};

View File

@@ -45,7 +45,7 @@ static void addConfigForQuestionableConstructs(ClangDiagnosticConfigsModel &mode
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Warnings for questionable constructs"));
config.setIsReadOnly(true);
config.setCommandLineWarnings(QStringList{
config.setClangOptions(QStringList{
QStringLiteral("-Wall"),
QStringLiteral("-Wextra"),
} + commonWarnings());
@@ -60,7 +60,7 @@ static void addConfigForPedanticWarnings(ClangDiagnosticConfigsModel &model)
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Pedantic Warnings"));
config.setIsReadOnly(true);
config.setCommandLineWarnings(QStringList{QStringLiteral("-Wpedantic")} + commonWarnings());
config.setClangOptions(QStringList{QStringLiteral("-Wpedantic")} + commonWarnings());
model.appendOrUpdate(config);
}
@@ -72,7 +72,7 @@ static void addConfigForAlmostEveryWarning(ClangDiagnosticConfigsModel &model)
config.setDisplayName(QCoreApplication::translate("ClangDiagnosticConfigsModel",
"Warnings for almost everything"));
config.setIsReadOnly(true);
config.setCommandLineWarnings(QStringList{
config.setClangOptions(QStringList{
QStringLiteral("-Weverything"),
QStringLiteral("-Wno-c++98-compat"),
QStringLiteral("-Wno-c++98-compat-pedantic"),
@@ -158,6 +158,23 @@ ClangDiagnosticConfigsModel::displayNameWithBuiltinIndication(const ClangDiagnos
: config.displayName();
}
QVector<Core::Id> ClangDiagnosticConfigsModel::changedOrRemovedConfigs(
const ClangDiagnosticConfigs &oldConfigs, const ClangDiagnosticConfigs &newConfigs)
{
ClangDiagnosticConfigsModel newConfigsModel(newConfigs);
QVector<Core::Id> changedConfigs;
for (const ClangDiagnosticConfig &old: oldConfigs) {
const int i = newConfigsModel.indexOfConfig(old.id());
if (i == -1)
changedConfigs.append(old.id()); // Removed
else if (newConfigsModel.configs()[i] != old)
changedConfigs.append(old.id()); // Changed
}
return changedConfigs;
}
int ClangDiagnosticConfigsModel::indexOfConfig(const Core::Id &id) const
{
return Utils::indexOf(m_diagnosticConfigs, [&](const ClangDiagnosticConfig &config) {

View File

@@ -29,6 +29,8 @@
#include "clangdiagnosticconfig.h"
#include <QVector>
namespace CppTools {
class CPPTOOLS_EXPORT ClangDiagnosticConfigsModel
@@ -47,11 +49,11 @@ public:
ClangDiagnosticConfigs configs() const;
bool hasConfigWithId(const Core::Id &id) const;
const ClangDiagnosticConfig &configWithId(const Core::Id &id) const;
int indexOfConfig(const Core::Id &id) const;
static QString displayNameWithBuiltinIndication(const ClangDiagnosticConfig &config);
private:
int indexOfConfig(const Core::Id &id) const;
static QVector<Core::Id> changedOrRemovedConfigs(const ClangDiagnosticConfigs &oldConfigs,
const ClangDiagnosticConfigs &newConfigs);
private:
ClangDiagnosticConfigs m_diagnosticConfigs;

View File

@@ -25,6 +25,8 @@
#include "clangdiagnosticconfigswidget.h"
#include "ui_clangdiagnosticconfigswidget.h"
#include "ui_clazychecks.h"
#include "ui_tidychecks.h"
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -45,6 +47,7 @@ ClangDiagnosticConfigsWidget::ClangDiagnosticConfigsWidget(
, m_diagnosticConfigsModel(diagnosticConfigsModel)
{
m_ui->setupUi(this);
setupPluginsWidgets();
connectConfigChooserCurrentIndex();
connect(m_ui->copyButton, &QPushButton::clicked,
@@ -108,6 +111,18 @@ void ClangDiagnosticConfigsWidget::onRemoveButtonClicked()
syncConfigChooserToModel();
}
void ClangDiagnosticConfigsWidget::onClangTidyItemChanged(QListWidgetItem *item)
{
const QString prefix = item->text();
ClangDiagnosticConfig config = currentConfig();
QString checks = config.clangTidyChecks();
item->checkState() == Qt::Checked
? checks.append(',' + prefix)
: checks.remove(',' + prefix);
config.setClangTidyChecks(checks);
updateConfig(config);
}
static bool isAcceptedWarningOption(const QString &option)
{
return option == "-w"
@@ -162,10 +177,8 @@ void ClangDiagnosticConfigsWidget::onDiagnosticOptionsEdited()
// Commit valid changes
ClangDiagnosticConfig updatedConfig = currentConfig();
updatedConfig.setCommandLineWarnings(normalizedOptions);
m_diagnosticConfigsModel.appendOrUpdate(updatedConfig);
emit customConfigsChanged(customConfigs());
updatedConfig.setClangOptions(normalizedOptions);
updateConfig(updatedConfig);
}
void ClangDiagnosticConfigsWidget::syncWidgetsToModel(const Core::Id &configToSelect)
@@ -213,12 +226,74 @@ void ClangDiagnosticConfigsWidget::syncOtherWidgetsToComboBox()
// Update main button row
m_ui->removeButton->setEnabled(!config.isReadOnly());
// Update child widgets
// Update Text Edit
const QString options = m_notAcceptedOptions.contains(config.id())
? m_notAcceptedOptions.value(config.id())
: config.commandLineWarnings().join(QLatin1Char(' '));
: config.clangOptions().join(QLatin1Char(' '));
setDiagnosticOptions(options);
m_ui->diagnosticOptionsTextEdit->setReadOnly(config.isReadOnly());
syncClangTidyWidgets(config);
syncClazyWidgets(config);
}
void ClangDiagnosticConfigsWidget::syncClangTidyWidgets(const ClangDiagnosticConfig &config)
{
disconnectClangTidyItemChanged();
const QString tidyChecks = config.clangTidyChecks();
for (int row = 0; row < m_tidyChecks->checksList->count(); ++row) {
QListWidgetItem *item = m_tidyChecks->checksList->item(row);
Qt::ItemFlags flags = item->flags();
flags |= Qt::ItemIsUserCheckable;
if (config.isReadOnly())
flags &= ~Qt::ItemIsEnabled;
else
flags |= Qt::ItemIsEnabled;
item->setFlags(flags);
if (tidyChecks.indexOf(item->text()) != -1)
item->setCheckState(Qt::Checked);
else
item->setCheckState(Qt::Unchecked);
}
connectClangTidyItemChanged();
}
void ClangDiagnosticConfigsWidget::syncClazyWidgets(const ClangDiagnosticConfig &config)
{
const QString clazyChecks = config.clazyChecks();
if (clazyChecks.isEmpty())
m_clazyChecks->clazyLevel->setCurrentIndex(0);
else
m_clazyChecks->clazyLevel->setCurrentText(clazyChecks);
m_clazyChecksWidget->setEnabled(!config.isReadOnly());
}
void ClangDiagnosticConfigsWidget::setClazyLevelDescription(int index)
{
// Levels descriptions are taken from https://github.com/KDE/clazy
static const QString levelDescriptions[] {
QString(),
tr("Very stable checks, 99.99% safe, no false-positives."),
tr("Similar to level 0, but sometimes (rarely) there might be\n"
"some false-positives."),
tr("Sometimes has false-positives (20-30%)."),
tr("Not always correct, possibly very noisy, might require\n"
"a knowledgeable developer to review, might have a very big\n"
"rate of false-positives, might have bugs.")
};
QTC_ASSERT(m_clazyChecks, return);
m_clazyChecks->levelDescription->setText(levelDescriptions[static_cast<unsigned>(index)]);
}
void ClangDiagnosticConfigsWidget::updateConfig(const ClangDiagnosticConfig &config)
{
m_diagnosticConfigsModel.appendOrUpdate(config);
emit customConfigsChanged(customConfigs());
}
bool ClangDiagnosticConfigsWidget::isConfigChooserEmpty() const
@@ -264,6 +339,18 @@ void ClangDiagnosticConfigsWidget::updateValidityWidgets(const QString &errorMes
m_ui->validationResultLabel->setStyleSheet(styleSheet);
}
void ClangDiagnosticConfigsWidget::connectClangTidyItemChanged()
{
connect(m_tidyChecks->checksList, &QListWidget::itemChanged,
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
}
void ClangDiagnosticConfigsWidget::disconnectClangTidyItemChanged()
{
disconnect(m_tidyChecks->checksList, &QListWidget::itemChanged,
this, &ClangDiagnosticConfigsWidget::onClangTidyItemChanged);
}
void ClangDiagnosticConfigsWidget::connectConfigChooserCurrentIndex()
{
connect(m_ui->configChooserComboBox,
@@ -314,4 +401,31 @@ void ClangDiagnosticConfigsWidget::refresh(
syncWidgetsToModel(configToSelect);
}
void ClangDiagnosticConfigsWidget::setupPluginsWidgets()
{
m_clazyChecks.reset(new CppTools::Ui::ClazyChecks);
m_clazyChecksWidget = new QWidget();
m_clazyChecks->setupUi(m_clazyChecksWidget);
connect(m_clazyChecks->clazyLevel,
static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged),
[this](int index) {
setClazyLevelDescription(index);
ClangDiagnosticConfig config = currentConfig();
if (index == 0)
config.setClazyChecks(QString());
else
config.setClazyChecks(m_clazyChecks->clazyLevel->itemText(index));
updateConfig(config);
});
m_tidyChecks.reset(new CppTools::Ui::TidyChecks);
m_tidyChecksWidget = new QWidget();
m_tidyChecks->setupUi(m_tidyChecksWidget);
connectClangTidyItemChanged();
m_ui->pluginChecksTabs->addTab(m_tidyChecksWidget, tr("Clang-Tidy"));
m_ui->pluginChecksTabs->addTab(m_clazyChecksWidget, tr("Clazy"));
m_ui->pluginChecksTabs->setCurrentIndex(0);
}
} // CppTools namespace

View File

@@ -33,9 +33,17 @@
#include <QHash>
#include <QWidget>
#include <memory>
QT_FORWARD_DECLARE_CLASS(QListWidgetItem)
namespace CppTools {
namespace Ui { class ClangDiagnosticConfigsWidget; }
namespace Ui {
class ClangDiagnosticConfigsWidget;
class ClazyChecks;
class TidyChecks;
}
class CPPTOOLS_EXPORT ClangDiagnosticConfigsWidget : public QWidget
{
@@ -59,15 +67,23 @@ signals:
void customConfigsChanged(const CppTools::ClangDiagnosticConfigs &customConfigs);
private:
void setupPluginsWidgets();
void onCurrentConfigChanged(int);
void onCopyButtonClicked();
void onRemoveButtonClicked();
void onClangTidyItemChanged(QListWidgetItem *item);
void onDiagnosticOptionsEdited();
void syncWidgetsToModel(const Core::Id &configToSelect = Core::Id());
void syncConfigChooserToModel(const Core::Id &configToSelect = Core::Id());
void syncOtherWidgetsToComboBox();
void syncClangTidyWidgets(const ClangDiagnosticConfig &config);
void syncClazyWidgets(const ClangDiagnosticConfig &config);
void setClazyLevelDescription(int index);
void updateConfig(const CppTools::ClangDiagnosticConfig &config);
bool isConfigChooserEmpty() const;
const ClangDiagnosticConfig &currentConfig() const;
@@ -75,6 +91,9 @@ private:
void setDiagnosticOptions(const QString &options);
void updateValidityWidgets(const QString &errorMessage);
void connectClangTidyItemChanged();
void disconnectClangTidyItemChanged();
void connectConfigChooserCurrentIndex();
void disconnectConfigChooserCurrentIndex();
void connectDiagnosticOptionsChanged();
@@ -84,6 +103,12 @@ private:
Ui::ClangDiagnosticConfigsWidget *m_ui;
ClangDiagnosticConfigsModel m_diagnosticConfigsModel;
QHash<Core::Id, QString> m_notAcceptedOptions;
std::unique_ptr<CppTools::Ui::ClazyChecks> m_clazyChecks;
QWidget *m_clazyChecksWidget = nullptr;
std::unique_ptr<CppTools::Ui::TidyChecks> m_tidyChecks;
QWidget *m_tidyChecksWidget = nullptr;
};
} // CppTools namespace

View File

@@ -93,6 +93,9 @@
</property>
</widget>
</item>
<item>
<widget class="QTabWidget" name="pluginChecksTabs"/>
</item>
</layout>
</widget>
<customwidgets>

View File

@@ -27,8 +27,10 @@
#include <coreplugin/icore.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorerconstants.h>
#include <utils/fileutils.h>
#include <utils/qtcassert.h>
#include <utils/qtcfallthrough.h>
@@ -37,6 +39,8 @@
namespace CppTools {
static constexpr char SYSTEM_INCLUDE_PREFIX[] = "-isystem";
CompilerOptionsBuilder::CompilerOptionsBuilder(const ProjectPart &projectPart,
const QString &clangVersion,
const QString &clangResourceDirectory)
@@ -119,10 +123,23 @@ void CompilerOptionsBuilder::enableExceptions()
add(QLatin1String("-fexceptions"));
}
static Utils::FileName absoluteDirectory(const QString &filePath)
{
return Utils::FileName::fromString(QFileInfo(filePath + '/').absolutePath());
}
static Utils::FileName projectTopLevelDirectory(const ProjectPart &projectPart)
{
if (!projectPart.project)
return Utils::FileName();
return projectPart.project->projectDirectory();
}
void CompilerOptionsBuilder::addHeaderPathOptions()
{
typedef ProjectPartHeaderPath HeaderPath;
const QString defaultPrefix = includeDirOption();
const Utils::FileName projectDirectory = projectTopLevelDirectory(m_projectPart);
QStringList result;
@@ -134,6 +151,7 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
continue;
QString prefix;
Utils::FileName path;
switch (headerPath.type) {
case HeaderPath::FrameworkPath:
prefix = QLatin1String("-F");
@@ -141,7 +159,11 @@ void CompilerOptionsBuilder::addHeaderPathOptions()
default: // This shouldn't happen, but let's be nice..:
// intentional fall-through:
case HeaderPath::IncludePath:
prefix = defaultPrefix;
path = absoluteDirectory(headerPath.path);
if (path == projectDirectory || path.isChildOf(projectDirectory))
prefix = defaultPrefix;
else
prefix = SYSTEM_INCLUDE_PREFIX;
break;
}
@@ -409,7 +431,7 @@ void CompilerOptionsBuilder::addDefineFunctionMacrosMsvc()
QString CompilerOptionsBuilder::includeDirOption() const
{
return QLatin1String("-isystem");
return QLatin1String("-I");
}
QByteArray CompilerOptionsBuilder::macroOption(const ProjectExplorer::Macro &macro) const
@@ -506,7 +528,7 @@ void CompilerOptionsBuilder::addPredefinedHeaderPathsOptions()
void CompilerOptionsBuilder::addClangIncludeFolder()
{
QTC_CHECK(!m_clangVersion.isEmpty());
add(includeDirOption());
add(SYSTEM_INCLUDE_PREFIX);
add(clangIncludeDirectory());
}

View File

@@ -55,6 +55,12 @@ static QString clangDiagnosticConfigsArrayDisplayNameKey()
static QString clangDiagnosticConfigsArrayWarningsKey()
{ return QLatin1String("diagnosticOptions"); }
static QString clangDiagnosticConfigsArrayClangTidyChecksKey()
{ return QLatin1String("clangTidyChecks"); }
static QString clangDiagnosticConfigsArrayClazyChecksKey()
{ return QLatin1String("clazyChecks"); }
static QString pchUsageKey()
{ return QLatin1String(Constants::CPPTOOLS_MODEL_MANAGER_PCH_USAGE); }
@@ -67,15 +73,12 @@ static QString skipIndexingBigFilesKey()
static QString indexerFileSizeLimitKey()
{ return QLatin1String(Constants::CPPTOOLS_INDEXER_FILE_SIZE_LIMIT); }
static QString tidyChecksKey()
{ return QLatin1String(Constants::CPPTOOLS_TIDY_CHECKS); }
static QString clazyChecksKey()
{ return QLatin1String(Constants::CPPTOOLS_CLAZY_CHECKS); }
void CppCodeModelSettings::fromSettings(QSettings *s)
static ClangDiagnosticConfigs customDiagnosticConfigsFromSettings(QSettings *s)
{
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
QTC_ASSERT(s->group() == QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP),
return ClangDiagnosticConfigs());
ClangDiagnosticConfigs configs;
const int size = s->beginReadArray(clangDiagnosticConfigsArrayKey());
for (int i = 0; i < size; ++i) {
@@ -84,15 +87,30 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
ClangDiagnosticConfig config;
config.setId(Core::Id::fromSetting(s->value(clangDiagnosticConfigsArrayIdKey())));
config.setDisplayName(s->value(clangDiagnosticConfigsArrayDisplayNameKey()).toString());
config.setCommandLineWarnings(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList());
m_clangCustomDiagnosticConfigs.append(config);
config.setClangOptions(s->value(clangDiagnosticConfigsArrayWarningsKey()).toStringList());
config.setClangTidyChecks(s->value(clangDiagnosticConfigsArrayClangTidyChecksKey()).toString());
config.setClazyChecks(s->value(clangDiagnosticConfigsArrayClazyChecksKey()).toString());
configs.append(config);
}
s->endArray();
const Core::Id diagnosticConfigId = Core::Id::fromSetting(
s->value(clangDiagnosticConfigKey(),
initialClangDiagnosticConfigId().toSetting()));
setClangDiagnosticConfigId(diagnosticConfigId);
return configs;
}
static Core::Id clangDiagnosticConfigIdFromSettings(QSettings *s)
{
QTC_ASSERT(s->group() == QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP), return Core::Id());
return Core::Id::fromSetting(
s->value(clangDiagnosticConfigKey(), initialClangDiagnosticConfigId().toSetting()));
}
void CppCodeModelSettings::fromSettings(QSettings *s)
{
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
setClangCustomDiagnosticConfigs(customDiagnosticConfigsFromSettings(s));
setClangDiagnosticConfigId(clangDiagnosticConfigIdFromSettings(s));
const QVariant pchUsageVariant = s->value(pchUsageKey(), initialPchUsage());
setPCHUsage(static_cast<PCHUsage>(pchUsageVariant.toInt()));
@@ -107,11 +125,6 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
const QVariant indexerFileSizeLimit = s->value(indexerFileSizeLimitKey(), 5);
setIndexerFileSizeLimitInMb(indexerFileSizeLimit.toInt());
const QVariant tidyChecks = s->value(tidyChecksKey(), QString());
setTidyChecks(tidyChecks.toString());
const QVariant clazyChecks = s->value(clazyChecksKey(), QString());
setClazyChecks(clazyChecks.toString());
s->endGroup();
emit changed();
@@ -120,6 +133,8 @@ void CppCodeModelSettings::fromSettings(QSettings *s)
void CppCodeModelSettings::toSettings(QSettings *s)
{
s->beginGroup(QLatin1String(Constants::CPPTOOLS_SETTINGSGROUP));
const ClangDiagnosticConfigs previousConfigs = customDiagnosticConfigsFromSettings(s);
const Core::Id previousConfigId = clangDiagnosticConfigIdFromSettings(s);
s->beginWriteArray(clangDiagnosticConfigsArrayKey());
for (int i = 0, size = m_clangCustomDiagnosticConfigs.size(); i < size; ++i) {
@@ -128,7 +143,9 @@ void CppCodeModelSettings::toSettings(QSettings *s)
s->setArrayIndex(i);
s->setValue(clangDiagnosticConfigsArrayIdKey(), config.id().toSetting());
s->setValue(clangDiagnosticConfigsArrayDisplayNameKey(), config.displayName());
s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.commandLineWarnings());
s->setValue(clangDiagnosticConfigsArrayWarningsKey(), config.clangOptions());
s->setValue(clangDiagnosticConfigsArrayClangTidyChecksKey(), config.clangTidyChecks());
s->setValue(clangDiagnosticConfigsArrayClazyChecksKey(), config.clazyChecks());
}
s->endArray();
@@ -138,11 +155,18 @@ void CppCodeModelSettings::toSettings(QSettings *s)
s->setValue(interpretAmbiguousHeadersAsCHeadersKey(), interpretAmbigiousHeadersAsCHeaders());
s->setValue(skipIndexingBigFilesKey(), skipIndexingBigFiles());
s->setValue(indexerFileSizeLimitKey(), indexerFileSizeLimitInMb());
s->setValue(tidyChecksKey(), tidyChecks());
s->setValue(clazyChecksKey(), clazyChecks());
s->endGroup();
QVector<Core::Id> invalidated
= ClangDiagnosticConfigsModel::changedOrRemovedConfigs(previousConfigs,
m_clangCustomDiagnosticConfigs);
if (previousConfigId != clangDiagnosticConfigId() && !invalidated.contains(previousConfigId))
invalidated.append(previousConfigId);
if (!invalidated.isEmpty())
emit clangDiagnosticConfigsInvalidated(invalidated);
emit changed();
}
@@ -212,23 +236,3 @@ void CppCodeModelSettings::setIndexerFileSizeLimitInMb(int sizeInMB)
{
m_indexerFileSizeLimitInMB = sizeInMB;
}
QString CppCodeModelSettings::tidyChecks() const
{
return m_tidyChecks;
}
void CppCodeModelSettings::setTidyChecks(QString checks)
{
m_tidyChecks = checks;
}
QString CppCodeModelSettings::clazyChecks() const
{
return m_clazyChecks;
}
void CppCodeModelSettings::setClazyChecks(QString checks)
{
m_clazyChecks = checks;
}

View File

@@ -72,13 +72,8 @@ public:
int indexerFileSizeLimitInMb() const;
void setIndexerFileSizeLimitInMb(int sizeInMB);
QString tidyChecks() const;
void setTidyChecks(QString checks);
QString clazyChecks() const;
void setClazyChecks(QString checks);
signals:
void clangDiagnosticConfigsInvalidated(const QVector<Core::Id> &configId);
void changed();
private:
@@ -88,9 +83,6 @@ private:
int m_indexerFileSizeLimitInMB = 5;
ClangDiagnosticConfigs m_clangCustomDiagnosticConfigs;
Core::Id m_clangDiagnosticConfigId;
QString m_tidyChecks;
QString m_clazyChecks;
};
} // namespace CppTools

View File

@@ -29,8 +29,6 @@
#include "cppmodelmanager.h"
#include "cpptoolsconstants.h"
#include "ui_cppcodemodelsettingspage.h"
#include "ui_clazychecks.h"
#include "ui_tidychecks.h"
#include <coreplugin/icore.h>
#include <utils/algorithm.h>
@@ -86,79 +84,6 @@ void CppCodeModelSettingsWidget::setupClangCodeModelWidgets()
diagnosticConfigsModel,
m_settings->clangDiagnosticConfigId());
m_ui->clangSettingsGroupBox->layout()->addWidget(m_clangDiagnosticConfigsWidget);
m_ui->clangPlugins->setEnabled(isClangActive);
setupPluginsWidgets();
}
void CppCodeModelSettingsWidget::setupPluginsWidgets()
{
m_clazyChecks.reset(new CppTools::Ui::ClazyChecks);
m_clazyChecksWidget = new QWidget();
m_clazyChecks->setupUi(m_clazyChecksWidget);
m_tidyChecks.reset(new CppTools::Ui::TidyChecks);
m_tidyChecksWidget = new QWidget();
m_tidyChecks->setupUi(m_tidyChecksWidget);
m_ui->pluginChecks->addTab(m_tidyChecksWidget, tr("ClangTidy"));
m_ui->pluginChecks->addTab(m_clazyChecksWidget, tr("Clazy"));
m_ui->pluginChecks->setCurrentIndex(0);
setupTidyChecks();
setupClazyChecks();
}
void CppCodeModelSettingsWidget::setupTidyChecks()
{
m_currentTidyChecks = m_settings->tidyChecks();
for (int row = 0; row < m_tidyChecks->checksList->count(); ++row) {
QListWidgetItem *item = m_tidyChecks->checksList->item(row);
item->setFlags(item->flags() | Qt::ItemIsUserCheckable);
if (m_currentTidyChecks.indexOf(item->text()) != -1)
item->setCheckState(Qt::Checked);
else
item->setCheckState(Qt::Unchecked);
}
connect(m_tidyChecks->checksList, &QListWidget::itemChanged, [this](QListWidgetItem *item) {
const QString prefix = item->text();
item->checkState() == Qt::Checked
? m_currentTidyChecks.append(',' + prefix)
: m_currentTidyChecks.remove(',' + prefix);
});
}
void CppCodeModelSettingsWidget::setupClazyChecks()
{
// Levels descriptions are taken from https://github.com/KDE/clazy
static const std::array<QString, 5> levelDescriptions {{
QString(),
tr("Very stable checks, 99.99% safe, no false-positives."),
tr("Similar to level0, but sometimes (rarely) there might be\n"
"some false-positives."),
tr("Sometimes has false-positives (20-30%)."),
tr("Not always correct, possibly very noisy, might require\n"
"a knowledgeable developer to review, might have a very big\n"
"rate of false-positives, might have bugs.")
}};
m_currentClazyChecks = m_settings->clazyChecks();
if (!m_currentClazyChecks.isEmpty()) {
m_clazyChecks->clazyLevel->setCurrentText(m_currentClazyChecks);
const unsigned index = static_cast<unsigned>(m_clazyChecks->clazyLevel->currentIndex());
m_clazyChecks->levelDescription->setText(levelDescriptions[index]);
}
connect(m_clazyChecks->clazyLevel,
static_cast<void (QComboBox::*)(int index)>(&QComboBox::currentIndexChanged),
[this](int index) {
m_clazyChecks->levelDescription->setText(levelDescriptions[static_cast<unsigned>(index)]);
if (index == 0) {
m_currentClazyChecks.clear();
return;
}
m_currentClazyChecks = m_clazyChecks->clazyLevel->itemText(index);
});
}
void CppCodeModelSettingsWidget::setupGeneralWidgets()
@@ -192,16 +117,6 @@ bool CppCodeModelSettingsWidget::applyClangCodeModelWidgetsToSettings() const
settingsChanged = true;
}
if (m_settings->tidyChecks() != m_currentTidyChecks) {
m_settings->setTidyChecks(m_currentTidyChecks);
settingsChanged = true;
}
if (m_settings->clazyChecks() != m_currentClazyChecks) {
m_settings->setClazyChecks(m_currentClazyChecks);
settingsChanged = true;
}
return settingsChanged;
}

View File

@@ -32,8 +32,6 @@
#include <QPointer>
#include <QWidget>
#include <memory>
QT_FORWARD_DECLARE_CLASS(QComboBox)
QT_FORWARD_DECLARE_CLASS(QSettings)
@@ -41,11 +39,6 @@ namespace CppTools {
class ClangDiagnosticConfigsWidget;
namespace Ui {
class ClazyChecks;
class TidyChecks;
} // namespace Ui
namespace Internal {
namespace Ui { class CppCodeModelSettingsPage; }
@@ -64,9 +57,6 @@ public:
private:
void setupGeneralWidgets();
void setupClangCodeModelWidgets();
void setupPluginsWidgets();
void setupTidyChecks();
void setupClazyChecks();
bool applyGeneralWidgetsToSettings() const;
bool applyClangCodeModelWidgetsToSettings() const;
@@ -75,14 +65,6 @@ private:
Ui::CppCodeModelSettingsPage *m_ui = nullptr;
QPointer<ClangDiagnosticConfigsWidget> m_clangDiagnosticConfigsWidget;
QSharedPointer<CppCodeModelSettings> m_settings;
std::unique_ptr<CppTools::Ui::ClazyChecks> m_clazyChecks;
QWidget *m_clazyChecksWidget = nullptr;
QString m_currentClazyChecks;
std::unique_ptr<CppTools::Ui::TidyChecks> m_tidyChecks;
QWidget *m_tidyChecksWidget = nullptr;
QString m_currentTidyChecks;
};
class CppCodeModelSettingsPage: public Core::IOptionsPage

View File

@@ -114,18 +114,6 @@
<layout class="QVBoxLayout" name="verticalLayout_3"/>
</widget>
</item>
<item>
<widget class="QGroupBox" name="clangPlugins">
<property name="title">
<string>Clang Plugins</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
<widget class="QTabWidget" name="pluginChecks"/>
</item>
</layout>
</widget>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">

View File

@@ -56,8 +56,6 @@ const char CPPTOOLS_INTERPRET_AMBIGIUOUS_HEADERS_AS_C_HEADERS[]
= "InterpretAmbiguousHeadersAsCHeaders";
const char CPPTOOLS_SKIP_INDEXING_BIG_FILES[] = "SkipIndexingBigFiles";
const char CPPTOOLS_INDEXER_FILE_SIZE_LIMIT[] = "IndexerFileSizeLimit";
const char CPPTOOLS_TIDY_CHECKS[] = "TidyChecks";
const char CPPTOOLS_CLAZY_CHECKS[] = "ClazyChecks";
const char CPP_CLANG_BUILTIN_CONFIG_ID_EVERYTHING_WITH_EXCEPTIONS[]
= "Builtin.EverythingWithExceptions";

View File

@@ -530,7 +530,7 @@ DebuggerSettings::DebuggerSettings()
insertItem(UseToolTipsInBreakpointsView, item);
item = new SavedAction(this);
item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInBreakpointsView"));
item->setSettingsKey(debugModeGroup, QLatin1String("UseToolTipsInStackView"));
item->setText(tr("Use Tooltips in Stack View when Debugging"));
item->setToolTip(tr("<p>Checking this will enable tooltips in the stack "
"view during debugging."));

View File

@@ -365,7 +365,13 @@ void DebuggerRunTool::setBreakOnMain(bool on)
void DebuggerRunTool::setUseTerminal(bool on)
{
if (on && !d->terminalRunner && m_runParameters.cppEngineType == GdbEngineType) {
// CDB has a built-in console that might be preferred by some.
bool useCdbConsole = m_runParameters.cppEngineType == CdbEngineType
&& (m_runParameters.startMode == StartInternal
|| m_runParameters.startMode == StartExternal)
&& boolSetting(UseCdbConsole);
if (on && !d->terminalRunner && !useCdbConsole) {
d->terminalRunner = new TerminalRunner(this);
addStartDependency(d->terminalRunner);
}
@@ -891,15 +897,6 @@ DebuggerRunTool::DebuggerRunTool(RunControl *runControl, Kit *kit, bool allowTer
m_engine = createPdbEngine();
}
}
if (m_runParameters.cppEngineType == CdbEngineType
&& !boolSetting(UseCdbConsole)
&& m_runParameters.inferior.runMode == ApplicationLauncher::Console
&& (m_runParameters.startMode == StartInternal
|| m_runParameters.startMode == StartExternal)) {
d->terminalRunner = new TerminalRunner(this);
addStartDependency(d->terminalRunner);
}
}
DebuggerEngine *DebuggerRunTool::activeEngine() const

View File

@@ -292,7 +292,6 @@ void LldbEngine::setupEngine()
.arg(bp.id().toString()).arg(bp.state()));
}
}
notifyEngineSetupOk();
} else {
notifyEngineSetupFailed();
}

View File

@@ -88,16 +88,9 @@ bool ModelEditorPlugin::initialize(const QStringList &arguments, QString *errorS
Q_UNUSED(errorString);
d->modelsManager = new ModelsManager(this);
addAutoReleasedObject(d->modelsManager);
d->uiController = new UiController(this);
addAutoReleasedObject(d->uiController);
d->modelFactory = new ModelEditorFactory(d->uiController, this);
addAutoReleasedObject(d->modelFactory);
d->settingsController = new SettingsController(this);
addAutoReleasedObject(d->settingsController);
Core::JsExpander::registerQObjectForJs(QLatin1String("Modeling"), new JsExtension(this));

View File

@@ -63,11 +63,9 @@ AndroidQmakeBuildConfiguration::AndroidQmakeBuildConfiguration(Target *target)
: QmakeBuildConfiguration(target)
{
updateCacheAndEmitEnvironmentChanged();
auto updateGradle = [this] { AndroidManager::updateGradleProperties(BuildConfiguration::target()); };
connect(target->project(), &Project::parsingFinished, this, updateGradle);
connect(this, &AndroidQmakeBuildConfiguration::enabledChanged, this, updateGradle);
connect(target->project(), &Project::parsingFinished, this, [this] {
AndroidManager::updateGradleProperties(BuildConfiguration::target());
});
}
void AndroidQmakeBuildConfiguration::initialize(const BuildInfo *info)

View File

@@ -64,6 +64,8 @@ QWidget *ChangeStyleWidgetAction::createWidget(QWidget *parent)
QComboBox *comboBox = new QComboBox(parent);
comboBox->setToolTip(tr(enabledTooltip));
comboBox->addItem("Default");
comboBox->addItem("Fusion");
comboBox->addItem("Imagine");
comboBox->addItem("Material");
comboBox->addItem("Universal");
comboBox->setEditable(true);

View File

@@ -164,6 +164,8 @@ const int priorityGoIntoComponent = 40;
const int priorityGenericToolBar = 50;
const int priorityLast = 60;
const char addImagesDisplayString[] = QT_TRANSLATE_NOOP("QmlDesignerAddResources", "Image Files");
} //ComponentCoreConstants
} //QmlDesigner

View File

@@ -178,6 +178,16 @@ void DesignerActionManager::setupContext()
m_designerActionManagerView->setupContext();
}
QList<AddResourceHandler> DesignerActionManager::addResourceHandler() const
{
return m_addResourceHandler;
}
void DesignerActionManager::registerAddResourceHandler(const AddResourceHandler &handler)
{
m_addResourceHandler.append(handler);
}
class VisiblityModelNodeAction : public ModelNodeContextMenuAction
{
public:
@@ -359,7 +369,7 @@ bool selectionHasSameParentAndInBaseState(const SelectionContext &context)
bool isNotInLayout(const SelectionContext &context)
{
if (selectionNotEmpty(context)) {
const ModelNode &selectedModelNode = context.selectedModelNodes().constFirst();
const ModelNode selectedModelNode = context.selectedModelNodes().constFirst();
ModelNode parentModelNode;
if (selectedModelNode.hasParentProperty())
@@ -983,6 +993,22 @@ void DesignerActionManager::createDefaultDesignerActions()
addDesignerAction(new ChangeStyleAction());
}
void DesignerActionManager::createDefaultAddResourceHandler()
{
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.png",
ModelNodeOperations::addImageToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.jpg",
ModelNodeOperations::addImageToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.bmp",
ModelNodeOperations::addImageToProject));
registerAddResourceHandler(AddResourceHandler(ComponentCoreConstants::addImagesDisplayString,
"*.svg",
ModelNodeOperations::addImageToProject));
}
void DesignerActionManager::addDesignerAction(ActionInterface *newAction)
{
m_designerActions.append(QSharedPointer<ActionInterface>(newAction));

View File

@@ -42,6 +42,25 @@ namespace QmlDesigner {
class DesignerActionManagerView;
typedef std::function<bool (const QString &filename, const QString &targetDirectory)> AddResourceOperation;
struct AddResourceHandler
{
public:
AddResourceHandler( const QString &_category,
const QString &_filter,
AddResourceOperation _operation)
: category(_category)
,filter(_filter)
,operation(_operation)
{
}
QString category;
QString filter;
AddResourceOperation operation;
};
class DesignerActionToolBar : public Utils::StyledBar
{
public:
@@ -64,6 +83,7 @@ public:
QList<ActionInterface* > designerActions() const;
void createDefaultDesignerActions();
void createDefaultAddResourceHandler();
DesignerActionManagerView *view();
DesignerActionToolBar *createToolBar(QWidget *parent = 0) const;
@@ -76,9 +96,13 @@ public:
DesignerActionManager(const DesignerActionManager&) = delete;
DesignerActionManager & operator=(const DesignerActionManager&) = delete;
QList<AddResourceHandler> addResourceHandler() const;
void registerAddResourceHandler(const AddResourceHandler &handler);
private:
QList<QSharedPointer<ActionInterface> > m_designerActions;
DesignerActionManagerView *m_designerActionManagerView;
QList<AddResourceHandler> m_addResourceHandler;
};
} //QmlDesigner

View File

@@ -53,7 +53,7 @@ void DesignerActionManagerView::modelAboutToBeDetached(Model *model)
void DesignerActionManagerView::nodeCreated(const ModelNode &)
{
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::nodeRemoved(const ModelNode &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
@@ -63,17 +63,17 @@ void DesignerActionManagerView::nodeRemoved(const ModelNode &, const NodeAbstrac
void DesignerActionManagerView::nodeAboutToBeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
{
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::nodeReparented(const ModelNode &, const NodeAbstractProperty &, const NodeAbstractProperty &, AbstractView::PropertyChangeFlags)
{
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::propertiesRemoved(const QList<AbstractProperty> &)
{
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::rootNodeTypeChanged(const QString &, int, int)
@@ -96,7 +96,7 @@ void DesignerActionManagerView::rewriterEndTransaction()
void DesignerActionManagerView::currentStateChanged(const ModelNode &)
{
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::selectedNodesChanged(const QList<ModelNode> &selectedNodes, const QList<ModelNode> &)
@@ -112,7 +112,7 @@ void DesignerActionManagerView::selectedNodesChanged(const QList<ModelNode> &sel
void DesignerActionManagerView::nodeOrderChanged(const NodeListProperty &, const ModelNode &, int)
{
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::importsChanged(const QList<Import> &, const QList<Import> &)
@@ -127,21 +127,21 @@ void DesignerActionManagerView::setDesignerActionList(const QList<ActionInterfac
void DesignerActionManagerView::signalHandlerPropertiesChanged(const QVector<SignalHandlerProperty> &, AbstractView::PropertyChangeFlags)
{
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::variantPropertiesChanged(const QList<VariantProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
{
if (propertyChangeFlag == AbstractView::PropertiesAdded)
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
else if (hasSingleSelectedModelNode())
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::bindingPropertiesChanged(const QList<BindingProperty> &, AbstractView::PropertyChangeFlags propertyChangeFlag)
{
if (propertyChangeFlag == AbstractView::PropertiesAdded)
setupContext();
setupContext(SelectionContext::UpdateMode::Fast);
}
void DesignerActionManagerView::instancePropertyChanged(const QList<QPair<ModelNode, PropertyName> > &)

View File

@@ -56,6 +56,10 @@
#include <qmljseditor/qmljsfindreferences.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectnodes.h>
#include <projectexplorer/projecttree.h>
#include <utils/algorithm.h>
#include <utils/qtcassert.h>
@@ -1020,6 +1024,27 @@ void addTabBarToStackedContainer(const SelectionContext &selectionContext)
}
}
bool addImageToProject(const QString &fileName, const QString &directory)
{
const QString targetFile = directory + "/" + QFileInfo(fileName).fileName();
const bool success = QFile::copy(fileName, targetFile);
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
QTC_ASSERT(document, return false);
if (success) {
ProjectExplorer::Node *node = ProjectExplorer::ProjectTree::nodeForFile(document->fileName());
if (node) {
ProjectExplorer::FolderNode *containingFolder = node->parentFolderNode();
if (containingFolder)
containingFolder->addFiles(QStringList(targetFile));
}
}
return success;
}
} // namespace Mode
} //QmlDesigner

View File

@@ -72,7 +72,7 @@ void addItemToStackedContainer(const SelectionContext &selectionContext);
void increaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void decreaseIndexOfStackedContainer(const SelectionContext &selectionContext);
void addTabBarToStackedContainer(const SelectionContext &selectionContext);
bool addImageToProject(const QString &fileName, const QString &directory);
} // namespace ModelNodeOperationso
} //QmlDesigner

View File

@@ -397,7 +397,7 @@ void FormEditorView::changeToCustomTool()
int handlingRank = 0;
AbstractCustomTool *selectedCustomTool = 0;
const ModelNode &selectedModelNode = selectedModelNodes().constFirst();
const ModelNode selectedModelNode = selectedModelNodes().constFirst();
foreach (AbstractCustomTool *customTool, m_customToolList) {
if (customTool->wantHandleItem(selectedModelNode) > handlingRank) {

View File

@@ -45,9 +45,11 @@
#include <coreplugin/coreconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/messagebox.h>
#include <QApplication>
#include <QDrag>
#include <QFileDialog>
#include <QFileInfo>
#include <QFileSystemModel>
#include <QGridLayout>
@@ -76,6 +78,7 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
m_itemViewQuickWidget(new QQuickWidget),
m_resourcesView(new ItemLibraryResourceView(this)),
m_importTagsWidget(new QWidget(this)),
m_addResourcesWidget(new QWidget(this)),
m_filterFlag(QtBasic)
{
m_compressionTimer.setInterval(200);
@@ -148,7 +151,8 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
layout->addWidget(spacer, 1, 0);
layout->addWidget(lineEditFrame, 2, 0, 1, 1);
layout->addWidget(m_importTagsWidget.data(), 3, 0, 1, 1);
layout->addWidget(m_stackedWidget.data(), 4, 0, 1, 1);
layout->addWidget(m_addResourcesWidget.data(), 4, 0, 1, 1);
layout->addWidget(m_stackedWidget.data(), 5, 0, 1, 1);
setSearchFilter(QString());
@@ -164,6 +168,20 @@ ItemLibraryWidget::ItemLibraryWidget(QWidget *parent) :
auto *flowLayout = new Utils::FlowLayout(m_importTagsWidget.data());
flowLayout->setMargin(4);
m_addResourcesWidget->setVisible(false);
flowLayout = new Utils::FlowLayout(m_addResourcesWidget.data());
flowLayout->setMargin(4);
auto button = new QToolButton(m_addResourcesWidget.data());
auto font = button->font();
font.setPixelSize(9);
button->setFont(font);
button->setIcon(Utils::Icons::PLUS.icon());
button->setText(tr("Add New Resources..."));
button->setToolTip(tr("Add new resources to project."));
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
flowLayout->addWidget(button);
connect(button, &QToolButton::clicked, this, &ItemLibraryWidget::addResources);
// init the first load of the QML UI elements
reloadQmlSource();
}
@@ -232,12 +250,15 @@ void ItemLibraryWidget::setCurrentIndexOfStackedWidget(int index)
if (index == 2) {
m_filterLineEdit->setVisible(false);
m_importTagsWidget->setVisible(true);
m_addResourcesWidget->setVisible(false);
} if (index == 1) {
m_filterLineEdit->setVisible(true);
m_importTagsWidget->setVisible(false);
m_addResourcesWidget->setVisible(true);
} else {
m_filterLineEdit->setVisible(true);
m_importTagsWidget->setVisible(true);
m_addResourcesWidget->setVisible(false);
}
m_stackedWidget->setCurrentIndex(index);
@@ -279,6 +300,7 @@ void ItemLibraryWidget::setupImportTagWidget()
button->setIcon(Utils::Icons::PLUS.icon());
button->setText(import);
button->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
button->setToolTip(tr("Add import %1").arg(import));
connect(button, &QToolButton::clicked, this, [this, import]() {
addPossibleImport(import);
});
@@ -366,4 +388,47 @@ void ItemLibraryWidget::addPossibleImport(const QString &name)
QmlDesignerPlugin::instance()->currentDesignDocument()->updateSubcomponentManager();
}
void ItemLibraryWidget::addResources()
{
auto document = QmlDesignerPlugin::instance()->currentDesignDocument();
QTC_ASSERT(document, return);
QList<AddResourceHandler> handlers = QmlDesignerPlugin::instance()->viewManager().designerActionManager().addResourceHandler();
QMultiMap<QString, QString> map;
for (const AddResourceHandler &handler : handlers) {
map.insert(handler.category, handler.filter);
}
QStringList filters;
for (const QString &key : map.uniqueKeys()) {
QString str = key + " (";
str.append(map.values(key).join(" "));
str.append(")");
filters.append(str);
}
const auto fileNames = QFileDialog::getOpenFileNames(this,
tr("Add Resources"),
document->fileName().parentDir().toString(),
filters.join(";;"));
if (!fileNames.isEmpty()) {
const auto directory = QFileDialog::getExistingDirectory(this,
tr("Target Direcotry"),
document->fileName().parentDir().toString());
for (const QString &fileName : fileNames) {
for (const AddResourceHandler &handler : handlers) {
QString postfix = handler.filter;
postfix.remove(0, 1);
if (fileName.endsWith(postfix))
if (!handler.operation(fileName, directory))
Core::AsynchronousMessageBox::warning(tr("Failed to add File"), tr("Could not add %1 to project.").arg(fileName));
}
}
}
}
}

View File

@@ -96,6 +96,7 @@ private:
void removeImport(const QString &name);
void addImport(const QString &name, const QString &version);
void addPossibleImport(const QString &name);
void addResources();
QTimer m_compressionTimer;
QSize m_itemIconSize;
@@ -111,6 +112,7 @@ private:
QScopedPointer<QQuickWidget> m_itemViewQuickWidget;
QScopedPointer<ItemLibraryResourceView> m_resourcesView;
QScopedPointer<QWidget> m_importTagsWidget;
QScopedPointer<QWidget> m_addResourcesWidget;
QShortcut *m_qmlSourceUpdateShortcut;

View File

@@ -27,6 +27,7 @@
#include "navigatorview.h"
#include <bindingproperty.h>
#include <designersettings.h>
#include <nodeabstractproperty.h>
#include <nodehints.h>
#include <nodelistproperty.h>
@@ -207,7 +208,8 @@ QVariant NavigatorTreeModel::data(const QModelIndex &index, int role) const
} else if (role == Qt::ToolTipRole) {
if (currentQmlObjectNode.hasError()) {
QString errorString = currentQmlObjectNode.error();
if (currentQmlObjectNode.isRootNode())
if (DesignerSettings::getValue(DesignerSettingsKey::STANDALONE_MODE).toBool() &&
currentQmlObjectNode.isRootNode())
errorString.append(QString("\n%1").arg(tr("Changing the setting \"%1\" might solve the issue.").arg(
tr("Use QML emulation layer that is built with the selected Qt"))));

View File

@@ -145,7 +145,7 @@ void PropertyEditorContextObject::toogleExportAlias()
if (rewriterView->selectedModelNodes().isEmpty())
return;
const ModelNode &selectedNode = rewriterView->selectedModelNodes().constFirst();
const ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
if (QmlObjectNode::isValidQmlObjectNode(selectedNode)) {
QmlObjectNode objectNode(selectedNode);
@@ -208,6 +208,25 @@ void PropertyEditorContextObject::changeTypeName(const QString &typeName)
}
void PropertyEditorContextObject::insertKeyframe(const QString &propertyName)
{
if (!m_model || !m_model->rewriterView())
return;
/* Ideally we should not missuse the rewriterView
* If we add more code here we have to forward the property editor view */
RewriterView *rewriterView = m_model->rewriterView();
if (rewriterView->selectedModelNodes().isEmpty())
return;
ModelNode selectedNode = rewriterView->selectedModelNodes().constFirst();
rewriterView->emitCustomNotification("INSERT_KEYFRAME",
{ selectedNode },
{ propertyName });
}
int PropertyEditorContextObject::majorVersion() const
{
return m_majorVersion;
@@ -270,6 +289,20 @@ void PropertyEditorContextObject::setMinorVersion(int minorVersion)
emit minorVersionChanged();
}
bool PropertyEditorContextObject::hasActiveTimeline() const
{
return m_setHasActiveTimeline;
}
void PropertyEditorContextObject::setHasActiveTimeline(bool b)
{
if (b == m_setHasActiveTimeline)
return;
m_setHasActiveTimeline = b;
emit hasActiveTimelineChanged();
}
void PropertyEditorContextObject::insertInQmlContext(QQmlContext *context)
{
m_qmlContext = context;

View File

@@ -55,6 +55,8 @@ class PropertyEditorContextObject : public QObject
Q_PROPERTY(bool hasAliasExport READ hasAliasExport NOTIFY hasAliasExportChanged)
Q_PROPERTY(bool hasActiveTimeline READ hasActiveTimeline NOTIFY hasActiveTimelineChanged)
Q_PROPERTY(QQmlPropertyMap* backendValues READ backendValues WRITE setBackendValues NOTIFY backendValuesChanged)
Q_PROPERTY(QQmlComponent* specificQmlComponent READ specificQmlComponent NOTIFY specificQmlComponentChanged)
@@ -81,6 +83,7 @@ public:
Q_INVOKABLE void toogleExportAlias();
Q_INVOKABLE void changeTypeName(const QString &typeName);
Q_INVOKABLE void insertKeyframe(const QString &propertyName);
int majorVersion() const;
int majorQtQuickVersion() const;
@@ -91,6 +94,9 @@ public:
int minorVersion() const;
void setMinorVersion(int minorVersion);
bool hasActiveTimeline() const;
void setHasActiveTimeline(bool b);
void insertInQmlContext(QQmlContext *context);
QQmlComponent *specificQmlComponent();
@@ -110,6 +116,7 @@ signals:
void minorQtQuickVersionChanged();
void specificQmlComponentChanged();
void hasAliasExportChanged();
void hasActiveTimelineChanged();
public slots:
void setGlobalBaseUrl(const QUrl &newBaseUrl);
@@ -153,6 +160,8 @@ private:
Model *m_model = nullptr;
bool m_aliasExport = false;
bool m_setHasActiveTimeline = false;
};
} //QmlDesigner {

View File

@@ -29,6 +29,7 @@
#include "propertyeditortransaction.h"
#include <qmldesignerconstants.h>
#include <qmldesignerplugin.h>
#include <qmltimelinemutator.h>
#include <qmlobjectnode.h>
#include <nodemetainfo.h>
@@ -328,6 +329,9 @@ void PropertyEditorQmlBackend::setup(const QmlObjectNode &qmlObjectNode, const Q
contextObject()->setIsBaseState(qmlObjectNode.isInBaseState());
contextObject()->setHasAliasExport(qmlObjectNode.isAliasExported());
contextObject()->setHasActiveTimeline(QmlTimelineMutator::hasActiveTimeline(qmlObjectNode.view()));
contextObject()->setSelectionChanged(false);
contextObject()->setSelectionChanged(false);

View File

@@ -30,6 +30,7 @@
#include "propertyeditortransaction.h"
#include <qmldesignerconstants.h>
#include <qmltimelinemutator.h>
#include <nodemetainfo.h>
#include <invalididexception.h>
@@ -368,6 +369,14 @@ bool PropertyEditorView::locked() const
return m_locked;
}
void PropertyEditorView::nodeCreated(const ModelNode &modelNode)
{
if (!m_qmlBackEndForCurrentType->contextObject()->hasActiveTimeline()
&& QmlTimelineMutator::isValidQmlTimelineMutator(modelNode)) {
m_qmlBackEndForCurrentType->contextObject()->setHasActiveTimeline(QmlTimelineMutator::hasActiveTimeline(this));
}
}
void PropertyEditorView::updateSize()
{
if (!m_qmlBackEndForCurrentType)

View File

@@ -93,6 +93,8 @@ public:
bool locked() const;
void nodeCreated(const ModelNode &createdNode);
protected:
void timerEvent(QTimerEvent *event) override;
void setupPane(const TypeName &typeName);

View File

@@ -65,6 +65,7 @@ public:
QList<ModelNode> allTargets() const;
QList<QmlTimelineFrames> framesForTarget(const ModelNode &target) const;
void destroyFramesForTarget(const ModelNode &target);
static bool hasActiveTimeline(AbstractView *view);
private:
void addFramesIfNotExists(const ModelNode &node, const PropertyName &propertyName);

View File

@@ -210,6 +210,23 @@ void QmlTimelineMutator::destroyFramesForTarget(const ModelNode &target)
frames.destroy();
}
bool QmlTimelineMutator::hasActiveTimeline(AbstractView *view)
{
if (view && view->isAttached()) {
if (!view->model()->hasImport(Import::createLibraryImport("QtQuick.Timeline", "1.0"), true, true))
return false;
const ModelNode root = view->rootModelNode();
if (root.isValid())
for (const ModelNode &child : root.directSubModelNodes()) {
if (QmlTimelineMutator::isValidQmlTimelineMutator(child))
return QmlTimelineMutator(child).isEnabled();
}
}
return false;
}
void QmlTimelineMutator::addFramesIfNotExists(const ModelNode &node, const PropertyName &propertyName)
{
if (!isValid())

View File

@@ -76,6 +76,7 @@ void DesignerSettings::fromSettings(QSettings *settings)
restoreValue(settings, DesignerSettingsKey::IGNORE_DEVICE_PIXEL_RATIO, false);
restoreValue(settings, DesignerSettingsKey::STATESEDITOR_EXPANDED, false);
restoreValue(settings, DesignerSettingsKey::NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS, true);
restoreValue(settings, DesignerSettingsKey::STANDALONE_MODE, false);
settings->endGroup();
settings->endGroup();

View File

@@ -63,6 +63,7 @@ const char STATESEDITOR_EXPANDED[] = "StatesEditorExpanded";
const char NAVIGATOR_SHOW_ONLY_VISIBLE_ITEMS[] = "NavigatorShowOnlyVisibleItems";
const char REFORMAT_UI_QML_FILES[] = "ReformatUiQmlFiles"; /* These settings are not exposed in ui. */
const char IGNORE_DEVICE_PIXEL_RATIO[] = "IgnoreDevicePixelRaio"; /* The settings can be used to turn off the feature, if there are serious issues */
const char STANDALONE_MODE[] = "StandAloneMode";
}
class DesignerSettings : public QHash<QByteArray, QVariant>

View File

@@ -229,8 +229,10 @@ static void hideToolButtons(QList<QToolButton*> &buttons)
void DesignModeWidget::setup()
{
viewManager().designerActionManager().createDefaultDesignerActions();
viewManager().designerActionManager().polishActions();
auto &actionManager = viewManager().designerActionManager();
actionManager.createDefaultDesignerActions();
actionManager.createDefaultAddResourceHandler();
actionManager.polishActions();
QList<Core::INavigationWidgetFactory *> factories =
Core::INavigationWidgetFactory::allNavigationFactories();

View File

@@ -222,7 +222,7 @@ static PropertyName unusedProperty(const ModelNode &modelNode)
void BindingModel::addBindingForCurrentNode()
{
if (connectionView()->selectedModelNodes().count() == 1) {
const ModelNode &modelNode = connectionView()->selectedModelNodes().constFirst();
const ModelNode modelNode = connectionView()->selectedModelNodes().constFirst();
if (modelNode.isValid()) {
try {
modelNode.bindingProperty(unusedProperty(modelNode)).setExpression(QLatin1String("none.none"));

View File

@@ -271,7 +271,7 @@ void ConnectionModel::addConnection()
if (connectionView()->selectedModelNodes().count() == 1
&& !connectionView()->selectedModelNodes().constFirst().id().isEmpty()) {
const ModelNode &selectedNode = connectionView()->selectedModelNodes().constFirst();
const ModelNode selectedNode = connectionView()->selectedModelNodes().constFirst();
newNode.bindingProperty("target").setExpression(selectedNode.id());
} else {
newNode.bindingProperty("target").setExpression(QLatin1String("parent"));

View File

@@ -265,7 +265,7 @@ QStringList DynamicPropertiesModel::possibleTargetProperties(const BindingProper
void DynamicPropertiesModel::addDynamicPropertyForCurrentNode()
{
if (connectionView()->selectedModelNodes().count() == 1) {
const ModelNode &modelNode = connectionView()->selectedModelNodes().constFirst();
const ModelNode modelNode = connectionView()->selectedModelNodes().constFirst();
if (modelNode.isValid()) {
try {
modelNode.variantProperty(unusedProperty(modelNode)).setDynamicTypeNameAndValue("string", QLatin1String("none.none"));

View File

@@ -210,6 +210,11 @@ void SettingsPageWidget::setSettings(const DesignerSettings &settings)
DesignerSettingsKey::ENABLE_MODEL_EXCEPTION_OUTPUT).toBool());
m_ui.controls2StyleComboBox->setCurrentText(m_ui.styleLineEdit->text());
if (settings.value(DesignerSettingsKey::STANDALONE_MODE).toBool()) {
m_ui.emulationGroupBox->hide();
m_ui.debugGroupBox->hide();
}
}
SettingsPage::SettingsPage() :

View File

@@ -216,7 +216,7 @@
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_04">
<widget class="QGroupBox" name="emulationGroupBox">
<property name="title">
<string>QML Emulation Layer</string>
</property>
@@ -411,7 +411,7 @@
</layout>
</item>
<item>
<widget class="QGroupBox" name="groupBox_08">
<widget class="QGroupBox" name="debugGroupBox">
<property name="title">
<string>Debugging</string>
</property>

View File

@@ -107,41 +107,39 @@ static void setViewDefaults(Utils::TreeView *view)
static QString displayHeader(Fields header)
{
static const char ctxt[] = "QmlProfiler::Internal::QmlProfilerEventsMainView";
switch (header) {
case Callee:
return QCoreApplication::translate(ctxt, "Callee");
return QmlProfilerStatisticsMainView::tr("Callee");
case CalleeDescription:
return QCoreApplication::translate(ctxt, "Callee Description");
return QmlProfilerStatisticsMainView::tr("Callee Description");
case Caller:
return QCoreApplication::translate(ctxt, "Caller");
return QmlProfilerStatisticsMainView::tr("Caller");
case CallerDescription:
return QCoreApplication::translate(ctxt, "Caller Description");
return QmlProfilerStatisticsMainView::tr("Caller Description");
case CallCount:
return QCoreApplication::translate(ctxt, "Calls");
return QmlProfilerStatisticsMainView::tr("Calls");
case Details:
return QCoreApplication::translate(ctxt, "Details");
return QmlProfilerStatisticsMainView::tr("Details");
case Location:
return QCoreApplication::translate(ctxt, "Location");
return QmlProfilerStatisticsMainView::tr("Location");
case MaxTime:
return QCoreApplication::translate(ctxt, "Longest Time");
return QmlProfilerStatisticsMainView::tr("Longest Time");
case TimePerCall:
return QCoreApplication::translate(ctxt, "Mean Time");
return QmlProfilerStatisticsMainView::tr("Mean Time");
case SelfTime:
return QCoreApplication::translate(ctxt, "Self Time");
return QmlProfilerStatisticsMainView::tr("Self Time");
case SelfTimeInPercent:
return QCoreApplication::translate(ctxt, "Self Time in Percent");
return QmlProfilerStatisticsMainView::tr("Self Time in Percent");
case MinTime:
return QCoreApplication::translate(ctxt, "Shortest Time");
return QmlProfilerStatisticsMainView::tr("Shortest Time");
case TimeInPercent:
return QCoreApplication::translate(ctxt, "Time in Percent");
return QmlProfilerStatisticsMainView::tr("Time in Percent");
case TotalTime:
return QCoreApplication::translate(ctxt, "Total Time");
return QmlProfilerStatisticsMainView::tr("Total Time");
case Type:
return QCoreApplication::translate(ctxt, "Type");
return QmlProfilerStatisticsMainView::tr("Type");
case MedianTime:
return QCoreApplication::translate(ctxt, "Median Time");
return QmlProfilerStatisticsMainView::tr("Median Time");
default:
return QString();
}

View File

@@ -7934,10 +7934,13 @@ void BaseTextEditor::setContextHelpId(const QString &id)
void TextEditorWidget::contextHelpId(const IContext::HelpIdCallback &callback)
{
if (d->m_contextHelpId.isEmpty() && !d->m_hoverHandlers.isEmpty())
d->m_hoverHandlers.first()->contextHelpId(this, textCursor().position(), callback);
else
if (d->m_contextHelpId.isEmpty() && !d->m_hoverHandlers.isEmpty()) {
d->m_hoverHandlers.first()->contextHelpId(this,
Text::wordStartCursor(textCursor()).position(),
callback);
} else {
callback(d->m_contextHelpId);
}
}
void TextEditorWidget::setContextHelpId(const QString &id)