diff options
author | Clinton Stimpson <clinton@elemtech.com> | 2007-11-05 18:20:54 (GMT) |
---|---|---|
committer | Clinton Stimpson <clinton@elemtech.com> | 2007-11-05 18:20:54 (GMT) |
commit | cfa723d45792ef6969304fb7d9274778f662a116 (patch) | |
tree | 740899517a9a87583acad024d06e1cf4d2e0d011 | |
parent | 7bd73d3e0dd1cc1515575b58db41e80f17474532 (diff) | |
download | CMake-cfa723d45792ef6969304fb7d9274778f662a116.zip CMake-cfa723d45792ef6969304fb7d9274778f662a116.tar.gz CMake-cfa723d45792ef6969304fb7d9274778f662a116.tar.bz2 |
ENH: Prompt user for generator when there is none.
Many minor improvements, bug fixes, and style fixes.
-rw-r--r-- | Source/QtDialog/CMakeSetup.cxx | 1 | ||||
-rw-r--r-- | Source/QtDialog/CMakeSetupDialog.cxx | 205 | ||||
-rw-r--r-- | Source/QtDialog/CMakeSetupDialog.h | 25 | ||||
-rw-r--r-- | Source/QtDialog/QCMake.cxx | 67 | ||||
-rw-r--r-- | Source/QtDialog/QCMake.h | 25 | ||||
-rw-r--r-- | Source/QtDialog/QCMakeCacheView.cxx | 112 | ||||
-rw-r--r-- | Source/QtDialog/QCMakeCacheView.h | 7 |
7 files changed, 301 insertions, 141 deletions
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx index 16178cd..b29e742 100644 --- a/Source/QtDialog/CMakeSetup.cxx +++ b/Source/QtDialog/CMakeSetup.cxx @@ -31,6 +31,7 @@ int main(int argc, char** argv) // TODO handle CMake args CMakeSetupDialog dialog; + dialog.setWindowTitle("CMakeSetup"); dialog.show(); return app.exec(); diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx index e718bc5..3a39c81 100644 --- a/Source/QtDialog/CMakeSetupDialog.cxx +++ b/Source/QtDialog/CMakeSetupDialog.cxx @@ -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()); +} diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h index a8221be..d1efcce 100644 --- a/Source/QtDialog/CMakeSetupDialog.h +++ b/Source/QtDialog/CMakeSetupDialog.h @@ -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 diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx index 495d404..367f6b3 100644 --- a/Source/QtDialog/QCMake.cxx +++ b/Source/QtDialog/QCMake.cxx @@ -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; +} + diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h index bfd2585..d28a917 100644 --- a/Source/QtDialog/QCMake.h +++ b/Source/QtDialog/QCMake.h @@ -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; }; diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx index 4003c2f..9b732e8 100644 --- a/Source/QtDialog/QCMakeCacheView.cxx +++ b/Source/QtDialog/QCMakeCacheView.cxx @@ -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()) { diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h index 892d84f..91d1053 100644 --- a/Source/QtDialog/QCMakeCacheView.h +++ b/Source/QtDialog/QCMakeCacheView.h @@ -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 |