summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClinton Stimpson <clinton@elemtech.com>2007-11-03 14:30:52 (GMT)
committerClinton Stimpson <clinton@elemtech.com>2007-11-03 14:30:52 (GMT)
commit77ad85a6ab00959b972f5f2ad86382e2161b92b6 (patch)
treedffe50dd916306eefcefd39e0f7fb20dc375bc27
parentc139a096c7cb73a8184b69f20a837d97c00b5a96 (diff)
downloadCMake-77ad85a6ab00959b972f5f2ad86382e2161b92b6.zip
CMake-77ad85a6ab00959b972f5f2ad86382e2161b92b6.tar.gz
CMake-77ad85a6ab00959b972f5f2ad86382e2161b92b6.tar.bz2
ENH: Add interrupt button near progress bar.
Implement help button. Implement cancel button. Add scrollable output window. Replace ON/OFF & combobox editors with checkboxes. Tab/backtab in cache table jumps between values (not names and values) Add tooltips to show help strings. Add application icon and qtmain for Windows. BUG: Fix save of cache values on configure.
-rw-r--r--Source/QtDialog/CMakeLists.txt9
-rw-r--r--Source/QtDialog/CMakeSetup.cxx1
-rw-r--r--Source/QtDialog/CMakeSetup.icobin0 -> 24542 bytes
-rw-r--r--Source/QtDialog/CMakeSetup.png (renamed from Source/QtDialog/CMakeSetupDialog.png)bin358 -> 358 bytes
-rw-r--r--Source/QtDialog/CMakeSetup.qrc2
-rw-r--r--Source/QtDialog/CMakeSetup.rc1
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx173
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h12
-rw-r--r--Source/QtDialog/CMakeSetupDialog.ui253
-rw-r--r--Source/QtDialog/QCMake.cxx28
-rw-r--r--Source/QtDialog/QCMake.h38
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx169
-rw-r--r--Source/QtDialog/QCMakeCacheView.h39
13 files changed, 461 insertions, 264 deletions
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
index 540887c..81c36cf 100644
--- a/Source/QtDialog/CMakeLists.txt
+++ b/Source/QtDialog/CMakeLists.txt
@@ -6,7 +6,6 @@ IF(NOT QT4_FOUND)
MESSAGE(SEND_ERROR "Failed to find Qt 4.3 or greater.")
ELSE(NOT QT4_FOUND)
- SET(QT_USE_QTMAIN TRUE)
INCLUDE(${QT_USE_FILE})
SET(SRCS
@@ -18,7 +17,6 @@ ELSE(NOT QT4_FOUND)
QCMakeCacheView.cxx
QCMakeCacheView.h
)
-
QT4_WRAP_UI(UI_SRCS
CMakeSetupDialog.ui
)
@@ -30,13 +28,16 @@ ELSE(NOT QT4_FOUND)
QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
SET(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
+ IF(WIN32)
+ SET(SRCS ${SRCS} CMakeSetup.rc)
+ ENDIF(WIN32)
+ # TODO Mac OS X icon
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
ADD_EXECUTABLE(QtDialog WIN32 MACOSX_BUNDLE ${SRCS})
- TARGET_LINK_LIBRARIES(QtDialog CMakeLib ${QT_LIBRARIES})
- ADD_DEPENDENCIES(QtDialog cmake)
+ TARGET_LINK_LIBRARIES(QtDialog CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES})
ENDIF(NOT QT4_FOUND)
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
index 9b4f28b..5ae5c42 100644
--- a/Source/QtDialog/CMakeSetup.cxx
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -26,6 +26,7 @@ int main(int argc, char** argv)
QApplication app(argc, argv);
app.setApplicationName("CMakeSetup");
app.setOrganizationName("Kitware");
+ app.setWindowIcon(QIcon(":/Icons/CMakeSetup.png"));
// TODO handle CMake args
diff --git a/Source/QtDialog/CMakeSetup.ico b/Source/QtDialog/CMakeSetup.ico
new file mode 100644
index 0000000..90fbdac
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.ico
Binary files differ
diff --git a/Source/QtDialog/CMakeSetupDialog.png b/Source/QtDialog/CMakeSetup.png
index 7bbcee4..7bbcee4 100644
--- a/Source/QtDialog/CMakeSetupDialog.png
+++ b/Source/QtDialog/CMakeSetup.png
Binary files differ
diff --git a/Source/QtDialog/CMakeSetup.qrc b/Source/QtDialog/CMakeSetup.qrc
index 14357e0..88d6340 100644
--- a/Source/QtDialog/CMakeSetup.qrc
+++ b/Source/QtDialog/CMakeSetup.qrc
@@ -1,5 +1,5 @@
<RCC>
<qresource prefix="/Icons" >
- <file>CMakeSetupDialog.png</file>
+ <file>CMakeSetup.png</file>
</qresource>
</RCC>
diff --git a/Source/QtDialog/CMakeSetup.rc b/Source/QtDialog/CMakeSetup.rc
new file mode 100644
index 0000000..fcc887d
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "CMakeSetup.ico"
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
index d54c7cf..36fdb6f 100644
--- a/Source/QtDialog/CMakeSetupDialog.cxx
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -21,6 +21,9 @@
#include <QThread>
#include <QProgressBar>
#include <QMessageBox>
+#include <QStatusBar>
+#include <QToolButton>
+#include <QDialogButtonBox>
#include "QCMake.h"
#include "QCMakeCacheView.h"
@@ -44,9 +47,17 @@ protected:
CMakeSetupDialog::CMakeSetupDialog()
{
// create the GUI
- this->setupUi(this);
+ this->resize(700, 500);
+ QWidget* cont = new QWidget(this);
+ this->setupUi(cont);
+ 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
@@ -64,36 +75,26 @@ void CMakeSetupDialog::initialize()
SIGNAL(propertiesChanged(const QCMakeCachePropertyList&)),
this->CacheValues->cacheModel(),
SLOT(setProperties(const QCMakeCachePropertyList&)));
- QObject::connect(this,
- SIGNAL(propertiesChanged(const QCMakeCachePropertyList&)),
- this->CMakeThread->CMakeInstance,
- SLOT(setProperties(const QCMakeCachePropertyList&)));
- QObject::connect(this->configureButton, SIGNAL(clicked(bool)),
+ QObject::connect(this->ConfigureButton, SIGNAL(clicked(bool)),
this, SLOT(doConfigure()));
- QObject::connect(this, SIGNAL(configure()),
- this->CMakeThread->CMakeInstance, SLOT(configure()));
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)),
+ QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)),
this, SLOT(doOk()));
- QObject::connect(this, SIGNAL(ok()),
- this->CMakeThread->CMakeInstance, SLOT(generate()));
- QObject::connect(this->cancelButton, SIGNAL(clicked(bool)),
+ QObject::connect(this->CancelButton, SIGNAL(clicked(bool)),
this, SLOT(doCancel()));
- QObject::connect(this, SIGNAL(cancel()),
- this->CMakeThread->CMakeInstance, SLOT(interrupt()));
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(textChanged(QString)),
+ QObject::connect(this->BinaryDirectory, SIGNAL(editTextChanged(QString)),
this->CMakeThread->CMakeInstance, SLOT(setBinaryDirectory(QString)));
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(sourceDirChanged(QString)),
@@ -105,6 +106,16 @@ void CMakeSetupDialog::initialize()
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()
@@ -116,49 +127,119 @@ CMakeSetupDialog::~CMakeSetupDialog()
void CMakeSetupDialog::doConfigure()
{
- emit this->propertiesChanged(this->CacheValues->cacheModel()->properties());
- emit this->configure();
+ 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("Configure Done", 2000);
+ this->statusBar()->showMessage(tr("Configure Done"), 2000);
if(error != 0)
- {
- bool dummy;
- this->error("Error", "Error in configuration process, project files may be invalid", &dummy);
- }
+ {
+ 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("Generate Done", 2000);
+ this->statusBar()->showMessage(tr("Generate Done"), 2000);
if(error != 0)
- {
- bool dummy;
- this->error("Error", "Error in generation process, project files may be invalid", &dummy);
- }
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error in generation process, project files may be invalid"),
+ QMessageBox::Ok);
+ }
+ else
+ {
+ QApplication::quit();
+ }
}
void CMakeSetupDialog::doOk()
{
- emit this->ok();
+ this->InterruptButton->setEnabled(true);
+ this->setEnabledState(false);
+ this->Output->clear();
+ QMetaObject::invokeMethod(this->CMakeThread->CMakeInstance,
+ "generate", Qt::QueuedConnection);
}
void CMakeSetupDialog::doCancel()
{
- emit this->cancel();
+ 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::Ok | QMessageBox::Cancel);
+ if(btn == QMessageBox::Cancel)
+ {
+ return;
+ }
+ }
+
+ QApplication::quit();
}
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, "TODO", this->SourceDirectory->text());
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Enter Path to Source"), this->SourceDirectory->text());
if(!dir.isEmpty())
{
this->updateSourceDirectory(dir);
@@ -172,7 +253,8 @@ void CMakeSetupDialog::updateSourceDirectory(const QString& dir)
void CMakeSetupDialog::doBinaryBrowse()
{
- QString dir = QFileDialog::getExistingDirectory(this, "TODO", this->BinaryDirectory->currentText());
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Enter Path to Build"), this->BinaryDirectory->currentText());
if(!dir.isEmpty())
{
this->setBinaryDirectory(dir);
@@ -182,18 +264,16 @@ void CMakeSetupDialog::doBinaryBrowse()
void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
{
if(dir != this->BinaryDirectory->currentText())
- {
+ {
+ this->Output->clear();
this->BinaryDirectory->setEditText(dir);
- }
+ }
}
void CMakeSetupDialog::showProgress(const QString& msg, float percent)
{
- if(percent >= 0)
- {
- this->statusBar()->showMessage(msg);
- this->ProgressBar->setValue(qRound(percent * 100));
- }
+ this->statusBar()->showMessage(msg);
+ this->ProgressBar->setValue(qRound(percent * 100));
}
void CMakeSetupDialog::error(const QString& title, const QString& message, bool* cancel)
@@ -201,9 +281,22 @@ void CMakeSetupDialog::error(const QString& title, const QString& message, bool*
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);
}
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
index 5ae32cd..7dec607 100644
--- a/Source/QtDialog/CMakeSetupDialog.h
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -22,6 +22,7 @@
class QCMakeThread;
class CMakeCacheModel;
class QProgressBar;
+class QToolButton;
/// Qt user interface for CMake
class CMakeSetupDialog : public QMainWindow, public Ui::CMakeSetupDialog
@@ -31,18 +32,13 @@ public:
CMakeSetupDialog();
~CMakeSetupDialog();
-signals:
- void configure();
- void ok();
- void cancel();
- void propertiesChanged(const QCMakeCachePropertyList&);
-
protected slots:
void initialize();
void doConfigure();
void doOk();
void doCancel();
void doHelp();
+ void doInterrupt();
void finishConfigure(int error);
void finishGenerate(int error);
void error(const QString& title, const QString& message, bool* cancel);
@@ -51,13 +47,13 @@ protected slots:
void doBinaryBrowse();
void updateSourceDirectory(const QString& dir);
void setBinaryDirectory(const QString& dir);
-
void showProgress(const QString& msg, float percent);
+ void setEnabledState(bool);
protected:
QCMakeThread* CMakeThread;
QProgressBar* ProgressBar;
-
+ QToolButton* InterruptButton;
};
diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui
index 9080f98..3942eb1 100644
--- a/Source/QtDialog/CMakeSetupDialog.ui
+++ b/Source/QtDialog/CMakeSetupDialog.ui
@@ -1,82 +1,83 @@
<ui version="4.0" >
<class>CMakeSetupDialog</class>
- <widget class="QMainWindow" name="CMakeSetupDialog" >
+ <widget class="QWidget" name="CMakeSetupDialog" >
<property name="geometry" >
<rect>
<x>0</x>
<y>0</y>
- <width>650</width>
- <height>505</height>
+ <width>673</width>
+ <height>460</height>
</rect>
</property>
- <property name="windowTitle" >
- <string>CMakeSetup</string>
- </property>
- <property name="windowIcon" >
- <iconset resource="CMakeSetup.qrc" >:/Icons/CMakeSetupDialog.png</iconset>
- </property>
- <widget class="QWidget" name="centralwidget" >
- <layout class="QGridLayout" >
- <item row="0" column="0" >
- <widget class="QFrame" name="frame" >
- <property name="frameShape" >
- <enum>QFrame::NoFrame</enum>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QFrame" name="frame" >
+ <property name="frameShape" >
+ <enum>QFrame::NoFrame</enum>
+ </property>
+ <property name="frameShadow" >
+ <enum>QFrame::Raised</enum>
+ </property>
+ <layout class="QVBoxLayout" >
+ <property name="leftMargin" >
+ <number>0</number>
</property>
- <property name="frameShadow" >
- <enum>QFrame::Raised</enum>
+ <property name="topMargin" >
+ <number>0</number>
</property>
- <layout class="QGridLayout" >
- <property name="leftMargin" >
- <number>0</number>
- </property>
- <property name="topMargin" >
- <number>0</number>
- </property>
- <property name="rightMargin" >
- <number>0</number>
- </property>
- <property name="bottomMargin" >
- <number>0</number>
- </property>
- <item row="0" column="0" >
- <widget class="QLabel" name="label" >
- <property name="text" >
- <string>Where is the source code:</string>
- </property>
- </widget>
- </item>
- <item row="0" column="1" >
- <widget class="QLineEdit" name="SourceDirectory" />
- </item>
- <item row="0" column="2" >
- <widget class="QPushButton" name="BrowseSourceDirectoryButton" >
- <property name="text" >
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="1" column="0" >
- <widget class="QLabel" name="label_2" >
- <property name="text" >
- <string>Where to build the binaries:</string>
- </property>
- </widget>
- </item>
- <item row="1" column="1" >
- <widget class="QComboBox" name="BinaryDirectory" >
- <property name="editable" >
- <bool>true</bool>
- </property>
- </widget>
- </item>
- <item row="1" column="2" >
- <widget class="QPushButton" name="BrowseBinaryDirectoryButton" >
- <property name="text" >
- <string>Browse...</string>
- </property>
- </widget>
- </item>
- <item row="2" column="0" colspan="3" >
+ <property name="rightMargin" >
+ <number>0</number>
+ </property>
+ <property name="bottomMargin" >
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Where is the source code:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="SourceDirectory" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QPushButton" name="BrowseSourceDirectoryButton" >
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Where to build the binaries:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="BinaryDirectory" >
+ <property name="editable" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2" >
+ <widget class="QPushButton" name="BrowseBinaryDirectoryButton" >
+ <property name="text" >
+ <string>Browse...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QSplitter" name="splitter" >
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
<widget class="QCMakeCacheView" name="CacheValues" >
<property name="alternatingRowColors" >
<bool>true</bool>
@@ -85,61 +86,65 @@
<enum>QAbstractItemView::SelectRows</enum>
</property>
</widget>
- </item>
- <item row="3" column="0" colspan="3" >
- <layout class="QHBoxLayout" >
- <item>
- <widget class="QPushButton" name="configureButton" >
- <property name="text" >
- <string>Configure</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="generateButton" >
- <property name="text" >
- <string>Ok</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QPushButton" name="cancelButton" >
- <property name="text" >
- <string>Cancel</string>
- </property>
- </widget>
- </item>
- <item>
- <spacer>
- <property name="orientation" >
- <enum>Qt::Horizontal</enum>
- </property>
- <property name="sizeHint" >
- <size>
- <width>40</width>
- <height>20</height>
- </size>
- </property>
- </spacer>
- </item>
- </layout>
- </item>
- </layout>
- </widget>
- </item>
- </layout>
- </widget>
- <widget class="QMenuBar" name="menubar" >
- <property name="geometry" >
- <rect>
- <x>0</x>
- <y>0</y>
- <width>650</width>
- <height>29</height>
- </rect>
- </property>
- </widget>
- <widget class="QStatusBar" name="statusbar" />
+ <widget class="QTextEdit" name="Output" >
+ <property name="lineWrapMode" >
+ <enum>QTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout" >
+ <item>
+ <widget class="QPushButton" name="ConfigureButton" >
+ <property name="text" >
+ <string>Configure</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="GenerateButton" >
+ <property name="text" >
+ <string>Ok</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="CancelButton" >
+ <property name="text" >
+ <string>Cancel</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="HelpButton" >
+ <property name="text" >
+ <string>Help</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
</widget>
<customwidgets>
<customwidget>
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
index f75050c..a81d6af 100644
--- a/Source/QtDialog/QCMake.cxx
+++ b/Source/QtDialog/QCMake.cxx
@@ -118,9 +118,17 @@ void QCMake::setProperties(const QCMakeCachePropertyList& props)
{
if ( it.Find(prop.Key.toAscii().data()) )
{
- it.SetValue(prop.Value.toAscii().data());
+ if(prop.Value.type() == QVariant::Bool)
+ {
+ it.SetValue(prop.Value.toBool() ? "ON" : "OFF");
+ }
+ else
+ {
+ it.SetValue(prop.Value.toString().toAscii().data());
+ }
}
}
+ cachem->SaveCache(this->BinaryDirectory.toAscii().data());
}
QCMakeCachePropertyList QCMake::properties()
@@ -147,14 +155,7 @@ QCMakeCachePropertyList QCMake::properties()
if(i.GetType() == cmCacheManager::BOOL)
{
prop.Type = QCMakeCacheProperty::BOOL;
- if(cmSystemTools::IsOn(prop.Value.toAscii().data()))
- {
- prop.Value = QString("ON");
- }
- else
- {
- prop.Value = QString("OFF");
- }
+ prop.Value = cmSystemTools::IsOn(i.GetValue());
}
else if(i.GetType() == cmCacheManager::PATH)
{
@@ -183,7 +184,14 @@ void QCMake::interrupt()
void QCMake::progressCallback(const char* msg, float percent, void* cd)
{
QCMake* self = reinterpret_cast<QCMake*>(cd);
- emit self->progressChanged(msg, percent);
+ if(percent >= 0)
+ {
+ emit self->progressChanged(msg, percent);
+ }
+ else
+ {
+ emit self->outputMessage(msg);
+ }
QCoreApplication::processEvents();
}
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
index 15c13ec..38d94e6 100644
--- a/Source/QtDialog/QCMake.h
+++ b/Source/QtDialog/QCMake.h
@@ -20,17 +20,19 @@
#include <QObject>
#include <QString>
+#include <QVariant>
#include <QList>
#include <QMetaType>
class cmake;
-// struct to represent cache properties in Qt
+/// struct to represent cache properties in Qt
+/// Value is of type String or Bool
struct QCMakeCacheProperty
{
enum PropertyType { BOOL, PATH, FILEPATH, STRING };
QString Key;
- QString Value;
+ QVariant Value;
QString Help;
PropertyType Type;
bool Advanced;
@@ -41,9 +43,9 @@ Q_DECLARE_METATYPE(QCMakeCacheProperty)
typedef QList<QCMakeCacheProperty> QCMakeCachePropertyList;
Q_DECLARE_METATYPE(QCMakeCachePropertyList)
-// Qt API for CMake library.
-// Wrapper like class allows for easier integration with
-// Qt features such as, signal/slot connections, multi-threading, etc..
+/// Qt API for CMake library.
+/// Wrapper like class allows for easier integration with
+/// Qt features such as, signal/slot connections, multi-threading, etc..
class QCMake : public QObject
{
Q_OBJECT
@@ -52,31 +54,53 @@ public:
~QCMake();
public slots:
+ /// load the cache file in a directory
void loadCache(const QString& dir);
+ /// set the source directory containing the source
void setSourceDirectory(const QString& dir);
+ /// set the binary directory to build in
void setBinaryDirectory(const QString& dir);
+ /// set the desired generator to use
void setGenerator(const QString& generator);
+ /// do the configure step
void configure();
+ /// generate the files
void generate();
+ /// set the property values
void setProperties(const QCMakeCachePropertyList&);
+ /// interrupt the configure or generate process
void interrupt();
public:
+ /// get the list of cache properties
QCMakeCachePropertyList properties();
+ /// get the current binary directory
QString binaryDirectory();
+ /// get the current source directory
QString sourceDirectory();
+ /// get the current generator
QString generator();
+ /// get the available generators
+ QStringList availableGenerators();
signals:
+ /// signal when properties change (during read from disk or configure process)
void propertiesChanged(const QCMakeCachePropertyList& vars);
+ /// signal when the generator changes
void generatorChanged(const QString& gen);
+ /// signal when there is an error message
void error(const QString& title, const QString& message, bool*);
+ /// signal when the source directory changes (binary directory already
+ /// containing a CMakeCache.txt file)
void sourceDirChanged(const QString& dir);
+ /// signal for progress events
void progressChanged(const QString& msg, float percent);
+ /// signal when configure is done
void configureDone(int error);
+ /// signal when generate is done
void generateDone(int error);
- void configureReady();
- void generateReady();
+ /// signal when there is an output message
+ void outputMessage(const QString& msg);
protected:
cmake* CMakeInstance;
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
index a0040c7..9f25b82 100644
--- a/Source/QtDialog/QCMakeCacheView.cxx
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -24,7 +24,7 @@
#include <QEvent>
QCMakeCacheView::QCMakeCacheView(QWidget* p)
- : QTableView(p)
+ : QTableView(p), Init(false)
{
QCMakeCacheModel* m = new QCMakeCacheModel(this);
this->setModel(m);
@@ -35,16 +35,17 @@ QCMakeCacheView::QCMakeCacheView(QWidget* p)
this->setItemDelegate(delegate);
}
-bool QCMakeCacheView::event(QEvent* e)
+void QCMakeCacheView::showEvent(QShowEvent* e)
{
- if(e->type() == QEvent::Polish)
+ if(!this->Init)
{
// initialize the table view column size
int colWidth = this->columnWidth(0) + this->columnWidth(1);
this->setColumnWidth(0, colWidth/2);
this->setColumnWidth(1, colWidth/2);
+ this->Init = true;
}
- return QTableView::event(e);
+ return QTableView::showEvent(e);
}
QCMakeCacheModel* QCMakeCacheView::cacheModel() const
@@ -52,8 +53,42 @@ QCMakeCacheModel* QCMakeCacheView::cacheModel() const
return qobject_cast<QCMakeCacheModel*>(this->model());
}
+QModelIndex QCMakeCacheView::moveCursor(CursorAction act,
+ Qt::KeyboardModifiers mod)
+{
+ // tab through values only (not names)
+ QModelIndex current = this->currentIndex();
+ if(act == MoveNext)
+ {
+ if(!current.isValid())
+ {
+ return this->model()->index(0, 1);
+ }
+ else if(current.column() == 0)
+ {
+ return this->model()->index(current.row(), 1);
+ }
+ else
+ {
+ return this->model()->index(current.row()+1, 1);
+ }
+ }
+ else if(act == MovePrevious)
+ {
+ if(!current.isValid())
+ {
+ return this->model()->index(0, 1);
+ }
+ else
+ {
+ return this->model()->index(current.row()-1, 1);
+ }
+ }
+ return QTableView::moveCursor(act, mod);
+}
+
QCMakeCacheModel::QCMakeCacheModel(QObject* p)
- : QAbstractTableModel(p)
+ : QAbstractTableModel(p), IsDirty(false)
{
}
@@ -61,10 +96,16 @@ QCMakeCacheModel::~QCMakeCacheModel()
{
}
+bool QCMakeCacheModel::isDirty() const
+{
+ return this->IsDirty;
+}
+
void QCMakeCacheModel::setProperties(const QCMakeCachePropertyList& props)
{
this->Properties = props;
this->reset();
+ this->IsDirty = false;
}
QCMakeCachePropertyList QCMakeCacheModel::properties() const
@@ -80,25 +121,40 @@ int QCMakeCacheModel::columnCount ( const QModelIndex & parent ) const
QVariant QCMakeCacheModel::data ( const QModelIndex & index, int role ) const
{
if(index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
- {
+ {
return this->Properties[index.row()].Key;
- }
+ }
+ else if(index.column() == 0 && role == Qt::ToolTipRole)
+ {
+ return this->data(index, Qt::DisplayRole).toString() + "\n" +
+ this->data(index, QCMakeCacheModel::HelpRole).toString();
+ }
else if(index.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
- {
- return this->Properties[index.row()].Value;
- }
+ {
+ if(this->Properties[index.row()].Type != QCMakeCacheProperty::BOOL)
+ {
+ return this->Properties[index.row()].Value;
+ }
+ }
+ else if(index.column() == 1 && role == Qt::CheckStateRole)
+ {
+ if(this->Properties[index.row()].Type == QCMakeCacheProperty::BOOL)
+ {
+ return this->Properties[index.row()].Value.toBool() ? Qt::Checked : Qt::Unchecked;
+ }
+ }
else if(role == QCMakeCacheModel::HelpRole)
- {
+ {
return this->Properties[index.row()].Help;
- }
+ }
else if(role == QCMakeCacheModel::TypeRole)
- {
+ {
return this->Properties[index.row()].Type;
- }
+ }
else if(role == QCMakeCacheModel::AdvancedRole)
- {
+ {
return this->Properties[index.row()].Advanced;
- }
+ }
return QVariant();
}
@@ -110,39 +166,59 @@ QModelIndex QCMakeCacheModel::parent ( const QModelIndex & index ) const
int QCMakeCacheModel::rowCount ( const QModelIndex & parent ) const
{
if(parent.isValid())
+ {
return 0;
+ }
return this->Properties.count();
}
QVariant QCMakeCacheModel::headerData ( int section, Qt::Orientation orient, int role ) const
{
+ // return header labels
if(role == Qt::DisplayRole && orient == Qt::Horizontal)
- {
+ {
return section == 0 ? "Name" : "Value";
- }
+ }
return QVariant();
}
Qt::ItemFlags QCMakeCacheModel::flags ( const QModelIndex& index ) const
{
+ Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
+ // all column 1's are editable
if(index.column() == 1)
- {
- return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
- }
- return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
+ {
+ f |= Qt::ItemIsEditable;
+ // booleans are editable in place
+ if(this->Properties[index.row()].Type == QCMakeCacheProperty::BOOL)
+ {
+ f |= Qt::ItemIsUserCheckable;
+ }
+ }
+ return f;
}
bool QCMakeCacheModel::setData ( const QModelIndex & index, const QVariant& value, int role )
{
if(index.column() == 0 && (role == Qt::DisplayRole || role == Qt::EditRole))
- {
+ {
this->Properties[index.row()].Key = value.toString();
- }
+ this->IsDirty = true;
+ emit this->dataChanged(index, index);
+ }
else if(index.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
- {
+ {
this->Properties[index.row()].Value = value.toString();
- }
+ this->IsDirty = true;
+ emit this->dataChanged(index, index);
+ }
+ else if(index.column() == 1 && (role == Qt::CheckStateRole))
+ {
+ this->Properties[index.row()].Value = value.toInt() == Qt::Checked;
+ this->IsDirty = true;
+ emit this->dataChanged(index, index);
+ }
return false;
}
@@ -158,23 +234,24 @@ QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* parent,
{
QVariant type = index.data(QCMakeCacheModel::TypeRole);
if(type == QCMakeCacheProperty::BOOL)
- {
- return new QCMakeCacheBoolEditor(index.data().toString(), parent);
- }
+ {
+ return NULL;
+ }
else if(type == QCMakeCacheProperty::PATH)
- {
- return new QCMakeCachePathEditor(index.data().toString(), parent);
- }
+ {
+ return new QCMakeCachePathEditor(index.data().toString(), false, parent);
+ }
else if(type == QCMakeCacheProperty::FILEPATH)
- {
- }
+ {
+ return new QCMakeCachePathEditor(index.data().toString(), true, parent);
+ }
return new QLineEdit(parent);
}
-QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, QWidget* p)
- : QWidget(p), LineEdit(this)
+QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, bool fp, QWidget* p)
+ : QWidget(p), LineEdit(this), IsFilePath(fp)
{
QHBoxLayout* l = new QHBoxLayout(this);
l->setMargin(0);
@@ -192,17 +269,19 @@ QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, QWidget* p)
void QCMakeCachePathEditor::chooseFile()
{
- QString path = QFileDialog::getExistingDirectory(this, "TODO", this->value());
+ QString path;
+ if(this->IsFilePath)
+ {
+ path = QFileDialog::getOpenFileName(this, "TODO");
+ }
+ else
+ {
+ path = QFileDialog::getExistingDirectory(this, "TODO", this->value());
+ }
if(!path.isEmpty())
- {
+ {
this->LineEdit.setText(path);
- }
-}
-
-QString QCMakeCachePathEditor::value() const
-{
- return this->LineEdit.text();
+ }
}
-
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
index da71de1..692f451 100644
--- a/Source/QtDialog/QCMakeCacheView.h
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -20,7 +20,7 @@
#include <QTableView>
#include <QAbstractTableModel>
-#include <QComboBox>
+#include <QCheckBox>
#include <QLineEdit>
#include <QItemDelegate>
@@ -38,7 +38,9 @@ public:
QCMakeCacheModel* cacheModel() const;
protected:
- bool event(QEvent*);
+ QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
+ void showEvent(QShowEvent* e);
+ bool Init;
};
/// Qt model class for cache properties
@@ -55,6 +57,7 @@ public slots:
void setProperties(const QCMakeCachePropertyList& props);
public:
+ // satisfy [pure] virtuals
int columnCount ( const QModelIndex & parent ) const;
QVariant data ( const QModelIndex & index, int role ) const;
QModelIndex parent ( const QModelIndex & index ) const;
@@ -63,10 +66,14 @@ public:
Qt::ItemFlags flags ( const QModelIndex& index ) const;
bool setData ( const QModelIndex& index, const QVariant& value, int role );
+ // flag if a cache property has been modified
+ bool isDirty() const;
+ // get the properties
QCMakeCachePropertyList properties() const;
protected:
QCMakeCachePropertyList Properties;
+ bool IsDirty;
};
/// Qt delegate class for interaction (or other customization) with cache properties
@@ -75,41 +82,23 @@ 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;
};
-/// Editor widget for editing paths
+/// Editor widget for editing paths or file paths
class QCMakeCachePathEditor : public QWidget
{
Q_OBJECT
Q_PROPERTY(QString value READ value USER true)
public:
- QCMakeCachePathEditor(const QString& file, QWidget* p);
- QString value() const;
+ QCMakeCachePathEditor(const QString& file, bool isFilePath, QWidget* p);
+ QString value() const { return this->LineEdit->text(); }
protected slots:
void chooseFile();
protected:
QLineEdit LineEdit;
-};
-
-/// Editor widget for editing file paths
-class QCMakeCacheFilePathEditor : public QWidget
-{
-};
-
-/// Editor widget for editing booleans
-class QCMakeCacheBoolEditor : public QComboBox
-{
- Q_OBJECT
- Q_PROPERTY(QString value READ currentText USER true)
-public:
- QCMakeCacheBoolEditor(const QString& val, QWidget* p)
- : QComboBox(p)
- {
- this->addItem("ON");
- this->addItem("OFF");
- this->setCurrentIndex(val == "ON" ? 0 : 1);
- }
+ bool IsFilePath;
};
#endif