ENH: Beginnings of a Qt UI for CMake.
This commit is contained in:
parent
dcf21dd90b
commit
800cbd0550
|
@ -0,0 +1,37 @@
|
|||
|
||||
SET(QT_MIN_VERSION "4.3.0")
|
||||
FIND_PACKAGE(Qt4 REQUIRED)
|
||||
|
||||
IF(NOT QT4_FOUND)
|
||||
MESSAGE(SEND_ERROR "Failed to find Qt4.")
|
||||
ELSE(NOT QT4_FOUND)
|
||||
INCLUDE(${QT_USE_FILE})
|
||||
|
||||
SET(SRCS
|
||||
CMakeSetup.cxx
|
||||
CMakeSetupDialog.cxx
|
||||
QCMake.cxx
|
||||
QCMakeCacheView.cxx
|
||||
)
|
||||
|
||||
QT4_WRAP_UI(UI_SRCS
|
||||
CMakeSetupDialog.ui
|
||||
)
|
||||
QT4_WRAP_CPP(MOC_SRCS
|
||||
CMakeSetupDialog.h
|
||||
QCMake.h
|
||||
QCMakeCacheView.h
|
||||
)
|
||||
QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
|
||||
|
||||
SET(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
|
||||
|
||||
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)
|
||||
|
||||
ENDIF(NOT QT4_FOUND)
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
#include <QApplication>
|
||||
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
#include "CMakeSetupDialog.h"
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
QApplication app(argc, argv);
|
||||
app.setApplicationName("CMakeSetup");
|
||||
app.setOrganizationName("Kitware");
|
||||
|
||||
// TODO handle CMake args
|
||||
|
||||
CMakeSetupDialog dialog;
|
||||
dialog.show();
|
||||
|
||||
return app.exec();
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
<RCC>
|
||||
<qresource prefix="/Icons" >
|
||||
<file>CMakeSetupDialog.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
|
@ -0,0 +1,193 @@
|
|||
|
||||
#include "CMakeSetupDialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QThread>
|
||||
#include <QProgressBar>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include "QCMake.h"
|
||||
#include "QCMakeCacheView.h"
|
||||
|
||||
// QCMake instance on a thread
|
||||
class QCMakeThread : public QThread
|
||||
{
|
||||
public:
|
||||
QCMakeThread(QObject* p) : QThread(p) { }
|
||||
QCMake* CMakeInstance;
|
||||
|
||||
protected:
|
||||
virtual void run()
|
||||
{
|
||||
this->CMakeInstance = new QCMake;
|
||||
this->exec();
|
||||
delete this->CMakeInstance;
|
||||
}
|
||||
};
|
||||
|
||||
CMakeSetupDialog::CMakeSetupDialog()
|
||||
{
|
||||
// create the GUI
|
||||
this->setupUi(this);
|
||||
this->ProgressBar = new QProgressBar();
|
||||
this->ProgressBar->setRange(0,100);
|
||||
this->statusBar()->addPermanentWidget(this->ProgressBar);
|
||||
|
||||
// start the cmake worker thread
|
||||
this->CMakeThread = new QCMakeThread(this);
|
||||
// TODO does this guarantee the QCMake instance is created before initialize is called?
|
||||
QObject::connect(this->CMakeThread, SIGNAL(started()),
|
||||
this, SLOT(initialize()));
|
||||
this->CMakeThread->start();
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::initialize()
|
||||
{
|
||||
// now the cmake worker thread is running, lets make our connections to it
|
||||
QObject::connect(this->CMakeThread->CMakeInstance,
|
||||
SIGNAL(propertiesChanged(const QCMakeCachePropertyList&)),
|
||||
this->CacheValues->cacheModel(),
|
||||
SLOT(setProperties(const QCMakeCachePropertyList&)));
|
||||
QObject::connect(this,
|
||||
SIGNAL(propertiesChanged(const QCMakeCachePropertyList&)),
|
||||
this->CMakeThread->CMakeInstance,
|
||||
SLOT(setProperties(const QCMakeCachePropertyList&)));
|
||||
|
||||
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)),
|
||||
this, SLOT(doOk()));
|
||||
QObject::connect(this, SIGNAL(ok()),
|
||||
this->CMakeThread->CMakeInstance, SLOT(generate()));
|
||||
|
||||
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)),
|
||||
this->CMakeThread->CMakeInstance, SLOT(setBinaryDirectory(QString)));
|
||||
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(sourceDirChanged(QString)),
|
||||
this, SLOT(updateSourceDirectory(QString)));
|
||||
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(progressChanged(QString, float)),
|
||||
this, SLOT(showProgress(QString,float)));
|
||||
|
||||
QObject::connect(this->CMakeThread->CMakeInstance, SIGNAL(error(QString, QString, bool*)),
|
||||
this, SLOT(error(QString,QString,bool*)), Qt::BlockingQueuedConnection);
|
||||
|
||||
}
|
||||
|
||||
CMakeSetupDialog::~CMakeSetupDialog()
|
||||
{
|
||||
// wait for thread to stop
|
||||
this->CMakeThread->quit();
|
||||
this->CMakeThread->wait();
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::doConfigure()
|
||||
{
|
||||
emit this->propertiesChanged(this->CacheValues->cacheModel()->properties());
|
||||
emit this->configure();
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::finishConfigure(int error)
|
||||
{
|
||||
this->ProgressBar->reset();
|
||||
this->statusBar()->showMessage("Configure Done", 2000);
|
||||
if(error != 0)
|
||||
{
|
||||
bool dummy;
|
||||
this->error("Error", "Error in configuration process, project files may be invalid", &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::finishGenerate(int error)
|
||||
{
|
||||
this->ProgressBar->reset();
|
||||
this->statusBar()->showMessage("Generate Done", 2000);
|
||||
if(error != 0)
|
||||
{
|
||||
bool dummy;
|
||||
this->error("Error", "Error in generation process, project files may be invalid", &dummy);
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::doOk()
|
||||
{
|
||||
emit this->ok();
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::doCancel()
|
||||
{
|
||||
emit this->cancel();
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::doHelp()
|
||||
{
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::doSourceBrowse()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this, "TODO", this->SourceDirectory->text());
|
||||
if(!dir.isEmpty())
|
||||
{
|
||||
this->updateSourceDirectory(dir);
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::updateSourceDirectory(const QString& dir)
|
||||
{
|
||||
this->SourceDirectory->setText(dir);
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::doBinaryBrowse()
|
||||
{
|
||||
QString dir = QFileDialog::getExistingDirectory(this, "TODO", this->BinaryDirectory->currentText());
|
||||
if(!dir.isEmpty())
|
||||
{
|
||||
this->setBinaryDirectory(dir);
|
||||
}
|
||||
}
|
||||
|
||||
void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
|
||||
{
|
||||
if(dir != this->BinaryDirectory->currentText())
|
||||
{
|
||||
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)
|
||||
{
|
||||
QMessageBox::StandardButton btn =
|
||||
QMessageBox::critical(this, title, message, QMessageBox::Ok | QMessageBox::Cancel);
|
||||
if(btn == QMessageBox::Cancel)
|
||||
{
|
||||
*cancel = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
#include <QMainWindow>
|
||||
#include "ui_CMakeSetupDialog.h"
|
||||
#include "QCMake.h"
|
||||
|
||||
class QCMakeThread;
|
||||
class CMakeCacheModel;
|
||||
class QProgressBar;
|
||||
|
||||
/// Qt user interface for CMake
|
||||
class CMakeSetupDialog : public QMainWindow, public Ui::CMakeSetupDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
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 finishConfigure(int error);
|
||||
void finishGenerate(int error);
|
||||
void error(const QString& title, const QString& message, bool* cancel);
|
||||
|
||||
void doSourceBrowse();
|
||||
void doBinaryBrowse();
|
||||
void updateSourceDirectory(const QString& dir);
|
||||
void setBinaryDirectory(const QString& dir);
|
||||
|
||||
void showProgress(const QString& msg, float percent);
|
||||
|
||||
protected:
|
||||
|
||||
QCMakeThread* CMakeThread;
|
||||
QProgressBar* ProgressBar;
|
||||
|
||||
};
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 358 B |
|
@ -0,0 +1,155 @@
|
|||
<ui version="4.0" >
|
||||
<class>CMakeSetupDialog</class>
|
||||
<widget class="QMainWindow" name="CMakeSetupDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>650</width>
|
||||
<height>505</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>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Raised</enum>
|
||||
</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" >
|
||||
<widget class="QCMakeCacheView" name="CacheValues" >
|
||||
<property name="alternatingRowColors" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="selectionBehavior" >
|
||||
<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>
|
||||
<customwidgets>
|
||||
<customwidget>
|
||||
<class>QCMakeCacheView</class>
|
||||
<extends>QTableView</extends>
|
||||
<header>QCMakeCacheView.h</header>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<resources>
|
||||
<include location="CMakeSetup.qrc" />
|
||||
</resources>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -0,0 +1,179 @@
|
|||
|
||||
#include "QCMake.h"
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
|
||||
#include "cmake.h"
|
||||
#include "cmCacheManager.h"
|
||||
#include "cmSystemTools.h"
|
||||
|
||||
QCMake::QCMake(QObject* p)
|
||||
: QObject(p)
|
||||
{
|
||||
static int metaId = qRegisterMetaType<QCMakeCacheProperty>();
|
||||
static int metaIdList = qRegisterMetaType<QCMakeCachePropertyList>();
|
||||
|
||||
QDir appDir(QCoreApplication::applicationDirPath());
|
||||
#if defined(Q_OS_WIN)
|
||||
this->CMakeExecutable = appDir.filePath("cmake.exe");
|
||||
#elif defined(Q_OS_MAC)
|
||||
# error "need to implement for Mac OS X"
|
||||
#else
|
||||
this->CMakeExecutable = appDir.filePath("cmake");
|
||||
#endif
|
||||
// TODO: check for existence?
|
||||
|
||||
cmSystemTools::DisableRunCommandOutput();
|
||||
cmSystemTools::SetRunCommandHideConsole(true);
|
||||
cmSystemTools::SetErrorCallback(QCMake::errorCallback, this);
|
||||
|
||||
this->CMakeInstance = new cmake;
|
||||
this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
|
||||
}
|
||||
|
||||
QCMake::~QCMake()
|
||||
{
|
||||
delete this->CMakeInstance;
|
||||
//cmDynamicLoader::FlushCache();
|
||||
}
|
||||
|
||||
void QCMake::loadCache(const QString& dir)
|
||||
{
|
||||
this->setBinaryDirectory(dir);
|
||||
}
|
||||
|
||||
void QCMake::setSourceDirectory(const QString& dir)
|
||||
{
|
||||
this->SourceDirectory = dir;
|
||||
emit this->sourceDirChanged(dir);
|
||||
}
|
||||
|
||||
void QCMake::setBinaryDirectory(const QString& dir)
|
||||
{
|
||||
cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
|
||||
this->BinaryDirectory = dir;
|
||||
this->CMakeInstance->GetCacheManager()->LoadCache(dir.toLocal8Bit().data());
|
||||
QCMakeCachePropertyList props = this->properties();
|
||||
emit this->propertiesChanged(props);
|
||||
cmCacheManager::CacheIterator itm = cachem->NewIterator();
|
||||
if ( itm.Find("CMAKE_HOME_DIRECTORY"))
|
||||
{
|
||||
setSourceDirectory(itm.GetValue());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void QCMake::setGenerator(const QString& generator)
|
||||
{
|
||||
}
|
||||
|
||||
void QCMake::configure()
|
||||
{
|
||||
this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toAscii().data());
|
||||
this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toAscii().data());
|
||||
this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toAscii().data());
|
||||
this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toAscii().data());
|
||||
this->CMakeInstance->SetGlobalGenerator(
|
||||
this->CMakeInstance->CreateGlobalGenerator("Unix Makefiles")); // TODO
|
||||
this->CMakeInstance->SetCMakeCommand(this->CMakeExecutable.toAscii().data());
|
||||
this->CMakeInstance->LoadCache();
|
||||
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
|
||||
int error = this->CMakeInstance->Configure();
|
||||
|
||||
emit this->propertiesChanged(this->properties());
|
||||
emit this->configureDone(error);
|
||||
}
|
||||
|
||||
void QCMake::generate()
|
||||
{
|
||||
cmSystemTools::ResetErrorOccuredFlag();
|
||||
int error = this->CMakeInstance->Generate();
|
||||
emit this->generateDone(error);
|
||||
}
|
||||
|
||||
void QCMake::setProperties(const QCMakeCachePropertyList& props)
|
||||
{
|
||||
cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
|
||||
cmCacheManager::CacheIterator it = cachem->NewIterator();
|
||||
foreach(QCMakeCacheProperty prop, props)
|
||||
{
|
||||
if ( it.Find(prop.Key.toAscii().data()) )
|
||||
{
|
||||
it.SetValue(prop.Value.toAscii().data());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QCMakeCachePropertyList QCMake::properties()
|
||||
{
|
||||
QCMakeCachePropertyList ret;
|
||||
|
||||
cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
|
||||
for(cmCacheManager::CacheIterator i = cachem->NewIterator();
|
||||
!i.IsAtEnd(); i.Next())
|
||||
{
|
||||
|
||||
if(i.GetType() == cmCacheManager::INTERNAL ||
|
||||
i.GetType() == cmCacheManager::STATIC)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
QCMakeCacheProperty prop;
|
||||
prop.Key = i.GetName();
|
||||
prop.Help = i.GetProperty("HELPSTRING");
|
||||
prop.Value = i.GetValue();
|
||||
prop.Advanced = i.GetPropertyAsBool("ADVANCED");
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
else if(i.GetType() == cmCacheManager::PATH)
|
||||
{
|
||||
prop.Type = QCMakeCacheProperty::PATH;
|
||||
}
|
||||
else if(i.GetType() == cmCacheManager::FILEPATH)
|
||||
{
|
||||
prop.Type = QCMakeCacheProperty::FILEPATH;
|
||||
}
|
||||
else if(i.GetType() == cmCacheManager::STRING)
|
||||
{
|
||||
prop.Type = QCMakeCacheProperty::STRING;
|
||||
}
|
||||
|
||||
ret.append(prop);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void QCMake::interrupt()
|
||||
{
|
||||
cmSystemTools::SetFatalErrorOccured();
|
||||
}
|
||||
|
||||
void QCMake::progressCallback(const char* msg, float percent, void* cd)
|
||||
{
|
||||
QCMake* self = reinterpret_cast<QCMake*>(cd);
|
||||
emit self->progressChanged(msg, percent);
|
||||
QCoreApplication::processEvents();
|
||||
}
|
||||
|
||||
void QCMake::errorCallback(const char* msg, const char* title, bool& stop, void* cd)
|
||||
{
|
||||
QCMake* self = reinterpret_cast<QCMake*>(cd);
|
||||
emit self->error(title, msg, &stop);
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
|
||||
#ifndef __QCMake_h
|
||||
#define __QCMake_h
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QList>
|
||||
#include <QMetaType>
|
||||
|
||||
class cmake;
|
||||
|
||||
// struct to represent cache properties in Qt
|
||||
struct QCMakeCacheProperty
|
||||
{
|
||||
enum PropertyType { BOOL, PATH, FILEPATH, STRING };
|
||||
QString Key;
|
||||
QString Value;
|
||||
QString Help;
|
||||
PropertyType Type;
|
||||
bool Advanced;
|
||||
};
|
||||
|
||||
// make types usable with QVariant
|
||||
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..
|
||||
class QCMake : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMake(QObject* p=0);
|
||||
~QCMake();
|
||||
|
||||
public slots:
|
||||
void loadCache(const QString& dir);
|
||||
void setSourceDirectory(const QString& dir);
|
||||
void setBinaryDirectory(const QString& dir);
|
||||
void setGenerator(const QString& generator);
|
||||
void configure();
|
||||
void generate();
|
||||
void setProperties(const QCMakeCachePropertyList&);
|
||||
void interrupt();
|
||||
|
||||
public:
|
||||
QCMakeCachePropertyList properties();
|
||||
QString binaryDirectory();
|
||||
QString sourceDirectory();
|
||||
QString generator();
|
||||
|
||||
signals:
|
||||
void propertiesChanged(const QCMakeCachePropertyList& vars);
|
||||
void generatorChanged(const QString& gen);
|
||||
void error(const QString& title, const QString& message, bool*);
|
||||
void sourceDirChanged(const QString& dir);
|
||||
void progressChanged(const QString& msg, float percent);
|
||||
void configureDone(int error);
|
||||
void generateDone(int error);
|
||||
void configureReady();
|
||||
void generateReady();
|
||||
|
||||
protected:
|
||||
cmake* CMakeInstance;
|
||||
|
||||
static void progressCallback(const char* msg, float percent, void* cd);
|
||||
static void errorCallback(const char* msg, const char* title, bool&, void* cd);
|
||||
|
||||
QString SourceDirectory;
|
||||
QString BinaryDirectory;
|
||||
QString Generator;
|
||||
QString CMakeExecutable;
|
||||
};
|
||||
|
||||
#endif // __QCMake_h
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
|
||||
#include "QCMakeCacheView.h"
|
||||
|
||||
#include <QToolButton>
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QHeaderView>
|
||||
#include <QEvent>
|
||||
|
||||
QCMakeCacheView::QCMakeCacheView(QWidget* p)
|
||||
: QTableView(p)
|
||||
{
|
||||
QCMakeCacheModel* m = new QCMakeCacheModel(this);
|
||||
this->setModel(m);
|
||||
this->horizontalHeader()->setStretchLastSection(true);
|
||||
this->verticalHeader()->hide();
|
||||
|
||||
QCMakeCacheModelDelegate* delegate = new QCMakeCacheModelDelegate(this);
|
||||
this->setItemDelegate(delegate);
|
||||
}
|
||||
|
||||
bool QCMakeCacheView::event(QEvent* e)
|
||||
{
|
||||
if(e->type() == QEvent::Polish)
|
||||
{
|
||||
// initialize the table view column size
|
||||
int colWidth = this->columnWidth(0) + this->columnWidth(1);
|
||||
this->setColumnWidth(0, colWidth/2);
|
||||
this->setColumnWidth(1, colWidth/2);
|
||||
}
|
||||
return QTableView::event(e);
|
||||
}
|
||||
|
||||
QCMakeCacheModel* QCMakeCacheView::cacheModel() const
|
||||
{
|
||||
return qobject_cast<QCMakeCacheModel*>(this->model());
|
||||
}
|
||||
|
||||
QCMakeCacheModel::QCMakeCacheModel(QObject* p)
|
||||
: QAbstractTableModel(p)
|
||||
{
|
||||
}
|
||||
|
||||
QCMakeCacheModel::~QCMakeCacheModel()
|
||||
{
|
||||
}
|
||||
|
||||
void QCMakeCacheModel::setProperties(const QCMakeCachePropertyList& props)
|
||||
{
|
||||
this->Properties = props;
|
||||
this->reset();
|
||||
}
|
||||
|
||||
QCMakeCachePropertyList QCMakeCacheModel::properties() const
|
||||
{
|
||||
return this->Properties;
|
||||
}
|
||||
|
||||
int QCMakeCacheModel::columnCount ( const QModelIndex & parent ) const
|
||||
{
|
||||
return 2;
|
||||
}
|
||||
|
||||
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() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
{
|
||||
return this->Properties[index.row()].Value;
|
||||
}
|
||||
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();
|
||||
}
|
||||
|
||||
QModelIndex QCMakeCacheModel::parent ( const QModelIndex & index ) const
|
||||
{
|
||||
return QModelIndex();
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
if(role == Qt::DisplayRole && orient == Qt::Horizontal)
|
||||
{
|
||||
return section == 0 ? "Name" : "Value";
|
||||
}
|
||||
return QVariant();
|
||||
}
|
||||
|
||||
Qt::ItemFlags QCMakeCacheModel::flags ( const QModelIndex& index ) const
|
||||
{
|
||||
if(index.column() == 1)
|
||||
{
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled;
|
||||
}
|
||||
return Qt::ItemIsSelectable | Qt::ItemIsEnabled;
|
||||
}
|
||||
|
||||
|
||||
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();
|
||||
}
|
||||
else if(index.column() == 1 && (role == Qt::DisplayRole || role == Qt::EditRole))
|
||||
{
|
||||
this->Properties[index.row()].Value = value.toString();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p)
|
||||
: QItemDelegate(p)
|
||||
{
|
||||
}
|
||||
|
||||
QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* parent,
|
||||
const QStyleOptionViewItem&, const QModelIndex& index) const
|
||||
{
|
||||
QVariant type = index.data(QCMakeCacheModel::TypeRole);
|
||||
if(type == QCMakeCacheProperty::BOOL)
|
||||
{
|
||||
return new QCMakeCacheBoolEditor(index.data().toString(), parent);
|
||||
}
|
||||
else if(type == QCMakeCacheProperty::PATH)
|
||||
{
|
||||
return new QCMakeCachePathEditor(index.data().toString(), parent);
|
||||
}
|
||||
else if(type == QCMakeCacheProperty::FILEPATH)
|
||||
{
|
||||
}
|
||||
|
||||
return new QLineEdit(parent);
|
||||
}
|
||||
|
||||
|
||||
QCMakeCachePathEditor::QCMakeCachePathEditor(const QString& file, QWidget* p)
|
||||
: QWidget(p), LineEdit(this)
|
||||
{
|
||||
QHBoxLayout* l = new QHBoxLayout(this);
|
||||
l->setMargin(0);
|
||||
l->setSpacing(0);
|
||||
l->addWidget(&this->LineEdit);
|
||||
QToolButton* tb = new QToolButton(this);
|
||||
tb->setText("...");
|
||||
l->addWidget(tb);
|
||||
QObject::connect(tb, SIGNAL(clicked(bool)),
|
||||
this, SLOT(chooseFile()));
|
||||
this->LineEdit.setText(file);
|
||||
tb->setFocusProxy(&this->LineEdit);
|
||||
this->setFocusProxy(&this->LineEdit);
|
||||
}
|
||||
|
||||
void QCMakeCachePathEditor::chooseFile()
|
||||
{
|
||||
QString path = QFileDialog::getExistingDirectory(this, "TODO", this->value());
|
||||
if(!path.isEmpty())
|
||||
{
|
||||
this->LineEdit.setText(path);
|
||||
}
|
||||
}
|
||||
|
||||
QString QCMakeCachePathEditor::value() const
|
||||
{
|
||||
return this->LineEdit.text();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
|
||||
#ifndef QCMakeCacheView_h
|
||||
#define QCMakeCacheView_h
|
||||
|
||||
#include <QTableView>
|
||||
#include <QAbstractTableModel>
|
||||
#include <QComboBox>
|
||||
#include <QLineEdit>
|
||||
#include <QItemDelegate>
|
||||
|
||||
#include "QCMake.h"
|
||||
class QCMakeCacheModel;
|
||||
|
||||
|
||||
/// Qt view class for cache properties
|
||||
class QCMakeCacheView : public QTableView
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMakeCacheView(QWidget* p);
|
||||
|
||||
QCMakeCacheModel* cacheModel() const;
|
||||
|
||||
protected:
|
||||
bool event(QEvent*);
|
||||
};
|
||||
|
||||
/// Qt model class for cache properties
|
||||
class QCMakeCacheModel : public QAbstractTableModel
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMakeCacheModel(QObject* parent);
|
||||
~QCMakeCacheModel();
|
||||
|
||||
enum { HelpRole = Qt::UserRole, TypeRole, AdvancedRole };
|
||||
|
||||
public slots:
|
||||
void setProperties(const QCMakeCachePropertyList& props);
|
||||
|
||||
public:
|
||||
int columnCount ( const QModelIndex & parent ) const;
|
||||
QVariant data ( const QModelIndex & index, int role ) const;
|
||||
QModelIndex parent ( const QModelIndex & index ) const;
|
||||
int rowCount ( const QModelIndex & parent ) const;
|
||||
QVariant headerData ( int section, Qt::Orientation orient, int role ) const;
|
||||
Qt::ItemFlags flags ( const QModelIndex& index ) const;
|
||||
bool setData ( const QModelIndex& index, const QVariant& value, int role );
|
||||
|
||||
QCMakeCachePropertyList properties() const;
|
||||
|
||||
protected:
|
||||
QCMakeCachePropertyList Properties;
|
||||
};
|
||||
|
||||
/// Qt delegate class for interaction (or other customization) with cache properties
|
||||
class QCMakeCacheModelDelegate : public QItemDelegate
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
QCMakeCacheModelDelegate(QObject* p);
|
||||
QWidget* createEditor(QWidget * parent, const QStyleOptionViewItem & option, const QModelIndex & index ) const;
|
||||
};
|
||||
|
||||
/// Editor widget for editing 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;
|
||||
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);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue