1 /*=========================================================================
3 Program: CMake - Cross-Platform Makefile Generator
4 Module: $RCSfile: CMakeSetupDialog.cxx,v $
6 Date: $Date: 2009-09-22 22:29:35 $
7 Version: $Revision: 1.62 $
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>
23 #include <QToolButton>
24 #include <QDialogButtonBox>
25 #include <QCloseEvent>
26 #include <QCoreApplication>
30 #include <QDragEnterEvent>
34 #include <QMacInstallDialog.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();
58 delete this->CMakeInstance
;
59 this->CMakeInstance
= NULL
;
62 CMakeSetupDialog::CMakeSetupDialog()
63 : ExitAfterGenerate(true), CacheModified(false), CurrentState(Interrupting
)
65 QString title
= QString(tr("CMake %1"));
66 title
= title
.arg(cmVersion::GetCMakeVersion());
67 this->setWindowTitle(title
);
71 settings
.beginGroup("Settings/StartPath");
72 int h
= settings
.value("Height", 500).toInt();
73 int w
= settings
.value("Width", 700).toInt();
76 QWidget
* cont
= new QWidget(this);
78 this->Splitter
->setStretchFactor(0, 3);
79 this->Splitter
->setStretchFactor(1, 1);
80 this->setCentralWidget(cont
);
81 this->ProgressBar
->reset();
82 this->RemoveEntry
->setEnabled(false);
83 this->AddEntry
->setEnabled(false);
85 QByteArray p
= settings
.value("SplitterSizes").toByteArray();
86 this->Splitter
->restoreState(p
);
88 bool groupView
= settings
.value("GroupView", false).toBool();
92 this->ViewType
->setCurrentIndex(2);
95 QMenu
* FileMenu
= this->menuBar()->addMenu(tr("&File"));
96 this->ReloadCacheAction
= FileMenu
->addAction(tr("&Reload Cache"));
97 QObject::connect(this->ReloadCacheAction
, SIGNAL(triggered(bool)),
98 this, SLOT(doReloadCache()));
99 this->DeleteCacheAction
= FileMenu
->addAction(tr("&Delete Cache"));
100 QObject::connect(this->DeleteCacheAction
, SIGNAL(triggered(bool)),
101 this, SLOT(doDeleteCache()));
102 this->ExitAction
= FileMenu
->addAction(tr("E&xit"));
103 QObject::connect(this->ExitAction
, SIGNAL(triggered(bool)),
104 this, SLOT(close()));
106 QMenu
* ToolsMenu
= this->menuBar()->addMenu(tr("&Tools"));
107 this->ConfigureAction
= ToolsMenu
->addAction(tr("&Configure"));
108 // prevent merging with Preferences menu item on Mac OS X
109 this->ConfigureAction
->setMenuRole(QAction::NoRole
);
110 QObject::connect(this->ConfigureAction
, SIGNAL(triggered(bool)),
111 this, SLOT(doConfigure()));
112 this->GenerateAction
= ToolsMenu
->addAction(tr("&Generate"));
113 QObject::connect(this->GenerateAction
, SIGNAL(triggered(bool)),
114 this, SLOT(doGenerate()));
115 QAction
* showChangesAction
= ToolsMenu
->addAction(tr("&Show My Changes"));
116 QObject::connect(showChangesAction
, SIGNAL(triggered(bool)),
117 this, SLOT(showUserChanges()));
118 #if defined(Q_WS_MAC)
119 this->InstallForCommandLineAction
120 = ToolsMenu
->addAction(tr("&Install For Command Line Use"));
121 QObject::connect(this->InstallForCommandLineAction
, SIGNAL(triggered(bool)),
122 this, SLOT(doInstallForCommandLine()));
124 QMenu
* OptionsMenu
= this->menuBar()->addMenu(tr("&Options"));
125 this->SuppressDevWarningsAction
= OptionsMenu
->addAction(tr("&Suppress dev Warnings (-Wno-dev)"));
126 this->SuppressDevWarningsAction
->setCheckable(true);
128 QAction
* debugAction
= OptionsMenu
->addAction(tr("&Debug Output"));
129 debugAction
->setCheckable(true);
130 QObject::connect(debugAction
, SIGNAL(toggled(bool)),
131 this, SLOT(setDebugOutput(bool)));
133 OptionsMenu
->addSeparator();
134 QAction
* expandAction
= OptionsMenu
->addAction(tr("&Expand Grouped Entries"));
135 QObject::connect(expandAction
, SIGNAL(triggered(bool)),
136 this->CacheValues
, SLOT(expandAll()));
137 QAction
* collapseAction
= OptionsMenu
->addAction(tr("&Collapse Grouped Entries"));
138 QObject::connect(collapseAction
, SIGNAL(triggered(bool)),
139 this->CacheValues
, SLOT(collapseAll()));
141 QMenu
* HelpMenu
= this->menuBar()->addMenu(tr("&Help"));
142 QAction
* a
= HelpMenu
->addAction(tr("About"));
143 QObject::connect(a
, SIGNAL(triggered(bool)),
144 this, SLOT(doAbout()));
145 a
= HelpMenu
->addAction(tr("Help"));
146 QObject::connect(a
, SIGNAL(triggered(bool)),
147 this, SLOT(doHelp()));
149 QShortcut
* filterShortcut
= new QShortcut(QKeySequence::Find
, this);
150 QObject::connect(filterShortcut
, SIGNAL(activated()),
151 this, SLOT(startSearch()));
153 this->setAcceptDrops(true);
155 // get the saved binary directories
156 QStringList buildPaths
= this->loadBuildPaths();
157 this->BinaryDirectory
->addItems(buildPaths
);
159 this->BinaryDirectory
->setCompleter(new QCMakeFileCompleter(this, true));
160 this->SourceDirectory
->setCompleter(new QCMakeFileCompleter(this, true));
162 // fixed pitch font in output window
163 QFont
outputFont("Courier");
164 this->Output
->setFont(outputFont
);
165 this->ErrorFormat
.setForeground(QBrush(Qt::red
));
167 // start the cmake worker thread
168 this->CMakeThread
= new QCMakeThread(this);
169 QObject::connect(this->CMakeThread
, SIGNAL(cmakeInitialized()),
170 this, SLOT(initialize()), Qt::QueuedConnection
);
171 this->CMakeThread
->start();
173 this->enterState(ReadyConfigure
);
176 void CMakeSetupDialog::initialize()
178 // now the cmake worker thread is running, lets make our connections to it
179 QObject::connect(this->CMakeThread
->cmakeInstance(),
180 SIGNAL(propertiesChanged(const QCMakePropertyList
&)),
181 this->CacheValues
->cacheModel(),
182 SLOT(setProperties(const QCMakePropertyList
&)));
184 QObject::connect(this->ConfigureButton
, SIGNAL(clicked(bool)),
185 this, SLOT(doConfigure()));
186 QObject::connect(this->CMakeThread
->cmakeInstance(),
187 SIGNAL(configureDone(int)),
188 this, SLOT(finishConfigure(int)));
189 QObject::connect(this->CMakeThread
->cmakeInstance(),
190 SIGNAL(generateDone(int)),
191 this, SLOT(finishGenerate(int)));
193 QObject::connect(this->GenerateButton
, SIGNAL(clicked(bool)),
194 this, SLOT(doGenerate()));
196 QObject::connect(this->BrowseSourceDirectoryButton
, SIGNAL(clicked(bool)),
197 this, SLOT(doSourceBrowse()));
198 QObject::connect(this->BrowseBinaryDirectoryButton
, SIGNAL(clicked(bool)),
199 this, SLOT(doBinaryBrowse()));
201 QObject::connect(this->BinaryDirectory
, SIGNAL(editTextChanged(QString
)),
202 this, SLOT(onBinaryDirectoryChanged(QString
)));
203 QObject::connect(this->SourceDirectory
, SIGNAL(textChanged(QString
)),
204 this, SLOT(onSourceDirectoryChanged(QString
)));
206 QObject::connect(this->CMakeThread
->cmakeInstance(),
207 SIGNAL(sourceDirChanged(QString
)),
208 this, SLOT(updateSourceDirectory(QString
)));
209 QObject::connect(this->CMakeThread
->cmakeInstance(),
210 SIGNAL(binaryDirChanged(QString
)),
211 this, SLOT(updateBinaryDirectory(QString
)));
213 QObject::connect(this->CMakeThread
->cmakeInstance(),
214 SIGNAL(progressChanged(QString
, float)),
215 this, SLOT(showProgress(QString
,float)));
217 QObject::connect(this->CMakeThread
->cmakeInstance(),
218 SIGNAL(errorMessage(QString
)),
219 this, SLOT(error(QString
)));
221 QObject::connect(this->CMakeThread
->cmakeInstance(),
222 SIGNAL(outputMessage(QString
)),
223 this, SLOT(message(QString
)));
225 QObject::connect(this->ViewType
, SIGNAL(currentIndexChanged(int)),
226 this, SLOT(setViewType(int)));
227 QObject::connect(this->Search
, SIGNAL(textChanged(QString
)),
228 this, SLOT(setSearchFilter(QString
)));
230 QObject::connect(this->CMakeThread
->cmakeInstance(),
231 SIGNAL(generatorChanged(QString
)),
232 this, SLOT(updateGeneratorLabel(QString
)));
233 this->updateGeneratorLabel(QString());
235 QObject::connect(this->CacheValues
->cacheModel(),
236 SIGNAL(dataChanged(QModelIndex
,QModelIndex
)),
237 this, SLOT(setCacheModified()));
239 QObject::connect(this->CacheValues
->selectionModel(),
240 SIGNAL(selectionChanged(QItemSelection
,QItemSelection
)),
241 this, SLOT(selectionChanged()));
242 QObject::connect(this->RemoveEntry
, SIGNAL(clicked(bool)),
243 this, SLOT(removeSelectedCacheEntries()));
244 QObject::connect(this->AddEntry
, SIGNAL(clicked(bool)),
245 this, SLOT(addCacheEntry()));
247 QObject::connect(this->SuppressDevWarningsAction
, SIGNAL(triggered(bool)),
248 this->CMakeThread
->cmakeInstance(), SLOT(setSuppressDevWarnings(bool)));
250 if(!this->SourceDirectory
->text().isEmpty() ||
251 !this->BinaryDirectory
->lineEdit()->text().isEmpty())
253 this->onSourceDirectoryChanged(this->SourceDirectory
->text());
254 this->onBinaryDirectoryChanged(this->BinaryDirectory
->lineEdit()->text());
258 this->onBinaryDirectoryChanged(this->BinaryDirectory
->lineEdit()->text());
262 CMakeSetupDialog::~CMakeSetupDialog()
265 settings
.beginGroup("Settings/StartPath");
266 settings
.setValue("Height", this->height());
267 settings
.setValue("Width", this->width());
268 settings
.setValue("SplitterSizes", this->Splitter
->saveState());
270 // wait for thread to stop
271 this->CMakeThread
->quit();
272 this->CMakeThread
->wait(2000);
275 void CMakeSetupDialog::doConfigure()
277 if(this->CurrentState
== Configuring
)
284 // make sure build directory exists
285 QString bindir
= this->CMakeThread
->cmakeInstance()->binaryDirectory();
289 QString message
= tr("Build directory does not exist, "
290 "should I create it?")
294 QString title
= tr("Create Directory");
295 QMessageBox::StandardButton btn
;
296 btn
= QMessageBox::information(this, title
, message
,
297 QMessageBox::Yes
| QMessageBox::No
);
298 if(btn
== QMessageBox::No
)
305 // if no generator, prompt for it and other setup stuff
306 if(this->CMakeThread
->cmakeInstance()->generator().isEmpty())
308 if(!this->setupFirstConfigure())
315 this->addBinaryPath(dir
.absolutePath());
317 this->enterState(Configuring
);
319 this->CacheValues
->selectionModel()->clear();
320 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
321 "setProperties", Qt::QueuedConnection
,
322 Q_ARG(QCMakePropertyList
,
323 this->CacheValues
->cacheModel()->properties()));
324 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
325 "configure", Qt::QueuedConnection
);
328 void CMakeSetupDialog::finishConfigure(int err
)
330 if(0 == err
&& !this->CacheValues
->cacheModel()->newPropertyCount())
332 this->enterState(ReadyGenerate
);
336 this->enterState(ReadyConfigure
);
337 this->CacheValues
->scrollToTop();
342 QMessageBox::critical(this, tr("Error"),
343 tr("Error in configuration process, project files may be invalid"),
348 void CMakeSetupDialog::finishGenerate(int err
)
350 this->enterState(ReadyGenerate
);
353 QMessageBox::critical(this, tr("Error"),
354 tr("Error in generation process, project files may be invalid"),
359 void CMakeSetupDialog::doInstallForCommandLine()
361 QMacInstallDialog
setupdialog(0);
365 void CMakeSetupDialog::doGenerate()
367 if(this->CurrentState
== Generating
)
373 this->enterState(Generating
);
374 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
375 "generate", Qt::QueuedConnection
);
378 void CMakeSetupDialog::closeEvent(QCloseEvent
* e
)
380 // prompt for close if there are unsaved changes, and we're not busy
381 if(this->CacheModified
)
383 QString message
= tr("You have changed options but not rebuilt, "
384 "are you sure you want to exit?");
385 QString title
= tr("Confirm Exit");
386 QMessageBox::StandardButton btn
;
387 btn
= QMessageBox::critical(this, title
, message
,
388 QMessageBox::Yes
| QMessageBox::No
);
389 if(btn
== QMessageBox::No
)
395 // don't close if we're busy, unless the user really wants to
396 if(this->CurrentState
== Configuring
)
398 QString message
= "You are in the middle of a Configure.\n"
399 "If you Exit now the configure information will be lost.\n"
400 "Are you sure you want to Exit?";
401 QString title
= tr("Confirm Exit");
402 QMessageBox::StandardButton btn
;
403 btn
= QMessageBox::critical(this, title
, message
,
404 QMessageBox::Yes
| QMessageBox::No
);
405 if(btn
== QMessageBox::No
)
415 // let the generate finish
416 if(this->CurrentState
== Generating
)
422 void CMakeSetupDialog::doHelp()
424 QString msg
= tr("CMake is used to configure and generate build files for "
425 "software projects. The basic steps for configuring a project are as "
426 "follows:\r\n\r\n1. Select the source directory for the project. This should "
427 "contain the CMakeLists.txt files for the project.\r\n\r\n2. Select the build "
428 "directory for the project. This is the directory where the project will be "
429 "built. It can be the same or a different directory than the source "
430 "directory. For easy clean up, a separate build directory is recommended. "
431 "CMake will create the directory if it does not exist.\r\n\r\n3. Once the "
432 "source and binary directories are selected, it is time to press the "
433 "Configure button. This will cause CMake to read all of the input files and "
434 "discover all the variables used by the project. The first time a variable "
435 "is displayed it will be in Red. Users should inspect red variables making "
436 "sure the values are correct. For some projects the Configure process can "
437 "be iterative, so continue to press the Configure button until there are no "
438 "longer red entries.\r\n\r\n4. Once there are no longer red entries, you "
439 "should click the Generate button. This will write the build files to the build "
443 QFontMetrics
met(this->font());
444 int msgWidth
= met
.width(msg
);
445 dialog
.setMinimumSize(msgWidth
/15,20);
446 dialog
.setWindowTitle(tr("Help"));
447 QVBoxLayout
* l
= new QVBoxLayout(&dialog
);
448 QLabel
* lab
= new QLabel(&dialog
);
450 lab
->setWordWrap(true);
451 QDialogButtonBox
* btns
= new QDialogButtonBox(QDialogButtonBox::Ok
,
452 Qt::Horizontal
, &dialog
);
453 QObject::connect(btns
, SIGNAL(accepted()), &dialog
, SLOT(accept()));
459 void CMakeSetupDialog::doInterrupt()
461 this->enterState(Interrupting
);
462 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
463 "interrupt", Qt::QueuedConnection
);
466 void CMakeSetupDialog::doSourceBrowse()
468 QString dir
= QFileDialog::getExistingDirectory(this,
469 tr("Enter Path to Source"), this->SourceDirectory
->text());
472 this->setSourceDirectory(dir
);
476 void CMakeSetupDialog::updateSourceDirectory(const QString
& dir
)
478 if(this->SourceDirectory
->text() != dir
)
480 this->SourceDirectory
->blockSignals(true);
481 this->SourceDirectory
->setText(dir
);
482 this->SourceDirectory
->blockSignals(false);
486 void CMakeSetupDialog::updateBinaryDirectory(const QString
& dir
)
488 if(this->BinaryDirectory
->currentText() != dir
)
490 this->BinaryDirectory
->blockSignals(true);
491 this->BinaryDirectory
->setEditText(dir
);
492 this->BinaryDirectory
->blockSignals(false);
496 void CMakeSetupDialog::doBinaryBrowse()
498 QString dir
= QFileDialog::getExistingDirectory(this,
499 tr("Enter Path to Build"), this->BinaryDirectory
->currentText());
500 if(!dir
.isEmpty() && dir
!= this->BinaryDirectory
->currentText())
502 this->setBinaryDirectory(dir
);
506 void CMakeSetupDialog::setBinaryDirectory(const QString
& dir
)
508 this->BinaryDirectory
->setEditText(dir
);
511 void CMakeSetupDialog::onSourceDirectoryChanged(const QString
& dir
)
513 this->Output
->clear();
514 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
515 "setSourceDirectory", Qt::QueuedConnection
, Q_ARG(QString
, dir
));
518 void CMakeSetupDialog::onBinaryDirectoryChanged(const QString
& dir
)
520 QString title
= QString(tr("CMake %1 - %2"));
521 title
= title
.arg(cmVersion::GetCMakeVersion());
522 title
= title
.arg(dir
);
523 this->setWindowTitle(title
);
525 this->CacheModified
= false;
526 this->CacheValues
->cacheModel()->clear();
527 qobject_cast
<QCMakeCacheModelDelegate
*>(this->CacheValues
->itemDelegate())->clearChanges();
528 this->Output
->clear();
529 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
530 "setBinaryDirectory", Qt::QueuedConnection
, Q_ARG(QString
, dir
));
533 void CMakeSetupDialog::setSourceDirectory(const QString
& dir
)
535 this->SourceDirectory
->setText(dir
);
538 void CMakeSetupDialog::showProgress(const QString
& /*msg*/, float percent
)
540 this->ProgressBar
->setValue(qRound(percent
* 100));
543 void CMakeSetupDialog::error(const QString
& message
)
545 this->Output
->setCurrentCharFormat(this->ErrorFormat
);
546 this->Output
->append(message
);
549 void CMakeSetupDialog::message(const QString
& message
)
551 this->Output
->setCurrentCharFormat(this->MessageFormat
);
552 this->Output
->append(message
);
555 void CMakeSetupDialog::setEnabledState(bool enabled
)
557 // disable parts of the GUI during configure/generate
558 this->CacheValues
->cacheModel()->setEditEnabled(enabled
);
559 this->SourceDirectory
->setEnabled(enabled
);
560 this->BrowseSourceDirectoryButton
->setEnabled(enabled
);
561 this->BinaryDirectory
->setEnabled(enabled
);
562 this->BrowseBinaryDirectoryButton
->setEnabled(enabled
);
563 this->ReloadCacheAction
->setEnabled(enabled
);
564 this->DeleteCacheAction
->setEnabled(enabled
);
565 this->ExitAction
->setEnabled(enabled
);
566 this->ConfigureAction
->setEnabled(enabled
);
567 this->AddEntry
->setEnabled(enabled
);
568 this->RemoveEntry
->setEnabled(false); // let selection re-enable it
571 bool CMakeSetupDialog::setupFirstConfigure()
573 FirstConfigure dialog
;
575 // initialize dialog and restore saved settings
578 dialog
.setGenerators(this->CMakeThread
->cmakeInstance()->availableGenerators());
580 // restore from settings
581 dialog
.loadFromSettings();
583 if(dialog
.exec() == QDialog::Accepted
)
585 dialog
.saveToSettings();
586 this->CMakeThread
->cmakeInstance()->setGenerator(dialog
.getGenerator());
588 QCMakeCacheModel
* m
= this->CacheValues
->cacheModel();
590 if(dialog
.compilerSetup())
592 QString fortranCompiler
= dialog
.getFortranCompiler();
593 if(!fortranCompiler
.isEmpty())
595 m
->insertProperty(QCMakeProperty::FILEPATH
, "CMAKE_Fortran_COMPILER",
596 "Fortran compiler.", fortranCompiler
, false);
598 QString cxxCompiler
= dialog
.getCXXCompiler();
599 if(!cxxCompiler
.isEmpty())
601 m
->insertProperty(QCMakeProperty::FILEPATH
, "CMAKE_CXX_COMPILER",
602 "CXX compiler.", cxxCompiler
, false);
605 QString cCompiler
= dialog
.getCCompiler();
606 if(!cCompiler
.isEmpty())
608 m
->insertProperty(QCMakeProperty::FILEPATH
, "CMAKE_C_COMPILER",
609 "C compiler.", cCompiler
, false);
612 else if(dialog
.crossCompilerSetup())
614 QString fortranCompiler
= dialog
.getFortranCompiler();
615 if(!fortranCompiler
.isEmpty())
617 m
->insertProperty(QCMakeProperty::FILEPATH
, "CMAKE_Fortran_COMPILER",
618 "Fortran compiler.", fortranCompiler
, false);
621 QString mode
= dialog
.getCrossIncludeMode();
622 m
->insertProperty(QCMakeProperty::STRING
, "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE",
623 "CMake Find Include Mode", mode
, false);
624 mode
= dialog
.getCrossLibraryMode();
625 m
->insertProperty(QCMakeProperty::STRING
, "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY",
626 "CMake Find Library Mode", mode
, false);
627 mode
= dialog
.getCrossProgramMode();
628 m
->insertProperty(QCMakeProperty::STRING
, "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM",
629 "CMake Find Program Mode", mode
, false);
631 QString rootPath
= dialog
.getCrossRoot();
632 m
->insertProperty(QCMakeProperty::PATH
, "CMAKE_FIND_ROOT_PATH",
633 "CMake Find Root Path", rootPath
, false);
635 QString systemName
= dialog
.getSystemName();
636 m
->insertProperty(QCMakeProperty::STRING
, "CMAKE_SYSTEM_NAME",
637 "CMake System Name", systemName
, false);
638 QString cxxCompiler
= dialog
.getCXXCompiler();
639 m
->insertProperty(QCMakeProperty::FILEPATH
, "CMAKE_CXX_COMPILER",
640 "CXX compiler.", cxxCompiler
, false);
641 QString cCompiler
= dialog
.getCCompiler();
642 m
->insertProperty(QCMakeProperty::FILEPATH
, "CMAKE_C_COMPILER",
643 "C compiler.", cCompiler
, false);
645 else if(dialog
.crossCompilerToolChainFile())
647 QString toolchainFile
= dialog
.getCrossCompilerToolChainFile();
648 m
->insertProperty(QCMakeProperty::FILEPATH
, "CMAKE_TOOLCHAIN_FILE",
649 "Cross Compile ToolChain File", toolchainFile
, false);
657 void CMakeSetupDialog::updateGeneratorLabel(const QString
& gen
)
659 QString str
= tr("Current Generator: ");
668 this->Generator
->setText(str
);
671 void CMakeSetupDialog::doReloadCache()
673 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
674 "reloadCache", Qt::QueuedConnection
);
677 void CMakeSetupDialog::doDeleteCache()
679 QString title
= tr("Delete Cache");
680 QString message
= "Are you sure you want to delete the cache?";
681 QMessageBox::StandardButton btn
;
682 btn
= QMessageBox::information(this, title
, message
,
683 QMessageBox::Yes
| QMessageBox::No
);
684 if(btn
== QMessageBox::No
)
688 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
689 "deleteCache", Qt::QueuedConnection
);
692 void CMakeSetupDialog::doAbout()
694 QString msg
= "CMake %1\n"
698 msg
= msg
.arg(cmVersion::GetCMakeVersion());
699 msg
= msg
.arg(qVersion());
702 dialog
.setWindowTitle(tr("About"));
703 QVBoxLayout
* l
= new QVBoxLayout(&dialog
);
704 QLabel
* lab
= new QLabel(&dialog
);
707 lab
->setWordWrap(true);
708 QDialogButtonBox
* btns
= new QDialogButtonBox(QDialogButtonBox::Ok
,
709 Qt::Horizontal
, &dialog
);
710 QObject::connect(btns
, SIGNAL(accepted()), &dialog
, SLOT(accept()));
715 void CMakeSetupDialog::setExitAfterGenerate(bool b
)
717 this->ExitAfterGenerate
= b
;
720 void CMakeSetupDialog::addBinaryPath(const QString
& path
)
722 QString cleanpath
= QDir::cleanPath(path
);
725 this->BinaryDirectory
->blockSignals(true);
726 int idx
= this->BinaryDirectory
->findText(cleanpath
);
729 this->BinaryDirectory
->removeItem(idx
);
731 this->BinaryDirectory
->insertItem(0, cleanpath
);
732 this->BinaryDirectory
->setCurrentIndex(0);
733 this->BinaryDirectory
->blockSignals(false);
736 QStringList buildPaths
= this->loadBuildPaths();
737 buildPaths
.removeAll(cleanpath
);
738 buildPaths
.prepend(cleanpath
);
739 this->saveBuildPaths(buildPaths
);
742 void CMakeSetupDialog::dragEnterEvent(QDragEnterEvent
* e
)
744 if(!(this->CurrentState
== ReadyConfigure
||
745 this->CurrentState
== ReadyGenerate
))
751 const QMimeData
* dat
= e
->mimeData();
752 QList
<QUrl
> urls
= dat
->urls();
753 QString file
= urls
.count() ? urls
[0].toLocalFile() : QString();
754 if(!file
.isEmpty() &&
755 (file
.endsWith("CMakeCache.txt", Qt::CaseInsensitive
) ||
756 file
.endsWith("CMakeLists.txt", Qt::CaseInsensitive
) ) )
766 void CMakeSetupDialog::dropEvent(QDropEvent
* e
)
768 if(!(this->CurrentState
== ReadyConfigure
||
769 this->CurrentState
== ReadyGenerate
))
774 const QMimeData
* dat
= e
->mimeData();
775 QList
<QUrl
> urls
= dat
->urls();
776 QString file
= urls
.count() ? urls
[0].toLocalFile() : QString();
777 if(file
.endsWith("CMakeCache.txt", Qt::CaseInsensitive
))
779 QFileInfo
info(file
);
780 if(this->CMakeThread
->cmakeInstance()->binaryDirectory() != info
.absolutePath())
782 this->setBinaryDirectory(info
.absolutePath());
785 else if(file
.endsWith("CMakeLists.txt", Qt::CaseInsensitive
))
787 QFileInfo
info(file
);
788 if(this->CMakeThread
->cmakeInstance()->binaryDirectory() != info
.absolutePath())
790 this->setSourceDirectory(info
.absolutePath());
791 this->setBinaryDirectory(info
.absolutePath());
796 QStringList
CMakeSetupDialog::loadBuildPaths()
799 settings
.beginGroup("Settings/StartPath");
801 QStringList buildPaths
;
802 for(int i
=0; i
<10; i
++)
804 QString p
= settings
.value(QString("WhereBuild%1").arg(i
)).toString();
807 buildPaths
.append(p
);
813 void CMakeSetupDialog::saveBuildPaths(const QStringList
& paths
)
816 settings
.beginGroup("Settings/StartPath");
818 int num
= paths
.count();
824 for(int i
=0; i
<num
; i
++)
826 settings
.setValue(QString("WhereBuild%1").arg(i
), paths
[i
]);
830 void CMakeSetupDialog::setCacheModified()
832 this->CacheModified
= true;
833 this->enterState(ReadyConfigure
);
836 void CMakeSetupDialog::removeSelectedCacheEntries()
838 QModelIndexList idxs
= this->CacheValues
->selectionModel()->selectedRows();
839 QList
<QPersistentModelIndex
> pidxs
;
840 foreach(QModelIndex i
, idxs
)
844 foreach(QPersistentModelIndex pi
, pidxs
)
846 this->CacheValues
->model()->removeRow(pi
.row(), pi
.parent());
850 void CMakeSetupDialog::selectionChanged()
852 QModelIndexList idxs
= this->CacheValues
->selectionModel()->selectedRows();
854 (this->CurrentState
== ReadyConfigure
||
855 this->CurrentState
== ReadyGenerate
) )
857 this->RemoveEntry
->setEnabled(true);
861 this->RemoveEntry
->setEnabled(false);
865 void CMakeSetupDialog::enterState(CMakeSetupDialog::State s
)
867 if(s
== this->CurrentState
)
872 this->CurrentState
= s
;
874 if(s
== Interrupting
)
876 this->ConfigureButton
->setEnabled(false);
877 this->GenerateButton
->setEnabled(false);
879 else if(s
== Configuring
)
881 this->Output
->clear();
882 this->setEnabledState(false);
883 this->GenerateButton
->setEnabled(false);
884 this->GenerateAction
->setEnabled(false);
885 this->ConfigureButton
->setText(tr("&Stop"));
887 else if(s
== Generating
)
889 this->CacheModified
= false;
890 this->setEnabledState(false);
891 this->ConfigureButton
->setEnabled(false);
892 this->GenerateAction
->setEnabled(false);
893 this->GenerateButton
->setText(tr("&Stop"));
895 else if(s
== ReadyConfigure
)
897 this->ProgressBar
->reset();
898 this->setEnabledState(true);
899 this->GenerateButton
->setEnabled(false);
900 this->GenerateAction
->setEnabled(false);
901 this->ConfigureButton
->setEnabled(true);
902 this->ConfigureButton
->setText(tr("&Configure"));
903 this->GenerateButton
->setText(tr("&Generate"));
905 else if(s
== ReadyGenerate
)
907 this->ProgressBar
->reset();
908 this->setEnabledState(true);
909 this->GenerateButton
->setEnabled(true);
910 this->GenerateAction
->setEnabled(true);
911 this->ConfigureButton
->setEnabled(true);
912 this->ConfigureButton
->setText(tr("&Configure"));
913 this->GenerateButton
->setText(tr("&Generate"));
917 void CMakeSetupDialog::addCacheEntry()
919 QDialog
dialog(this);
920 dialog
.resize(400, 200);
921 dialog
.setWindowTitle(tr("Add Cache Entry"));
922 QVBoxLayout
* l
= new QVBoxLayout(&dialog
);
923 AddCacheEntry
* w
= new AddCacheEntry(&dialog
);
924 QDialogButtonBox
* btns
= new QDialogButtonBox(
925 QDialogButtonBox::Ok
| QDialogButtonBox::Cancel
,
926 Qt::Horizontal
, &dialog
);
927 QObject::connect(btns
, SIGNAL(accepted()), &dialog
, SLOT(accept()));
928 QObject::connect(btns
, SIGNAL(rejected()), &dialog
, SLOT(reject()));
932 if(QDialog::Accepted
== dialog
.exec())
934 QCMakeCacheModel
* m
= this->CacheValues
->cacheModel();
935 m
->insertProperty(w
->type(), w
->name(), w
->description(), w
->value(), false);
939 void CMakeSetupDialog::startSearch()
941 this->Search
->setFocus(Qt::OtherFocusReason
);
942 this->Search
->selectAll();
945 void CMakeSetupDialog::setDebugOutput(bool flag
)
947 QMetaObject::invokeMethod(this->CMakeThread
->cmakeInstance(),
948 "setDebugOutput", Qt::QueuedConnection
, Q_ARG(bool, flag
));
951 void CMakeSetupDialog::setViewType(int v
)
953 if(v
== 0) // simple view
955 this->CacheValues
->cacheModel()->setViewType(QCMakeCacheModel::FlatView
);
956 this->CacheValues
->setRootIsDecorated(false);
957 this->CacheValues
->setShowAdvanced(false);
959 else if(v
== 1) // advanced view
961 this->CacheValues
->cacheModel()->setViewType(QCMakeCacheModel::FlatView
);
962 this->CacheValues
->setRootIsDecorated(false);
963 this->CacheValues
->setShowAdvanced(true);
965 else if(v
== 2) // grouped view
967 this->CacheValues
->cacheModel()->setViewType(QCMakeCacheModel::GroupView
);
968 this->CacheValues
->setRootIsDecorated(true);
969 this->CacheValues
->setShowAdvanced(true);
973 settings
.beginGroup("Settings/StartPath");
974 settings
.setValue("GroupView", v
== 2);
978 void CMakeSetupDialog::showUserChanges()
980 QSet
<QCMakeProperty
> changes
=
981 qobject_cast
<QCMakeCacheModelDelegate
*>(this->CacheValues
->itemDelegate())->changes();
983 QDialog
dialog(this);
984 dialog
.setWindowTitle(tr("My Changes"));
985 dialog
.resize(600, 400);
986 QVBoxLayout
* l
= new QVBoxLayout(&dialog
);
987 QTextEdit
* textedit
= new QTextEdit(&dialog
);
988 textedit
->setReadOnly(true);
989 l
->addWidget(textedit
);
990 QDialogButtonBox
* btns
= new QDialogButtonBox(QDialogButtonBox::Close
,
991 Qt::Horizontal
, &dialog
);
992 QObject::connect(btns
, SIGNAL(rejected()), &dialog
, SLOT(accept()));
998 foreach(QCMakeProperty prop
, changes
)
1003 case QCMakeProperty::BOOL
:
1006 case QCMakeProperty::PATH
:
1009 case QCMakeProperty::FILEPATH
:
1012 case QCMakeProperty::STRING
:
1017 if(prop
.Type
== QCMakeProperty::BOOL
)
1019 value
= prop
.Value
.toBool() ? "1" : "0";
1023 value
= prop
.Value
.toString();
1026 QString
line("%1:%2=");
1027 line
= line
.arg(prop
.Key
);
1028 line
= line
.arg(type
);
1030 command
+= QString("-D%1\"%2\" ").arg(line
).arg(value
);
1031 cache
+= QString("%1%2\n").arg(line
).arg(value
);
1034 textedit
->append(tr("Commandline options:"));
1035 textedit
->append(command
);
1036 textedit
->append("\n");
1037 textedit
->append(tr("Cache file:"));
1038 textedit
->append(cache
);
1043 void CMakeSetupDialog::setSearchFilter(const QString
& str
)
1045 this->CacheValues
->selectionModel()->clear();
1046 this->CacheValues
->setSearchFilter(str
);