ENH: check in almost building VMS stuff with VMSBuild directory since the bootstrap...
[cmake.git] / Source / QtDialog / CMakeSetupDialog.cxx
blob57f2aae5f8df8193e93efd59bab1fe973e4e7ac4
1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: CMakeSetupDialog.cxx,v $
5 Language: C++
6 Date: $Date: 2009-03-30 14:56:43 $
7 Version: $Revision: 1.57 $
9 Copyright (c) 2002 Kitware, Inc., Insight Consortium. All rights reserved.
10 See Copyright.txt or http://www.cmake.org/HTML/Copyright.html for details.
12 This software is distributed WITHOUT ANY WARRANTY; without even
13 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14 PURPOSE. See the above copyright notices for more information.
16 =========================================================================*/
18 #include "CMakeSetupDialog.h"
19 #include <QFileDialog>
20 #include <QProgressBar>
21 #include <QMessageBox>
22 #include <QStatusBar>
23 #include <QToolButton>
24 #include <QDialogButtonBox>
25 #include <QCloseEvent>
26 #include <QCoreApplication>
27 #include <QSettings>
28 #include <QMenu>
29 #include <QMenuBar>
30 #include <QDragEnterEvent>
31 #include <QMimeData>
32 #include <QUrl>
33 #include <QShortcut>
34 #include <QMacInstallDialog.h>
36 #include "QCMake.h"
37 #include "QCMakeCacheView.h"
38 #include "AddCacheEntry.h"
39 #include "FirstConfigure.h"
40 #include "cmVersion.h"
42 QCMakeThread::QCMakeThread(QObject* p)
43 : QThread(p), CMakeInstance(NULL)
47 QCMake* QCMakeThread::cmakeInstance() const
49 return this->CMakeInstance;
52 void QCMakeThread::run()
54 this->CMakeInstance = new QCMake;
55 // emit that this cmake thread is ready for use
56 emit this->cmakeInitialized();
57 this->exec();
58 delete this->CMakeInstance;
59 this->CMakeInstance = NULL;
62 CMakeSetupDialog::CMakeSetupDialog()
63 : ExitAfterGenerate(true), CacheModified(false), CurrentState(Interrupting)
65 // create the GUI
66 QSettings settings;
67 settings.beginGroup("Settings/StartPath");
68 int h = settings.value("Height", 500).toInt();
69 int w = settings.value("Width", 700).toInt();
70 this->resize(w, h);
72 QWidget* cont = new QWidget(this);
73 this->setupUi(cont);
74 this->Splitter->setStretchFactor(0, 3);
75 this->Splitter->setStretchFactor(1, 1);
76 this->setCentralWidget(cont);
77 this->ProgressBar->reset();
78 this->RemoveEntry->setEnabled(false);
79 this->AddEntry->setEnabled(false);
81 bool groupView = settings.value("GroupView", false).toBool();
82 if(groupView)
84 this->setViewType(2);
85 this->ViewType->setCurrentIndex(2);
88 QMenu* FileMenu = this->menuBar()->addMenu(tr("&File"));
89 this->ReloadCacheAction = FileMenu->addAction(tr("&Reload Cache"));
90 QObject::connect(this->ReloadCacheAction, SIGNAL(triggered(bool)),
91 this, SLOT(doReloadCache()));
92 this->DeleteCacheAction = FileMenu->addAction(tr("&Delete Cache"));
93 QObject::connect(this->DeleteCacheAction, SIGNAL(triggered(bool)),
94 this, SLOT(doDeleteCache()));
95 this->ExitAction = FileMenu->addAction(tr("E&xit"));
96 QObject::connect(this->ExitAction, SIGNAL(triggered(bool)),
97 this, SLOT(close()));
99 QMenu* ToolsMenu = this->menuBar()->addMenu(tr("&Tools"));
100 this->ConfigureAction = ToolsMenu->addAction(tr("&Configure"));
101 // prevent merging with Preferences menu item on Mac OS X
102 this->ConfigureAction->setMenuRole(QAction::NoRole);
103 QObject::connect(this->ConfigureAction, SIGNAL(triggered(bool)),
104 this, SLOT(doConfigure()));
105 this->GenerateAction = ToolsMenu->addAction(tr("&Generate"));
106 QObject::connect(this->GenerateAction, SIGNAL(triggered(bool)),
107 this, SLOT(doGenerate()));
108 #if defined(Q_WS_MAC)
109 this->InstallForCommandLineAction
110 = ToolsMenu->addAction(tr("&Install For Command Line Use"));
111 QObject::connect(this->InstallForCommandLineAction, SIGNAL(triggered(bool)),
112 this, SLOT(doInstallForCommandLine()));
113 #endif
114 QMenu* OptionsMenu = this->menuBar()->addMenu(tr("&Options"));
115 this->SuppressDevWarningsAction = OptionsMenu->addAction(tr("&Suppress dev Warnings (-Wno-dev)"));
116 this->SuppressDevWarningsAction->setCheckable(true);
118 QAction* debugAction = OptionsMenu->addAction(tr("&Debug Output"));
119 debugAction->setCheckable(true);
120 QObject::connect(debugAction, SIGNAL(toggled(bool)),
121 this, SLOT(setDebugOutput(bool)));
123 OptionsMenu->addSeparator();
124 QAction* expandAction = OptionsMenu->addAction(tr("&Expand Grouped Entries"));
125 QObject::connect(expandAction, SIGNAL(triggered(bool)),
126 this->CacheValues, SLOT(expandAll()));
127 QAction* collapseAction = OptionsMenu->addAction(tr("&Collapse Grouped Entries"));
128 QObject::connect(collapseAction, SIGNAL(triggered(bool)),
129 this->CacheValues, SLOT(collapseAll()));
131 QMenu* HelpMenu = this->menuBar()->addMenu(tr("&Help"));
132 QAction* a = HelpMenu->addAction(tr("About"));
133 QObject::connect(a, SIGNAL(triggered(bool)),
134 this, SLOT(doAbout()));
135 a = HelpMenu->addAction(tr("Help"));
136 QObject::connect(a, SIGNAL(triggered(bool)),
137 this, SLOT(doHelp()));
139 QShortcut* filterShortcut = new QShortcut(QKeySequence::Find, this);
140 QObject::connect(filterShortcut, SIGNAL(activated()),
141 this, SLOT(startSearch()));
143 this->setAcceptDrops(true);
145 // get the saved binary directories
146 QStringList buildPaths = this->loadBuildPaths();
147 this->BinaryDirectory->addItems(buildPaths);
149 this->BinaryDirectory->setCompleter(new QCMakeFileCompleter(this, true));
150 this->SourceDirectory->setCompleter(new QCMakeFileCompleter(this, true));
152 // fixed pitch font in output window
153 QFont outputFont("Courier");
154 this->Output->setFont(outputFont);
155 this->ErrorFormat.setForeground(QBrush(Qt::red));
157 // start the cmake worker thread
158 this->CMakeThread = new QCMakeThread(this);
159 QObject::connect(this->CMakeThread, SIGNAL(cmakeInitialized()),
160 this, SLOT(initialize()), Qt::QueuedConnection);
161 this->CMakeThread->start();
163 this->enterState(ReadyConfigure);
166 void CMakeSetupDialog::initialize()
168 // now the cmake worker thread is running, lets make our connections to it
169 QObject::connect(this->CMakeThread->cmakeInstance(),
170 SIGNAL(propertiesChanged(const QCMakePropertyList&)),
171 this->CacheValues->cacheModel(),
172 SLOT(setProperties(const QCMakePropertyList&)));
174 QObject::connect(this->ConfigureButton, SIGNAL(clicked(bool)),
175 this, SLOT(doConfigure()));
176 QObject::connect(this->CMakeThread->cmakeInstance(),
177 SIGNAL(configureDone(int)),
178 this, SLOT(finishConfigure(int)));
179 QObject::connect(this->CMakeThread->cmakeInstance(),
180 SIGNAL(generateDone(int)),
181 this, SLOT(finishGenerate(int)));
183 QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)),
184 this, SLOT(doGenerate()));
186 QObject::connect(this->BrowseSourceDirectoryButton, SIGNAL(clicked(bool)),
187 this, SLOT(doSourceBrowse()));
188 QObject::connect(this->BrowseBinaryDirectoryButton, SIGNAL(clicked(bool)),
189 this, SLOT(doBinaryBrowse()));
191 QObject::connect(this->BinaryDirectory, SIGNAL(editTextChanged(QString)),
192 this, SLOT(onBinaryDirectoryChanged(QString)));
193 QObject::connect(this->SourceDirectory, SIGNAL(textChanged(QString)),
194 this, SLOT(onSourceDirectoryChanged(QString)));
196 QObject::connect(this->CMakeThread->cmakeInstance(),
197 SIGNAL(sourceDirChanged(QString)),
198 this, SLOT(updateSourceDirectory(QString)));
199 QObject::connect(this->CMakeThread->cmakeInstance(),
200 SIGNAL(binaryDirChanged(QString)),
201 this, SLOT(updateBinaryDirectory(QString)));
203 QObject::connect(this->CMakeThread->cmakeInstance(),
204 SIGNAL(progressChanged(QString, float)),
205 this, SLOT(showProgress(QString,float)));
207 QObject::connect(this->CMakeThread->cmakeInstance(),
208 SIGNAL(errorMessage(QString)),
209 this, SLOT(error(QString)));
211 QObject::connect(this->CMakeThread->cmakeInstance(),
212 SIGNAL(outputMessage(QString)),
213 this, SLOT(message(QString)));
215 QObject::connect(this->ViewType, SIGNAL(currentIndexChanged(int)),
216 this, SLOT(setViewType(int)));
217 QObject::connect(this->Search, SIGNAL(textChanged(QString)),
218 this->CacheValues, SLOT(setSearchFilter(QString)));
220 QObject::connect(this->CMakeThread->cmakeInstance(),
221 SIGNAL(generatorChanged(QString)),
222 this, SLOT(updateGeneratorLabel(QString)));
223 this->updateGeneratorLabel(QString());
225 QObject::connect(this->CacheValues->cacheModel(),
226 SIGNAL(dataChanged(QModelIndex,QModelIndex)),
227 this, SLOT(setCacheModified()));
229 QObject::connect(this->CacheValues->selectionModel(),
230 SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
231 this, SLOT(selectionChanged()));
232 QObject::connect(this->RemoveEntry, SIGNAL(clicked(bool)),
233 this, SLOT(removeSelectedCacheEntries()));
234 QObject::connect(this->AddEntry, SIGNAL(clicked(bool)),
235 this, SLOT(addCacheEntry()));
237 QObject::connect(this->SuppressDevWarningsAction, SIGNAL(triggered(bool)),
238 this->CMakeThread->cmakeInstance(), SLOT(setSuppressDevWarnings(bool)));
240 if(!this->SourceDirectory->text().isEmpty() ||
241 !this->BinaryDirectory->lineEdit()->text().isEmpty())
243 this->onSourceDirectoryChanged(this->SourceDirectory->text());
244 this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text());
246 else
248 this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text());
252 CMakeSetupDialog::~CMakeSetupDialog()
254 QSettings settings;
255 settings.beginGroup("Settings/StartPath");
256 settings.setValue("Height", this->height());
257 settings.setValue("Width", this->width());
259 // wait for thread to stop
260 this->CMakeThread->quit();
261 this->CMakeThread->wait(2000);
264 void CMakeSetupDialog::doConfigure()
266 if(this->CurrentState == Configuring)
268 // stop configure
269 doInterrupt();
270 return;
273 // make sure build directory exists
274 QString bindir = this->CMakeThread->cmakeInstance()->binaryDirectory();
275 QDir dir(bindir);
276 if(!dir.exists())
278 QString message = tr("Build directory does not exist, "
279 "should I create it?")
280 + "\n\n"
281 + tr("Directory: ");
282 message += bindir;
283 QString title = tr("Create Directory");
284 QMessageBox::StandardButton btn;
285 btn = QMessageBox::information(this, title, message,
286 QMessageBox::Yes | QMessageBox::No);
287 if(btn == QMessageBox::No)
289 return;
291 dir.mkpath(".");
294 // if no generator, prompt for it and other setup stuff
295 if(this->CMakeThread->cmakeInstance()->generator().isEmpty())
297 if(!this->setupFirstConfigure())
299 return;
303 // remember path
304 this->addBinaryPath(dir.absolutePath());
306 this->enterState(Configuring);
308 this->CacheValues->selectionModel()->clear();
309 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
310 "setProperties", Qt::QueuedConnection,
311 Q_ARG(QCMakePropertyList,
312 this->CacheValues->cacheModel()->properties()));
313 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
314 "configure", Qt::QueuedConnection);
317 void CMakeSetupDialog::finishConfigure(int err)
319 if(0 == err && !this->CacheValues->cacheModel()->newPropertyCount())
321 this->enterState(ReadyGenerate);
323 else
325 this->enterState(ReadyConfigure);
326 this->CacheValues->scrollToTop();
329 if(err != 0)
331 QMessageBox::critical(this, tr("Error"),
332 tr("Error in configuration process, project files may be invalid"),
333 QMessageBox::Ok);
337 void CMakeSetupDialog::finishGenerate(int err)
339 this->enterState(ReadyGenerate);
340 if(err != 0)
342 QMessageBox::critical(this, tr("Error"),
343 tr("Error in generation process, project files may be invalid"),
344 QMessageBox::Ok);
348 void CMakeSetupDialog::doInstallForCommandLine()
350 QMacInstallDialog setupdialog(0);
351 setupdialog.exec();
354 void CMakeSetupDialog::doGenerate()
356 if(this->CurrentState == Generating)
358 // stop generate
359 doInterrupt();
360 return;
362 this->enterState(Generating);
363 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
364 "generate", Qt::QueuedConnection);
367 void CMakeSetupDialog::closeEvent(QCloseEvent* e)
369 // prompt for close if there are unsaved changes, and we're not busy
370 if(this->CacheModified)
372 QString message = tr("You have changed options but not rebuilt, "
373 "are you sure you want to exit?");
374 QString title = tr("Confirm Exit");
375 QMessageBox::StandardButton btn;
376 btn = QMessageBox::critical(this, title, message,
377 QMessageBox::Yes | QMessageBox::No);
378 if(btn == QMessageBox::No)
380 e->ignore();
384 // don't close if we're busy, unless the user really wants to
385 if(this->CurrentState == Configuring)
387 QString message = "You are in the middle of a Configure.\n"
388 "If you Exit now the configure information will be lost.\n"
389 "Are you sure you want to Exit?";
390 QString title = tr("Confirm Exit");
391 QMessageBox::StandardButton btn;
392 btn = QMessageBox::critical(this, title, message,
393 QMessageBox::Yes | QMessageBox::No);
394 if(btn == QMessageBox::No)
396 e->ignore();
398 else
400 this->doInterrupt();
404 // let the generate finish
405 if(this->CurrentState == Generating)
407 e->ignore();
411 void CMakeSetupDialog::doHelp()
413 QString msg = tr("CMake is used to configure and generate build files for "
414 "software projects. The basic steps for configuring a project are as "
415 "follows:\r\n\r\n1. Select the source directory for the project. This should "
416 "contain the CMakeLists.txt files for the project.\r\n\r\n2. Select the build "
417 "directory for the project. This is the directory where the project will be "
418 "built. It can be the same or a different directory than the source "
419 "directory. For easy clean up, a separate build directory is recommended. "
420 "CMake will create the directory if it does not exist.\r\n\r\n3. Once the "
421 "source and binary directories are selected, it is time to press the "
422 "Configure button. This will cause CMake to read all of the input files and "
423 "discover all the variables used by the project. The first time a variable "
424 "is displayed it will be in Red. Users should inspect red variables making "
425 "sure the values are correct. For some projects the Configure process can "
426 "be iterative, so continue to press the Configure button until there are no "
427 "longer red entries.\r\n\r\n4. Once there are no longer red entries, you "
428 "should click the Generate button. This will write the build files to the build "
429 "directory.");
431 QDialog dialog;
432 QFontMetrics met(this->font());
433 int msgWidth = met.width(msg);
434 dialog.setMinimumSize(msgWidth/15,20);
435 dialog.setWindowTitle(tr("Help"));
436 QVBoxLayout* l = new QVBoxLayout(&dialog);
437 QLabel* lab = new QLabel(&dialog);
438 lab->setText(msg);
439 lab->setWordWrap(true);
440 QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
441 Qt::Horizontal, &dialog);
442 QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
443 l->addWidget(lab);
444 l->addWidget(btns);
445 dialog.exec();
448 void CMakeSetupDialog::doInterrupt()
450 this->enterState(Interrupting);
451 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
452 "interrupt", Qt::QueuedConnection);
455 void CMakeSetupDialog::doSourceBrowse()
457 QString dir = QFileDialog::getExistingDirectory(this,
458 tr("Enter Path to Source"), this->SourceDirectory->text());
459 if(!dir.isEmpty())
461 this->setSourceDirectory(dir);
465 void CMakeSetupDialog::updateSourceDirectory(const QString& dir)
467 if(this->SourceDirectory->text() != dir)
469 this->SourceDirectory->blockSignals(true);
470 this->SourceDirectory->setText(dir);
471 this->SourceDirectory->blockSignals(false);
475 void CMakeSetupDialog::updateBinaryDirectory(const QString& dir)
477 if(this->BinaryDirectory->currentText() != dir)
479 this->BinaryDirectory->blockSignals(true);
480 this->BinaryDirectory->setEditText(dir);
481 this->BinaryDirectory->blockSignals(false);
485 void CMakeSetupDialog::doBinaryBrowse()
487 QString dir = QFileDialog::getExistingDirectory(this,
488 tr("Enter Path to Build"), this->BinaryDirectory->currentText());
489 if(!dir.isEmpty() && dir != this->BinaryDirectory->currentText())
491 this->setBinaryDirectory(dir);
495 void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
497 this->BinaryDirectory->setEditText(dir);
500 void CMakeSetupDialog::onSourceDirectoryChanged(const QString& dir)
502 this->Output->clear();
503 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
504 "setSourceDirectory", Qt::QueuedConnection, Q_ARG(QString, dir));
507 void CMakeSetupDialog::onBinaryDirectoryChanged(const QString& dir)
509 this->CacheModified = false;
510 this->CacheValues->cacheModel()->clear();
511 this->Output->clear();
512 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
513 "setBinaryDirectory", Qt::QueuedConnection, Q_ARG(QString, dir));
516 void CMakeSetupDialog::setSourceDirectory(const QString& dir)
518 this->SourceDirectory->setText(dir);
521 void CMakeSetupDialog::showProgress(const QString& /*msg*/, float percent)
523 this->ProgressBar->setValue(qRound(percent * 100));
526 void CMakeSetupDialog::error(const QString& message)
528 this->Output->setCurrentCharFormat(this->ErrorFormat);
529 this->Output->append(message);
532 void CMakeSetupDialog::message(const QString& message)
534 this->Output->setCurrentCharFormat(this->MessageFormat);
535 this->Output->append(message);
538 void CMakeSetupDialog::setEnabledState(bool enabled)
540 // disable parts of the GUI during configure/generate
541 this->CacheValues->cacheModel()->setEditEnabled(enabled);
542 this->SourceDirectory->setEnabled(enabled);
543 this->BrowseSourceDirectoryButton->setEnabled(enabled);
544 this->BinaryDirectory->setEnabled(enabled);
545 this->BrowseBinaryDirectoryButton->setEnabled(enabled);
546 this->ReloadCacheAction->setEnabled(enabled);
547 this->DeleteCacheAction->setEnabled(enabled);
548 this->ExitAction->setEnabled(enabled);
549 this->ConfigureAction->setEnabled(enabled);
550 this->AddEntry->setEnabled(enabled);
551 this->RemoveEntry->setEnabled(false); // let selection re-enable it
554 bool CMakeSetupDialog::setupFirstConfigure()
556 FirstConfigure dialog;
558 // initialize dialog and restore saved settings
560 // add generators
561 dialog.setGenerators(this->CMakeThread->cmakeInstance()->availableGenerators());
563 // restore from settings
564 dialog.loadFromSettings();
566 if(dialog.exec() == QDialog::Accepted)
568 dialog.saveToSettings();
569 this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator());
571 QCMakeCacheModel* m = this->CacheValues->cacheModel();
573 if(dialog.compilerSetup())
575 QString fortranCompiler = dialog.getFortranCompiler();
576 if(!fortranCompiler.isEmpty())
578 m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_Fortran_COMPILER",
579 "Fortran compiler.", fortranCompiler, false);
581 QString cxxCompiler = dialog.getCXXCompiler();
582 if(!cxxCompiler.isEmpty())
584 m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
585 "CXX compiler.", cxxCompiler, false);
588 QString cCompiler = dialog.getCCompiler();
589 if(!cCompiler.isEmpty())
591 m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
592 "C compiler.", cCompiler, false);
595 else if(dialog.crossCompilerSetup())
597 QString fortranCompiler = dialog.getFortranCompiler();
598 if(!fortranCompiler.isEmpty())
600 m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_Fortran_COMPILER",
601 "Fortran compiler.", fortranCompiler, false);
604 QString mode = dialog.getCrossIncludeMode();
605 m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE",
606 "CMake Find Include Mode", mode, false);
607 mode = dialog.getCrossLibraryMode();
608 m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY",
609 "CMake Find Library Mode", mode, false);
610 mode = dialog.getCrossProgramMode();
611 m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM",
612 "CMake Find Program Mode", mode, false);
614 QString rootPath = dialog.getCrossRoot();
615 m->insertProperty(QCMakeProperty::PATH, "CMAKE_FIND_ROOT_PATH",
616 "CMake Find Root Path", rootPath, false);
618 QString systemName = dialog.getSystemName();
619 m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_NAME",
620 "CMake System Name", systemName, false);
621 QString cxxCompiler = dialog.getCXXCompiler();
622 m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
623 "CXX compiler.", cxxCompiler, false);
624 QString cCompiler = dialog.getCCompiler();
625 m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
626 "C compiler.", cCompiler, false);
628 else if(dialog.crossCompilerToolChainFile())
630 QString toolchainFile = dialog.getCrossCompilerToolChainFile();
631 m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE",
632 "Cross Compile ToolChain File", toolchainFile, false);
634 return true;
637 return false;
640 void CMakeSetupDialog::updateGeneratorLabel(const QString& gen)
642 QString str = tr("Current Generator: ");
643 if(gen.isEmpty())
645 str += tr("None");
647 else
649 str += gen;
651 this->Generator->setText(str);
654 void CMakeSetupDialog::doReloadCache()
656 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
657 "reloadCache", Qt::QueuedConnection);
660 void CMakeSetupDialog::doDeleteCache()
662 QString title = tr("Delete Cache");
663 QString message = "Are you sure you want to delete the cache?";
664 QMessageBox::StandardButton btn;
665 btn = QMessageBox::information(this, title, message,
666 QMessageBox::Yes | QMessageBox::No);
667 if(btn == QMessageBox::No)
669 return;
671 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
672 "deleteCache", Qt::QueuedConnection);
675 void CMakeSetupDialog::doAbout()
677 QString msg = "CMake %1\n"
678 "Using Qt %2\n"
679 "www.cmake.org";
681 msg = msg.arg(cmVersion::GetCMakeVersion());
682 msg = msg.arg(qVersion());
684 QDialog dialog;
685 dialog.setWindowTitle(tr("About"));
686 QVBoxLayout* l = new QVBoxLayout(&dialog);
687 QLabel* lab = new QLabel(&dialog);
688 l->addWidget(lab);
689 lab->setText(msg);
690 lab->setWordWrap(true);
691 QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
692 Qt::Horizontal, &dialog);
693 QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
694 l->addWidget(btns);
695 dialog.exec();
698 void CMakeSetupDialog::setExitAfterGenerate(bool b)
700 this->ExitAfterGenerate = b;
703 void CMakeSetupDialog::addBinaryPath(const QString& path)
705 QString cleanpath = QDir::cleanPath(path);
707 // update UI
708 this->BinaryDirectory->blockSignals(true);
709 int idx = this->BinaryDirectory->findText(cleanpath);
710 if(idx != -1)
712 this->BinaryDirectory->removeItem(idx);
714 this->BinaryDirectory->insertItem(0, cleanpath);
715 this->BinaryDirectory->setCurrentIndex(0);
716 this->BinaryDirectory->blockSignals(false);
718 // save to registry
719 QStringList buildPaths = this->loadBuildPaths();
720 buildPaths.removeAll(cleanpath);
721 buildPaths.prepend(cleanpath);
722 this->saveBuildPaths(buildPaths);
725 void CMakeSetupDialog::dragEnterEvent(QDragEnterEvent* e)
727 if(!(this->CurrentState == ReadyConfigure ||
728 this->CurrentState == ReadyGenerate))
730 e->ignore();
731 return;
734 const QMimeData* dat = e->mimeData();
735 QList<QUrl> urls = dat->urls();
736 QString file = urls.count() ? urls[0].toLocalFile() : QString();
737 if(!file.isEmpty() &&
738 (file.endsWith("CMakeCache.txt", Qt::CaseInsensitive) ||
739 file.endsWith("CMakeLists.txt", Qt::CaseInsensitive) ) )
741 e->accept();
743 else
745 e->ignore();
749 void CMakeSetupDialog::dropEvent(QDropEvent* e)
751 if(!(this->CurrentState == ReadyConfigure ||
752 this->CurrentState == ReadyGenerate))
754 return;
757 const QMimeData* dat = e->mimeData();
758 QList<QUrl> urls = dat->urls();
759 QString file = urls.count() ? urls[0].toLocalFile() : QString();
760 if(file.endsWith("CMakeCache.txt", Qt::CaseInsensitive))
762 QFileInfo info(file);
763 if(this->CMakeThread->cmakeInstance()->binaryDirectory() != info.absolutePath())
765 this->setBinaryDirectory(info.absolutePath());
768 else if(file.endsWith("CMakeLists.txt", Qt::CaseInsensitive))
770 QFileInfo info(file);
771 if(this->CMakeThread->cmakeInstance()->binaryDirectory() != info.absolutePath())
773 this->setSourceDirectory(info.absolutePath());
774 this->setBinaryDirectory(info.absolutePath());
779 QStringList CMakeSetupDialog::loadBuildPaths()
781 QSettings settings;
782 settings.beginGroup("Settings/StartPath");
784 QStringList buildPaths;
785 for(int i=0; i<10; i++)
787 QString p = settings.value(QString("WhereBuild%1").arg(i)).toString();
788 if(!p.isEmpty())
790 buildPaths.append(p);
793 return buildPaths;
796 void CMakeSetupDialog::saveBuildPaths(const QStringList& paths)
798 QSettings settings;
799 settings.beginGroup("Settings/StartPath");
801 int num = paths.count();
802 if(num > 10)
804 num = 10;
807 for(int i=0; i<num; i++)
809 settings.setValue(QString("WhereBuild%1").arg(i), paths[i]);
813 void CMakeSetupDialog::setCacheModified()
815 this->CacheModified = true;
816 this->enterState(ReadyConfigure);
819 void CMakeSetupDialog::removeSelectedCacheEntries()
821 QModelIndexList idxs = this->CacheValues->selectionModel()->selectedRows();
822 QList<QPersistentModelIndex> pidxs;
823 foreach(QModelIndex i, idxs)
825 pidxs.append(i);
827 foreach(QPersistentModelIndex pi, pidxs)
829 this->CacheValues->model()->removeRow(pi.row(), pi.parent());
833 void CMakeSetupDialog::selectionChanged()
835 QModelIndexList idxs = this->CacheValues->selectionModel()->selectedRows();
836 if(idxs.count() &&
837 (this->CurrentState == ReadyConfigure ||
838 this->CurrentState == ReadyGenerate) )
840 this->RemoveEntry->setEnabled(true);
842 else
844 this->RemoveEntry->setEnabled(false);
848 void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
850 if(s == this->CurrentState)
852 return;
855 this->CurrentState = s;
857 if(s == Interrupting)
859 this->ConfigureButton->setEnabled(false);
860 this->GenerateButton->setEnabled(false);
862 else if(s == Configuring)
864 this->Output->clear();
865 this->setEnabledState(false);
866 this->GenerateButton->setEnabled(false);
867 this->GenerateAction->setEnabled(false);
868 this->ConfigureButton->setText(tr("&Stop"));
870 else if(s == Generating)
872 this->CacheModified = false;
873 this->setEnabledState(false);
874 this->ConfigureButton->setEnabled(false);
875 this->GenerateAction->setEnabled(false);
876 this->GenerateButton->setText(tr("&Stop"));
878 else if(s == ReadyConfigure)
880 this->ProgressBar->reset();
881 this->setEnabledState(true);
882 this->GenerateButton->setEnabled(false);
883 this->GenerateAction->setEnabled(false);
884 this->ConfigureButton->setEnabled(true);
885 this->ConfigureButton->setText(tr("&Configure"));
886 this->GenerateButton->setText(tr("&Generate"));
888 else if(s == ReadyGenerate)
890 this->ProgressBar->reset();
891 this->setEnabledState(true);
892 this->GenerateButton->setEnabled(true);
893 this->GenerateAction->setEnabled(true);
894 this->ConfigureButton->setEnabled(true);
895 this->ConfigureButton->setText(tr("&Configure"));
896 this->GenerateButton->setText(tr("&Generate"));
900 void CMakeSetupDialog::addCacheEntry()
902 QDialog dialog(this);
903 dialog.resize(400, 200);
904 dialog.setWindowTitle(tr("Add Cache Entry"));
905 QVBoxLayout* l = new QVBoxLayout(&dialog);
906 AddCacheEntry* w = new AddCacheEntry(&dialog);
907 QDialogButtonBox* btns = new QDialogButtonBox(
908 QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
909 Qt::Horizontal, &dialog);
910 QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
911 QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(reject()));
912 l->addWidget(w);
913 l->addStretch();
914 l->addWidget(btns);
915 if(QDialog::Accepted == dialog.exec())
917 QCMakeCacheModel* m = this->CacheValues->cacheModel();
918 m->insertProperty(w->type(), w->name(), w->description(), w->value(), false);
922 void CMakeSetupDialog::startSearch()
924 this->Search->setFocus(Qt::OtherFocusReason);
925 this->Search->selectAll();
928 void CMakeSetupDialog::setDebugOutput(bool flag)
930 QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
931 "setDebugOutput", Qt::QueuedConnection, Q_ARG(bool, flag));
934 void CMakeSetupDialog::setViewType(int v)
936 if(v == 0) // simple view
938 this->CacheValues->cacheModel()->setViewType(QCMakeCacheModel::FlatView);
939 this->CacheValues->setRootIsDecorated(false);
940 this->CacheValues->setShowAdvanced(false);
942 else if(v == 1) // advanced view
944 this->CacheValues->cacheModel()->setViewType(QCMakeCacheModel::FlatView);
945 this->CacheValues->setRootIsDecorated(false);
946 this->CacheValues->setShowAdvanced(true);
948 else if(v == 2) // grouped view
950 this->CacheValues->cacheModel()->setViewType(QCMakeCacheModel::GroupView);
951 this->CacheValues->setRootIsDecorated(true);
952 this->CacheValues->setShowAdvanced(true);
955 QSettings settings;
956 settings.beginGroup("Settings/StartPath");
957 settings.setValue("GroupView", v == 2);