| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324 |
- /*=========================================================================
- Program: CMake - Cross-Platform Makefile Generator
- Module: $RCSfile$
- Language: C++
- Date: $Date$
- Version: $Revision$
- Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
- See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
- This software is distributed WITHOUT ANY WARRANTY; without even
- the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
- PURPOSE. See the above copyright notices for more information.
- =========================================================================*/
- #include "CMakeSetupDialog.h"
- #include <QFileDialog>
- #include <QThread>
- #include <QProgressBar>
- #include <QMessageBox>
- #include <QStatusBar>
- #include <QToolButton>
- #include <QDialogButtonBox>
- #include <QCloseEvent>
- #include "QCMake.h"
- #include "QCMakeCacheView.h"
- // QCMake instance on a thread
- class QCMakeThread : public QThread
- {
- public:
- QCMakeThread(QObject* p) : QThread(p) { }
- QCMake* CMakeInstance;
- protected:
- virtual void run()
- {
- this->CMakeInstance = new QCMake;
- this->exec();
- delete this->CMakeInstance;
- }
- };
- CMakeSetupDialog::CMakeSetupDialog()
- {
- // create the GUI
- this->resize(700, 500);
- QWidget* cont = new QWidget(this);
- this->setupUi(cont);
- this->Splitter->setStretchFactor(0, 2);
- this->Splitter->setStretchFactor(1, 1);
- this->setCentralWidget(cont);
- this->ProgressBar = new QProgressBar();
- this->ProgressBar->setRange(0,100);
- this->InterruptButton = new QToolButton();
- this->InterruptButton->setEnabled(false);
- this->InterruptButton->setIcon(
- this->style()->standardPixmap(QStyle::SP_DialogCancelButton));
- this->statusBar()->addPermanentWidget(this->InterruptButton);
- this->statusBar()->addPermanentWidget(this->ProgressBar);
-
- // 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()));
- this->CMakeThread->start();
- }
- void CMakeSetupDialog::initialize()
- {
- // now the cmake worker thread is running, lets make our connections to it
- 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)),
- this, SLOT(finishConfigure(int)));
- QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(generateDone(int)),
- this, SLOT(finishGenerate(int)));
- QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)),
- this, SLOT(doOk()));
-
- QObject::connect(this->CancelButton, SIGNAL(clicked(bool)),
- this, SLOT(close()));
-
- QObject::connect(this->BrowseSourceDirectoryButton, SIGNAL(clicked(bool)),
- this, SLOT(doSourceBrowse()));
- QObject::connect(this->BrowseBinaryDirectoryButton, SIGNAL(clicked(bool)),
- this, SLOT(doBinaryBrowse()));
-
- QObject::connect(this->BinaryDirectory, SIGNAL(editTextChanged(QString)),
- this->CMakeThread->CMakeInstance, SLOT(setBinaryDirectory(QString)));
- QObject::connect(this->SourceDirectory, SIGNAL(textChanged(QString)),
- this->CMakeThread->CMakeInstance, SLOT(setSourceDirectory(QString)));
- QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(sourceDirChanged(QString)),
- this, SLOT(updateSourceDirectory(QString)));
-
- 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->InterruptButton, SIGNAL(clicked(bool)),
- this->CMakeThread->CMakeInstance, SLOT(interrupt()));
- QObject::connect(this->InterruptButton, SIGNAL(clicked(bool)),
- this, SLOT(doInterrupt()));
-
- QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(outputMessage(QString)),
- this->Output, SLOT(append(QString)));
-
- QObject::connect(this->HelpButton, SIGNAL(clicked(bool)),
- this, SLOT(doHelp()));
- }
- CMakeSetupDialog::~CMakeSetupDialog()
- {
- // wait for thread to stop
- this->CMakeThread->quit();
- this->CMakeThread->wait();
- }
-
- 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"
- "Directory: ");
- message += this->BinaryDirectory->currentText();
- QString title = tr("Create Directory");
- QMessageBox::StandardButton btn =
- QMessageBox::information(this, title, message, QMessageBox::Yes | QMessageBox::No);
- if(btn == QMessageBox::No)
- {
- return;
- }
- dir.mkpath(".");
- }
- this->InterruptButton->setEnabled(true);
- this->setEnabledState(false);
- this->Output->clear();
- QMetaObject::invokeMethod(this->CMakeThread->CMakeInstance,
- "setProperties", Qt::QueuedConnection,
- Q_ARG(QCMakeCachePropertyList,
- this->CacheValues->cacheModel()->properties()));
- QMetaObject::invokeMethod(this->CMakeThread->CMakeInstance,
- "configure", Qt::QueuedConnection);
- }
- void CMakeSetupDialog::finishConfigure(int error)
- {
- this->InterruptButton->setEnabled(false);
- this->setEnabledState(true);
- this->ProgressBar->reset();
- this->statusBar()->showMessage(tr("Configure Done"), 2000);
- if(error != 0)
- {
- QMessageBox::critical(this, tr("Error"),
- tr("Error in configuration process, project files may be invalid"),
- QMessageBox::Ok);
- }
- }
- void CMakeSetupDialog::finishGenerate(int error)
- {
- this->InterruptButton->setEnabled(false);
- this->setEnabledState(true);
- this->ProgressBar->reset();
- this->statusBar()->showMessage(tr("Generate Done"), 2000);
- if(error != 0)
- {
- QMessageBox::critical(this, tr("Error"),
- tr("Error in generation process, project files may be invalid"),
- QMessageBox::Ok);
- }
- else
- {
- QApplication::quit();
- }
- }
- void CMakeSetupDialog::doOk()
- {
- this->InterruptButton->setEnabled(true);
- this->setEnabledState(false);
- this->Output->clear();
- QMetaObject::invokeMethod(this->CMakeThread->CMakeInstance,
- "generate", Qt::QueuedConnection);
- }
-
- void CMakeSetupDialog::closeEvent(QCloseEvent* e)
- {
- 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);
- if(btn == QMessageBox::No)
- {
- e->ignore();
- }
- }
- }
- 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"
- "directory and exit CMake.");
- QDialog dialog;
- QVBoxLayout* l = new QVBoxLayout(&dialog);
- QLabel* label = new QLabel(&dialog);
- l->addWidget(label);
- label->setText(msg);
- label->setWordWrap(true);
- QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
- Qt::Horizontal, &dialog);
- QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
- l->addWidget(btns);
- dialog.exec();
- }
- void CMakeSetupDialog::doInterrupt()
- {
- this->InterruptButton->setEnabled(false);
- this->statusBar()->showMessage(tr("Interrupting..."));
- }
- void CMakeSetupDialog::doSourceBrowse()
- {
- QString dir = QFileDialog::getExistingDirectory(this,
- tr("Enter Path to Source"), this->SourceDirectory->text());
- if(!dir.isEmpty())
- {
- this->SourceDirectory->setText(dir);
- }
- }
- void CMakeSetupDialog::updateSourceDirectory(const QString& dir)
- {
- if(this->SourceDirectory->text() != dir)
- {
- this->SourceDirectory->setText(dir);
- }
- }
- void CMakeSetupDialog::doBinaryBrowse()
- {
- QString dir = QFileDialog::getExistingDirectory(this,
- tr("Enter Path to Build"), this->BinaryDirectory->currentText());
- if(!dir.isEmpty())
- {
- this->setBinaryDirectory(dir);
- }
- }
- void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
- {
- if(dir != this->BinaryDirectory->currentText())
- {
- this->CacheValues->cacheModel()->setProperties(QCMakeCachePropertyList());
- this->Output->clear();
- this->BinaryDirectory->setEditText(dir);
- }
- }
- void CMakeSetupDialog::showProgress(const QString& msg, float percent)
- {
- this->statusBar()->showMessage(msg);
- this->ProgressBar->setValue(qRound(percent * 100));
- }
-
- void CMakeSetupDialog::error(const QString& title, const QString& message, bool* cancel)
- {
- QMessageBox::StandardButton btn =
- QMessageBox::critical(this, title, message, QMessageBox::Ok | QMessageBox::Cancel);
- if(btn == QMessageBox::Cancel)
- {
- *cancel = false;
- }
- }
- void CMakeSetupDialog::setEnabledState(bool enabled)
- {
- this->CacheValues->setEnabled(enabled);
- this->SourceDirectory->setEnabled(enabled);
- this->BrowseSourceDirectoryButton->setEnabled(enabled);
- this->BinaryDirectory->setEnabled(enabled);
- this->BrowseBinaryDirectoryButton->setEnabled(enabled);
- this->ConfigureButton->setEnabled(enabled);
- this->GenerateButton->setEnabled(enabled);
- this->CancelButton->setEnabled(enabled);
- this->HelpButton->setEnabled(enabled);
- }
|