Files
Daksh Mamodiya fdc2c2b9c7 cmake-gui: settle preset application before Configure/Generate
Selecting a configure preset applies on the worker thread, but Configure
and Generate stayed enabled and could snapshot the stale cache model
first. Tokenize preset application, disable the dependent actions until
the completion lands, and accept only the latest request.

Fixes: #28085
2026-09-11 23:24:10 +05:30

205 lines
6.5 KiB
C++

/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
file LICENSE.rst or https://cmake.org/licensing for details. */
#pragma once
#include "cmConfigure.h" // IWYU pragma: keep
#include "cmCMakePresetsGraph.h"
#include "cmDiagnostics.h"
#include "cmake.h"
#ifdef _MSC_VER
# pragma warning(disable : 4127)
# pragma warning(disable : 4512)
#endif
#include <memory>
#include <vector>
#include <QAtomicInt>
#include <QList>
#include <QMetaType>
#include <QObject>
#include <QProcessEnvironment>
#include <QString>
#include <QStringList>
#include <QTimer>
#include <QVariant>
#include "QCMakePreset.h"
/// struct to represent cmake properties in Qt
/// Value is of type String or Bool
struct QCMakeProperty
{
enum PropertyType
{
BOOL,
PATH,
FILEPATH,
STRING
};
QString Key;
QVariant Value;
QStringList Strings;
QString Help;
PropertyType Type;
bool Advanced;
bool operator==(QCMakeProperty const& other) const
{
return this->Key == other.Key;
}
bool operator<(QCMakeProperty const& other) const
{
return this->Key < other.Key;
}
};
// list of properties
using QCMakePropertyList = QList<QCMakeProperty>;
// allow QVariant to be a property or list of properties
Q_DECLARE_METATYPE(QCMakeProperty)
Q_DECLARE_METATYPE(QCMakePropertyList)
Q_DECLARE_METATYPE(QProcessEnvironment)
/// Qt API for CMake library.
/// Wrapper like class allows for easier integration with
/// Qt features such as, signal/slot connections, multi-threading, etc..
class QCMake : public QObject
{
Q_OBJECT
public:
QCMake(QObject* p = nullptr);
~QCMake();
public slots:
/// load the cache file in a directory
void loadCache(QString const& dir);
/// set the source directory containing the source
void setSourceDirectory(QString const& dir);
/// set the binary directory to build in
void setBinaryDirectory(QString const& dir);
/// set the preset name to use
void setPreset(QString const& name, bool setBinary = true);
/// apply a preset on behalf of the UI, emitting a tokenized completion
void applyPreset(QString const& name, bool setBinary, quint64 requestId);
/// set the desired generator to use
void setGenerator(QString const& generator);
/// set the desired generator to use
void setPlatform(QString const& platform);
/// set the desired generator to use
void setToolset(QString const& toolset);
/// set the configure and generate environment
void setEnvironment(QProcessEnvironment const& environment);
/// do the configure step
void configure();
/// generate the files
void generate();
/// open the project
void open();
/// set the property values
void setProperties(QCMakePropertyList const&);
/// interrupt the configure or generate process (if connecting, make a direct
/// connection)
void interrupt();
/// delete the cache in binary directory
void deleteCache();
/// reload the cache in binary directory
void reloadCache();
/// set whether to do debug output
void setDebugOutput(bool);
/// set diagnostic action
void setDiagnosticAction(cmDiagnostics::DiagnosticCategory,
cmDiagnostics::DiagnosticAction);
/// check if project IDE open is possible and emit openPossible signal
void checkOpenPossible();
/// Reload the presets files and tree
void loadPresets();
public:
/// get the list of cache properties
QCMakePropertyList properties() const;
/// get the current binary directory
QString binaryDirectory() const;
/// get the current binary directory, possibly a relative path
QString relativeBinaryDirectory() const;
/// get the current source directory
QString sourceDirectory() const;
/// get the current generator
QString generator() const;
/// get the configure and generate environment
QProcessEnvironment environment() const;
/// get the available generators
std::vector<cmake::GeneratorInfo> const& availableGenerators() const;
/// get whether to do debug output
bool getDebugOutput() const;
/// get diagnostic action
cmDiagnosticAction getDiagnosticAction(cmDiagnosticCategory) const;
signals:
/// signal when properties change (during read from disk or configure
/// process)
void propertiesChanged(QCMakePropertyList const& vars);
/// signal when the generator changes
void generatorChanged(QString const& gen);
/// signal when the source directory changes (binary directory already
/// containing a CMakeCache.txt file)
void sourceDirChanged(QString const& dir);
/// signal when the binary directory changes
void binaryDirChanged(QString const& dir);
/// signal when the preset list changes
void presetsChanged(QVector<QCMakePreset> const& presets);
/// signal when the selected preset changes
void presetChanged(QString const& name);
/// signal when a tokenized preset application finishes, with its properties
void presetApplied(quint64 requestId, QString const& name,
QCMakePropertyList const& vars);
/// signal when there's an error reading the presets files
void presetLoadError(QString const& dir, QString const& error);
/// signal for progress events
void progressChanged(QString const& msg, float percent);
/// signal when configure is done
void configureDone(int error);
/// signal when generate is done
void generateDone(int error);
/// signal when there is an output message
void outputMessage(QString const& msg);
/// signal when there is an error message
void errorMessage(QString const& msg);
/// signal when debug output changes
void debugOutputChanged(bool);
/// signal when the toolset changes
void toolsetChanged(QString const& toolset);
/// signal when the platform changes
void platformChanged(QString const& platform);
/// signal when open is done
void openDone(bool successful);
/// signal when open is done
void openPossible(bool possible);
protected:
std::unique_ptr<cmake> CMakeInstance;
bool interruptCallback();
void progressCallback(std::string const& msg, float percent);
void messageCallback(std::string const& msg, char const* title);
void stdoutCallback(std::string const& msg);
void stderrCallback(std::string const& msg);
void setUpEnvironment() const;
QString SourceDirectory;
QString BinaryDirectory;
QString MaybeRelativeBinaryDirectory;
QString Generator;
QString Platform;
QString Toolset;
std::vector<cmake::GeneratorInfo> AvailableGenerators;
cmCMakePresetsGraph CMakePresetsGraph;
QString PresetName;
QString CMakeExecutable;
QAtomicInt InterruptFlag;
QProcessEnvironment StartEnvironment;
QProcessEnvironment Environment;
bool ApplyingPreset = false;
};