[cmake-commits] clinton committed CMakeLists.txt NONE 1.1 CMakeSetup.cxx NONE 1.1 CMakeSetup.qrc NONE 1.1 CMakeSetupDialog.cxx NONE 1.1 CMakeSetupDialog.h NONE 1.1 CMakeSetupDialog.png NONE 1.1 CMakeSetupDialog.ui NONE 1.1 QCMake.cxx NONE 1.1 QCMake.h NONE 1.1 QCMakeCacheView.cxx NONE 1.1 QCMakeCacheView.h NONE 1.1

cmake-commits at cmake.org cmake-commits at cmake.org
Fri Nov 2 11:50:19 EDT 2007


Update of /cvsroot/CMake/CMake/Source/QtDialog
In directory public:/mounts/ram/cvs-serv4608

Added Files:
	CMakeLists.txt CMakeSetup.cxx CMakeSetup.qrc 
	CMakeSetupDialog.cxx CMakeSetupDialog.h CMakeSetupDialog.png 
	CMakeSetupDialog.ui QCMake.cxx QCMake.h QCMakeCacheView.cxx 
	QCMakeCacheView.h 
Log Message:
ENH:  Beginnings of a Qt UI for CMake.


--- NEW FILE: QCMakeCacheView.cxx ---

#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();
}




--- NEW FILE: CMakeSetupDialog.ui ---
<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>

--- NEW FILE: QCMakeCacheView.h ---

#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


--- NEW FILE: CMakeSetupDialog.png ---
(This appears to be a binary file; contents omitted.)

--- NEW FILE: CMakeSetup.qrc ---
<RCC>
    <qresource prefix="/Icons" >
        <file>CMakeSetupDialog.png</file>
    </qresource>
</RCC>

--- NEW FILE: CMakeSetupDialog.cxx ---

#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;
  }
}



--- NEW FILE: CMakeSetupDialog.h ---

#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;

};


--- NEW FILE: CMakeLists.txt ---

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)


--- NEW FILE: CMakeSetup.cxx ---

#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();
}


--- NEW FILE: QCMake.h ---

#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


--- NEW FILE: QCMake.cxx ---

#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);
}




More information about the Cmake-commits mailing list