diff --git a/plugins/cmake/settings/cmakecachedelegate.cpp b/plugins/cmake/settings/cmakecachedelegate.cpp index 53a6be2d34..21258803c6 100644 --- a/plugins/cmake/settings/cmakecachedelegate.cpp +++ b/plugins/cmake/settings/cmakecachedelegate.cpp @@ -1,190 +1,204 @@ /* KDevelop CMake Support * * Copyright 2008 Aleix Pol * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "cmakecachedelegate.h" #include #include #include +#include #include #include CMakeCacheDelegate::CMakeCacheDelegate(QObject * parent) : QItemDelegate(parent) { m_sample=new KUrlRequester(); } CMakeCacheDelegate::~CMakeCacheDelegate() { delete m_sample; } QWidget * CMakeCacheDelegate::createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index) const { QWidget *ret=nullptr; if(index.column()==2) { QModelIndex typeIdx=index.sibling(index.row(), 1); QString type=typeIdx.model()->data(typeIdx, Qt::DisplayRole).toString(); if(type==QLatin1String("BOOL")) { QCheckBox* box=new QCheckBox(parent); connect(box, &QCheckBox::toggled, this, &CMakeCacheDelegate::checkboxToggled); ret = box; } + else if(type==QLatin1String("STRING")) + { + QModelIndex stringsIdx=index.sibling(index.row(), 5); + QString strings=typeIdx.model()->data(stringsIdx, Qt::DisplayRole).toString(); + if (!strings.isEmpty()) { + QComboBox* comboBox = new QComboBox(parent); + comboBox->setEditable(true); + comboBox->addItems(strings.split(';')); + ret = comboBox; + } else { + ret=QItemDelegate::createEditor(parent, option, index); + } + } else if(type==QLatin1String("PATH") || type==QLatin1String("FILEPATH")) { KUrlRequester *r=new KUrlRequester(parent); if(type==QLatin1String("FILEPATH")) r->setMode(KFile::File); else r->setMode(KFile::Directory | KFile::ExistingOnly); emit const_cast(this)->sizeHintChanged ( index ); qCDebug(CMAKE) << "EMITINT!" << index; ret=r; } else { ret=QItemDelegate::createEditor(parent, option, index); } if(!ret) qCDebug(CMAKE) << "Did not recognize type " << type; } return ret; } void CMakeCacheDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const { if(index.column()==2) { QModelIndex typeIdx=index.sibling(index.row(), 1); QString type=index.model()->data(typeIdx, Qt::DisplayRole).toString(); QString value=index.model()->data(index, Qt::DisplayRole).toString(); if(type==QLatin1String("BOOL")) { QCheckBox *boolean=qobject_cast(editor); boolean->setCheckState(value==QLatin1String("ON") ? Qt::Checked : Qt::Unchecked); } else if(type==QLatin1String("PATH") || type==QLatin1String("FILEPATH")) { KUrlRequester *url=qobject_cast(editor); url->setUrl(QUrl(value)); } else { QItemDelegate::setEditorData(editor, index); } } else qCDebug(CMAKE) << "Error. trying to edit a read-only field"; } void CMakeCacheDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const { if(index.column()==2) { QModelIndex typeIdx=index.sibling(index.row(), 1); QString type=model->data(typeIdx, Qt::DisplayRole).toString(); QString value; if(type==QLatin1String("BOOL")) { QCheckBox *boolean=qobject_cast(editor); value = boolean->isChecked() ? "ON" : "OFF"; } else if(type==QLatin1String("PATH") || type==QLatin1String("FILEPATH")) { KUrlRequester *urlreq=qobject_cast(editor); value = urlreq->url().toDisplayString(QUrl::StripTrailingSlash | QUrl::PreferLocalFile); //CMake usually don't put it } else { QItemDelegate::setModelData(editor, model, index); return; } model->setData(index, value, Qt::DisplayRole); } else qCDebug(CMAKE) << "Error. trying to edit a read-only field"; } void CMakeCacheDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const { if(index.column()==2) { QModelIndex typeIdx=index.sibling(index.row(), 1); QString type=index.model()->data(typeIdx, Qt::DisplayRole).toString(); if(type==QLatin1String("BOOL")) return; } QItemDelegate::paint(painter, option, index); } QSize CMakeCacheDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index ) const { // qCDebug(CMAKE) << "calculant" << index << bool(option.state & QStyle::State_Editing); QSize ret=QItemDelegate::sizeHint(option, index); if(index.column()==2 && option.state & QStyle::State_Editing) { QModelIndex typeIdx=index.sibling(index.row(), 1); QString type=index.model()->data(typeIdx, Qt::DisplayRole).toString(); if(type==QLatin1String("PATH")) { ret.setHeight(m_sample->sizeHint().height()); } } return ret; } void CMakeCacheDelegate::checkboxToggled() { // whenever the check box gets toggled, we directly want to set the // model data which is done by closing the editor which in turn // calls setModelData. otherwise, the behavior is quite confusing, see e.g. // https://bugs.kde.org/show_bug.cgi?id=304352 QCheckBox* editor = qobject_cast(sender()); Q_ASSERT(editor); closeEditor(editor); } void CMakeCacheDelegate::closingEditor(QWidget * editor, QAbstractItemDelegate::EndEditHint hint) { Q_UNUSED(editor); Q_UNUSED(hint); qCDebug(CMAKE) << "closing..."; } // void CMakeCacheDelegate::updateEditorGeometry ( QWidget * editor, const QStyleOptionViewItem & option, // const QModelIndex & index ) const // { // if(index.column()==2) // { // QModelIndex typeIdx=index.sibling(index.row(), 1); // QString type=index.model()->data(typeIdx, Qt::DisplayRole).toString(); // if(type=="PATH") // { // KUrlRequester* urlreq=qobject_cast(editor); // urlreq->setGeometry(QRect(option.rect.topLeft(), urlreq->sizeHint())); // return; // } // } // QItemDelegate::updateEditorGeometry( editor, option, index ); // } diff --git a/plugins/cmake/settings/cmakecachemodel.cpp b/plugins/cmake/settings/cmakecachemodel.cpp index 69a35c3529..3dbe3b4e3f 100644 --- a/plugins/cmake/settings/cmakecachemodel.cpp +++ b/plugins/cmake/settings/cmakecachemodel.cpp @@ -1,217 +1,224 @@ /* KDevelop CMake Support * * Copyright 2007 Aleix Pol * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "cmakecachemodel.h" #include #include #include "cmakecachereader.h" #include //4 columns: name, type, value, comment //name:type=value - comment CMakeCacheModel::CMakeCacheModel(QObject *parent, const KDevelop::Path &path) : QStandardItemModel(parent), m_filePath(path) { read(); } void CMakeCacheModel::reset() { emit beginResetModel(); clear(); m_internal.clear(); m_modifiedRows.clear(); read(); emit endResetModel(); } void CMakeCacheModel::read() { // Set headers QStringList labels; labels.append(i18n("Name")); labels.append(i18n("Type")); labels.append(i18n("Value")); labels.append(i18n("Comment")); labels.append(i18n("Advanced")); + labels.append(i18n("Strings")); setHorizontalHeaderLabels(labels); QFile file(m_filePath.toLocalFile()); if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) { qCDebug(CMAKE) << "error. Could not find the file"; return; } int currentIdx=0; QStringList currentComment; QTextStream in(&file); QHash variablePos; while (!in.atEnd()) { QString line = in.readLine().trimmed(); if(line.startsWith(QLatin1String("//"))) currentComment += line.right(line.count()-2); else if(!line.isEmpty() && !line.startsWith('#')) //it is a variable { CacheLine c; c.readLine(line); if(c.isCorrect()) { QString name=c.name(), flag=c.flag(); QString type=c.type(); QString value=c.value(); QList lineItems; lineItems.append(new QStandardItem(name)); lineItems.append(new QStandardItem(type)); lineItems.append(new QStandardItem(value)); lineItems.append(new QStandardItem(currentComment.join(QStringLiteral("\n")))); if(flag==QLatin1String("INTERNAL")) { m_internal.insert(name); - } else if(flag==QLatin1String("ADVANCED")) + } else if(flag==QLatin1String("ADVANCED") || flag==QLatin1String("STRINGS")) { if(variablePos.contains(name)) { int pos=variablePos[name]; - QStandardItem *p = item(pos, 4); + + // if the flag is not ADVANCED, it's STRINGS. + // The latter is stored in column 5 + int column = flag==QLatin1String("ADVANCED") ? 4 : 5; + QStandardItem *p = item(pos, column); if(!p) { p=new QStandardItem(value); - setItem(pos, 4, p); + setItem(pos, column, p); } else { p->setText(value); } } else { qCDebug(CMAKE) << "Flag for an unknown variable"; } } if(!flag.isEmpty()) { lineItems[0]->setText(lineItems[0]->text()+'-'+flag); } insertRow(currentIdx, lineItems); - variablePos[name]=currentIdx; + if (!variablePos.contains(name)) { + variablePos[name]=currentIdx; + } currentIdx++; currentComment.clear(); } } else if(line.startsWith('#') && line.contains(QLatin1String("INTERNAL"))) { m_internalBegin=currentIdx; // qCDebug(CMAKE) << "Comment: " << line << " -.- " << currentIdx; } else if(!line.startsWith('#') && !line.isEmpty()) { qCDebug(CMAKE) << "unrecognized cache line: " << line; } } } bool CMakeCacheModel::setData(const QModelIndex& index, const QVariant& value, int role) { bool ret = QStandardItemModel::setData(index, value, role); if (ret) { m_modifiedRows.insert(index.row()); } return ret; } QVariantMap CMakeCacheModel::changedValues() const { QVariantMap ret; for(int i=0; itext()+':'+type->text(), valu->text()); } return ret; } QString CMakeCacheModel::value(const QString & varName) const { for(int i=0; itext()==varName) { QStandardItem* valu = item(i, 2); return valu->text(); } } return QString(); } bool CMakeCacheModel::isAdvanced(int i) const { QStandardItem *p=item(i, 4); bool isAdv= (p!=nullptr) || i>m_internalBegin; if(!isAdv) { p=item(i, 1); isAdv = p->text()==QLatin1String("INTERNAL") || p->text()==QLatin1String("STATIC"); } return isAdv || m_internal.contains(item(i,0)->text()); } bool CMakeCacheModel::isInternal(int i) const { bool isInt= i>m_internalBegin; return isInt; } QList< QModelIndex > CMakeCacheModel::persistentIndices() const { QList< QModelIndex > ret; for(int i=0; itext()==QLatin1String("BOOL")) { QStandardItem* valu = item(i, 2); ret.append(valu->index()); } } return ret; } KDevelop::Path CMakeCacheModel::filePath() const { return m_filePath; } diff --git a/plugins/cmake/settings/cmakepreferences.cpp b/plugins/cmake/settings/cmakepreferences.cpp index f2bcb81f54..75a9d7838e 100644 --- a/plugins/cmake/settings/cmakepreferences.cpp +++ b/plugins/cmake/settings/cmakepreferences.cpp @@ -1,409 +1,410 @@ /* KDevelop CMake Support * * Copyright 2006 Matt Rogers * Copyright 2007-2008 Aleix Pol * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA * 02110-1301, USA. */ #include "cmakepreferences.h" #include #include #include #include #include #include #include #include #include #include "ui_cmakebuildsettings.h" #include "cmakecachedelegate.h" #include "cmakebuilddirchooser.h" #include "cmakebuilderconfig.h" #include #include #include #include #include #include using namespace KDevelop; CMakePreferences::CMakePreferences(IPlugin* plugin, const ProjectConfigOptions& options, QWidget* parent) : ConfigPage(plugin, nullptr, parent), m_project(options.project), m_currentModel(nullptr) { m_prefsUi = new Ui::CMakeBuildSettings; m_prefsUi->setupUi(this); m_prefsUi->addBuildDir->setIcon(QIcon::fromTheme( QStringLiteral("list-add") )); m_prefsUi->removeBuildDir->setIcon(QIcon::fromTheme( QStringLiteral("list-remove") )); m_prefsUi->addBuildDir->setText(QString()); m_prefsUi->removeBuildDir->setText(QString()); m_prefsUi->cacheList->setItemDelegate(new CMakeCacheDelegate(m_prefsUi->cacheList)); m_prefsUi->cacheList->setSelectionMode(QAbstractItemView::SingleSelection); m_prefsUi->cacheList->horizontalHeader()->setStretchLastSection(true); m_prefsUi->cacheList->verticalHeader()->hide(); // configure the extraArguments widget to span the advanced box width but not // expand the dialog to the width of the longest element in the argument history. // static_cast needed because KComboBox::minimumSizeHint() override mistakingly made it protected m_prefsUi->extraArguments->setMinimumWidth(static_cast(m_prefsUi->extraArguments)->minimumSizeHint().width()); m_extraArgumentsHistory = new CMakeExtraArgumentsHistory(m_prefsUi->extraArguments); connect(m_prefsUi->buildDirs, static_cast(&KComboBox::currentIndexChanged), this, &CMakePreferences::buildDirChanged); connect(m_prefsUi->showInternal, &QCheckBox::stateChanged, this, &CMakePreferences::showInternal); connect(m_prefsUi->addBuildDir, &QPushButton::pressed, this, &CMakePreferences::createBuildDir); connect(m_prefsUi->removeBuildDir, &QPushButton::pressed, this, &CMakePreferences::removeBuildDir); connect(m_prefsUi->showAdvanced, &QPushButton::toggled, this, &CMakePreferences::showAdvanced); connect(m_prefsUi->environment, &EnvironmentSelectionWidget::currentProfileChanged, this, &CMakePreferences::changed); connect(m_prefsUi->configureEnvironment, &EnvironmentConfigureButton::environmentConfigured, this, &CMakePreferences::changed); connect(m_prefsUi->installationPrefix, &KUrlRequester::textChanged, this, &CMakePreferences::changed); connect(m_prefsUi->buildType, static_cast(&QComboBox::currentIndexChanged), this, &CMakePreferences::changed); connect(m_prefsUi->buildType, &QComboBox::currentTextChanged, this, &CMakePreferences::changed); connect(m_prefsUi->extraArguments, &KComboBox::currentTextChanged, this, &CMakePreferences::changed); connect(m_prefsUi->extraArguments, &KComboBox::editTextChanged, this, &CMakePreferences::changed); connect(m_prefsUi->cMakeExecutable, &KUrlRequester::textChanged, this, &CMakePreferences::changed); showInternal(m_prefsUi->showInternal->checkState()); m_subprojFolder = Path(options.projectTempFile).parent(); qCDebug(CMAKE) << "Source folder: " << m_srcFolder << options.projectTempFile; // foreach(const QVariant &v, args) // { // qCDebug(CMAKE) << "arg: " << v.toString(); // } m_prefsUi->configureEnvironment->setSelectionWidget(m_prefsUi->environment); m_prefsUi->showAdvanced->setChecked(false); showAdvanced(false); reset(); // load the initial values } CMakePreferences::~CMakePreferences() { CMake::removeOverrideBuildDirIndex(m_project); delete m_extraArgumentsHistory; delete m_prefsUi; } void CMakePreferences::initAdvanced() { m_prefsUi->environment->setCurrentProfile( CMake::currentEnvironment(m_project) ); m_prefsUi->installationPrefix->setText(CMake::currentInstallDir(m_project).toLocalFile()); m_prefsUi->installationPrefix->setMode(KFile::Directory); const QString buildType = CMake::currentBuildType(m_project); if (m_prefsUi->buildType->findText(buildType) == -1) { m_prefsUi->buildType->addItem(buildType); } m_prefsUi->buildType->setCurrentIndex(m_prefsUi->buildType->findText(buildType)); m_prefsUi->extraArguments->setEditText(CMake::currentExtraArguments(m_project)); m_prefsUi->cMakeExecutable->setText(CMake::currentCMakeExecutable(m_project).toLocalFile()); } void CMakePreferences::reset() { qCDebug(CMAKE) << "********loading"; m_prefsUi->buildDirs->clear(); m_prefsUi->buildDirs->addItems( CMake::allBuildDirs(m_project) ); CMake::removeOverrideBuildDirIndex(m_project); // addItems() triggers buildDirChanged(), compensate for it m_prefsUi->buildDirs->setCurrentIndex( CMake::currentBuildDirIndex(m_project) ); initAdvanced(); m_srcFolder = m_project->path(); m_prefsUi->removeBuildDir->setEnabled(m_prefsUi->buildDirs->count()!=0); // QString cmDir=group.readEntry("CMakeDirectory"); // m_prefsUi->kcfg_cmakeDir->setUrl(QUrl(cmDir)); // qCDebug(CMAKE) << "cmakedir" << cmDir; } void CMakePreferences::apply() { qCDebug(CMAKE) << "*******saving"; // the build directory list is incrementally maintained through createBuildDir() and removeBuildDir(). // We won't rewrite it here based on the data from m_prefsUi->buildDirs. CMake::removeOverrideBuildDirIndex( m_project, true ); // save current selection int savedBuildDir = CMake::currentBuildDirIndex(m_project); if (savedBuildDir < 0) { // no build directory exists: skip any writing to config file as well as configuring return; } CMake::setCurrentEnvironment( m_project, m_prefsUi->environment->currentProfile() ); CMake::setCurrentInstallDir( m_project, Path(m_prefsUi->installationPrefix->text()) ); const QString buildType = m_prefsUi->buildType->currentText(); if (m_prefsUi->buildType->findText(buildType) == -1) { m_prefsUi->buildType->addItem(buildType); } CMake::setCurrentBuildType( m_project, buildType ); CMake::setCurrentExtraArguments( m_project, m_prefsUi->extraArguments->currentText() ); CMake::setCurrentCMakeExecutable( m_project, Path(m_prefsUi->cMakeExecutable->text()) ); qCDebug(CMAKE) << "writing to cmake config: using builddir " << CMake::currentBuildDirIndex(m_project); qCDebug(CMAKE) << "writing to cmake config: builddir path " << CMake::currentBuildDir(m_project); qCDebug(CMAKE) << "writing to cmake config: installdir " << CMake::currentInstallDir(m_project); qCDebug(CMAKE) << "writing to cmake config: build type " << CMake::currentBuildType(m_project); qCDebug(CMAKE) << "writing to cmake config: cmake executable " << CMake::currentCMakeExecutable(m_project); qCDebug(CMAKE) << "writing to cmake config: environment " << CMake::currentEnvironment(m_project); //We run cmake on the builddir to generate it configure(); } void CMakePreferences::defaults() { // do nothing } void CMakePreferences::configureCacheView() { // Sets up the cache view after model re-creation/reset. // Emits changed(false) because model re-creation probably means // mass programmatical invocation of itemChanged(), which invokes changed(true) - which is not what we want. m_prefsUi->cacheList->setModel(m_currentModel); m_prefsUi->cacheList->hideColumn(1); m_prefsUi->cacheList->hideColumn(3); m_prefsUi->cacheList->hideColumn(4); + m_prefsUi->cacheList->hideColumn(5); m_prefsUi->cacheList->horizontalHeader()->resizeSection(0, 200); if( m_currentModel ) { m_prefsUi->cacheList->setEnabled( true ); foreach(const QModelIndex & idx, m_currentModel->persistentIndices()) { m_prefsUi->cacheList->openPersistentEditor(idx); } } else { m_prefsUi->cacheList->setEnabled( false ); } showInternal(m_prefsUi->showInternal->checkState()); } void CMakePreferences::updateCache(const Path &newBuildDir) { const Path file = newBuildDir.isValid() ? Path(newBuildDir, QStringLiteral("CMakeCache.txt")) : Path(); if(QFile::exists(file.toLocalFile())) { if (m_currentModel) { m_currentModel->deleteLater(); } m_currentModel = new CMakeCacheModel(this, file); configureCacheView(); connect(m_currentModel, &CMakeCacheModel::itemChanged, this, &CMakePreferences::cacheEdited); connect(m_currentModel, &CMakeCacheModel::modelReset, this, &CMakePreferences::configureCacheView); connect(m_prefsUi->cacheList->selectionModel(), &QItemSelectionModel::currentChanged, this, &CMakePreferences::listSelectionChanged); } else { disconnect(m_prefsUi->cacheList->selectionModel(), &QItemSelectionModel::currentChanged, this, nullptr); if (m_currentModel) { m_currentModel->deleteLater(); m_currentModel = nullptr; } configureCacheView(); } if( !m_currentModel ) emit changed(); } void CMakePreferences::listSelectionChanged(const QModelIndex & index, const QModelIndex& ) { qCDebug(CMAKE) << "item " << index << " selected"; QModelIndex idx = index.sibling(index.row(), 3); QModelIndex idxType = index.sibling(index.row(), 1); QString comment=QStringLiteral("%1. %2") .arg(m_currentModel->itemFromIndex(idxType)->text()) .arg(m_currentModel->itemFromIndex(idx)->text()); m_prefsUi->commentText->setText(comment); } void CMakePreferences::showInternal(int state) { if(!m_currentModel) return; bool showAdv=(state == Qt::Checked); for(int i=0; irowCount(); i++) { bool hidden=m_currentModel->isInternal(i) || (!showAdv && m_currentModel->isAdvanced(i)); m_prefsUi->cacheList->setRowHidden(i, hidden); } } void CMakePreferences::buildDirChanged(int index) { CMake::setOverrideBuildDirIndex( m_project, index ); const Path buildDir = CMake::currentBuildDir(m_project); initAdvanced(); updateCache(buildDir); qCDebug(CMAKE) << "builddir Changed" << buildDir; emit changed(); } void CMakePreferences::cacheUpdated() { const Path buildDir = CMake::currentBuildDir(m_project); updateCache(buildDir); qCDebug(CMAKE) << "cache updated for" << buildDir; } void CMakePreferences::createBuildDir() { CMakeBuildDirChooser bdCreator; bdCreator.setProject( m_project ); // NOTE: (on removing the trailing slashes) // Generally, we have no clue about how shall a trailing slash look in the current system. // Moreover, the slash may be a part of the filename. // It may be '/' or '\', so maybe should we rely on CMake::allBuildDirs() for returning well-formed paths? QStringList used = CMake::allBuildDirs( m_project ); bdCreator.setAlreadyUsed(used); bdCreator.setCMakeExecutable(Path(CMakeBuilderSettings::self()->cmakeExecutable().toLocalFile())); if(bdCreator.exec()) { int addedBuildDirIndex = m_prefsUi->buildDirs->count(); // Initialize the kconfig items with the values from the dialog, this ensures the settings // end up in the config file once the changes are saved qCDebug(CMAKE) << "adding to cmake config: new builddir index" << addedBuildDirIndex; qCDebug(CMAKE) << "adding to cmake config: builddir path " << bdCreator.buildFolder(); qCDebug(CMAKE) << "adding to cmake config: installdir " << bdCreator.installPrefix(); qCDebug(CMAKE) << "adding to cmake config: extra args" << bdCreator.extraArguments(); qCDebug(CMAKE) << "adding to cmake config: build type " << bdCreator.buildType(); qCDebug(CMAKE) << "adding to cmake config: cmake executable " << bdCreator.cmakeExecutable(); qCDebug(CMAKE) << "adding to cmake config: environment empty"; CMake::setOverrideBuildDirIndex( m_project, addedBuildDirIndex ); CMake::setBuildDirCount( m_project, addedBuildDirIndex + 1 ); CMake::setCurrentBuildDir( m_project, bdCreator.buildFolder() ); CMake::setCurrentInstallDir( m_project, bdCreator.installPrefix() ); CMake::setCurrentExtraArguments( m_project, bdCreator.extraArguments() ); CMake::setCurrentBuildType( m_project, bdCreator.buildType() ); CMake::setCurrentCMakeExecutable(m_project, bdCreator.cmakeExecutable()); CMake::setCurrentEnvironment( m_project, QString() ); QString newbuilddir = bdCreator.buildFolder().toLocalFile(); m_prefsUi->buildDirs->addItem( newbuilddir ); m_prefsUi->buildDirs->setCurrentIndex( addedBuildDirIndex ); m_prefsUi->removeBuildDir->setEnabled( true ); qCDebug(CMAKE) << "Emitting changed signal for cmake kcm"; emit changed(); } //TODO: Save it for next runs } void CMakePreferences::removeBuildDir() { int curr=m_prefsUi->buildDirs->currentIndex(); if(curr < 0) return; Path removedPath = CMake::currentBuildDir( m_project ); QString removed = removedPath.toLocalFile(); if(QDir(removed).exists()) { KMessageBox::ButtonCode ret = KMessageBox::warningYesNo(this, i18n("The %1 directory is about to be removed in KDevelop's list.\n" "Do you want KDevelop to remove it in the file system as well?", removed)); if(ret == KMessageBox::Yes) { auto deleteJob = KIO::del(removedPath.toUrl()); KJobWidgets::setWindow(deleteJob, this); if (!deleteJob->exec()) KMessageBox::error(this, i18n("Could not remove: %1", removed)); } } qCDebug(CMAKE) << "removing from cmake config: using builddir " << curr; qCDebug(CMAKE) << "removing from cmake config: builddir path " << removedPath; qCDebug(CMAKE) << "removing from cmake config: installdir " << CMake::currentInstallDir( m_project ); qCDebug(CMAKE) << "removing from cmake config: extra args" << CMake::currentExtraArguments( m_project ); qCDebug(CMAKE) << "removing from cmake config: buildtype " << CMake::currentBuildType( m_project ); qCDebug(CMAKE) << "removing from cmake config: cmake executable " << CMake::currentCMakeExecutable(m_project); qCDebug(CMAKE) << "removing from cmake config: environment " << CMake::currentEnvironment( m_project ); CMake::removeBuildDirConfig(m_project); m_prefsUi->buildDirs->removeItem( curr ); // this triggers buildDirChanged() if(m_prefsUi->buildDirs->count()==0) m_prefsUi->removeBuildDir->setEnabled(false); emit changed(); } void CMakePreferences::configure() { IProjectBuilder *b=m_project->buildSystemManager()->builder(); KJob* job=b->configure(m_project); if( m_currentModel ) { QVariantMap map = m_currentModel->changedValues(); job->setProperty("extraCMakeCacheValues", map); connect(job, &KJob::finished, m_currentModel, &CMakeCacheModel::reset); } else { connect(job, &KJob::finished, this, &CMakePreferences::cacheUpdated); } connect(job, &KJob::finished, m_project, &IProject::reloadModel); ICore::self()->runController()->registerJob(job); } void CMakePreferences::showAdvanced(bool v) { qCDebug(CMAKE) << "toggle pressed: " << v; m_prefsUi->advancedBox->setHidden(!v); } QString CMakePreferences::name() const { return i18n("CMake"); } QString CMakePreferences::fullName() const { return i18n("Configure CMake settings"); } QIcon CMakePreferences::icon() const { return QIcon::fromTheme("cmake"); }