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.
This commit is contained in:
parent
c139a096c7
commit
77ad85a6ab
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 358 B After Width: | Height: | Size: 358 B |
|
@ -1,5 +1,5 @@
|
|||
<RCC>
|
||||
<qresource prefix="/Icons" >
|
||||
<file>CMakeSetupDialog.png</file>
|
||||
<file>CMakeSetup.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
IDI_ICON1 ICON DISCARDABLE "CMakeSetup.ico"
|
|
@ -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);
|
||||
|
@ -183,18 +265,16 @@ 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));
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::error(const QString& title, const QString& message, bool* cancel)
|
||||
{
|
||||
|
@ -206,4 +286,17 @@ void CMakeSetupDialog::error(const QString& title, const QString& message, bool*
|
|||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,21 +1,14 @@
|
|||
<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" >
|
||||
|
@ -25,7 +18,7 @@
|
|||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<layout class="QVBoxLayout" >
|
||||
<property name="leftMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
|
@ -38,6 +31,8 @@
|
|||
<property name="bottomMargin" >
|
||||
<number>0</number>
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" >
|
||||
<item row="0" column="0" >
|
||||
<widget class="QLabel" name="label" >
|
||||
<property name="text" >
|
||||
|
@ -76,7 +71,13 @@
|
|||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" colspan="3" >
|
||||
</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,30 +86,46 @@
|
|||
<enum>QAbstractItemView::SelectRows</enum>
|
||||
</property>
|
||||
</widget>
|
||||
<widget class="QTextEdit" name="Output" >
|
||||
<property name="lineWrapMode" >
|
||||
<enum>QTextEdit::NoWrap</enum>
|
||||
</property>
|
||||
<property name="readOnly" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" colspan="3" >
|
||||
<item>
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QPushButton" name="configureButton" >
|
||||
<widget class="QPushButton" name="ConfigureButton" >
|
||||
<property name="text" >
|
||||
<string>Configure</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="generateButton" >
|
||||
<widget class="QPushButton" name="GenerateButton" >
|
||||
<property name="text" >
|
||||
<string>Ok</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="cancelButton" >
|
||||
<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" >
|
||||
|
@ -129,18 +146,6 @@
|
|||
</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>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QCMakeCacheView</class>
|
||||
|
|
|
@ -118,10 +118,18 @@ 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);
|
||||
if(percent >= 0)
|
||||
{
|
||||
emit self->progressChanged(msg, percent);
|
||||
}
|
||||
else
|
||||
{
|
||||
emit self->outputMessage(msg);
|
||||
}
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
@ -83,10 +124,25 @@ QVariant QCMakeCacheModel::data ( const QModelIndex & index, int role ) const
|
|||
{
|
||||
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))
|
||||
{
|
||||
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;
|
||||
|
@ -110,12 +166,15 @@ 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";
|
||||
|
@ -125,11 +184,18 @@ QVariant QCMakeCacheModel::headerData ( int section, Qt::Orientation orient, int
|
|||
|
||||
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;
|
||||
f |= Qt::ItemIsEditable;
|
||||
// booleans are editable in place
|
||||
if(this->Properties[index.row()].Type == QCMakeCacheProperty::BOOL)
|
||||
{
|
||||
f |= Qt::ItemIsUserCheckable;
|
||||
}
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
|
@ -138,10 +204,20 @@ bool QCMakeCacheModel::setData ( const QModelIndex & index, const QVariant& valu
|
|||
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;
|
||||
}
|
||||
|
@ -159,22 +235,23 @@ 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();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue