Files
cmake/Source/QtDialog/CMakeSetupDialog.h
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

168 lines
4.3 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 <memory>
#include <QEventLoop>
#include <QMainWindow>
#include <QThread>
#include <QVector>
#include "QCMake.h"
#include "QCMakePreset.h"
#include "ui_CMakeSetupDialog.h"
class QCMakePresetItemModel;
class QCMakeThread;
class CMakeCacheModel;
class QProgressBar;
class QToolButton;
#ifdef QT_WINEXTRAS
class QWinTaskbarButton;
#endif
/// Qt user interface for CMake
class CMakeSetupDialog
: public QMainWindow
, public Ui::CMakeSetupDialog
{
Q_OBJECT
public:
CMakeSetupDialog();
~CMakeSetupDialog();
public slots:
void setBinaryDirectory(QString const& dir);
void setSourceDirectory(QString const& dir);
void setDeferredPreset(QString const& preset);
void setStartupBinaryDirectory(bool startup);
protected slots:
void initialize();
void doConfigure();
void doGenerate();
void doOpenProject();
void doInstallForCommandLine();
void doHelp();
void doAbout();
void doInterrupt();
void error(QString const& message);
void message(QString const& message);
void doSourceBrowse();
void doBinaryBrowse();
void doReloadCache();
void doDeleteCache();
void updateSourceDirectory(QString const& dir);
void updateBinaryDirectory(QString const& dir);
void updatePresets(QVector<QCMakePreset> const& presets);
void updatePreset(QString const& name);
void onPresetApplied(quint64 requestId, QString const& name,
QCMakePropertyList const& properties);
void showPresetLoadError(QString const& dir, QString const& message);
void showProgress(QString const& msg, float percent);
void setEnabledState(bool);
bool setupFirstConfigure();
void updateGeneratorLabel(QString const& gen);
void setExitAfterGenerate(bool);
void addBinaryPath(QString const&);
QStringList loadBuildPaths();
void saveBuildPaths(QStringList const&);
void onBinaryDirectoryChanged(QString const& dir);
void onSourceDirectoryChanged(QString const& dir);
void onBuildPresetChanged(QString const& name);
void setCacheModified();
void removeSelectedCacheEntries();
void selectionChanged();
void editEnvironment();
void addCacheEntry();
void startSearch();
void setDebugOutput(bool);
void setAdvancedView(bool);
void setGroupedView(bool);
void showUserChanges();
void setSearchFilter(QString const& str);
bool prepareConfigure();
bool doConfigureInternal();
bool doGenerateInternal();
void exitLoop(int);
void doOutputContextMenu(QPoint pt);
void doOutputFindDialog();
void doOutputFindNext(bool directionForward = true);
void doOutputFindPrev();
void doOutputErrorNext();
void doRegexExplorerDialog();
/// display the modal warning messages dialog window
void doWarningMessagesDialog();
protected:
enum State
{
Interrupting,
ReadyConfigure,
ReadyGenerate,
Configuring,
Generating
};
void enterState(State s);
// Recompute command/control availability from state and pending. Kept out
// of enterState() since pending can toggle without a lifecycle change.
void updateCommandState();
void closeEvent(QCloseEvent*);
void dragEnterEvent(QDragEnterEvent*);
void dropEvent(QDropEvent*);
QCMakeThread* CMakeThread;
bool ExitAfterGenerate;
bool CacheModified;
bool ConfigureNeeded;
QAction* ReloadCacheAction;
QAction* DeleteCacheAction;
QAction* ExitAction;
QAction* ConfigureAction;
QAction* GenerateAction;
QAction* InstallForCommandLineAction;
State CurrentState;
QString DeferredPreset;
bool StartupBinaryDirectory = false;
// Only the completion matching LatestPresetRequestId is accepted; a request
// is outstanding while PresetApplicationPending holds.
quint64 LatestPresetRequestId = 0;
bool PresetApplicationPending = false;
QTextCharFormat ErrorFormat;
QTextCharFormat MessageFormat;
QStringList AddVariableNames;
QStringList AddVariableTypes;
QStringList FindHistory;
QEventLoop LocalLoop;
#ifdef QT_WINEXTRAS
QWinTaskbarButton* TaskbarButton;
#endif
float ProgressOffset;
float ProgressFactor;
};
// QCMake instance on a thread
class QCMakeThread : public QThread
{
Q_OBJECT
public:
QCMakeThread(QObject* p);
QCMake* cmakeInstance() const;
signals:
void cmakeInitialized();
protected:
virtual void run();
std::unique_ptr<QCMake> CMakeInstance;
};