ENH: Prompt user for generator when there is none.
Many minor improvements, bug fixes, and style fixes.
This commit is contained in:
parent
7bd73d3e0d
commit
cfa723d457
|
@ -31,6 +31,7 @@ int main(int argc, char** argv)
|
|||
// TODO handle CMake args
|
||||
|
||||
CMakeSetupDialog dialog;
|
||||
dialog.setWindowTitle("CMakeSetup");
|
||||
dialog.show();
|
||||
|
||||
return app.exec();
|
||||
|
|
|
@ -18,32 +18,46 @@
|
|||
#include "CMakeSetupDialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QThread>
|
||||
#include <QProgressBar>
|
||||
#include <QMessageBox>
|
||||
#include <QStatusBar>
|
||||
#include <QToolButton>
|
||||
#include <QDialogButtonBox>
|
||||
#include <QCloseEvent>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "QCMake.h"
|
||||
#include "QCMakeCacheView.h"
|
||||
|
||||
// QCMake instance on a thread
|
||||
class QCMakeThread : public QThread
|
||||
QCMakeThread::QCMakeThread(QObject* p)
|
||||
: QThread(p), CMakeInstance(NULL)
|
||||
{
|
||||
public:
|
||||
QCMakeThread(QObject* p) : QThread(p) { }
|
||||
QCMake* CMakeInstance;
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void run()
|
||||
{
|
||||
this->CMakeInstance = new QCMake;
|
||||
this->exec();
|
||||
delete this->CMakeInstance;
|
||||
}
|
||||
};
|
||||
QCMake* QCMakeThread::cmakeInstance() const
|
||||
{
|
||||
return this->CMakeInstance;
|
||||
}
|
||||
|
||||
void QCMakeThread::processEvents()
|
||||
{
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void QCMakeThread::run()
|
||||
{
|
||||
this->CMakeInstance = new QCMake;
|
||||
// make the cmake thread to process events it receives from the GUI thread
|
||||
QObject::connect(this->CMakeInstance, SIGNAL(progressChanged(QString, float)),
|
||||
this, SLOT(processEvents()), Qt::DirectConnection);
|
||||
QObject::connect(this->CMakeInstance, SIGNAL(outputMessage(QString)),
|
||||
this, SLOT(processEvents()), Qt::DirectConnection);
|
||||
// emit that this cmake thread is ready for use
|
||||
emit this->cmakeInitialized();
|
||||
this->exec();
|
||||
delete this->CMakeInstance;
|
||||
this->CMakeInstance = NULL;
|
||||
}
|
||||
|
||||
CMakeSetupDialog::CMakeSetupDialog()
|
||||
{
|
||||
|
@ -65,25 +79,26 @@ CMakeSetupDialog::CMakeSetupDialog()
|
|||
|
||||
// start the cmake worker thread
|
||||
this->CMakeThread = new QCMakeThread(this);
|
||||
// TODO does this guarantee the QCMake instance is created before initialize is called?
|
||||
QObject::connect(this->CMakeThread, SIGNAL(started()),
|
||||
this, SLOT(initialize()));
|
||||
QObject::connect(this->CMakeThread, SIGNAL(cmakeInitialized()),
|
||||
this, SLOT(initialize()), Qt::QueuedConnection);
|
||||
this->CMakeThread->start();
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::initialize()
|
||||
{
|
||||
// now the cmake worker thread is running, lets make our connections to it
|
||||
QObject::connect(this->CMakeThread->CMakeInstance,
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
SIGNAL(propertiesChanged(const QCMakeCachePropertyList&)),
|
||||
this->CacheValues->cacheModel(),
|
||||
SLOT(setProperties(const QCMakeCachePropertyList&)));
|
||||
|
||||
QObject::connect(this->ConfigureButton, SIGNAL(clicked(bool)),
|
||||
this, SLOT(doConfigure()));
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(configureDone(int)),
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
SIGNAL(configureDone(int)),
|
||||
this, SLOT(finishConfigure(int)));
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(generateDone(int)),
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
SIGNAL(generateDone(int)),
|
||||
this, SLOT(finishGenerate(int)));
|
||||
|
||||
QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)),
|
||||
|
@ -98,25 +113,31 @@ void CMakeSetupDialog::initialize()
|
|||
this, SLOT(doBinaryBrowse()));
|
||||
|
||||
QObject::connect(this->BinaryDirectory, SIGNAL(editTextChanged(QString)),
|
||||
this->CMakeThread->CMakeInstance, SLOT(setBinaryDirectory(QString)));
|
||||
this, SLOT(setBinaryDirectory(QString)));
|
||||
QObject::connect(this->SourceDirectory, SIGNAL(textChanged(QString)),
|
||||
this->CMakeThread->CMakeInstance, SLOT(setSourceDirectory(QString)));
|
||||
this->CMakeThread->cmakeInstance(),
|
||||
SLOT(setSourceDirectory(QString)));
|
||||
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(sourceDirChanged(QString)),
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
SIGNAL(sourceDirChanged(QString)),
|
||||
this, SLOT(updateSourceDirectory(QString)));
|
||||
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(progressChanged(QString, float)),
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
SIGNAL(progressChanged(QString, float)),
|
||||
this, SLOT(showProgress(QString,float)));
|
||||
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(error(QString, QString, bool*)),
|
||||
this, SLOT(error(QString,QString,bool*)), Qt::BlockingQueuedConnection);
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
SIGNAL(error(QString, QString, bool*)),
|
||||
this, SLOT(error(QString,QString,bool*)),
|
||||
Qt::BlockingQueuedConnection);
|
||||
|
||||
QObject::connect(this->InterruptButton, SIGNAL(clicked(bool)),
|
||||
this->CMakeThread->CMakeInstance, SLOT(interrupt()));
|
||||
this->CMakeThread->cmakeInstance(), SLOT(interrupt()));
|
||||
QObject::connect(this->InterruptButton, SIGNAL(clicked(bool)),
|
||||
this, SLOT(doInterrupt()));
|
||||
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(outputMessage(QString)),
|
||||
QObject::connect(this->CMakeThread->cmakeInstance(),
|
||||
SIGNAL(outputMessage(QString)),
|
||||
this->Output, SLOT(append(QString)));
|
||||
|
||||
QObject::connect(this->HelpButton, SIGNAL(clicked(bool)),
|
||||
|
@ -135,36 +156,45 @@ void CMakeSetupDialog::doConfigure()
|
|||
QDir dir(this->BinaryDirectory->currentText());
|
||||
if(!dir.exists())
|
||||
{
|
||||
QString message = tr("Build directory does not exist, should I create it?\n\n"
|
||||
QString message = tr("Build directory does not exist, "
|
||||
"should I create it?\n\n"
|
||||
"Directory: ");
|
||||
message += this->BinaryDirectory->currentText();
|
||||
QString title = tr("Create Directory");
|
||||
QMessageBox::StandardButton btn =
|
||||
QMessageBox::information(this, title, message, QMessageBox::Yes | QMessageBox::No);
|
||||
QMessageBox::StandardButton btn;
|
||||
btn = QMessageBox::information(this, title, message,
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if(btn == QMessageBox::No)
|
||||
{
|
||||
return;
|
||||
}
|
||||
dir.mkpath(".");
|
||||
}
|
||||
|
||||
// prompt for generator if one doesn't exist
|
||||
if(this->CMakeThread->cmakeInstance()->generator().isEmpty())
|
||||
{
|
||||
this->promptForGenerator();
|
||||
}
|
||||
|
||||
this->InterruptButton->setEnabled(true);
|
||||
this->setEnabledState(false);
|
||||
this->Output->clear();
|
||||
QMetaObject::invokeMethod(this->CMakeThread->CMakeInstance,
|
||||
QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
|
||||
"setProperties", Qt::QueuedConnection,
|
||||
Q_ARG(QCMakeCachePropertyList,
|
||||
this->CacheValues->cacheModel()->properties()));
|
||||
QMetaObject::invokeMethod(this->CMakeThread->CMakeInstance,
|
||||
QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
|
||||
"configure", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::finishConfigure(int error)
|
||||
void CMakeSetupDialog::finishConfigure(int err)
|
||||
{
|
||||
this->InterruptButton->setEnabled(false);
|
||||
this->setEnabledState(true);
|
||||
this->ProgressBar->reset();
|
||||
this->statusBar()->showMessage(tr("Configure Done"), 2000);
|
||||
if(error != 0)
|
||||
if(err != 0)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Error in configuration process, project files may be invalid"),
|
||||
|
@ -172,13 +202,13 @@ void CMakeSetupDialog::finishConfigure(int error)
|
|||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::finishGenerate(int error)
|
||||
void CMakeSetupDialog::finishGenerate(int err)
|
||||
{
|
||||
this->InterruptButton->setEnabled(false);
|
||||
this->setEnabledState(true);
|
||||
this->ProgressBar->reset();
|
||||
this->statusBar()->showMessage(tr("Generate Done"), 2000);
|
||||
if(error != 0)
|
||||
if(err != 0)
|
||||
{
|
||||
QMessageBox::critical(this, tr("Error"),
|
||||
tr("Error in generation process, project files may be invalid"),
|
||||
|
@ -195,19 +225,27 @@ void CMakeSetupDialog::doOk()
|
|||
this->InterruptButton->setEnabled(true);
|
||||
this->setEnabledState(false);
|
||||
this->Output->clear();
|
||||
QMetaObject::invokeMethod(this->CMakeThread->CMakeInstance,
|
||||
QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
|
||||
"generate", Qt::QueuedConnection);
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::closeEvent(QCloseEvent* e)
|
||||
{
|
||||
// don't close if we're busy
|
||||
if(this->InterruptButton->isEnabled())
|
||||
{
|
||||
e->ignore();
|
||||
}
|
||||
|
||||
// prompt for close if there are unsaved changes
|
||||
if(this->CacheValues->cacheModel()->isDirty())
|
||||
{
|
||||
QString message = tr("You have changed options but not rebuilt, "
|
||||
"are you sure you want to exit?");
|
||||
QString title = tr("Confirm Exit");
|
||||
QMessageBox::StandardButton btn =
|
||||
QMessageBox::critical(this, title, message, QMessageBox::Yes | QMessageBox::No);
|
||||
QMessageBox::StandardButton btn;
|
||||
btn = QMessageBox::critical(this, title, message,
|
||||
QMessageBox::Yes | QMessageBox::No);
|
||||
if(btn == QMessageBox::No)
|
||||
{
|
||||
e->ignore();
|
||||
|
@ -217,30 +255,31 @@ void CMakeSetupDialog::closeEvent(QCloseEvent* e)
|
|||
|
||||
void CMakeSetupDialog::doHelp()
|
||||
{
|
||||
QString msg = tr("CMake is used to configure and generate build files for"
|
||||
"software projects. The basic steps for configuring a project are as"
|
||||
"follows:\r\n\r\n1. Select the source directory for the project. This should"
|
||||
"contain the CMakeLists.txt files for the project.\r\n\r\n2. Select the build"
|
||||
"directory for the project. This is the directory where the project will be"
|
||||
"built. It can be the same or a different directory than the source"
|
||||
"directory. For easy clean up, a separate build directory is recommended."
|
||||
"CMake will create the directory if it does not exist.\r\n\r\n3. Once the"
|
||||
"source and binary directories are selected, it is time to press the"
|
||||
"Configure button. This will cause CMake to read all of the input files and"
|
||||
"discover all the variables used by the project. The first time a variable"
|
||||
"is displayed it will be in Red. Users should inspect red variables making"
|
||||
"sure the values are correct. For some projects the Configure process can"
|
||||
"be iterative, so continue to press the Configure button until there are no"
|
||||
"longer red entries.\r\n\r\n4. Once there are no longer red entries, you"
|
||||
"should click the OK button. This will write the build files to the build"
|
||||
QString msg = tr("CMake is used to configure and generate build files for "
|
||||
"software projects. The basic steps for configuring a project are as "
|
||||
"follows:\r\n\r\n1. Select the source directory for the project. This should "
|
||||
"contain the CMakeLists.txt files for the project.\r\n\r\n2. Select the build "
|
||||
"directory for the project. This is the directory where the project will be "
|
||||
"built. It can be the same or a different directory than the source "
|
||||
"directory. For easy clean up, a separate build directory is recommended. "
|
||||
"CMake will create the directory if it does not exist.\r\n\r\n3. Once the "
|
||||
"source and binary directories are selected, it is time to press the "
|
||||
"Configure button. This will cause CMake to read all of the input files and "
|
||||
"discover all the variables used by the project. The first time a variable "
|
||||
"is displayed it will be in Red. Users should inspect red variables making "
|
||||
"sure the values are correct. For some projects the Configure process can "
|
||||
"be iterative, so continue to press the Configure button until there are no "
|
||||
"longer red entries.\r\n\r\n4. Once there are no longer red entries, you "
|
||||
"should click the OK button. This will write the build files to the build "
|
||||
"directory and exit CMake.");
|
||||
|
||||
QDialog dialog;
|
||||
dialog.setWindowTitle(tr("CMakeSetup Help"));
|
||||
QVBoxLayout* l = new QVBoxLayout(&dialog);
|
||||
QLabel* label = new QLabel(&dialog);
|
||||
l->addWidget(label);
|
||||
label->setText(msg);
|
||||
label->setWordWrap(true);
|
||||
QLabel* lab = new QLabel(&dialog);
|
||||
l->addWidget(lab);
|
||||
lab->setText(msg);
|
||||
lab->setWordWrap(true);
|
||||
QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
|
||||
Qt::Horizontal, &dialog);
|
||||
QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
|
||||
|
@ -276,7 +315,7 @@ void CMakeSetupDialog::doBinaryBrowse()
|
|||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this,
|
||||
tr("Enter Path to Build"), this->BinaryDirectory->currentText());
|
||||
if(!dir.isEmpty())
|
||||
if(!dir.isEmpty() && dir != this->BinaryDirectory->currentText())
|
||||
{
|
||||
this->setBinaryDirectory(dir);
|
||||
}
|
||||
|
@ -284,12 +323,11 @@ void CMakeSetupDialog::doBinaryBrowse()
|
|||
|
||||
void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
|
||||
{
|
||||
if(dir != this->BinaryDirectory->currentText())
|
||||
{
|
||||
this->CacheValues->cacheModel()->setProperties(QCMakeCachePropertyList());
|
||||
this->Output->clear();
|
||||
this->BinaryDirectory->setEditText(dir);
|
||||
}
|
||||
this->CacheValues->cacheModel()->clear();
|
||||
this->Output->clear();
|
||||
this->BinaryDirectory->setEditText(dir);
|
||||
QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
|
||||
"setBinaryDirectory", Qt::QueuedConnection, Q_ARG(QString, dir));
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::showProgress(const QString& msg, float percent)
|
||||
|
@ -298,10 +336,12 @@ void CMakeSetupDialog::showProgress(const QString& msg, float percent)
|
|||
this->ProgressBar->setValue(qRound(percent * 100));
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::error(const QString& title, const QString& message, bool* cancel)
|
||||
void CMakeSetupDialog::error(const QString& title, const QString& message,
|
||||
bool* cancel)
|
||||
{
|
||||
QMessageBox::StandardButton btn =
|
||||
QMessageBox::critical(this, title, message, QMessageBox::Ok | QMessageBox::Cancel);
|
||||
QMessageBox::StandardButton btn;
|
||||
btn = QMessageBox::critical(this, title, message,
|
||||
QMessageBox::Ok | QMessageBox::Cancel);
|
||||
if(btn == QMessageBox::Cancel)
|
||||
{
|
||||
*cancel = false;
|
||||
|
@ -318,7 +358,28 @@ void CMakeSetupDialog::setEnabledState(bool enabled)
|
|||
this->ConfigureButton->setEnabled(enabled);
|
||||
this->GenerateButton->setEnabled(enabled);
|
||||
this->CancelButton->setEnabled(enabled);
|
||||
this->HelpButton->setEnabled(enabled);
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::promptForGenerator()
|
||||
{
|
||||
QStringList gens = this->CMakeThread->cmakeInstance()->availableGenerators();
|
||||
QDialog dialog;
|
||||
dialog.setWindowTitle(tr("CMakeSetup choose generator"));
|
||||
QLabel* lab = new QLabel(&dialog);
|
||||
lab->setText(tr("Please select what build system you want CMake to generate files for.\n"
|
||||
"You should select the tool that you will use to build the project.\n"
|
||||
"Press OK once you have made your selection."));
|
||||
QComboBox* combo = new QComboBox(&dialog);
|
||||
combo->addItems(gens);
|
||||
QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
|
||||
Qt::Horizontal, &dialog);
|
||||
QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
|
||||
|
||||
QVBoxLayout* l = new QVBoxLayout(&dialog);
|
||||
l->addWidget(lab);
|
||||
l->addWidget(combo);
|
||||
l->addWidget(btns);
|
||||
dialog.exec();
|
||||
this->CMakeThread->cmakeInstance()->setGenerator(combo->currentText());
|
||||
}
|
||||
|
||||
|
|
|
@ -15,8 +15,12 @@
|
|||
|
||||
=========================================================================*/
|
||||
|
||||
#ifndef CMakeSetupDialog_h
|
||||
#define CMakeSetupDialog_h
|
||||
|
||||
#include "QCMake.h"
|
||||
#include <QMainWindow>
|
||||
#include <QThread>
|
||||
#include "ui_CMakeSetupDialog.h"
|
||||
|
||||
class QCMakeThread;
|
||||
|
@ -48,6 +52,7 @@ protected slots:
|
|||
void setBinaryDirectory(const QString& dir);
|
||||
void showProgress(const QString& msg, float percent);
|
||||
void setEnabledState(bool);
|
||||
void promptForGenerator();
|
||||
|
||||
protected:
|
||||
void closeEvent(QCloseEvent*);
|
||||
|
@ -57,3 +62,23 @@ protected:
|
|||
QToolButton* InterruptButton;
|
||||
};
|
||||
|
||||
// QCMake instance on a thread
|
||||
class QCMakeThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMakeThread(QObject* p);
|
||||
QCMake* cmakeInstance() const;
|
||||
|
||||
signals:
|
||||
void cmakeInitialized();
|
||||
|
||||
protected slots:
|
||||
void processEvents();
|
||||
|
||||
protected:
|
||||
virtual void run();
|
||||
QCMake* CMakeInstance;
|
||||
};
|
||||
|
||||
#endif // CMakeSetupDialog_h
|
||||
|
|
|
@ -17,18 +17,19 @@
|
|||
|
||||
#include "QCMake.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QCoreApplication>
|
||||
|
||||
#include "cmake.h"
|
||||
#include "cmCacheManager.h"
|
||||
#include "cmSystemTools.h"
|
||||
#include "cmExternalMakefileProjectGenerator.h"
|
||||
|
||||
QCMake::QCMake(QObject* p)
|
||||
: QObject(p)
|
||||
{
|
||||
static int metaId = qRegisterMetaType<QCMakeCacheProperty>();
|
||||
static int metaIdList = qRegisterMetaType<QCMakeCachePropertyList>();
|
||||
qRegisterMetaType<QCMakeCacheProperty>();
|
||||
qRegisterMetaType<QCMakeCachePropertyList>();
|
||||
|
||||
QDir appDir(QCoreApplication::applicationDirPath());
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -46,6 +47,14 @@ QCMake::QCMake(QObject* p)
|
|||
|
||||
this->CMakeInstance = new cmake;
|
||||
this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
|
||||
|
||||
std::vector<std::string> generators;
|
||||
this->CMakeInstance->GetRegisteredGenerators(generators);
|
||||
std::vector<std::string>::iterator iter;
|
||||
for(iter = generators.begin(); iter != generators.end(); ++iter)
|
||||
{
|
||||
this->AvailableGenerators.append(QString::fromStdString(*iter));
|
||||
}
|
||||
}
|
||||
|
||||
QCMake::~QCMake()
|
||||
|
@ -74,7 +83,17 @@ void QCMake::setBinaryDirectory(const QString& dir)
|
|||
{
|
||||
cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
|
||||
this->BinaryDirectory = dir;
|
||||
this->CMakeInstance->GetCacheManager()->LoadCache(dir.toLocal8Bit().data());
|
||||
this->setGenerator(QString());
|
||||
if(!this->CMakeInstance->GetCacheManager()->LoadCache(dir.toLocal8Bit().data()))
|
||||
{
|
||||
QDir testDir(dir);
|
||||
if(testDir.exists("CMakeCache.txt"))
|
||||
{
|
||||
cmSystemTools::Error("There is a CMakeCache.txt file for the current binary "
|
||||
"tree but cmake does not have permission to read it. "
|
||||
"Please check the permissions of the directory you are trying to run CMake on.");
|
||||
}
|
||||
}
|
||||
QCMakeCachePropertyList props = this->properties();
|
||||
emit this->propertiesChanged(props);
|
||||
cmCacheManager::CacheIterator itm = cachem->NewIterator();
|
||||
|
@ -82,12 +101,24 @@ void QCMake::setBinaryDirectory(const QString& dir)
|
|||
{
|
||||
setSourceDirectory(itm.GetValue());
|
||||
}
|
||||
if ( itm.Find("CMAKE_GENERATOR"))
|
||||
{
|
||||
const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR");
|
||||
std::string curGen = cmExternalMakefileProjectGenerator::
|
||||
CreateFullGeneratorName(itm.GetValue(), extraGen);
|
||||
this->setGenerator(QString::fromStdString(curGen));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QCMake::setGenerator(const QString& generator)
|
||||
void QCMake::setGenerator(const QString& gen)
|
||||
{
|
||||
if(this->Generator != gen)
|
||||
{
|
||||
this->Generator = gen;
|
||||
emit this->generatorChanged(this->Generator);
|
||||
}
|
||||
}
|
||||
|
||||
void QCMake::configure()
|
||||
|
@ -97,23 +128,23 @@ void QCMake::configure()
|
|||
this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toAscii().data());
|
||||
this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toAscii().data());
|
||||
this->CMakeInstance->SetGlobalGenerator(
|
||||
this->CMakeInstance->CreateGlobalGenerator("Unix Makefiles")); // TODO
|
||||
this->CMakeInstance->CreateGlobalGenerator(this->Generator.toAscii().data()));
|
||||
this->CMakeInstance->SetCMakeCommand(this->CMakeExecutable.toAscii().data());
|
||||
this->CMakeInstance->LoadCache();
|
||||
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
|
||||
int error = this->CMakeInstance->Configure();
|
||||
int err = this->CMakeInstance->Configure();
|
||||
|
||||
emit this->propertiesChanged(this->properties());
|
||||
emit this->configureDone(error);
|
||||
emit this->configureDone(err);
|
||||
}
|
||||
|
||||
void QCMake::generate()
|
||||
{
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
int error = this->CMakeInstance->Generate();
|
||||
emit this->generateDone(error);
|
||||
int err = this->CMakeInstance->Generate();
|
||||
emit this->generateDone(err);
|
||||
}
|
||||
|
||||
void QCMake::setProperties(const QCMakeCachePropertyList& props)
|
||||
|
@ -137,7 +168,7 @@ void QCMake::setProperties(const QCMakeCachePropertyList& props)
|
|||
cachem->SaveCache(this->BinaryDirectory.toAscii().data());
|
||||
}
|
||||
|
||||
QCMakeCachePropertyList QCMake::properties()
|
||||
QCMakeCachePropertyList QCMake::properties() const
|
||||
{
|
||||
QCMakeCachePropertyList ret;
|
||||
|
||||
|
@ -198,12 +229,22 @@ void QCMake::progressCallback(const char* msg, float percent, void* cd)
|
|||
{
|
||||
emit self->outputMessage(msg);
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void QCMake::errorCallback(const char* msg, const char* title, bool& stop, void* cd)
|
||||
void QCMake::errorCallback(const char* msg, const char* title,
|
||||
bool& stop, void* cd)
|
||||
{
|
||||
QCMake* self = reinterpret_cast<QCMake*>(cd);
|
||||
emit self->error(title, msg, &stop);
|
||||
}
|
||||
|
||||
QString QCMake::generator() const
|
||||
{
|
||||
return this->Generator;
|
||||
}
|
||||
|
||||
QStringList QCMake::availableGenerators() const
|
||||
{
|
||||
return this->AvailableGenerators;
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <QString>
|
||||
#include <QVariant>
|
||||
#include <QList>
|
||||
#include <QStringList>
|
||||
#include <QMetaType>
|
||||
|
||||
class cmake;
|
||||
|
@ -40,8 +41,14 @@ struct QCMakeCacheProperty
|
|||
QString Help;
|
||||
PropertyType Type;
|
||||
bool Advanced;
|
||||
bool operator==(const QCMakeCacheProperty& other) const { return this->Key == other.Key; }
|
||||
bool operator<(const QCMakeCacheProperty& other) const { return this->Key < other.Key; }
|
||||
bool operator==(const QCMakeCacheProperty& other) const
|
||||
{
|
||||
return this->Key == other.Key;
|
||||
}
|
||||
bool operator<(const QCMakeCacheProperty& other) const
|
||||
{
|
||||
return this->Key < other.Key;
|
||||
}
|
||||
};
|
||||
|
||||
// make types usable with QVariant
|
||||
|
@ -79,15 +86,15 @@ public slots:
|
|||
|
||||
public:
|
||||
/// get the list of cache properties
|
||||
QCMakeCachePropertyList properties();
|
||||
QCMakeCachePropertyList properties() const;
|
||||
/// get the current binary directory
|
||||
QString binaryDirectory();
|
||||
QString binaryDirectory() const;
|
||||
/// get the current source directory
|
||||
QString sourceDirectory();
|
||||
QString sourceDirectory() const;
|
||||
/// get the current generator
|
||||
QString generator();
|
||||
QString generator() const;
|
||||
/// get the available generators
|
||||
QStringList availableGenerators();
|
||||
QStringList availableGenerators() const;
|
||||
|
||||
signals:
|
||||
/// signal when properties change (during read from disk or configure process)
|
||||
|
@ -112,11 +119,13 @@ protected:
|
|||
cmake* CMakeInstance;
|
||||
|
||||
static void progressCallback(const char* msg, float percent, void* cd);
|
||||
static void errorCallback(const char* msg, const char* title, bool&, void* cd);
|
||||
static void errorCallback(const char* msg, const char* title,
|
||||
bool&, void* cd);
|
||||
|
||||
QString SourceDirectory;
|
||||
QString BinaryDirectory;
|
||||
QString Generator;
|
||||
QStringList AvailableGenerators;
|
||||
QString CMakeExecutable;
|
||||
};
|
||||
|
||||
|
|
|
@ -22,17 +22,28 @@
|
|||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QEvent>
|
||||
#include <QFileInfo>
|
||||
#include <QStyle>
|
||||
#include <QKeyEvent>
|
||||
|
||||
QCMakeCacheView::QCMakeCacheView(QWidget* p)
|
||||
: QTableView(p), Init(false)
|
||||
{
|
||||
// hook up our model
|
||||
QCMakeCacheModel* m = new QCMakeCacheModel(this);
|
||||
this->setModel(m);
|
||||
this->horizontalHeader()->setStretchLastSection(true);
|
||||
this->verticalHeader()->hide();
|
||||
|
||||
// our delegate for creating our editors
|
||||
QCMakeCacheModelDelegate* delegate = new QCMakeCacheModelDelegate(this);
|
||||
this->setItemDelegate(delegate);
|
||||
|
||||
// set up headers and sizes
|
||||
int h = 0;
|
||||
QFontMetrics met(this->font());
|
||||
h = qMax(met.height(), this->style()->pixelMetric(QStyle::PM_IndicatorHeight));
|
||||
this->verticalHeader()->setDefaultSectionSize(h + 4);
|
||||
this->horizontalHeader()->setStretchLastSection(true);
|
||||
this->verticalHeader()->hide();
|
||||
}
|
||||
|
||||
void QCMakeCacheView::showEvent(QShowEvent* e)
|
||||
|
@ -106,6 +117,11 @@ static uint qHash(const QCMakeCacheProperty& p)
|
|||
return qHash(p.Key);
|
||||
}
|
||||
|
||||
void QCMakeCacheModel::clear()
|
||||
{
|
||||
this->setProperties(QCMakeCachePropertyList());
|
||||
}
|
||||
|
||||
void QCMakeCacheModel::setProperties(const QCMakeCachePropertyList& props)
|
||||
{
|
||||
QSet<QCMakeCacheProperty> newProps = props.toSet();
|
||||
|
@ -132,63 +148,63 @@ QCMakeCachePropertyList QCMakeCacheModel::properties() const
|
|||
return this->Properties;
|
||||
}
|
||||
|
||||
int QCMakeCacheModel::columnCount (const QModelIndex& /*parent*/ ) const
|
||||
int QCMakeCacheModel::columnCount (const QModelIndex& /*p*/ ) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
QVariant QCMakeCacheModel::data (const QModelIndex& index, int role) const
|
||||
QVariant QCMakeCacheModel::data (const QModelIndex& idx, int role) const
|
||||
{
|
||||
if(index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
if(idx.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
{
|
||||
return this->Properties[index.row()].Key;
|
||||
return this->Properties[idx.row()].Key;
|
||||
}
|
||||
else if(index.column() == 0 && role == Qt::ToolTipRole)
|
||||
else if(idx.column() == 0 && role == Qt::ToolTipRole)
|
||||
{
|
||||
return this->data(index, Qt::DisplayRole).toString() + "\n" +
|
||||
this->data(index, QCMakeCacheModel::HelpRole).toString();
|
||||
return this->data(idx, Qt::DisplayRole).toString() + "\n" +
|
||||
this->data(idx, QCMakeCacheModel::HelpRole).toString();
|
||||
}
|
||||
else if(index.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
else if(idx.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
{
|
||||
if(this->Properties[index.row()].Type != QCMakeCacheProperty::BOOL)
|
||||
if(this->Properties[idx.row()].Type != QCMakeCacheProperty::BOOL)
|
||||
{
|
||||
return this->Properties[index.row()].Value;
|
||||
return this->Properties[idx.row()].Value;
|
||||
}
|
||||
}
|
||||
else if(index.column() == 1 && role == Qt::CheckStateRole)
|
||||
else if(idx.column() == 1 && role == Qt::CheckStateRole)
|
||||
{
|
||||
if(this->Properties[index.row()].Type == QCMakeCacheProperty::BOOL)
|
||||
if(this->Properties[idx.row()].Type == QCMakeCacheProperty::BOOL)
|
||||
{
|
||||
return this->Properties[index.row()].Value.toBool() ? Qt::Checked : Qt::Unchecked;
|
||||
return this->Properties[idx.row()].Value.toBool() ? Qt::Checked : Qt::Unchecked;
|
||||
}
|
||||
}
|
||||
else if(role == QCMakeCacheModel::HelpRole)
|
||||
{
|
||||
return this->Properties[index.row()].Help;
|
||||
return this->Properties[idx.row()].Help;
|
||||
}
|
||||
else if(role == QCMakeCacheModel::TypeRole)
|
||||
{
|
||||
return this->Properties[index.row()].Type;
|
||||
return this->Properties[idx.row()].Type;
|
||||
}
|
||||
else if(role == QCMakeCacheModel::AdvancedRole)
|
||||
{
|
||||
return this->Properties[index.row()].Advanced;
|
||||
return this->Properties[idx.row()].Advanced;
|
||||
}
|
||||
else if(role == Qt::BackgroundRole && index.row()+1 <= this->NewCount)
|
||||
else if(role == Qt::BackgroundRole && idx.row()+1 <= this->NewCount)
|
||||
{
|
||||
return QBrush(QColor(255,100,100));
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
QModelIndex QCMakeCacheModel::parent (const QModelIndex& /*index*/) const
|
||||
QModelIndex QCMakeCacheModel::parent (const QModelIndex& /*idx*/) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
int QCMakeCacheModel::rowCount (const QModelIndex& parent) const
|
||||
int QCMakeCacheModel::rowCount (const QModelIndex& p) const
|
||||
{
|
||||
if(parent.isValid())
|
||||
if(p.isValid())
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -205,15 +221,15 @@ QVariant QCMakeCacheModel::headerData (int section, Qt::Orientation orient, int
|
|||
return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags QCMakeCacheModel::flags (const QModelIndex& index) const
|
||||
Qt::ItemFlags QCMakeCacheModel::flags (const QModelIndex& idx) const
|
||||
{
|
||||
Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||
// all column 1's are editable
|
||||
if(index.column() == 1)
|
||||
if(idx.column() == 1)
|
||||
{
|
||||
f |= Qt::ItemIsEditable;
|
||||
// booleans are editable in place
|
||||
if(this->Properties[index.row()].Type == QCMakeCacheProperty::BOOL)
|
||||
if(this->Properties[idx.row()].Type == QCMakeCacheProperty::BOOL)
|
||||
{
|
||||
f |= Qt::ItemIsUserCheckable;
|
||||
}
|
||||
|
@ -222,25 +238,25 @@ Qt::ItemFlags QCMakeCacheModel::flags (const QModelIndex& index) const
|
|||
}
|
||||
|
||||
|
||||
bool QCMakeCacheModel::setData (const QModelIndex& index, const QVariant& value, int role)
|
||||
bool QCMakeCacheModel::setData (const QModelIndex& idx, const QVariant& value, int role)
|
||||
{
|
||||
if(index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
if(idx.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
{
|
||||
this->Properties[index.row()].Key = value.toString();
|
||||
this->Properties[idx.row()].Key = value.toString();
|
||||
this->IsDirty = true;
|
||||
emit this->dataChanged(index, index);
|
||||
emit this->dataChanged(idx, idx);
|
||||
}
|
||||
else if(index.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
else if(idx.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
{
|
||||
this->Properties[index.row()].Value = value.toString();
|
||||
this->Properties[idx.row()].Value = value.toString();
|
||||
this->IsDirty = true;
|
||||
emit this->dataChanged(index, index);
|
||||
emit this->dataChanged(idx, idx);
|
||||
}
|
||||
else if(index.column() == 1 && (role == Qt::CheckStateRole))
|
||||
else if(idx.column() == 1 && (role == Qt::CheckStateRole))
|
||||
{
|
||||
this->Properties[index.row()].Value = value.toInt() == Qt::Checked;
|
||||
this->Properties[idx.row()].Value = value.toInt() == Qt::Checked;
|
||||
this->IsDirty = true;
|
||||
emit this->dataChanged(index, index);
|
||||
emit this->dataChanged(idx, idx);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -252,28 +268,28 @@ QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p)
|
|||
{
|
||||
}
|
||||
|
||||
QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* parent,
|
||||
const QStyleOptionViewItem&, const QModelIndex& index) const
|
||||
QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p,
|
||||
const QStyleOptionViewItem&, const QModelIndex& idx) const
|
||||
{
|
||||
QVariant type = index.data(QCMakeCacheModel::TypeRole);
|
||||
QVariant type = idx.data(QCMakeCacheModel::TypeRole);
|
||||
if(type == QCMakeCacheProperty::BOOL)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
else if(type == QCMakeCacheProperty::PATH)
|
||||
{
|
||||
return new QCMakeCachePathEditor(index.data().toString(), false, parent);
|
||||
return new QCMakeCachePathEditor(idx.data().toString(), false, p);
|
||||
}
|
||||
else if(type == QCMakeCacheProperty::FILEPATH)
|
||||
{
|
||||
return new QCMakeCachePathEditor(index.data().toString(), true, parent);
|
||||
return new QCMakeCachePathEditor(idx.data().toString(), true, p);
|
||||
}
|
||||
|
||||
return new QLineEdit(parent);
|
||||
return new QLineEdit(p);
|
||||
}
|
||||
|
||||
|
||||
QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, bool fp, QWidget* p)
|
||||
|
||||
QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, bool fp,
|
||||
QWidget* p)
|
||||
: QWidget(p), LineEdit(this), IsFilePath(fp)
|
||||
{
|
||||
QHBoxLayout* l = new QHBoxLayout(this);
|
||||
|
@ -286,6 +302,7 @@ QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, bool fp, QWidg
|
|||
QObject::connect(tb, SIGNAL(clicked(bool)),
|
||||
this, SLOT(chooseFile()));
|
||||
this->LineEdit.setText(file);
|
||||
this->LineEdit.selectAll();
|
||||
tb->setFocusProxy(&this->LineEdit);
|
||||
this->setFocusProxy(&this->LineEdit);
|
||||
}
|
||||
|
@ -295,11 +312,14 @@ void QCMakeCachePathEditor::chooseFile()
|
|||
QString path;
|
||||
if(this->IsFilePath)
|
||||
{
|
||||
path = QFileDialog::getOpenFileName(this, "TODO");
|
||||
QFileInfo info(this->value());
|
||||
path = QFileDialog::getOpenFileName(this, tr("Select File"),
|
||||
info.absolutePath());
|
||||
}
|
||||
else
|
||||
{
|
||||
path = QFileDialog::getExistingDirectory(this, "TODO", this->value());
|
||||
path = QFileDialog::getExistingDirectory(this, tr("Select Path"),
|
||||
this->value());
|
||||
}
|
||||
if(!path.isEmpty())
|
||||
{
|
||||
|
|
|
@ -55,6 +55,7 @@ public:
|
|||
|
||||
public slots:
|
||||
void setProperties(const QCMakeCachePropertyList& props);
|
||||
void clear();
|
||||
|
||||
public:
|
||||
// satisfy [pure] virtuals
|
||||
|
@ -77,14 +78,16 @@ protected:
|
|||
bool IsDirty;
|
||||
};
|
||||
|
||||
/// Qt delegate class for interaction (or other customization) with cache properties
|
||||
/// Qt delegate class for interaction (or other customization)
|
||||
/// with cache properties
|
||||
class QCMakeCacheModelDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMakeCacheModelDelegate(QObject* p);
|
||||
/// create our own editors for cache properties
|
||||
QWidget* createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
|
||||
QWidget* createEditor(QWidget* parent, const QStyleOptionViewItem& option,
|
||||
const QModelIndex& index ) const;
|
||||
};
|
||||
|
||||
/// Editor widget for editing paths or file paths
|
||||
|
|
Loading…
Reference in New Issue