forked from qt-creator/qt-creator
Merge remote-tracking branch 'origin/4.0'
Change-Id: I80bc3371c6d7cf9f2d46cbcf8e79e4761213d8aa
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include "cmakeprojectmanager.h"
|
||||
#include "cmaketool.h"
|
||||
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagemanager.h>
|
||||
#include <coreplugin/progressmanager/progressmanager.h>
|
||||
#include <projectexplorer/kit.h>
|
||||
@@ -49,6 +50,7 @@
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemWatcher>
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <QSet>
|
||||
#include <QTemporaryDir>
|
||||
@@ -61,20 +63,37 @@ namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
|
||||
static QStringList toArguments(const CMakeConfig &config, const ProjectExplorer::Kit *k) {
|
||||
const QStringList argList
|
||||
= Utils::transform(config, [k](const CMakeConfigItem &i) -> QString {
|
||||
const QString tmp = i.toString();
|
||||
return tmp.isEmpty() ? QString()
|
||||
: QString::fromLatin1("-D") + k->macroExpander()->expand(tmp);
|
||||
});
|
||||
return Utils::filtered(argList, [](const QString &s) { return !s.isEmpty(); });
|
||||
return Utils::transform(config, [k](const CMakeConfigItem &i) -> QString {
|
||||
QString a = QString::fromLatin1("-D");
|
||||
a.append(QString::fromUtf8(i.key));
|
||||
switch (i.type) {
|
||||
case CMakeConfigItem::FILEPATH:
|
||||
a.append(QLatin1String(":FILEPATH="));
|
||||
break;
|
||||
case CMakeConfigItem::PATH:
|
||||
a.append(QLatin1String(":PATH="));
|
||||
break;
|
||||
case CMakeConfigItem::BOOL:
|
||||
a.append(QLatin1String(":BOOL="));
|
||||
break;
|
||||
case CMakeConfigItem::STRING:
|
||||
a.append(QLatin1String(":STRING="));
|
||||
break;
|
||||
case CMakeConfigItem::INTERNAL:
|
||||
a.append(QLatin1String(":INTERNAL="));
|
||||
break;
|
||||
}
|
||||
a.append(i.expandedValue(k));
|
||||
|
||||
return a;
|
||||
});
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------------
|
||||
// BuildDirManager:
|
||||
// --------------------------------------------------------------------
|
||||
|
||||
BuildDirManager::BuildDirManager(const CMakeBuildConfiguration *bc) :
|
||||
BuildDirManager::BuildDirManager(CMakeBuildConfiguration *bc) :
|
||||
m_buildConfiguration(bc),
|
||||
m_watcher(new QFileSystemWatcher(this))
|
||||
{
|
||||
@@ -82,7 +101,7 @@ BuildDirManager::BuildDirManager(const CMakeBuildConfiguration *bc) :
|
||||
m_projectName = sourceDirectory().fileName();
|
||||
|
||||
m_reparseTimer.setSingleShot(true);
|
||||
m_reparseTimer.setInterval(500);
|
||||
m_reparseTimer.setInterval(5000);
|
||||
connect(&m_reparseTimer, &QTimer::timeout, this, &BuildDirManager::parse);
|
||||
|
||||
connect(m_watcher, &QFileSystemWatcher::fileChanged, this, [this]() {
|
||||
@@ -155,6 +174,7 @@ void BuildDirManager::resetData()
|
||||
{
|
||||
m_hasData = false;
|
||||
|
||||
m_cmakeCache.clear();
|
||||
m_projectName.clear();
|
||||
m_buildTargets.clear();
|
||||
m_watchedFiles.clear();
|
||||
@@ -177,22 +197,23 @@ bool BuildDirManager::persistCMakeState()
|
||||
delete m_tempDir;
|
||||
m_tempDir = nullptr;
|
||||
|
||||
parse();
|
||||
resetData();
|
||||
QTimer::singleShot(0, this, &BuildDirManager::parse); // make sure signals only happen afterwards!
|
||||
return true;
|
||||
}
|
||||
|
||||
void BuildDirManager::parse()
|
||||
{
|
||||
checkConfiguration();
|
||||
|
||||
CMakeTool *tool = CMakeKitInformation::cmakeTool(kit());
|
||||
const QString generator = CMakeGeneratorKitInformation::generator(kit());
|
||||
|
||||
QTC_ASSERT(tool, return);
|
||||
QTC_ASSERT(!generator.isEmpty(), return);
|
||||
|
||||
// Pop up a dialog asking the user to rerun cmake
|
||||
QString cbpFile = CMakeManager::findCbpFile(QDir(workDirectory().toString()));
|
||||
QFileInfo cbpFileFi(cbpFile);
|
||||
|
||||
const QString cbpFile = CMakeManager::findCbpFile(QDir(workDirectory().toString()));
|
||||
const QFileInfo cbpFileFi = cbpFile.isEmpty() ? QFileInfo() : QFileInfo(cbpFile);
|
||||
if (!cbpFileFi.exists()) {
|
||||
// Initial create:
|
||||
startCMake(tool, generator, intendedConfiguration());
|
||||
@@ -201,8 +222,8 @@ void BuildDirManager::parse()
|
||||
|
||||
const bool mustUpdate = m_watchedFiles.isEmpty()
|
||||
|| Utils::anyOf(m_watchedFiles, [&cbpFileFi](const Utils::FileName &f) {
|
||||
return f.toFileInfo().lastModified() > cbpFileFi.lastModified();
|
||||
});
|
||||
return f.toFileInfo().lastModified() > cbpFileFi.lastModified();
|
||||
});
|
||||
if (mustUpdate) {
|
||||
startCMake(tool, generator, CMakeConfig());
|
||||
} else {
|
||||
@@ -254,21 +275,21 @@ void BuildDirManager::clearFiles()
|
||||
|
||||
CMakeConfig BuildDirManager::parsedConfiguration() const
|
||||
{
|
||||
if (!m_hasData)
|
||||
return CMakeConfig();
|
||||
|
||||
Utils::FileName cacheFile = workDirectory();
|
||||
cacheFile.appendPath(QLatin1String("CMakeCache.txt"));
|
||||
QString errorMessage;
|
||||
CMakeConfig result = parseConfiguration(cacheFile, &errorMessage);
|
||||
if (!errorMessage.isEmpty())
|
||||
emit errorOccured(errorMessage);
|
||||
const Utils::FileName sourceOfBuildDir
|
||||
= Utils::FileName::fromUtf8(CMakeConfigItem::valueOf("CMAKE_HOME_DIRECTORY", result));
|
||||
if (sourceOfBuildDir != sourceDirectory()) // Use case-insensitive compare where appropriate
|
||||
emit errorOccured(tr("The build directory is not for %1").arg(sourceDirectory().toUserOutput()));
|
||||
|
||||
return result;
|
||||
if (m_cmakeCache.isEmpty()) {
|
||||
Utils::FileName cacheFile = workDirectory();
|
||||
cacheFile.appendPath(QLatin1String("CMakeCache.txt"));
|
||||
if (!cacheFile.exists())
|
||||
return m_cmakeCache;
|
||||
QString errorMessage;
|
||||
m_cmakeCache = parseConfiguration(cacheFile, &errorMessage);
|
||||
if (!errorMessage.isEmpty())
|
||||
emit errorOccured(errorMessage);
|
||||
const Utils::FileName sourceOfBuildDir
|
||||
= Utils::FileName::fromUtf8(CMakeConfigItem::valueOf("CMAKE_HOME_DIRECTORY", m_cmakeCache));
|
||||
if (sourceOfBuildDir != sourceDirectory()) // Use case-insensitive compare where appropriate
|
||||
emit errorOccured(tr("The build directory is not for %1").arg(sourceDirectory().toUserOutput()));
|
||||
}
|
||||
return m_cmakeCache;
|
||||
}
|
||||
|
||||
void BuildDirManager::stopProcess()
|
||||
@@ -335,6 +356,7 @@ void BuildDirManager::extractData()
|
||||
return;
|
||||
|
||||
m_watcher->addPath(cbpFile);
|
||||
m_watcher->addPath(workDirectory().toString() + QLatin1String("/CMakeCache.txt"));
|
||||
|
||||
// setFolderName
|
||||
CMakeCbpParser cbpparser;
|
||||
@@ -497,6 +519,61 @@ void BuildDirManager::processCMakeError()
|
||||
});
|
||||
}
|
||||
|
||||
void BuildDirManager::checkConfiguration()
|
||||
{
|
||||
if (m_tempDir) // always throw away changes in the tmpdir!
|
||||
return;
|
||||
|
||||
ProjectExplorer::Kit *k = m_buildConfiguration->target()->kit();
|
||||
const CMakeConfig cache = parsedConfiguration();
|
||||
if (cache.isEmpty())
|
||||
return; // No cache file yet.
|
||||
|
||||
CMakeConfig newConfig;
|
||||
QSet<QString> changedKeys;
|
||||
QSet<QString> removedKeys;
|
||||
foreach (const CMakeConfigItem &iBc, intendedConfiguration()) {
|
||||
const CMakeConfigItem &iCache
|
||||
= Utils::findOrDefault(cache, [&iBc](const CMakeConfigItem &i) { return i.key == iBc.key; });
|
||||
if (iCache.isNull()) {
|
||||
removedKeys << QString::fromUtf8(iBc.key);
|
||||
} else if (QString::fromUtf8(iCache.value) != iBc.expandedValue(k)) {
|
||||
changedKeys << QString::fromUtf8(iBc.key);
|
||||
newConfig.append(iCache);
|
||||
} else {
|
||||
newConfig.append(iBc);
|
||||
}
|
||||
}
|
||||
|
||||
if (!changedKeys.isEmpty() || !removedKeys.isEmpty()) {
|
||||
QSet<QString> total = removedKeys + changedKeys;
|
||||
QStringList keyList = total.toList();
|
||||
Utils::sort(keyList);
|
||||
QString table = QLatin1String("<table>");
|
||||
foreach (const QString &k, keyList) {
|
||||
QString change;
|
||||
if (removedKeys.contains(k))
|
||||
change = tr("<removed>");
|
||||
else
|
||||
change = QString::fromUtf8(CMakeConfigItem::valueOf(k.toUtf8(), cache)).trimmed();
|
||||
if (change.isEmpty())
|
||||
change = tr("<empty>");
|
||||
table += QString::fromLatin1("\n<tr><td>%1</td><td>%2</td></tr>").arg(k).arg(change.toHtmlEscaped());
|
||||
}
|
||||
table += QLatin1String("\n</table>");
|
||||
|
||||
QPointer<QMessageBox> box = new QMessageBox(Core::ICore::mainWindow());
|
||||
box->setText(tr("CMake configuration has changed on disk."));
|
||||
box->setInformativeText(tr("The CMakeCache.txt file has changed: %1").arg(table));
|
||||
box->setStandardButtons(QMessageBox::Discard | QMessageBox::Apply);
|
||||
box->setDefaultButton(QMessageBox::Discard);
|
||||
|
||||
int ret = box->exec();
|
||||
if (ret == QMessageBox::Apply)
|
||||
m_buildConfiguration->setCMakeConfiguration(newConfig);
|
||||
}
|
||||
}
|
||||
|
||||
static QByteArray trimCMakeCacheLine(const QByteArray &in) {
|
||||
int start = 0;
|
||||
while (start < in.count() && (in.at(start) == ' ' || in.at(start) == '\t'))
|
||||
@@ -587,6 +664,8 @@ CMakeConfig BuildDirManager::parseConfiguration(const Utils::FileName &cacheFile
|
||||
|
||||
void BuildDirManager::maybeForceReparse()
|
||||
{
|
||||
checkConfiguration();
|
||||
|
||||
const QByteArray GENERATOR_KEY = "CMAKE_GENERATOR";
|
||||
const QByteArray EXTRA_GENERATOR_KEY = "CMAKE_EXTRA_GENERATOR";
|
||||
const QByteArray CMAKE_COMMAND_KEY = "CMAKE_COMMAND";
|
||||
|
||||
@@ -63,7 +63,7 @@ class BuildDirManager : public QObject
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
BuildDirManager(const CMakeBuildConfiguration *bc);
|
||||
BuildDirManager(CMakeBuildConfiguration *bc);
|
||||
~BuildDirManager() override;
|
||||
|
||||
const ProjectExplorer::Kit *kit() const;
|
||||
@@ -87,6 +87,8 @@ public:
|
||||
void clearFiles();
|
||||
CMakeConfig parsedConfiguration() const;
|
||||
|
||||
void checkConfiguration();
|
||||
|
||||
static CMakeConfig parseConfiguration(const Utils::FileName &cacheFile,
|
||||
QString *errorMessage);
|
||||
|
||||
@@ -106,12 +108,12 @@ private:
|
||||
void processCMakeOutput();
|
||||
void processCMakeError();
|
||||
|
||||
|
||||
bool m_hasData = false;
|
||||
|
||||
const CMakeBuildConfiguration *m_buildConfiguration = nullptr;
|
||||
CMakeBuildConfiguration *m_buildConfiguration = nullptr;
|
||||
Utils::QtcProcess *m_cmakeProcess = nullptr;
|
||||
QTemporaryDir *m_tempDir = nullptr;
|
||||
mutable CMakeConfig m_cmakeCache;
|
||||
|
||||
QSet<Utils::FileName> m_watchedFiles;
|
||||
QString m_projectName;
|
||||
|
||||
@@ -156,10 +156,6 @@ void CMakeBuildConfiguration::ctor()
|
||||
|
||||
void CMakeBuildConfiguration::maybeForceReparse()
|
||||
{
|
||||
ProjectExplorer::Kit *k = target()->kit();
|
||||
CMakeConfig config = cmakeConfiguration();
|
||||
config.append(CMakeConfigurationKitInformation::configuration(k)); // last value wins...
|
||||
setCMakeConfiguration(config);
|
||||
m_buildDirManager->maybeForceReparse();
|
||||
}
|
||||
|
||||
@@ -206,18 +202,14 @@ QList<ConfigModel::DataItem> CMakeBuildConfiguration::completeCMakeConfiguration
|
||||
if (m_completeConfigurationCache.isEmpty())
|
||||
m_completeConfigurationCache = m_buildDirManager->parsedConfiguration();
|
||||
|
||||
CMakeConfig cache = Utils::filtered(m_completeConfigurationCache,
|
||||
[](const CMakeConfigItem &i) {
|
||||
return i.type != CMakeConfigItem::INTERNAL
|
||||
&& i.type != CMakeConfigItem::STATIC;
|
||||
});
|
||||
return Utils::transform(cache, [](const CMakeConfigItem &i) {
|
||||
return Utils::transform(m_completeConfigurationCache,
|
||||
[this](const CMakeConfigItem &i) {
|
||||
ConfigModel::DataItem j;
|
||||
j.key = QString::fromUtf8(i.key);
|
||||
j.value = QString::fromUtf8(i.value);
|
||||
j.description = QString::fromUtf8(i.documentation);
|
||||
|
||||
j.isAdvanced = i.isAdvanced;
|
||||
j.isAdvanced = i.isAdvanced || i.type == CMakeConfigItem::INTERNAL;
|
||||
switch (i.type) {
|
||||
case CMakeConfigItem::FILEPATH:
|
||||
j.type = ConfigModel::DataItem::FILE;
|
||||
@@ -272,7 +264,6 @@ void CMakeBuildConfiguration::setCurrentCMakeConfiguration(const QList<ConfigMod
|
||||
return ni;
|
||||
});
|
||||
|
||||
// There is a buildDirManager, so there must also be an active BC:
|
||||
const CMakeConfig config = cmakeConfiguration() + newConfig;
|
||||
setCMakeConfiguration(config);
|
||||
|
||||
@@ -303,11 +294,28 @@ static CMakeConfig removeDuplicates(const CMakeConfig &config)
|
||||
void CMakeBuildConfiguration::setCMakeConfiguration(const CMakeConfig &config)
|
||||
{
|
||||
m_configuration = removeDuplicates(config);
|
||||
|
||||
const Kit *k = target()->kit();
|
||||
CMakeConfig kitConfig = CMakeConfigurationKitInformation::configuration(k);
|
||||
bool hasKitOverride = false;
|
||||
foreach (const CMakeConfigItem &i, m_configuration) {
|
||||
const QString b = CMakeConfigItem::expandedValueOf(k, i.key, kitConfig);
|
||||
if (!b.isNull() && i.expandedValue(k) != b) {
|
||||
hasKitOverride = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasKitOverride)
|
||||
setWarning(tr("CMake Configuration set by the Kit was overridden in the project."));
|
||||
else
|
||||
setWarning(QString());
|
||||
}
|
||||
|
||||
CMakeConfig CMakeBuildConfiguration::cmakeConfiguration() const
|
||||
{
|
||||
return m_configuration;
|
||||
return removeDuplicates(CMakeConfigurationKitInformation::configuration(target()->kit())
|
||||
+ m_configuration);
|
||||
}
|
||||
|
||||
void CMakeBuildConfiguration::setError(const QString &message)
|
||||
@@ -319,11 +327,24 @@ void CMakeBuildConfiguration::setError(const QString &message)
|
||||
emit errorOccured(m_error);
|
||||
}
|
||||
|
||||
void CMakeBuildConfiguration::setWarning(const QString &message)
|
||||
{
|
||||
if (m_warning == message)
|
||||
return;
|
||||
m_warning = message;
|
||||
emit warningOccured(m_warning);
|
||||
}
|
||||
|
||||
QString CMakeBuildConfiguration::error() const
|
||||
{
|
||||
return m_error;
|
||||
}
|
||||
|
||||
QString CMakeBuildConfiguration::warning() const
|
||||
{
|
||||
return m_warning;
|
||||
}
|
||||
|
||||
ProjectExplorer::NamedWidget *CMakeBuildConfiguration::createConfigWidget()
|
||||
{
|
||||
return new CMakeBuildSettingsWidget(this);
|
||||
@@ -475,7 +496,6 @@ CMakeBuildInfo *CMakeBuildConfigurationFactory::createBuildInfo(const ProjectExp
|
||||
auto info = new CMakeBuildInfo(this);
|
||||
info->kitId = k->id();
|
||||
info->sourceDirectory = sourceDir;
|
||||
info->configuration = CMakeConfigurationKitInformation::configuration(k);
|
||||
|
||||
CMakeConfigItem buildTypeItem;
|
||||
switch (buildType) {
|
||||
|
||||
@@ -68,6 +68,7 @@ public:
|
||||
CMakeConfig cmakeConfiguration() const;
|
||||
|
||||
QString error() const;
|
||||
QString warning() const;
|
||||
|
||||
BuildDirManager *buildDirManager() const;
|
||||
|
||||
@@ -83,6 +84,7 @@ public:
|
||||
|
||||
signals:
|
||||
void errorOccured(const QString &message);
|
||||
void warningOccured(const QString &message);
|
||||
|
||||
void parsingStarted();
|
||||
void dataAvailable();
|
||||
@@ -97,9 +99,11 @@ private:
|
||||
void setCurrentCMakeConfiguration(const QList<ConfigModel::DataItem> &items);
|
||||
|
||||
void setError(const QString &message);
|
||||
void setWarning(const QString &message);
|
||||
|
||||
CMakeConfig m_configuration;
|
||||
QString m_error;
|
||||
QString m_warning;
|
||||
|
||||
mutable QList<CMakeConfigItem> m_completeConfigurationCache;
|
||||
|
||||
|
||||
@@ -48,6 +48,7 @@
|
||||
#include <QPushButton>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QSpacerItem>
|
||||
#include <QMenu>
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
namespace Internal {
|
||||
@@ -108,6 +109,17 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
||||
boxLayout->addWidget(m_errorMessageLabel);
|
||||
mainLayout->addLayout(boxLayout, row, 0, 1, 3, Qt::AlignHCenter);
|
||||
|
||||
++row;
|
||||
m_warningLabel = new QLabel;
|
||||
m_warningLabel->setPixmap(Core::Icons::WARNING.pixmap());
|
||||
m_warningLabel->setVisible(false);
|
||||
m_warningMessageLabel = new QLabel;
|
||||
m_warningMessageLabel->setVisible(false);
|
||||
auto boxLayout2 = new QHBoxLayout;
|
||||
boxLayout2->addWidget(m_warningLabel);
|
||||
boxLayout2->addWidget(m_warningMessageLabel);
|
||||
mainLayout->addLayout(boxLayout2, row, 0, 1, 3, Qt::AlignHCenter);
|
||||
|
||||
++row;
|
||||
mainLayout->addItem(new QSpacerItem(20, 10), row, 0);
|
||||
|
||||
@@ -142,6 +154,20 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
||||
mainLayout->addWidget(findWrapper, row, 0, 1, 2);
|
||||
|
||||
auto buttonLayout = new QVBoxLayout;
|
||||
m_addButton = new QPushButton(tr("&Add"));
|
||||
buttonLayout->addWidget(m_addButton);
|
||||
{
|
||||
m_addButtonMenu = new QMenu;
|
||||
m_addButtonMenu->addAction(tr("&Boolean"))->setData(
|
||||
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::BOOLEAN)));
|
||||
m_addButtonMenu->addAction(tr("&String"))->setData(
|
||||
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::STRING)));
|
||||
m_addButtonMenu->addAction(tr("&Directory"))->setData(
|
||||
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::DIRECTORY)));
|
||||
m_addButtonMenu->addAction(tr("&File"))->setData(
|
||||
QVariant::fromValue(static_cast<int>(ConfigModel::DataItem::FILE)));
|
||||
m_addButton->setMenu(m_addButtonMenu);
|
||||
}
|
||||
m_editButton = new QPushButton(tr("&Edit"));
|
||||
buttonLayout->addWidget(m_editButton);
|
||||
m_resetButton = new QPushButton(tr("&Reset"));
|
||||
@@ -161,6 +187,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
||||
|
||||
updateAdvancedCheckBox();
|
||||
setError(bc->error());
|
||||
setWarning(bc->warning());
|
||||
|
||||
connect(project, &CMakeProject::parsingStarted, this, [this]() {
|
||||
updateButtonState();
|
||||
@@ -201,24 +228,49 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
|
||||
m_configView->setCurrentIndex(idx);
|
||||
m_configView->edit(idx);
|
||||
});
|
||||
connect(m_addButtonMenu, &QMenu::triggered, this, [this](QAction *action) {
|
||||
ConfigModel::DataItem::Type type =
|
||||
static_cast<ConfigModel::DataItem::Type>(action->data().value<int>());
|
||||
QString value = tr("<UNSET>");
|
||||
if (type == ConfigModel::DataItem::BOOLEAN)
|
||||
value = QString::fromLatin1("OFF");
|
||||
|
||||
m_configModel->appendConfiguration(tr("<UNSET>"), value, type);
|
||||
QModelIndex idx;
|
||||
idx = m_configView->model()->index(
|
||||
m_configView->model()->rowCount(idx) - 1, 0);
|
||||
m_configView->setCurrentIndex(idx);
|
||||
m_configView->edit(idx);
|
||||
});
|
||||
|
||||
connect(bc, &CMakeBuildConfiguration::errorOccured, this, &CMakeBuildSettingsWidget::setError);
|
||||
connect(bc, &CMakeBuildConfiguration::warningOccured, this, &CMakeBuildSettingsWidget::setWarning);
|
||||
}
|
||||
|
||||
void CMakeBuildSettingsWidget::setError(const QString &message)
|
||||
{
|
||||
bool showWarning = !message.isEmpty();
|
||||
m_errorLabel->setVisible(showWarning);
|
||||
bool showError = !message.isEmpty();
|
||||
m_errorLabel->setVisible(showError);
|
||||
m_errorLabel->setToolTip(message);
|
||||
m_errorMessageLabel->setVisible(showWarning);
|
||||
m_errorMessageLabel->setVisible(showError);
|
||||
m_errorMessageLabel->setText(message);
|
||||
m_errorMessageLabel->setToolTip(message);
|
||||
|
||||
m_configView->setVisible(!showWarning);
|
||||
m_editButton->setVisible(!showWarning);
|
||||
m_resetButton->setVisible(!showWarning);
|
||||
m_showAdvancedCheckBox->setVisible(!showWarning);
|
||||
m_reconfigureButton->setVisible(!showWarning);
|
||||
m_configView->setVisible(!showError);
|
||||
m_editButton->setVisible(!showError);
|
||||
m_resetButton->setVisible(!showError);
|
||||
m_showAdvancedCheckBox->setVisible(!showError);
|
||||
m_reconfigureButton->setVisible(!showError);
|
||||
}
|
||||
|
||||
void CMakeBuildSettingsWidget::setWarning(const QString &message)
|
||||
{
|
||||
bool showWarning = !message.isEmpty();
|
||||
m_warningLabel->setVisible(showWarning);
|
||||
m_warningLabel->setToolTip(message);
|
||||
m_warningMessageLabel->setVisible(showWarning);
|
||||
m_warningMessageLabel->setText(message);
|
||||
m_warningMessageLabel->setToolTip(message);
|
||||
}
|
||||
|
||||
void CMakeBuildSettingsWidget::updateButtonState()
|
||||
|
||||
@@ -37,6 +37,7 @@ class QLabel;
|
||||
class QPushButton;
|
||||
class QTreeView;
|
||||
class QSortFilterProxyModel;
|
||||
class QMenu;
|
||||
QT_END_NAMESPACE
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
@@ -54,6 +55,7 @@ public:
|
||||
CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc);
|
||||
|
||||
void setError(const QString &message);
|
||||
void setWarning(const QString &message);
|
||||
|
||||
private:
|
||||
void updateButtonState();
|
||||
@@ -64,13 +66,17 @@ private:
|
||||
ConfigModel *m_configModel;
|
||||
QSortFilterProxyModel *m_configFilterModel;
|
||||
Utils::ProgressIndicator *m_progressIndicator;
|
||||
QPushButton *m_addButton;
|
||||
QMenu *m_addButtonMenu;
|
||||
QPushButton *m_editButton;
|
||||
QPushButton *m_resetButton;
|
||||
QCheckBox *m_showAdvancedCheckBox;
|
||||
QPushButton *m_reconfigureButton;
|
||||
QTimer m_showProgressTimer;
|
||||
QLabel *m_errorLabel;
|
||||
QLabel *m_warningLabel;
|
||||
QLabel *m_errorMessageLabel;
|
||||
QLabel *m_warningMessageLabel;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
|
||||
#include "cmakeconfigitem.h"
|
||||
|
||||
#include <projectexplorer/kit.h>
|
||||
|
||||
#include <utils/macroexpander.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
#include <QString>
|
||||
@@ -60,6 +63,21 @@ QByteArray CMakeConfigItem::valueOf(const QByteArray &key, const QList<CMakeConf
|
||||
return QByteArray();
|
||||
}
|
||||
|
||||
QString CMakeConfigItem::expandedValueOf(const ProjectExplorer::Kit *k, const QByteArray &key,
|
||||
const QList<CMakeConfigItem> &input)
|
||||
{
|
||||
for (auto it = input.constBegin(); it != input.constEnd(); ++it) {
|
||||
if (it->key == key)
|
||||
return it->expandedValue(k);
|
||||
}
|
||||
return QString();
|
||||
}
|
||||
|
||||
QString CMakeConfigItem::expandedValue(const ProjectExplorer::Kit *k) const
|
||||
{
|
||||
return k->macroExpander()->expand(QString::fromUtf8(value));
|
||||
}
|
||||
|
||||
std::function<bool (const CMakeConfigItem &a, const CMakeConfigItem &b)> CMakeConfigItem::sortOperator()
|
||||
{
|
||||
return [](const CMakeConfigItem &a, const CMakeConfigItem &b) { return a.key < b.key; };
|
||||
|
||||
@@ -30,6 +30,8 @@
|
||||
|
||||
#include <functional>
|
||||
|
||||
namespace ProjectExplorer { class Kit; }
|
||||
|
||||
namespace CMakeProjectManager {
|
||||
|
||||
class CMakeConfigItem {
|
||||
@@ -41,9 +43,12 @@ public:
|
||||
CMakeConfigItem(const QByteArray &k, const QByteArray &v);
|
||||
|
||||
static QByteArray valueOf(const QByteArray &key, const QList<CMakeConfigItem> &input);
|
||||
|
||||
static QString expandedValueOf(const ProjectExplorer::Kit *k, const QByteArray &key,
|
||||
const QList<CMakeConfigItem> &input);
|
||||
bool isNull() const { return key.isEmpty(); }
|
||||
|
||||
QString expandedValue(const ProjectExplorer::Kit *k) const;
|
||||
|
||||
static std::function<bool(const CMakeConfigItem &a, const CMakeConfigItem &b)> sortOperator();
|
||||
static CMakeConfigItem fromString(const QString &s);
|
||||
QString toString() const;
|
||||
|
||||
@@ -341,8 +341,10 @@ void CMakeProject::runCMake()
|
||||
return;
|
||||
|
||||
BuildDirManager *bdm = bc->buildDirManager();
|
||||
if (bdm && !bdm->isParsing())
|
||||
if (bdm && !bdm->isParsing()) {
|
||||
bdm->checkConfiguration();
|
||||
bdm->forceReparse();
|
||||
}
|
||||
}
|
||||
|
||||
QList<CMakeBuildTarget> CMakeProject::buildTargets() const
|
||||
|
||||
@@ -35,7 +35,8 @@ namespace CMakeProjectManager {
|
||||
static bool isTrue(const QString &value)
|
||||
{
|
||||
const QString lower = value.toLower();
|
||||
return lower == QStringLiteral("true") || lower == QStringLiteral("on") || lower == QStringLiteral("1");
|
||||
return lower == QStringLiteral("true") || lower == QStringLiteral("on")
|
||||
|| lower == QStringLiteral("1") || lower == QStringLiteral("yes");
|
||||
}
|
||||
|
||||
ConfigModel::ConfigModel(QObject *parent) : QAbstractTableModel(parent)
|
||||
@@ -71,7 +72,10 @@ Qt::ItemFlags ConfigModel::flags(const QModelIndex &index) const
|
||||
else
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsEditable | Qt::ItemIsSelectable;
|
||||
} else {
|
||||
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
Qt::ItemFlags flags = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
if (item.isUserNew)
|
||||
return flags |= Qt::ItemIsEditable;
|
||||
return flags;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -163,7 +167,7 @@ bool ConfigModel::setData(const QModelIndex &index, const QVariant &value, int r
|
||||
InternalDataItem &item = itemAtRow(index.row());
|
||||
switch (index.column()) {
|
||||
case 0:
|
||||
if (!item.key.isEmpty())
|
||||
if (!item.key.isEmpty() && !item.isUserNew)
|
||||
return false;
|
||||
item.key = newValue;
|
||||
item.isUserNew = true;
|
||||
@@ -202,6 +206,25 @@ QVariant ConfigModel::headerData(int section, Qt::Orientation orientation, int r
|
||||
}
|
||||
}
|
||||
|
||||
void ConfigModel::appendConfiguration(const QString &key,
|
||||
const QString &value,
|
||||
const ConfigModel::DataItem::Type type,
|
||||
const QString &description)
|
||||
{
|
||||
DataItem item;
|
||||
item.key = key;
|
||||
item.type = type;
|
||||
item.value = value;
|
||||
item.description = description;
|
||||
|
||||
InternalDataItem internalItem(item);
|
||||
internalItem.isUserNew = true;
|
||||
|
||||
beginResetModel();
|
||||
m_configuration.append(internalItem);
|
||||
endResetModel();
|
||||
}
|
||||
|
||||
void ConfigModel::setConfiguration(const QList<ConfigModel::DataItem> &config)
|
||||
{
|
||||
QList<DataItem> tmp = config;
|
||||
|
||||
@@ -55,6 +55,10 @@ public:
|
||||
bool setData(const QModelIndex &index, const QVariant &value, int role) override;
|
||||
QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
|
||||
|
||||
void appendConfiguration(const QString &key,
|
||||
const QString &value = QString(),
|
||||
const DataItem::Type type = DataItem::UNKNOWN,
|
||||
const QString &description = QString());
|
||||
void setConfiguration(const QList<DataItem> &config);
|
||||
void flush();
|
||||
void resetAllChanges();
|
||||
|
||||
Reference in New Issue
Block a user