summaryrefslogtreecommitdiff
path: root/Source/QtDialog
diff options
context:
space:
mode:
Diffstat (limited to 'Source/QtDialog')
-rw-r--r--Source/QtDialog/AddCacheEntry.cxx83
-rw-r--r--Source/QtDialog/AddCacheEntry.h36
-rw-r--r--Source/QtDialog/AddCacheEntry.ui97
-rw-r--r--Source/QtDialog/CMake.desktop12
-rw-r--r--Source/QtDialog/CMakeLists.txt123
-rw-r--r--Source/QtDialog/CMakeSetup.cxx205
-rw-r--r--Source/QtDialog/CMakeSetup.icnsbin0 -> 138205 bytes
-rw-r--r--Source/QtDialog/CMakeSetup.icobin0 -> 24542 bytes
-rw-r--r--Source/QtDialog/CMakeSetup.qrc8
-rw-r--r--Source/QtDialog/CMakeSetup.rc1
-rw-r--r--Source/QtDialog/CMakeSetup128.pngbin0 -> 13269 bytes
-rw-r--r--Source/QtDialog/CMakeSetup32.pngbin0 -> 358 bytes
-rw-r--r--Source/QtDialog/CMakeSetupDialog.cxx1152
-rw-r--r--Source/QtDialog/CMakeSetupDialog.h132
-rw-r--r--Source/QtDialog/CMakeSetupDialog.ui310
-rw-r--r--Source/QtDialog/Compilers.h21
-rw-r--r--Source/QtDialog/Compilers.ui87
-rw-r--r--Source/QtDialog/CrossCompiler.ui213
-rw-r--r--Source/QtDialog/Delete16.pngbin0 -> 731 bytes
-rw-r--r--Source/QtDialog/FirstConfigure.cxx509
-rw-r--r--Source/QtDialog/FirstConfigure.h177
-rw-r--r--Source/QtDialog/MacInstallDialog.ui103
-rw-r--r--Source/QtDialog/Plus16.pngbin0 -> 358 bytes
-rw-r--r--Source/QtDialog/QCMake.cxx448
-rw-r--r--Source/QtDialog/QCMake.h154
-rw-r--r--Source/QtDialog/QCMakeCacheView.cxx735
-rw-r--r--Source/QtDialog/QCMakeCacheView.h172
-rw-r--r--Source/QtDialog/QCMakeWidgets.cxx134
-rw-r--r--Source/QtDialog/QCMakeWidgets.h87
-rw-r--r--Source/QtDialog/QMacInstallDialog.cxx121
-rw-r--r--Source/QtDialog/QMacInstallDialog.h20
-rw-r--r--Source/QtDialog/QtDialogCPack.cmake.in18
-rw-r--r--Source/QtDialog/cmakecache.xml8
-rwxr-xr-xSource/QtDialog/postflight.sh.in3
-rwxr-xr-xSource/QtDialog/postupgrade.sh.in2
35 files changed, 5171 insertions, 0 deletions
diff --git a/Source/QtDialog/AddCacheEntry.cxx b/Source/QtDialog/AddCacheEntry.cxx
new file mode 100644
index 000000000..e7fedc5c5
--- /dev/null
+++ b/Source/QtDialog/AddCacheEntry.cxx
@@ -0,0 +1,83 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "AddCacheEntry.h"
+#include <QMetaProperty>
+#include <QCompleter>
+
+static const int NumTypes = 4;
+static const QByteArray TypeStrings[NumTypes] =
+ { "BOOL", "PATH", "FILEPATH", "STRING" };
+static const QCMakeProperty::PropertyType Types[NumTypes] =
+ { QCMakeProperty::BOOL, QCMakeProperty::PATH,
+ QCMakeProperty::FILEPATH, QCMakeProperty::STRING};
+
+AddCacheEntry::AddCacheEntry(QWidget* p, const QStringList& completions)
+ : QWidget(p)
+{
+ this->setupUi(this);
+ for(int i=0; i<NumTypes; i++)
+ {
+ this->Type->addItem(TypeStrings[i]);
+ }
+ QWidget* cb = new QCheckBox();
+ QWidget* path = new QCMakePathEditor();
+ QWidget* filepath = new QCMakeFilePathEditor();
+ QWidget* string = new QLineEdit();
+ this->StackedWidget->addWidget(cb);
+ this->StackedWidget->addWidget(path);
+ this->StackedWidget->addWidget(filepath);
+ this->StackedWidget->addWidget(string);
+ this->setTabOrder(this->Name, this->Type);
+ this->setTabOrder(this->Type, cb);
+ this->setTabOrder(cb, path);
+ this->setTabOrder(path, filepath);
+ this->setTabOrder(filepath, string);
+ this->setTabOrder(string, this->Description);
+ this->Name->setCompleter(new QCompleter(completions, this));
+}
+
+QString AddCacheEntry::name() const
+{
+ return this->Name->text();
+}
+
+QVariant AddCacheEntry::value() const
+{
+ QWidget* w = this->StackedWidget->currentWidget();
+ if(qobject_cast<QLineEdit*>(w))
+ {
+ return static_cast<QLineEdit*>(w)->text();
+ }
+ else if(qobject_cast<QCheckBox*>(w))
+ {
+ return static_cast<QCheckBox*>(w)->isChecked();
+ }
+ return QVariant();
+}
+
+QString AddCacheEntry::description() const
+{
+ return this->Description->text();
+}
+
+QCMakeProperty::PropertyType AddCacheEntry::type() const
+{
+ int idx = this->Type->currentIndex();
+ if(idx >= 0 && idx < NumTypes)
+ {
+ return Types[idx];
+ }
+ return QCMakeProperty::BOOL;
+}
+
+
diff --git a/Source/QtDialog/AddCacheEntry.h b/Source/QtDialog/AddCacheEntry.h
new file mode 100644
index 000000000..e219d4ee7
--- /dev/null
+++ b/Source/QtDialog/AddCacheEntry.h
@@ -0,0 +1,36 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef AddCacheEntry_h
+#define AddCacheEntry_h
+
+#include <QWidget>
+#include <QCheckBox>
+#include <QStringList>
+
+#include "QCMake.h"
+#include "ui_AddCacheEntry.h"
+
+class AddCacheEntry : public QWidget, public Ui::AddCacheEntry
+{
+ Q_OBJECT
+public:
+ AddCacheEntry(QWidget* p, const QStringList& completions);
+
+ QString name() const;
+ QVariant value() const;
+ QString description() const;
+ QCMakeProperty::PropertyType type() const;
+};
+
+#endif
+
diff --git a/Source/QtDialog/AddCacheEntry.ui b/Source/QtDialog/AddCacheEntry.ui
new file mode 100644
index 000000000..a81587473
--- /dev/null
+++ b/Source/QtDialog/AddCacheEntry.ui
@@ -0,0 +1,97 @@
+<ui version="4.0" >
+ <class>AddCacheEntry</class>
+ <widget class="QWidget" name="AddCacheEntry" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>380</width>
+ <height>158</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Name:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="Name" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>Type:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="Type" >
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QLabel" name="label_5" >
+ <property name="text" >
+ <string>Value:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="2" column="1" >
+ <widget class="QStackedWidget" name="StackedWidget" >
+ <property name="currentIndex" >
+ <number>0</number>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="0" >
+ <widget class="QLabel" name="label_3" >
+ <property name="text" >
+ <string>Description:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="3" column="1" >
+ <widget class="QLineEdit" name="Description" />
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ <customwidget>
+ <class>QCMakeFilePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections>
+ <connection>
+ <sender>Type</sender>
+ <signal>currentIndexChanged(int)</signal>
+ <receiver>StackedWidget</receiver>
+ <slot>setCurrentIndex(int)</slot>
+ <hints>
+ <hint type="sourcelabel" >
+ <x>229</x>
+ <y>34</y>
+ </hint>
+ <hint type="destinationlabel" >
+ <x>287</x>
+ <y>65</y>
+ </hint>
+ </hints>
+ </connection>
+ </connections>
+</ui>
diff --git a/Source/QtDialog/CMake.desktop b/Source/QtDialog/CMake.desktop
new file mode 100644
index 000000000..645eb76e9
--- /dev/null
+++ b/Source/QtDialog/CMake.desktop
@@ -0,0 +1,12 @@
+[Desktop Entry]
+Version=1.0
+Name=CMake
+Comment=Cross-platform buildsystem
+Exec=cmake-gui %f
+Icon=CMakeSetup32.png
+Terminal=false
+X-MultipleArgs=false
+Type=Application
+Categories=Development;
+StartupNotify=true
+MimeType=application/x-cmakecache;
diff --git a/Source/QtDialog/CMakeLists.txt b/Source/QtDialog/CMakeLists.txt
new file mode 100644
index 000000000..07ec10674
--- /dev/null
+++ b/Source/QtDialog/CMakeLists.txt
@@ -0,0 +1,123 @@
+#=============================================================================
+# CMake - Cross Platform Makefile Generator
+# Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+#
+# Distributed under the OSI-approved BSD License (the "License");
+# see accompanying file Copyright.txt for details.
+#
+# This software is distributed WITHOUT ANY WARRANTY; without even the
+# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+# See the License for more information.
+#=============================================================================
+PROJECT(QtDialog)
+SET(QT_MIN_VERSION "4.4.0")
+FIND_PACKAGE(Qt4 REQUIRED)
+
+IF(NOT QT4_FOUND)
+ MESSAGE(SEND_ERROR "Failed to find Qt 4.4 or greater.")
+ELSE(NOT QT4_FOUND)
+
+ INCLUDE(${QT_USE_FILE})
+ SET(CMAKE_PACKAGE_QTGUI TRUE)
+ SET(SRCS
+ AddCacheEntry.cxx
+ AddCacheEntry.h
+ CMakeSetup.cxx
+ CMakeSetupDialog.cxx
+ CMakeSetupDialog.h
+ FirstConfigure.cxx
+ FirstConfigure.h
+ QCMake.cxx
+ QCMake.h
+ QCMakeCacheView.cxx
+ QCMakeCacheView.h
+ QCMakeWidgets.cxx
+ QCMakeWidgets.h
+ QMacInstallDialog.cxx
+ QMacInstallDialog.h
+ )
+ QT4_WRAP_UI(UI_SRCS
+ CMakeSetupDialog.ui
+ Compilers.ui
+ CrossCompiler.ui
+ AddCacheEntry.ui
+ MacInstallDialog.ui
+ )
+ QT4_WRAP_CPP(MOC_SRCS
+ AddCacheEntry.h
+ Compilers.h
+ CMakeSetupDialog.h
+ FirstConfigure.h
+ QCMake.h
+ QCMakeCacheView.h
+ QCMakeWidgets.h
+ QMacInstallDialog.h
+ )
+ QT4_ADD_RESOURCES(RC_SRCS CMakeSetup.qrc)
+
+ SET(SRCS ${SRCS} ${UI_SRCS} ${MOC_SRCS} ${RC_SRCS})
+ IF(Q_WS_WIN)
+ SET(SRCS ${SRCS} CMakeSetup.rc)
+ ENDIF(Q_WS_WIN)
+ IF(Q_WS_MAC)
+ SET(SRCS ${SRCS} CMakeSetup.icns)
+ SET(MACOSX_BUNDLE_ICON_FILE CMakeSetup.icns)
+ SET_SOURCE_FILES_PROPERTIES(CMakeSetup.icns PROPERTIES
+ MACOSX_PACKAGE_LOCATION Resources)
+ ENDIF(Q_WS_MAC)
+
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_BINARY_DIR})
+ INCLUDE_DIRECTORIES(${CMAKE_CURRENT_SOURCE_DIR})
+
+ ADD_EXECUTABLE(cmake-gui WIN32 MACOSX_BUNDLE ${SRCS})
+ TARGET_LINK_LIBRARIES(cmake-gui CMakeLib ${QT_QTMAIN_LIBRARY} ${QT_LIBRARIES})
+ IF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4)
+ IF(APPLE)
+ SET_TARGET_PROPERTIES(cmake-gui PROPERTIES
+ OUTPUT_NAME ${CMAKE_BUNDLE_NAME})
+ ENDIF(APPLE)
+ SET(CMAKE_INSTALL_DESTINATION_ARGS
+ BUNDLE DESTINATION "${CMAKE_BUNDLE_LOCATION}")
+ ENDIF(${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.4)
+
+ INSTALL(TARGETS cmake-gui RUNTIME DESTINATION bin ${CMAKE_INSTALL_DESTINATION_ARGS})
+
+ IF(UNIX)
+ # install a desktop file so CMake appears in the application start menu
+ # with an icon
+ INSTALL(FILES CMake.desktop DESTINATION share/applications )
+ INSTALL(FILES CMakeSetup32.png DESTINATION share/pixmaps )
+ INSTALL(FILES cmakecache.xml DESTINATION share/mime/packages )
+ ENDIF(UNIX)
+
+ IF(APPLE)
+ SET(CMAKE_POSTFLIGHT_SCRIPT
+ "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh")
+ SET(CMAKE_POSTUPGRADE_SCRIPT
+ "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh")
+ configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postflight.sh.in"
+ "${CMake_BINARY_DIR}/Source/QtDialog/postflight.sh")
+ configure_file("${CMake_SOURCE_DIR}/Source/QtDialog/postupgrade.sh.in"
+ "${CMake_BINARY_DIR}/Source/QtDialog/postupgrade.sh")
+ INSTALL(CODE "execute_process(COMMAND ln -s \"../MacOS/${CMAKE_BUNDLE_NAME}\" cmake-gui
+ WORKING_DIRECTORY \$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin)")
+ ENDIF(APPLE)
+
+ if(APPLE OR WIN32)
+ # install rules for including 3rd party libs such as Qt
+ # if a system Qt is used (e.g. installed in /usr/lib/), it will not be included in the installation
+ set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/bin/cmake-gui${CMAKE_EXECUTABLE_SUFFIX}")
+ if(APPLE)
+ set(fixup_exe "\$ENV{DESTDIR}\${CMAKE_INSTALL_PREFIX}/MacOS/${CMAKE_BUNDLE_NAME}")
+ endif(APPLE)
+ install(CODE "
+ include(\"${CMake_SOURCE_DIR}/Modules/BundleUtilities.cmake\")
+ set(BU_CHMOD_BUNDLE_ITEMS ON)
+ fixup_bundle(\"${fixup_exe}\" \"\" \"${QT_LIBRARY_DIR};${QT_BINARY_DIR}\")
+ ")
+ endif(APPLE OR WIN32)
+
+ CONFIGURE_FILE("${QtDialog_SOURCE_DIR}/QtDialogCPack.cmake.in"
+ "${QtDialog_BINARY_DIR}/QtDialogCPack.cmake" @ONLY)
+ENDIF(NOT QT4_FOUND)
+
diff --git a/Source/QtDialog/CMakeSetup.cxx b/Source/QtDialog/CMakeSetup.cxx
new file mode 100644
index 000000000..c942bc4ad
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.cxx
@@ -0,0 +1,205 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+#include "QCMake.h" // include to disable MS warnings
+#include <QApplication>
+#include <QDir>
+#include <QTranslator>
+#include <QLocale>
+#include "QMacInstallDialog.h"
+#include "CMakeSetupDialog.h"
+#include "cmDocumentation.h"
+#include "cmake.h"
+#include "cmVersion.h"
+#include <cmsys/CommandLineArguments.hxx>
+#include <cmsys/SystemTools.hxx>
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationName[][3] =
+{
+ {0,
+ " cmake-gui - CMake GUI.", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationUsage[][3] =
+{
+ {0,
+ " cmake-gui [options]\n"
+ " cmake-gui [options] <path-to-source>\n"
+ " cmake-gui [options] <path-to-existing-build>", 0},
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationDescription[][3] =
+{
+ {0,
+ "The \"cmake-gui\" executable is the CMake GUI. Project "
+ "configuration settings may be specified interactively. "
+ "Brief instructions are provided at the bottom of the "
+ "window when the program is running.", 0},
+ CMAKE_STANDARD_INTRODUCTION,
+ {0,0,0}
+};
+
+//----------------------------------------------------------------------------
+static const char * cmDocumentationOptions[][3] =
+{
+ {0,0,0}
+};
+
+int main(int argc, char** argv)
+{
+ cmSystemTools::FindExecutableDirectory(argv[0]);
+ // check docs first so that X is not need to get docs
+ // do docs, if args were given
+ cmDocumentation doc;
+ doc.addCMakeStandardDocSections();
+ if(argc >1 && doc.CheckOptions(argc, argv))
+ {
+ // Construct and print requested documentation.
+ cmake hcm;
+ hcm.AddCMakePaths();
+ // just incase the install is bad avoid a seg fault
+ const char* root = hcm.GetCacheDefinition("CMAKE_ROOT");
+ if(root)
+ {
+ doc.SetCMakeRoot(root);
+ }
+ std::vector<cmDocumentationEntry> commands;
+ std::vector<cmDocumentationEntry> compatCommands;
+ std::map<std::string,cmDocumentationSection *> propDocs;
+
+ std::vector<cmDocumentationEntry> generators;
+ hcm.GetCommandDocumentation(commands, true, false);
+ hcm.GetCommandDocumentation(compatCommands, false, true);
+ hcm.GetGeneratorDocumentation(generators);
+ hcm.GetPropertiesDocumentation(propDocs);
+ doc.SetName("cmake");
+ doc.SetSection("Name",cmDocumentationName);
+ doc.SetSection("Usage",cmDocumentationUsage);
+ doc.SetSection("Description",cmDocumentationDescription);
+ doc.AppendSection("Generators",generators);
+ doc.PrependSection("Options",cmDocumentationOptions);
+ doc.SetSection("Commands",commands);
+ doc.SetSection("Compatilbility Commands", compatCommands);
+ doc.SetSections(propDocs);
+
+ return (doc.PrintRequestedDocumentation(std::cout)? 0:1);
+ }
+
+ QApplication app(argc, argv);
+
+ // clean out standard Qt paths for plugins, which we don't use anyway
+ // when creating Mac bundles, it potentially causes problems
+ foreach(QString p, QApplication::libraryPaths())
+ {
+ QApplication::removeLibraryPath(p);
+ }
+
+ // if arg for install
+ for(int i =0; i < argc; i++)
+ {
+ if(strcmp(argv[i], "--mac-install") == 0)
+ {
+ QMacInstallDialog setupdialog(0);
+ setupdialog.exec();
+ return 0;
+ }
+ }
+ // tell the cmake library where cmake is
+ QDir cmExecDir(QApplication::applicationDirPath());
+#if defined(Q_OS_MAC)
+ cmExecDir.cd("../../../");
+#endif
+
+ // pick up translation files if they exists in the data directory
+ QDir translationsDir = cmExecDir;
+ translationsDir.cd(QString::fromLocal8Bit(".." CMAKE_DATA_DIR));
+ translationsDir.cd("i18n");
+ QTranslator translator;
+ QString transfile = QString("cmake_%1").arg(QLocale::system().name());
+ translator.load(transfile, translationsDir.path());
+ app.installTranslator(&translator);
+
+ // app setup
+ app.setApplicationName("CMakeSetup");
+ app.setOrganizationName("Kitware");
+ QIcon appIcon;
+ appIcon.addFile(":/Icons/CMakeSetup32.png");
+ appIcon.addFile(":/Icons/CMakeSetup128.png");
+ app.setWindowIcon(appIcon);
+
+ CMakeSetupDialog dialog;
+ dialog.show();
+
+ cmsys::CommandLineArguments arg;
+ arg.Initialize(argc, argv);
+ std::string binaryDirectory;
+ std::string sourceDirectory;
+ typedef cmsys::CommandLineArguments argT;
+ arg.AddArgument("-B", argT::CONCAT_ARGUMENT,
+ &binaryDirectory, "Binary Directory");
+ arg.AddArgument("-H", argT::CONCAT_ARGUMENT,
+ &sourceDirectory, "Source Directory");
+ // do not complain about unknown options
+ arg.StoreUnusedArguments(true);
+ arg.Parse();
+ if(!sourceDirectory.empty() && !binaryDirectory.empty())
+ {
+ dialog.setSourceDirectory(QString::fromLocal8Bit(sourceDirectory.c_str()));
+ dialog.setBinaryDirectory(QString::fromLocal8Bit(binaryDirectory.c_str()));
+ }
+ else
+ {
+ QStringList args = app.arguments();
+ if(args.count() == 2)
+ {
+ cmsys_stl::string filePath = cmSystemTools::CollapseFullPath(args[1].toLocal8Bit().data());
+
+ // check if argument is a directory containing CMakeCache.txt
+ cmsys_stl::string buildFilePath =
+ cmSystemTools::CollapseFullPath("CMakeCache.txt", filePath.c_str());
+
+ // check if argument is a CMakeCache.txt file
+ if(cmSystemTools::GetFilenameName(filePath) == "CMakeCache.txt" &&
+ cmSystemTools::FileExists(filePath.c_str()))
+ {
+ buildFilePath = filePath;
+ }
+
+ // check if argument is a directory containing CMakeLists.txt
+ cmsys_stl::string srcFilePath =
+ cmSystemTools::CollapseFullPath("CMakeLists.txt", filePath.c_str());
+
+ if(cmSystemTools::FileExists(buildFilePath.c_str()))
+ {
+ dialog.setBinaryDirectory(
+ QString::fromLocal8Bit(
+ cmSystemTools::GetFilenamePath(buildFilePath).c_str()
+ )
+ );
+ }
+ else if(cmSystemTools::FileExists(srcFilePath.c_str()))
+ {
+ dialog.setSourceDirectory(QString::fromLocal8Bit(filePath.c_str()));
+ dialog.setBinaryDirectory(
+ QString::fromLocal8Bit(cmSystemTools::CollapseFullPath(".").c_str())
+ );
+ }
+ }
+ }
+
+ return app.exec();
+}
+
diff --git a/Source/QtDialog/CMakeSetup.icns b/Source/QtDialog/CMakeSetup.icns
new file mode 100644
index 000000000..4a50c0416
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.icns
Binary files differ
diff --git a/Source/QtDialog/CMakeSetup.ico b/Source/QtDialog/CMakeSetup.ico
new file mode 100644
index 000000000..e13bb156f
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.ico
Binary files differ
diff --git a/Source/QtDialog/CMakeSetup.qrc b/Source/QtDialog/CMakeSetup.qrc
new file mode 100644
index 000000000..eaac19223
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.qrc
@@ -0,0 +1,8 @@
+<RCC>
+ <qresource prefix="/Icons" >
+ <file>CMakeSetup128.png</file>
+ <file>CMakeSetup32.png</file>
+ <file>Delete16.png</file>
+ <file>Plus16.png</file>
+ </qresource>
+</RCC>
diff --git a/Source/QtDialog/CMakeSetup.rc b/Source/QtDialog/CMakeSetup.rc
new file mode 100644
index 000000000..fcc887ddb
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup.rc
@@ -0,0 +1 @@
+IDI_ICON1 ICON DISCARDABLE "CMakeSetup.ico"
diff --git a/Source/QtDialog/CMakeSetup128.png b/Source/QtDialog/CMakeSetup128.png
new file mode 100644
index 000000000..12f1d9a9a
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup128.png
Binary files differ
diff --git a/Source/QtDialog/CMakeSetup32.png b/Source/QtDialog/CMakeSetup32.png
new file mode 100644
index 000000000..7bbcee413
--- /dev/null
+++ b/Source/QtDialog/CMakeSetup32.png
Binary files differ
diff --git a/Source/QtDialog/CMakeSetupDialog.cxx b/Source/QtDialog/CMakeSetupDialog.cxx
new file mode 100644
index 000000000..c0dde1c2c
--- /dev/null
+++ b/Source/QtDialog/CMakeSetupDialog.cxx
@@ -0,0 +1,1152 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "CMakeSetupDialog.h"
+#include <QFileDialog>
+#include <QProgressBar>
+#include <QMessageBox>
+#include <QStatusBar>
+#include <QToolButton>
+#include <QDialogButtonBox>
+#include <QCloseEvent>
+#include <QCoreApplication>
+#include <QSettings>
+#include <QMenu>
+#include <QMenuBar>
+#include <QDragEnterEvent>
+#include <QMimeData>
+#include <QUrl>
+#include <QShortcut>
+#include <QKeySequence>
+#include <QMacInstallDialog.h>
+
+#include "QCMake.h"
+#include "QCMakeCacheView.h"
+#include "AddCacheEntry.h"
+#include "FirstConfigure.h"
+#include "cmVersion.h"
+
+QCMakeThread::QCMakeThread(QObject* p)
+ : QThread(p), CMakeInstance(NULL)
+{
+}
+
+QCMake* QCMakeThread::cmakeInstance() const
+{
+ return this->CMakeInstance;
+}
+
+void QCMakeThread::run()
+{
+ this->CMakeInstance = new QCMake;
+ // emit that this cmake thread is ready for use
+ emit this->cmakeInitialized();
+ this->exec();
+ delete this->CMakeInstance;
+ this->CMakeInstance = NULL;
+}
+
+CMakeSetupDialog::CMakeSetupDialog()
+ : ExitAfterGenerate(true), CacheModified(false), ConfigureNeeded(true), CurrentState(Interrupting)
+{
+ QString title = QString(tr("CMake %1"));
+ title = title.arg(cmVersion::GetCMakeVersion());
+ this->setWindowTitle(title);
+
+ // create the GUI
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ int h = settings.value("Height", 500).toInt();
+ int w = settings.value("Width", 700).toInt();
+ this->resize(w, h);
+
+ this->AddVariableCompletions = settings.value("AddVariableCompletionEntries",
+ QStringList("CMAKE_INSTALL_PREFIX")).toStringList();
+
+ QWidget* cont = new QWidget(this);
+ this->setupUi(cont);
+ this->Splitter->setStretchFactor(0, 3);
+ this->Splitter->setStretchFactor(1, 1);
+ this->setCentralWidget(cont);
+ this->ProgressBar->reset();
+ this->RemoveEntry->setEnabled(false);
+ this->AddEntry->setEnabled(false);
+
+ QByteArray p = settings.value("SplitterSizes").toByteArray();
+ this->Splitter->restoreState(p);
+
+ bool groupView = settings.value("GroupView", false).toBool();
+ this->setGroupedView(groupView);
+ this->groupedCheck->setCheckState(groupView ? Qt::Checked : Qt::Unchecked);
+
+ bool advancedView = settings.value("AdvancedView", false).toBool();
+ this->setAdvancedView(advancedView);
+ this->advancedCheck->setCheckState(advancedView?Qt::Checked : Qt::Unchecked);
+
+ QMenu* FileMenu = this->menuBar()->addMenu(tr("&File"));
+ this->ReloadCacheAction = FileMenu->addAction(tr("&Reload Cache"));
+ QObject::connect(this->ReloadCacheAction, SIGNAL(triggered(bool)),
+ this, SLOT(doReloadCache()));
+ this->DeleteCacheAction = FileMenu->addAction(tr("&Delete Cache"));
+ QObject::connect(this->DeleteCacheAction, SIGNAL(triggered(bool)),
+ this, SLOT(doDeleteCache()));
+ this->ExitAction = FileMenu->addAction(tr("E&xit"));
+ this->ExitAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Q));
+ QObject::connect(this->ExitAction, SIGNAL(triggered(bool)),
+ this, SLOT(close()));
+
+ QMenu* ToolsMenu = this->menuBar()->addMenu(tr("&Tools"));
+ this->ConfigureAction = ToolsMenu->addAction(tr("&Configure"));
+ // prevent merging with Preferences menu item on Mac OS X
+ this->ConfigureAction->setMenuRole(QAction::NoRole);
+ QObject::connect(this->ConfigureAction, SIGNAL(triggered(bool)),
+ this, SLOT(doConfigure()));
+ this->GenerateAction = ToolsMenu->addAction(tr("&Generate"));
+ QObject::connect(this->GenerateAction, SIGNAL(triggered(bool)),
+ this, SLOT(doGenerate()));
+ QAction* showChangesAction = ToolsMenu->addAction(tr("&Show My Changes"));
+ QObject::connect(showChangesAction, SIGNAL(triggered(bool)),
+ this, SLOT(showUserChanges()));
+#if defined(Q_WS_MAC)
+ this->InstallForCommandLineAction
+ = ToolsMenu->addAction(tr("&Install For Command Line Use"));
+ QObject::connect(this->InstallForCommandLineAction, SIGNAL(triggered(bool)),
+ this, SLOT(doInstallForCommandLine()));
+#endif
+ QMenu* OptionsMenu = this->menuBar()->addMenu(tr("&Options"));
+ this->SuppressDevWarningsAction =
+ OptionsMenu->addAction(tr("&Suppress dev Warnings (-Wno-dev)"));
+ this->SuppressDevWarningsAction->setCheckable(true);
+ this->WarnUninitializedAction =
+ OptionsMenu->addAction(tr("&Warn Uninitialized (--warn-uninitialized)"));
+ this->WarnUninitializedAction->setCheckable(true);
+ this->WarnUnusedAction =
+ OptionsMenu->addAction(tr("&Warn Unused (--warn-unused-vars)"));
+ this->WarnUnusedAction->setCheckable(true);
+
+ QAction* debugAction = OptionsMenu->addAction(tr("&Debug Output"));
+ debugAction->setCheckable(true);
+ QObject::connect(debugAction, SIGNAL(toggled(bool)),
+ this, SLOT(setDebugOutput(bool)));
+
+ OptionsMenu->addSeparator();
+ QAction* expandAction = OptionsMenu->addAction(tr("&Expand Grouped Entries"));
+ QObject::connect(expandAction, SIGNAL(triggered(bool)),
+ this->CacheValues, SLOT(expandAll()));
+ QAction* collapseAction = OptionsMenu->addAction(tr("&Collapse Grouped Entries"));
+ QObject::connect(collapseAction, SIGNAL(triggered(bool)),
+ this->CacheValues, SLOT(collapseAll()));
+
+ QMenu* HelpMenu = this->menuBar()->addMenu(tr("&Help"));
+ QAction* a = HelpMenu->addAction(tr("About"));
+ QObject::connect(a, SIGNAL(triggered(bool)),
+ this, SLOT(doAbout()));
+ a = HelpMenu->addAction(tr("Help"));
+ QObject::connect(a, SIGNAL(triggered(bool)),
+ this, SLOT(doHelp()));
+
+ QShortcut* filterShortcut = new QShortcut(QKeySequence::Find, this);
+ QObject::connect(filterShortcut, SIGNAL(activated()),
+ this, SLOT(startSearch()));
+
+ this->setAcceptDrops(true);
+
+ // get the saved binary directories
+ QStringList buildPaths = this->loadBuildPaths();
+ this->BinaryDirectory->addItems(buildPaths);
+
+ this->BinaryDirectory->setCompleter(new QCMakeFileCompleter(this, true));
+ this->SourceDirectory->setCompleter(new QCMakeFileCompleter(this, true));
+
+ // fixed pitch font in output window
+ QFont outputFont("Courier");
+ this->Output->setFont(outputFont);
+ this->ErrorFormat.setForeground(QBrush(Qt::red));
+
+ // start the cmake worker thread
+ this->CMakeThread = new QCMakeThread(this);
+ QObject::connect(this->CMakeThread, SIGNAL(cmakeInitialized()),
+ this, SLOT(initialize()), Qt::QueuedConnection);
+ this->CMakeThread->start();
+
+ this->enterState(ReadyConfigure);
+
+ ProgressOffset = 0.0;
+ ProgressFactor = 1.0;
+}
+
+void CMakeSetupDialog::initialize()
+{
+ // now the cmake worker thread is running, lets make our connections to it
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(propertiesChanged(const QCMakePropertyList&)),
+ this->CacheValues->cacheModel(),
+ SLOT(setProperties(const QCMakePropertyList&)));
+
+ QObject::connect(this->ConfigureButton, SIGNAL(clicked(bool)),
+ this, SLOT(doConfigure()));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(), SIGNAL(configureDone(int)),
+ this, SLOT(exitLoop(int)));
+ QObject::connect(this->CMakeThread->cmakeInstance(), SIGNAL(generateDone(int)),
+ this, SLOT(exitLoop(int)));
+
+ QObject::connect(this->GenerateButton, SIGNAL(clicked(bool)),
+ this, SLOT(doGenerate()));
+
+ 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(editTextChanged(QString)),
+ this, SLOT(onBinaryDirectoryChanged(QString)));
+ QObject::connect(this->SourceDirectory, SIGNAL(textChanged(QString)),
+ this, SLOT(onSourceDirectoryChanged(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(sourceDirChanged(QString)),
+ this, SLOT(updateSourceDirectory(QString)));
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(binaryDirChanged(QString)),
+ this, SLOT(updateBinaryDirectory(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(progressChanged(QString, float)),
+ this, SLOT(showProgress(QString,float)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(errorMessage(QString)),
+ this, SLOT(error(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(outputMessage(QString)),
+ this, SLOT(message(QString)));
+
+ QObject::connect(this->groupedCheck, SIGNAL(toggled(bool)),
+ this, SLOT(setGroupedView(bool)));
+ QObject::connect(this->advancedCheck, SIGNAL(toggled(bool)),
+ this, SLOT(setAdvancedView(bool)));
+ QObject::connect(this->Search, SIGNAL(textChanged(QString)),
+ this, SLOT(setSearchFilter(QString)));
+
+ QObject::connect(this->CMakeThread->cmakeInstance(),
+ SIGNAL(generatorChanged(QString)),
+ this, SLOT(updateGeneratorLabel(QString)));
+ this->updateGeneratorLabel(QString());
+
+ QObject::connect(this->CacheValues->cacheModel(),
+ SIGNAL(dataChanged(QModelIndex,QModelIndex)),
+ this, SLOT(setCacheModified()));
+
+ QObject::connect(this->CacheValues->selectionModel(),
+ SIGNAL(selectionChanged(QItemSelection,QItemSelection)),
+ this, SLOT(selectionChanged()));
+ QObject::connect(this->RemoveEntry, SIGNAL(clicked(bool)),
+ this, SLOT(removeSelectedCacheEntries()));
+ QObject::connect(this->AddEntry, SIGNAL(clicked(bool)),
+ this, SLOT(addCacheEntry()));
+
+ QObject::connect(this->SuppressDevWarningsAction, SIGNAL(triggered(bool)),
+ this->CMakeThread->cmakeInstance(), SLOT(setSuppressDevWarnings(bool)));
+
+ QObject::connect(this->WarnUninitializedAction, SIGNAL(triggered(bool)),
+ this->CMakeThread->cmakeInstance(),
+ SLOT(setWarnUninitializedMode(bool)));
+ QObject::connect(this->WarnUnusedAction, SIGNAL(triggered(bool)),
+ this->CMakeThread->cmakeInstance(),
+ SLOT(setWarnUnusedMode(bool)));
+
+ if(!this->SourceDirectory->text().isEmpty() ||
+ !this->BinaryDirectory->lineEdit()->text().isEmpty())
+ {
+ this->onSourceDirectoryChanged(this->SourceDirectory->text());
+ this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text());
+ }
+ else
+ {
+ this->onBinaryDirectoryChanged(this->BinaryDirectory->lineEdit()->text());
+ }
+}
+
+CMakeSetupDialog::~CMakeSetupDialog()
+{
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("Height", this->height());
+ settings.setValue("Width", this->width());
+ settings.setValue("SplitterSizes", this->Splitter->saveState());
+
+ // wait for thread to stop
+ this->CMakeThread->quit();
+ this->CMakeThread->wait();
+}
+
+bool CMakeSetupDialog::prepareConfigure()
+{
+ // make sure build directory exists
+ QString bindir = this->CMakeThread->cmakeInstance()->binaryDirectory();
+ QDir dir(bindir);
+ if(!dir.exists())
+ {
+ QString msg = tr("Build directory does not exist, "
+ "should I create it?\n\n"
+ "Directory: ");
+ msg += bindir;
+ QString title = tr("Create Directory");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::information(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ return false;
+ }
+ if(!dir.mkpath("."))
+ {
+ QMessageBox::information(this, tr("Create Directory Failed"),
+ QString(tr("Failed to create directory %1")).arg(dir.path()),
+ QMessageBox::Ok);
+
+ return false;
+ }
+ }
+
+ // if no generator, prompt for it and other setup stuff
+ if(this->CMakeThread->cmakeInstance()->generator().isEmpty())
+ {
+ if(!this->setupFirstConfigure())
+ {
+ return false;
+ }
+ }
+
+ // remember path
+ this->addBinaryPath(dir.absolutePath());
+
+ return true;
+}
+
+void CMakeSetupDialog::exitLoop(int err)
+{
+ this->LocalLoop.exit(err);
+}
+
+void CMakeSetupDialog::doConfigure()
+{
+ if(this->CurrentState == Configuring)
+ {
+ // stop configure
+ doInterrupt();
+ return;
+ }
+
+ if(!prepareConfigure())
+ {
+ return;
+ }
+
+ this->enterState(Configuring);
+
+ bool ret = doConfigureInternal();
+
+ if(ret)
+ {
+ this->ConfigureNeeded = false;
+ }
+
+ if(ret && !this->CacheValues->cacheModel()->newPropertyCount())
+ {
+ this->enterState(ReadyGenerate);
+ }
+ else
+ {
+ this->enterState(ReadyConfigure);
+ this->CacheValues->scrollToTop();
+ }
+ this->ProgressBar->reset();
+}
+
+bool CMakeSetupDialog::doConfigureInternal()
+{
+ this->Output->clear();
+ this->CacheValues->selectionModel()->clear();
+
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setProperties", Qt::QueuedConnection,
+ Q_ARG(QCMakePropertyList,
+ this->CacheValues->cacheModel()->properties()));
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "configure", Qt::QueuedConnection);
+
+ int err = this->LocalLoop.exec();
+
+ if(err != 0)
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error in configuration process, project files may be invalid"),
+ QMessageBox::Ok);
+ }
+
+ return 0 == err;
+}
+
+void CMakeSetupDialog::doInstallForCommandLine()
+{
+ QMacInstallDialog setupdialog(0);
+ setupdialog.exec();
+}
+
+bool CMakeSetupDialog::doGenerateInternal()
+{
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "generate", Qt::QueuedConnection);
+
+ int err = this->LocalLoop.exec();
+
+ if(err != 0)
+ {
+ QMessageBox::critical(this, tr("Error"),
+ tr("Error in generation process, project files may be invalid"),
+ QMessageBox::Ok);
+ }
+
+ return 0 == err;
+}
+
+void CMakeSetupDialog::doGenerate()
+{
+ if(this->CurrentState == Generating)
+ {
+ // stop generate
+ doInterrupt();
+ return;
+ }
+
+ // see if we need to configure
+ // we'll need to configure if:
+ // the configure step hasn't been done yet
+ // generate was the last step done
+ if(this->ConfigureNeeded)
+ {
+ if(!prepareConfigure())
+ {
+ return;
+ }
+ }
+
+ this->enterState(Generating);
+
+ bool config_passed = true;
+ if(this->ConfigureNeeded)
+ {
+ this->CacheValues->cacheModel()->setShowNewProperties(false);
+ this->ProgressFactor = 0.5;
+ config_passed = doConfigureInternal();
+ this->ProgressOffset = 0.5;
+ }
+
+ if(config_passed)
+ {
+ doGenerateInternal();
+ }
+
+ this->ProgressOffset = 0.0;
+ this->ProgressFactor = 1.0;
+ this->CacheValues->cacheModel()->setShowNewProperties(true);
+
+ this->enterState(ReadyConfigure);
+ this->ProgressBar->reset();
+
+ this->ConfigureNeeded = true;
+}
+
+void CMakeSetupDialog::closeEvent(QCloseEvent* e)
+{
+ // prompt for close if there are unsaved changes, and we're not busy
+ if(this->CacheModified)
+ {
+ QString msg = tr("You have changed options but not rebuilt, "
+ "are you sure you want to exit?");
+ QString title = tr("Confirm Exit");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::critical(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ e->ignore();
+ }
+ }
+
+ // don't close if we're busy, unless the user really wants to
+ if(this->CurrentState == Configuring)
+ {
+ QString msg = tr("You are in the middle of a Configure.\n"
+ "If you Exit now the configure information will be lost.\n"
+ "Are you sure you want to Exit?");
+ QString title = tr("Confirm Exit");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::critical(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ e->ignore();
+ }
+ else
+ {
+ this->doInterrupt();
+ }
+ }
+
+ // let the generate finish
+ if(this->CurrentState == Generating)
+ {
+ e->ignore();
+ }
+}
+
+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 Generate button. This will write the build files to the build "
+ "directory.");
+
+ QDialog dialog;
+ QFontMetrics met(this->font());
+ int msgWidth = met.width(msg);
+ dialog.setMinimumSize(msgWidth/15,20);
+ dialog.setWindowTitle(tr("Help"));
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ QLabel* lab = new QLabel(&dialog);
+ lab->setText(msg);
+ lab->setWordWrap(true);
+ QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Ok,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ l->addWidget(lab);
+ l->addWidget(btns);
+ dialog.exec();
+}
+
+void CMakeSetupDialog::doInterrupt()
+{
+ this->enterState(Interrupting);
+ this->CMakeThread->cmakeInstance()->interrupt();
+}
+
+void CMakeSetupDialog::doSourceBrowse()
+{
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Enter Path to Source"), this->SourceDirectory->text());
+ if(!dir.isEmpty())
+ {
+ this->setSourceDirectory(dir);
+ }
+}
+
+void CMakeSetupDialog::updateSourceDirectory(const QString& dir)
+{
+ if(this->SourceDirectory->text() != dir)
+ {
+ this->SourceDirectory->blockSignals(true);
+ this->SourceDirectory->setText(dir);
+ this->SourceDirectory->blockSignals(false);
+ }
+}
+
+void CMakeSetupDialog::updateBinaryDirectory(const QString& dir)
+{
+ if(this->BinaryDirectory->currentText() != dir)
+ {
+ this->BinaryDirectory->blockSignals(true);
+ this->BinaryDirectory->setEditText(dir);
+ this->BinaryDirectory->blockSignals(false);
+ }
+}
+
+void CMakeSetupDialog::doBinaryBrowse()
+{
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Enter Path to Build"), this->BinaryDirectory->currentText());
+ if(!dir.isEmpty() && dir != this->BinaryDirectory->currentText())
+ {
+ this->setBinaryDirectory(dir);
+ }
+}
+
+void CMakeSetupDialog::setBinaryDirectory(const QString& dir)
+{
+ this->BinaryDirectory->setEditText(dir);
+}
+
+void CMakeSetupDialog::onSourceDirectoryChanged(const QString& dir)
+{
+ this->Output->clear();
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setSourceDirectory", Qt::QueuedConnection, Q_ARG(QString, dir));
+}
+
+void CMakeSetupDialog::onBinaryDirectoryChanged(const QString& dir)
+{
+ QString title = QString(tr("CMake %1 - %2"));
+ title = title.arg(cmVersion::GetCMakeVersion());
+ title = title.arg(dir);
+ this->setWindowTitle(title);
+
+ this->CacheModified = false;
+ this->CacheValues->cacheModel()->clear();
+ qobject_cast<QCMakeCacheModelDelegate*>(this->CacheValues->itemDelegate())->clearChanges();
+ this->Output->clear();
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setBinaryDirectory", Qt::QueuedConnection, Q_ARG(QString, dir));
+}
+
+void CMakeSetupDialog::setSourceDirectory(const QString& dir)
+{
+ this->SourceDirectory->setText(dir);
+}
+
+void CMakeSetupDialog::showProgress(const QString& /*msg*/, float percent)
+{
+ percent = (percent * ProgressFactor) + ProgressOffset;
+ this->ProgressBar->setValue(qRound(percent * 100));
+}
+
+void CMakeSetupDialog::error(const QString& msg)
+{
+ this->Output->setCurrentCharFormat(this->ErrorFormat);
+ this->Output->append(msg);
+}
+
+void CMakeSetupDialog::message(const QString& msg)
+{
+ this->Output->setCurrentCharFormat(this->MessageFormat);
+ this->Output->append(msg);
+}
+
+void CMakeSetupDialog::setEnabledState(bool enabled)
+{
+ // disable parts of the GUI during configure/generate
+ this->CacheValues->cacheModel()->setEditEnabled(enabled);
+ this->SourceDirectory->setEnabled(enabled);
+ this->BrowseSourceDirectoryButton->setEnabled(enabled);
+ this->BinaryDirectory->setEnabled(enabled);
+ this->BrowseBinaryDirectoryButton->setEnabled(enabled);
+ this->ReloadCacheAction->setEnabled(enabled);
+ this->DeleteCacheAction->setEnabled(enabled);
+ this->ExitAction->setEnabled(enabled);
+ this->ConfigureAction->setEnabled(enabled);
+ this->AddEntry->setEnabled(enabled);
+ this->RemoveEntry->setEnabled(false); // let selection re-enable it
+}
+
+bool CMakeSetupDialog::setupFirstConfigure()
+{
+ FirstConfigure dialog;
+
+ // initialize dialog and restore saved settings
+
+ // add generators
+ dialog.setGenerators(this->CMakeThread->cmakeInstance()->availableGenerators());
+
+ // restore from settings
+ dialog.loadFromSettings();
+
+ if(dialog.exec() == QDialog::Accepted)
+ {
+ dialog.saveToSettings();
+ this->CMakeThread->cmakeInstance()->setGenerator(dialog.getGenerator());
+
+ QCMakeCacheModel* m = this->CacheValues->cacheModel();
+
+ if(dialog.compilerSetup())
+ {
+ QString fortranCompiler = dialog.getFortranCompiler();
+ if(!fortranCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_Fortran_COMPILER",
+ "Fortran compiler.", fortranCompiler, false);
+ }
+ QString cxxCompiler = dialog.getCXXCompiler();
+ if(!cxxCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
+ "CXX compiler.", cxxCompiler, false);
+ }
+
+ QString cCompiler = dialog.getCCompiler();
+ if(!cCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
+ "C compiler.", cCompiler, false);
+ }
+ }
+ else if(dialog.crossCompilerSetup())
+ {
+ QString fortranCompiler = dialog.getFortranCompiler();
+ if(!fortranCompiler.isEmpty())
+ {
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_Fortran_COMPILER",
+ "Fortran compiler.", fortranCompiler, false);
+ }
+
+ QString mode = dialog.getCrossIncludeMode();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_INCLUDE",
+ tr("CMake Find Include Mode"), mode, false);
+ mode = dialog.getCrossLibraryMode();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_LIBRARY",
+ tr("CMake Find Library Mode"), mode, false);
+ mode = dialog.getCrossProgramMode();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_FIND_ROOT_PATH_MODE_PROGRAM",
+ tr("CMake Find Program Mode"), mode, false);
+
+ QString rootPath = dialog.getCrossRoot();
+ m->insertProperty(QCMakeProperty::PATH, "CMAKE_FIND_ROOT_PATH",
+ tr("CMake Find Root Path"), rootPath, false);
+
+ QString systemName = dialog.getSystemName();
+ m->insertProperty(QCMakeProperty::STRING, "CMAKE_SYSTEM_NAME",
+ tr("CMake System Name"), systemName, false);
+ QString cxxCompiler = dialog.getCXXCompiler();
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_CXX_COMPILER",
+ tr("CXX compiler."), cxxCompiler, false);
+ QString cCompiler = dialog.getCCompiler();
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_C_COMPILER",
+ tr("C compiler."), cCompiler, false);
+ }
+ else if(dialog.crossCompilerToolChainFile())
+ {
+ QString toolchainFile = dialog.getCrossCompilerToolChainFile();
+ m->insertProperty(QCMakeProperty::FILEPATH, "CMAKE_TOOLCHAIN_FILE",
+ tr("Cross Compile ToolChain File"), toolchainFile, false);
+ }
+ return true;
+ }
+
+ return false;
+}
+
+void CMakeSetupDialog::updateGeneratorLabel(const QString& gen)
+{
+ QString str = tr("Current Generator: ");
+ if(gen.isEmpty())
+ {
+ str += tr("None");
+ }
+ else
+ {
+ str += gen;
+ }
+ this->Generator->setText(str);
+}
+
+void CMakeSetupDialog::doReloadCache()
+{
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "reloadCache", Qt::QueuedConnection);
+}
+
+void CMakeSetupDialog::doDeleteCache()
+{
+ QString title = tr("Delete Cache");
+ QString msg = tr("Are you sure you want to delete the cache?");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::information(this, title, msg,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::No)
+ {
+ return;
+ }
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "deleteCache", Qt::QueuedConnection);
+}
+
+void CMakeSetupDialog::doAbout()
+{
+ QString msg = tr("CMake %1\n"
+ "Using Qt %2\n"
+ "www.cmake.org");
+
+ msg = msg.arg(cmVersion::GetCMakeVersion());
+ msg = msg.arg(qVersion());
+
+ QDialog dialog;
+ dialog.setWindowTitle(tr("About"));
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ QLabel* lab = new QLabel(&dialog);
+ l->addWidget(lab);
+ lab->setText(msg);
+ lab->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::setExitAfterGenerate(bool b)
+{
+ this->ExitAfterGenerate = b;
+}
+
+void CMakeSetupDialog::addBinaryPath(const QString& path)
+{
+ QString cleanpath = QDir::cleanPath(path);
+
+ // update UI
+ this->BinaryDirectory->blockSignals(true);
+ int idx = this->BinaryDirectory->findText(cleanpath);
+ if(idx != -1)
+ {
+ this->BinaryDirectory->removeItem(idx);
+ }
+ this->BinaryDirectory->insertItem(0, cleanpath);
+ this->BinaryDirectory->setCurrentIndex(0);
+ this->BinaryDirectory->blockSignals(false);
+
+ // save to registry
+ QStringList buildPaths = this->loadBuildPaths();
+ buildPaths.removeAll(cleanpath);
+ buildPaths.prepend(cleanpath);
+ this->saveBuildPaths(buildPaths);
+}
+
+void CMakeSetupDialog::dragEnterEvent(QDragEnterEvent* e)
+{
+ if(!(this->CurrentState == ReadyConfigure ||
+ this->CurrentState == ReadyGenerate))
+ {
+ e->ignore();
+ return;
+ }
+
+ const QMimeData* dat = e->mimeData();
+ QList<QUrl> urls = dat->urls();
+ QString file = urls.count() ? urls[0].toLocalFile() : QString();
+ if(!file.isEmpty() &&
+ (file.endsWith("CMakeCache.txt", Qt::CaseInsensitive) ||
+ file.endsWith("CMakeLists.txt", Qt::CaseInsensitive) ) )
+ {
+ e->accept();
+ }
+ else
+ {
+ e->ignore();
+ }
+}
+
+void CMakeSetupDialog::dropEvent(QDropEvent* e)
+{
+ if(!(this->CurrentState == ReadyConfigure ||
+ this->CurrentState == ReadyGenerate))
+ {
+ return;
+ }
+
+ const QMimeData* dat = e->mimeData();
+ QList<QUrl> urls = dat->urls();
+ QString file = urls.count() ? urls[0].toLocalFile() : QString();
+ if(file.endsWith("CMakeCache.txt", Qt::CaseInsensitive))
+ {
+ QFileInfo info(file);
+ if(this->CMakeThread->cmakeInstance()->binaryDirectory() != info.absolutePath())
+ {
+ this->setBinaryDirectory(info.absolutePath());
+ }
+ }
+ else if(file.endsWith("CMakeLists.txt", Qt::CaseInsensitive))
+ {
+ QFileInfo info(file);
+ if(this->CMakeThread->cmakeInstance()->binaryDirectory() != info.absolutePath())
+ {
+ this->setSourceDirectory(info.absolutePath());
+ this->setBinaryDirectory(info.absolutePath());
+ }
+ }
+}
+
+QStringList CMakeSetupDialog::loadBuildPaths()
+{
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+
+ QStringList buildPaths;
+ for(int i=0; i<10; i++)
+ {
+ QString p = settings.value(QString("WhereBuild%1").arg(i)).toString();
+ if(!p.isEmpty())
+ {
+ buildPaths.append(p);
+ }
+ }
+ return buildPaths;
+}
+
+void CMakeSetupDialog::saveBuildPaths(const QStringList& paths)
+{
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+
+ int num = paths.count();
+ if(num > 10)
+ {
+ num = 10;
+ }
+
+ for(int i=0; i<num; i++)
+ {
+ settings.setValue(QString("WhereBuild%1").arg(i), paths[i]);
+ }
+}
+
+void CMakeSetupDialog::setCacheModified()
+{
+ this->CacheModified = true;
+ this->enterState(ReadyConfigure);
+}
+
+void CMakeSetupDialog::removeSelectedCacheEntries()
+{
+ QModelIndexList idxs = this->CacheValues->selectionModel()->selectedRows();
+ QList<QPersistentModelIndex> pidxs;
+ foreach(QModelIndex i, idxs)
+ {
+ pidxs.append(i);
+ }
+ foreach(QPersistentModelIndex pi, pidxs)
+ {
+ this->CacheValues->model()->removeRow(pi.row(), pi.parent());
+ }
+}
+
+void CMakeSetupDialog::selectionChanged()
+{
+ QModelIndexList idxs = this->CacheValues->selectionModel()->selectedRows();
+ if(idxs.count() &&
+ (this->CurrentState == ReadyConfigure ||
+ this->CurrentState == ReadyGenerate) )
+ {
+ this->RemoveEntry->setEnabled(true);
+ }
+ else
+ {
+ this->RemoveEntry->setEnabled(false);
+ }
+}
+
+void CMakeSetupDialog::enterState(CMakeSetupDialog::State s)
+{
+ if(s == this->CurrentState)
+ {
+ return;
+ }
+
+ this->CurrentState = s;
+
+ if(s == Interrupting)
+ {
+ this->ConfigureButton->setEnabled(false);
+ this->GenerateButton->setEnabled(false);
+ }
+ else if(s == Configuring)
+ {
+ this->setEnabledState(false);
+ this->GenerateButton->setEnabled(false);
+ this->GenerateAction->setEnabled(false);
+ this->ConfigureButton->setText(tr("&Stop"));
+ }
+ else if(s == Generating)
+ {
+ this->CacheModified = false;
+ this->setEnabledState(false);
+ this->ConfigureButton->setEnabled(false);
+ this->GenerateAction->setEnabled(false);
+ this->GenerateButton->setText(tr("&Stop"));
+ }
+ else if(s == ReadyConfigure)
+ {
+ this->setEnabledState(true);
+ this->GenerateButton->setEnabled(true);
+ this->GenerateAction->setEnabled(true);
+ this->ConfigureButton->setEnabled(true);
+ this->ConfigureButton->setText(tr("&Configure"));
+ this->GenerateButton->setText(tr("&Generate"));
+ }
+ else if(s == ReadyGenerate)
+ {
+ this->setEnabledState(true);
+ this->GenerateButton->setEnabled(true);
+ this->GenerateAction->setEnabled(true);
+ this->ConfigureButton->setEnabled(true);
+ this->ConfigureButton->setText(tr("&Configure"));
+ this->GenerateButton->setText(tr("&Generate"));
+ }
+}
+
+void CMakeSetupDialog::addCacheEntry()
+{
+ QDialog dialog(this);
+ dialog.resize(400, 200);
+ dialog.setWindowTitle(tr("Add Cache Entry"));
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ AddCacheEntry* w = new AddCacheEntry(&dialog, this->AddVariableCompletions);
+ QDialogButtonBox* btns = new QDialogButtonBox(
+ QDialogButtonBox::Ok | QDialogButtonBox::Cancel,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(accepted()), &dialog, SLOT(accept()));
+ QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(reject()));
+ l->addWidget(w);
+ l->addStretch();
+ l->addWidget(btns);
+ if(QDialog::Accepted == dialog.exec())
+ {
+ QCMakeCacheModel* m = this->CacheValues->cacheModel();
+ m->insertProperty(w->type(), w->name(), w->description(), w->value(), false);
+
+ // only add variable names to the completion which are new
+ if (!this->AddVariableCompletions.contains(w->name()))
+ {
+ this->AddVariableCompletions << w->name();
+ // limit to at most 100 completion items
+ if (this->AddVariableCompletions.size() > 100)
+ {
+ this->AddVariableCompletions.removeFirst();
+ }
+ // make sure CMAKE_INSTALL_PREFIX is always there
+ if (!this->AddVariableCompletions.contains("CMAKE_INSTALL_PREFIX"))
+ {
+ this->AddVariableCompletions << QString("CMAKE_INSTALL_PREFIX");
+ }
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("AddVariableCompletionEntries",
+ this->AddVariableCompletions);
+ }
+ }
+}
+
+void CMakeSetupDialog::startSearch()
+{
+ this->Search->setFocus(Qt::OtherFocusReason);
+ this->Search->selectAll();
+}
+
+void CMakeSetupDialog::setDebugOutput(bool flag)
+{
+ QMetaObject::invokeMethod(this->CMakeThread->cmakeInstance(),
+ "setDebugOutput", Qt::QueuedConnection, Q_ARG(bool, flag));
+}
+
+void CMakeSetupDialog::setGroupedView(bool v)
+{
+ this->CacheValues->cacheModel()->setViewType(v ? QCMakeCacheModel::GroupView : QCMakeCacheModel::FlatView);
+ this->CacheValues->setRootIsDecorated(v);
+
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("GroupView", v);
+
+}
+
+void CMakeSetupDialog::setAdvancedView(bool v)
+{
+ this->CacheValues->setShowAdvanced(v);
+ QSettings settings;
+ settings.beginGroup("Settings/StartPath");
+ settings.setValue("AdvancedView", v);
+}
+
+void CMakeSetupDialog::showUserChanges()
+{
+ QSet<QCMakeProperty> changes =
+ qobject_cast<QCMakeCacheModelDelegate*>(this->CacheValues->itemDelegate())->changes();
+
+ QDialog dialog(this);
+ dialog.setWindowTitle(tr("My Changes"));
+ dialog.resize(600, 400);
+ QVBoxLayout* l = new QVBoxLayout(&dialog);
+ QTextEdit* textedit = new QTextEdit(&dialog);
+ textedit->setReadOnly(true);
+ l->addWidget(textedit);
+ QDialogButtonBox* btns = new QDialogButtonBox(QDialogButtonBox::Close,
+ Qt::Horizontal, &dialog);
+ QObject::connect(btns, SIGNAL(rejected()), &dialog, SLOT(accept()));
+ l->addWidget(btns);
+
+ QString command;
+ QString cache;
+
+ foreach(QCMakeProperty prop, changes)
+ {
+ QString type;
+ switch(prop.Type)
+ {
+ case QCMakeProperty::BOOL:
+ type = "BOOL";
+ break;
+ case QCMakeProperty::PATH:
+ type = "PATH";
+ break;
+ case QCMakeProperty::FILEPATH:
+ type = "FILEPATH";
+ break;
+ case QCMakeProperty::STRING:
+ type = "STRING";
+ break;
+ }
+ QString value;
+ if(prop.Type == QCMakeProperty::BOOL)
+ {
+ value = prop.Value.toBool() ? "1" : "0";
+ }
+ else
+ {
+ value = prop.Value.toString();
+ }
+
+ QString line("%1:%2=");
+ line = line.arg(prop.Key);
+ line = line.arg(type);
+
+ command += QString("-D%1\"%2\" ").arg(line).arg(value);
+ cache += QString("%1%2\n").arg(line).arg(value);
+ }
+
+ textedit->append(tr("Commandline options:"));
+ textedit->append(command);
+ textedit->append("\n");
+ textedit->append(tr("Cache file:"));
+ textedit->append(cache);
+
+ dialog.exec();
+}
+
+void CMakeSetupDialog::setSearchFilter(const QString& str)
+{
+ this->CacheValues->selectionModel()->clear();
+ this->CacheValues->setSearchFilter(str);
+}
+
+
diff --git a/Source/QtDialog/CMakeSetupDialog.h b/Source/QtDialog/CMakeSetupDialog.h
new file mode 100644
index 000000000..259967580
--- /dev/null
+++ b/Source/QtDialog/CMakeSetupDialog.h
@@ -0,0 +1,132 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef CMakeSetupDialog_h
+#define CMakeSetupDialog_h
+
+#include "QCMake.h"
+#include <QMainWindow>
+#include <QThread>
+#include <QEventLoop>
+#include "ui_CMakeSetupDialog.h"
+
+class QCMakeThread;
+class CMakeCacheModel;
+class QProgressBar;
+class QToolButton;
+
+/// Qt user interface for CMake
+class CMakeSetupDialog : public QMainWindow, public Ui::CMakeSetupDialog
+{
+ Q_OBJECT
+public:
+ CMakeSetupDialog();
+ ~CMakeSetupDialog();
+
+public slots:
+ void setBinaryDirectory(const QString& dir);
+ void setSourceDirectory(const QString& dir);
+
+protected slots:
+ void initialize();
+ void doConfigure();
+ void doGenerate();
+ void doInstallForCommandLine();
+ void doHelp();
+ void doAbout();
+ void doInterrupt();
+ void error(const QString& message);
+ void message(const QString& message);
+
+ void doSourceBrowse();
+ void doBinaryBrowse();
+ void doReloadCache();
+ void doDeleteCache();
+ void updateSourceDirectory(const QString& dir);
+ void updateBinaryDirectory(const QString& dir);
+ void showProgress(const QString& msg, float percent);
+ void setEnabledState(bool);
+ bool setupFirstConfigure();
+ void updateGeneratorLabel(const QString& gen);
+ void setExitAfterGenerate(bool);
+ void addBinaryPath(const QString&);
+ QStringList loadBuildPaths();
+ void saveBuildPaths(const QStringList&);
+ void onBinaryDirectoryChanged(const QString& dir);
+ void onSourceDirectoryChanged(const QString& dir);
+ void setCacheModified();
+ void removeSelectedCacheEntries();
+ void selectionChanged();
+ void addCacheEntry();
+ void startSearch();
+ void setDebugOutput(bool);
+ void setAdvancedView(bool);
+ void setGroupedView(bool);
+ void showUserChanges();
+ void setSearchFilter(const QString& str);
+ bool prepareConfigure();
+ bool doConfigureInternal();
+ bool doGenerateInternal();
+ void exitLoop(int);
+
+protected:
+
+ enum State { Interrupting, ReadyConfigure, ReadyGenerate, Configuring, Generating };
+ void enterState(State s);
+
+ void closeEvent(QCloseEvent*);
+ void dragEnterEvent(QDragEnterEvent*);
+ void dropEvent(QDropEvent*);
+
+ QCMakeThread* CMakeThread;
+ bool ExitAfterGenerate;
+ bool CacheModified;
+ bool ConfigureNeeded;
+ QAction* ReloadCacheAction;
+ QAction* DeleteCacheAction;
+ QAction* ExitAction;
+ QAction* ConfigureAction;
+ QAction* GenerateAction;
+ QAction* SuppressDevWarningsAction;
+ QAction* WarnUninitializedAction;
+ QAction* WarnUnusedAction;
+ QAction* InstallForCommandLineAction;
+ State CurrentState;
+
+ QTextCharFormat ErrorFormat;
+ QTextCharFormat MessageFormat;
+
+ QStringList AddVariableCompletions;
+
+ QEventLoop LocalLoop;
+
+ float ProgressOffset;
+ float ProgressFactor;
+};
+
+// QCMake instance on a thread
+class QCMakeThread : public QThread
+{
+ Q_OBJECT
+public:
+ QCMakeThread(QObject* p);
+ QCMake* cmakeInstance() const;
+
+signals:
+ void cmakeInitialized();
+
+protected:
+ virtual void run();
+ QCMake* CMakeInstance;
+};
+
+#endif // CMakeSetupDialog_h
diff --git a/Source/QtDialog/CMakeSetupDialog.ui b/Source/QtDialog/CMakeSetupDialog.ui
new file mode 100644
index 000000000..dc8ee3fbd
--- /dev/null
+++ b/Source/QtDialog/CMakeSetupDialog.ui
@@ -0,0 +1,310 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>CMakeSetupDialog</class>
+ <widget class="QWidget" name="CMakeSetupDialog">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>707</width>
+ <height>582</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>9</number>
+ </property>
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <item row="0" column="0">
+ <layout class="QGridLayout">
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <property name="spacing">
+ <number>6</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 &amp;Source...</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="sizePolicy">
+ <sizepolicy hsizetype="Ignored" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="editable">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="2">
+ <widget class="QPushButton" name="BrowseBinaryDirectoryButton">
+ <property name="text">
+ <string>Browse &amp;Build...</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QSplitter" name="Splitter">
+ <property name="orientation">
+ <enum>Qt::Vertical</enum>
+ </property>
+ <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="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="label_4">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text">
+ <string>Search:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="Search">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Minimum</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>40</width>
+ <height>23</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="groupedCheck">
+ <property name="text">
+ <string>Grouped</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="advancedCheck">
+ <property name="text">
+ <string>Advanced</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="AddEntry">
+ <property name="toolTip">
+ <string>Add New Entry</string>
+ </property>
+ <property name="text">
+ <string>&amp;Add Entry</string>
+ </property>
+ <property name="icon">
+ <iconset resource="CMakeSetup.qrc">
+ <normaloff>:/Icons/Plus16.png</normaloff>:/Icons/Plus16.png</iconset>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QToolButton" name="RemoveEntry">
+ <property name="toolTip">
+ <string>Remove Selected Entries</string>
+ </property>
+ <property name="text">
+ <string>&amp;Remove Entry</string>
+ </property>
+ <property name="icon">
+ <iconset resource="CMakeSetup.qrc">
+ <normaloff>:/Icons/Delete16.png</normaloff>:/Icons/Delete16.png</iconset>
+ </property>
+ <property name="toolButtonStyle">
+ <enum>Qt::ToolButtonTextBesideIcon</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
+ <widget class="QCMakeCacheView" name="CacheValues">
+ <property name="alternatingRowColors">
+ <bool>true</bool>
+ </property>
+ <property name="selectionMode">
+ <enum>QAbstractItemView::ExtendedSelection</enum>
+ </property>
+ <property name="selectionBehavior">
+ <enum>QAbstractItemView::SelectRows</enum>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_3">
+ <property name="text">
+ <string>Press Configure to update and display new values in red, then press Generate to generate selected build files.</string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ <property name="wordWrap">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <layout class="QHBoxLayout">
+ <property name="spacing">
+ <number>6</number>
+ </property>
+ <property name="margin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QPushButton" name="ConfigureButton">
+ <property name="text">
+ <string>&amp;Configure</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="GenerateButton">
+ <property name="text">
+ <string>&amp;Generate</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="Generator">
+ <property name="text">
+ <string>Current Generator:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <spacer>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeType">
+ <enum>QSizePolicy::Expanding</enum>
+ </property>
+ <property name="sizeHint" stdset="0">
+ <size>
+ <width>121</width>
+ <height>27</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QProgressBar" name="ProgressBar">
+ <property name="minimum">
+ <number>0</number>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="value">
+ <number>0</number>
+ </property>
+ <property name="textVisible">
+ <bool>false</bool>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="textDirection">
+ <enum>QProgressBar::BottomToTop</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ </layout>
+ </widget>
+ <widget class="QTextEdit" name="Output">
+ <property name="lineWrapMode">
+ <enum>QTextEdit::NoWrap</enum>
+ </property>
+ <property name="readOnly">
+ <bool>true</bool>
+ </property>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakeCacheView</class>
+ <extends>QTreeView</extends>
+ <header>QCMakeCacheView.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources>
+ <include location="CMakeSetup.qrc"/>
+ </resources>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/Compilers.h b/Source/QtDialog/Compilers.h
new file mode 100644
index 000000000..e9c90a504
--- /dev/null
+++ b/Source/QtDialog/Compilers.h
@@ -0,0 +1,21 @@
+
+
+#ifndef COMPILERS_HPP
+#define COMPILERS_HPP
+
+#include <QWidget>
+#include <ui_Compilers.h>
+
+class Compilers : public QWidget, public Ui::Compilers
+{
+ Q_OBJECT
+public:
+ Compilers(QWidget* p=NULL) :
+ QWidget(p)
+ {
+ this->setupUi(this);
+ }
+};
+
+#endif
+
diff --git a/Source/QtDialog/Compilers.ui b/Source/QtDialog/Compilers.ui
new file mode 100644
index 000000000..41f70acdb
--- /dev/null
+++ b/Source/QtDialog/Compilers.ui
@@ -0,0 +1,87 @@
+<ui version="4.0" >
+ <class>Compilers</class>
+ <widget class="QWidget" name="Compilers" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>506</width>
+ <height>115</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Form</string>
+ </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="QGroupBox" name="groupBox_4" >
+ <property name="title" >
+ <string>Compilers</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="leftMargin" >
+ <number>4</number>
+ </property>
+ <property name="topMargin" >
+ <number>4</number>
+ </property>
+ <property name="rightMargin" >
+ <number>4</number>
+ </property>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_16" >
+ <property name="text" >
+ <string>C</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QCMakeFilePathEditor" name="CCompiler" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_17" >
+ <property name="text" >
+ <string>C++</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QCMakeFilePathEditor" name="CXXCompiler" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_18" >
+ <property name="text" >
+ <string>Fortran</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QCMakeFilePathEditor" name="FortranCompiler" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakeFilePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/CrossCompiler.ui b/Source/QtDialog/CrossCompiler.ui
new file mode 100644
index 000000000..1fb1ebf49
--- /dev/null
+++ b/Source/QtDialog/CrossCompiler.ui
@@ -0,0 +1,213 @@
+<ui version="4.0" >
+ <class>CrossCompiler</class>
+ <widget class="QWidget" name="CrossCompiler" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>433</width>
+ <height>319</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>CrossCompiler</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QGroupBox" name="groupBox" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Target System</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_6" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Operating System</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="systemName" />
+ </item>
+ <item row="0" column="2" colspan="2" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_10" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Version</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QLineEdit" name="systemVersion" />
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_11" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Processor</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QLineEdit" name="systemProcessor" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="2" column="0" >
+ <widget class="QGroupBox" name="groupBox_2" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Preferred" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="title" >
+ <string>Find Program/Library/Include</string>
+ </property>
+ <layout class="QGridLayout" >
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label_9" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Target Root</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QCMakePathEditor" name="crossFindRoot" />
+ </item>
+ <item row="0" column="2" >
+ <widget class="QLabel" name="label_12" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Program Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="3" >
+ <widget class="QComboBox" name="crossProgramMode" />
+ </item>
+ <item row="1" column="0" >
+ <widget class="QLabel" name="label_13" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Library Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1" >
+ <widget class="QComboBox" name="crossLibraryMode" />
+ </item>
+ <item row="1" column="2" >
+ <widget class="QLabel" name="label_14" >
+ <property name="sizePolicy" >
+ <sizepolicy vsizetype="Fixed" hsizetype="Preferred" >
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <property name="text" >
+ <string>Include Mode</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="3" >
+ <widget class="QComboBox" name="crossIncludeMode" />
+ </item>
+ </layout>
+ </widget>
+ </item>
+ <item row="1" column="0" >
+ <widget class="Compilers" native="1" name="CrossCompilers" >
+ <property name="focusPolicy" >
+ <enum>Qt::TabFocus</enum>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>QCMakePathEditor</class>
+ <extends>QLineEdit</extends>
+ <header>QCMakeWidgets.h</header>
+ </customwidget>
+ <customwidget>
+ <class>Compilers</class>
+ <extends>QWidget</extends>
+ <header>Compilers.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <tabstops>
+ <tabstop>systemVersion</tabstop>
+ <tabstop>systemProcessor</tabstop>
+ <tabstop>CrossCompilers</tabstop>
+ <tabstop>crossFindRoot</tabstop>
+ <tabstop>crossProgramMode</tabstop>
+ <tabstop>crossLibraryMode</tabstop>
+ <tabstop>crossIncludeMode</tabstop>
+ </tabstops>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/Delete16.png b/Source/QtDialog/Delete16.png
new file mode 100644
index 000000000..16989fee1
--- /dev/null
+++ b/Source/QtDialog/Delete16.png
Binary files differ
diff --git a/Source/QtDialog/FirstConfigure.cxx b/Source/QtDialog/FirstConfigure.cxx
new file mode 100644
index 000000000..2a79877da
--- /dev/null
+++ b/Source/QtDialog/FirstConfigure.cxx
@@ -0,0 +1,509 @@
+
+#include "FirstConfigure.h"
+#include "Compilers.h"
+
+#include <QSettings>
+#include <QRadioButton>
+#include <QComboBox>
+#include <QVBoxLayout>
+
+
+StartCompilerSetup::StartCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ QVBoxLayout* l = new QVBoxLayout(this);
+ l->addWidget(new QLabel(tr("Specify the generator for this project")));
+ this->GeneratorOptions = new QComboBox(this);
+ l->addWidget(this->GeneratorOptions);
+ l->addSpacing(6);
+
+ this->CompilerSetupOptions[0] = new QRadioButton(tr("Use default native compilers"), this);
+ this->CompilerSetupOptions[1] = new QRadioButton(tr("Specify native compilers"), this);
+ this->CompilerSetupOptions[2] = new QRadioButton(tr("Specify toolchain file for cross-compiling"), this);
+ this->CompilerSetupOptions[3] = new QRadioButton(tr("Specify options for cross-compiling"), this);
+ l->addWidget(this->CompilerSetupOptions[0]);
+ l->addWidget(this->CompilerSetupOptions[1]);
+ l->addWidget(this->CompilerSetupOptions[2]);
+ l->addWidget(this->CompilerSetupOptions[3]);
+
+ this->CompilerSetupOptions[0]->setChecked(true);
+
+ QObject::connect(this->CompilerSetupOptions[0], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+ QObject::connect(this->CompilerSetupOptions[1], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+ QObject::connect(this->CompilerSetupOptions[2], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+ QObject::connect(this->CompilerSetupOptions[3], SIGNAL(toggled(bool)),
+ this, SLOT(onSelectionChanged(bool)));
+}
+
+StartCompilerSetup::~StartCompilerSetup()
+{
+}
+
+void StartCompilerSetup::setGenerators(const QStringList& gens)
+{
+ this->GeneratorOptions->clear();
+ this->GeneratorOptions->addItems(gens);
+};
+
+void StartCompilerSetup::setCurrentGenerator(const QString& gen)
+{
+ int idx = this->GeneratorOptions->findText(gen);
+ if(idx != -1)
+ {
+ this->GeneratorOptions->setCurrentIndex(idx);
+ }
+}
+
+QString StartCompilerSetup::getGenerator() const
+{
+ return this->GeneratorOptions->currentText();
+};
+
+bool StartCompilerSetup::defaultSetup() const
+{
+ return this->CompilerSetupOptions[0]->isChecked();
+}
+
+bool StartCompilerSetup::compilerSetup() const
+{
+ return this->CompilerSetupOptions[1]->isChecked();
+}
+
+bool StartCompilerSetup::crossCompilerToolChainFile() const
+{
+ return this->CompilerSetupOptions[2]->isChecked();
+}
+
+bool StartCompilerSetup::crossCompilerSetup() const
+{
+ return this->CompilerSetupOptions[3]->isChecked();
+}
+
+void StartCompilerSetup::onSelectionChanged(bool on)
+{
+ if(on)
+ selectionChanged();
+}
+
+int StartCompilerSetup::nextId() const
+{
+ if(compilerSetup())
+ return NativeSetup;
+ if(crossCompilerSetup())
+ return CrossSetup;
+ if(crossCompilerToolChainFile())
+ return ToolchainSetup;
+ return -1;
+}
+
+NativeCompilerSetup::NativeCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ QVBoxLayout* l = new QVBoxLayout(this);
+ QWidget* c = new QWidget(this);
+ l->addWidget(c);
+ this->setupUi(c);
+}
+
+NativeCompilerSetup::~NativeCompilerSetup()
+{
+}
+
+QString NativeCompilerSetup::getCCompiler() const
+{
+ return this->CCompiler->text();
+}
+
+void NativeCompilerSetup::setCCompiler(const QString& s)
+{
+ this->CCompiler->setText(s);
+}
+
+QString NativeCompilerSetup::getCXXCompiler() const
+{
+ return this->CXXCompiler->text();
+}
+
+void NativeCompilerSetup::setCXXCompiler(const QString& s)
+{
+ this->CXXCompiler->setText(s);
+}
+
+QString NativeCompilerSetup::getFortranCompiler() const
+{
+ return this->FortranCompiler->text();
+}
+
+void NativeCompilerSetup::setFortranCompiler(const QString& s)
+{
+ this->FortranCompiler->setText(s);
+}
+
+
+CrossCompilerSetup::CrossCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ this->setupUi(this);
+ QWidget::setTabOrder(systemName, systemVersion);
+ QWidget::setTabOrder(systemVersion, systemProcessor);
+ QWidget::setTabOrder(systemProcessor, CrossCompilers->CCompiler);
+ QWidget::setTabOrder(CrossCompilers->CCompiler, CrossCompilers->CXXCompiler);
+ QWidget::setTabOrder(CrossCompilers->CXXCompiler, CrossCompilers->FortranCompiler);
+ QWidget::setTabOrder(CrossCompilers->FortranCompiler, crossFindRoot);
+ QWidget::setTabOrder(crossFindRoot, crossProgramMode);
+ QWidget::setTabOrder(crossProgramMode, crossLibraryMode);
+ QWidget::setTabOrder(crossLibraryMode, crossIncludeMode);
+
+ // fill in combo boxes
+ QStringList modes;
+ modes << tr("Search in Target Root, then native system");
+ modes << tr("Search only in Target Root");
+ modes << tr("Search only in native system");
+ crossProgramMode->addItems(modes);
+ crossLibraryMode->addItems(modes);
+ crossIncludeMode->addItems(modes);
+ crossProgramMode->setCurrentIndex(2);
+ crossLibraryMode->setCurrentIndex(1);
+ crossIncludeMode->setCurrentIndex(1);
+
+ this->registerField("systemName*", this->systemName);
+}
+
+CrossCompilerSetup::~CrossCompilerSetup()
+{
+}
+
+QString CrossCompilerSetup::getCCompiler() const
+{
+ return this->CrossCompilers->CCompiler->text();
+}
+
+void CrossCompilerSetup::setCCompiler(const QString& s)
+{
+ this->CrossCompilers->CCompiler->setText(s);
+}
+
+QString CrossCompilerSetup::getCXXCompiler() const
+{
+ return this->CrossCompilers->CXXCompiler->text();
+}
+
+void CrossCompilerSetup::setCXXCompiler(const QString& s)
+{
+ this->CrossCompilers->CXXCompiler->setText(s);
+}
+
+QString CrossCompilerSetup::getFortranCompiler() const
+{
+ return this->CrossCompilers->FortranCompiler->text();
+}
+
+void CrossCompilerSetup::setFortranCompiler(const QString& s)
+{
+ this->CrossCompilers->FortranCompiler->setText(s);
+}
+
+QString CrossCompilerSetup::getSystem() const
+{
+ return this->systemName->text();
+}
+
+void CrossCompilerSetup::setSystem(const QString& t)
+{
+ this->systemName->setText(t);
+}
+
+
+QString CrossCompilerSetup::getVersion() const
+{
+ return this->systemVersion->text();
+}
+
+void CrossCompilerSetup::setVersion(const QString& t)
+{
+ this->systemVersion->setText(t);
+}
+
+
+QString CrossCompilerSetup::getProcessor() const
+{
+ return this->systemProcessor->text();
+}
+
+void CrossCompilerSetup::setProcessor(const QString& t)
+{
+ this->systemProcessor->setText(t);
+}
+
+QString CrossCompilerSetup::getFindRoot() const
+{
+ return this->crossFindRoot->text();
+}
+
+void CrossCompilerSetup::setFindRoot(const QString& t)
+{
+ return this->crossFindRoot->setText(t);
+}
+
+int CrossCompilerSetup::getProgramMode() const
+{
+ return this->crossProgramMode->currentIndex();
+}
+
+int CrossCompilerSetup::getLibraryMode() const
+{
+ return this->crossLibraryMode->currentIndex();
+}
+
+int CrossCompilerSetup::getIncludeMode() const
+{
+ return this->crossIncludeMode->currentIndex();
+}
+
+void CrossCompilerSetup::setProgramMode(int m)
+{
+ this->crossProgramMode->setCurrentIndex(m);
+}
+
+void CrossCompilerSetup::setLibraryMode(int m)
+{
+ this->crossLibraryMode->setCurrentIndex(m);
+}
+
+void CrossCompilerSetup::setIncludeMode(int m)
+{
+ this->crossIncludeMode->setCurrentIndex(m);
+}
+
+ToolchainCompilerSetup::ToolchainCompilerSetup(QWidget* p)
+ : QWizardPage(p)
+{
+ QVBoxLayout* l = new QVBoxLayout(this);
+ l->addWidget(new QLabel(tr("Specify the Toolchain file")));
+ this->ToolchainFile = new QCMakeFilePathEditor(this);
+ l->addWidget(this->ToolchainFile);
+}
+
+ToolchainCompilerSetup::~ToolchainCompilerSetup()
+{
+}
+
+QString ToolchainCompilerSetup::toolchainFile() const
+{
+ return this->ToolchainFile->text();
+}
+
+void ToolchainCompilerSetup::setToolchainFile(const QString& t)
+{
+ this->ToolchainFile->setText(t);
+}
+
+
+
+FirstConfigure::FirstConfigure()
+{
+ //this->setOption(QWizard::HaveFinishButtonOnEarlyPages, true);
+ this->mStartCompilerSetupPage = new StartCompilerSetup(this);
+ this->setPage(Start, this->mStartCompilerSetupPage);
+ QObject::connect(this->mStartCompilerSetupPage, SIGNAL(selectionChanged()),
+ this, SLOT(restart()));
+
+ this->mNativeCompilerSetupPage = new NativeCompilerSetup(this);
+ this->setPage(NativeSetup, this->mNativeCompilerSetupPage);
+
+ this->mCrossCompilerSetupPage = new CrossCompilerSetup(this);
+ this->setPage(CrossSetup, this->mCrossCompilerSetupPage);
+
+ this->mToolchainCompilerSetupPage = new ToolchainCompilerSetup(this);
+ this->setPage(ToolchainSetup, this->mToolchainCompilerSetupPage);
+}
+
+FirstConfigure::~FirstConfigure()
+{
+}
+
+void FirstConfigure::setGenerators(const QStringList& gens)
+{
+ this->mStartCompilerSetupPage->setGenerators(gens);
+}
+
+QString FirstConfigure::getGenerator() const
+{
+ return this->mStartCompilerSetupPage->getGenerator();
+}
+
+void FirstConfigure::loadFromSettings()
+{
+ QSettings settings;
+ // restore generator
+ settings.beginGroup("Settings/StartPath");
+ QString lastGen = settings.value("LastGenerator").toString();
+ this->mStartCompilerSetupPage->setCurrentGenerator(lastGen);
+ settings.endGroup();
+
+ // restore compiler setup
+ settings.beginGroup("Settings/Compiler");
+ this->mNativeCompilerSetupPage->setCCompiler(settings.value("CCompiler").toString());
+ this->mNativeCompilerSetupPage->setCXXCompiler(settings.value("CXXCompiler").toString());
+ this->mNativeCompilerSetupPage->setFortranCompiler(settings.value("FortranCompiler").toString());
+ settings.endGroup();
+
+ // restore cross compiler setup
+ settings.beginGroup("Settings/CrossCompiler");
+ this->mCrossCompilerSetupPage->setCCompiler(settings.value("CCompiler").toString());
+ this->mCrossCompilerSetupPage->setCXXCompiler(settings.value("CXXCompiler").toString());
+ this->mCrossCompilerSetupPage->setFortranCompiler(settings.value("FortranCompiler").toString());
+ this->mToolchainCompilerSetupPage->setToolchainFile(settings.value("ToolChainFile").toString());
+ this->mCrossCompilerSetupPage->setSystem(settings.value("SystemName").toString());
+ this->mCrossCompilerSetupPage->setVersion(settings.value("SystemVersion").toString());
+ this->mCrossCompilerSetupPage->setProcessor(settings.value("SystemProcessor").toString());
+ this->mCrossCompilerSetupPage->setFindRoot(settings.value("FindRoot").toString());
+ this->mCrossCompilerSetupPage->setProgramMode(settings.value("ProgramMode", 0).toInt());
+ this->mCrossCompilerSetupPage->setLibraryMode(settings.value("LibraryMode", 0).toInt());
+ this->mCrossCompilerSetupPage->setIncludeMode(settings.value("IncludeMode", 0).toInt());
+ settings.endGroup();
+}
+
+void FirstConfigure::saveToSettings()
+{
+ QSettings settings;
+
+ // save generator
+ settings.beginGroup("Settings/StartPath");
+ QString lastGen = this->mStartCompilerSetupPage->getGenerator();
+ settings.setValue("LastGenerator", lastGen);
+ settings.endGroup();
+
+ // save compiler setup
+ settings.beginGroup("Settings/Compiler");
+ settings.setValue("CCompiler", this->mNativeCompilerSetupPage->getCCompiler());
+ settings.setValue("CXXCompiler", this->mNativeCompilerSetupPage->getCXXCompiler());
+ settings.setValue("FortranCompiler", this->mNativeCompilerSetupPage->getFortranCompiler());
+ settings.endGroup();
+
+ // save cross compiler setup
+ settings.beginGroup("Settings/CrossCompiler");
+ settings.setValue("CCompiler", this->mCrossCompilerSetupPage->getCCompiler());
+ settings.setValue("CXXCompiler", this->mCrossCompilerSetupPage->getCXXCompiler());
+ settings.setValue("FortranCompiler", this->mCrossCompilerSetupPage->getFortranCompiler());
+ settings.setValue("ToolChainFile", this->getCrossCompilerToolChainFile());
+ settings.setValue("SystemName", this->mCrossCompilerSetupPage->getSystem());
+ settings.setValue("SystemVersion", this->mCrossCompilerSetupPage->getVersion());
+ settings.setValue("SystemProcessor", this->mCrossCompilerSetupPage->getProcessor());
+ settings.setValue("FindRoot", this->mCrossCompilerSetupPage->getFindRoot());
+ settings.setValue("ProgramMode", this->mCrossCompilerSetupPage->getProgramMode());
+ settings.setValue("LibraryMode", this->mCrossCompilerSetupPage->getLibraryMode());
+ settings.setValue("IncludeMode", this->mCrossCompilerSetupPage->getIncludeMode());
+ settings.endGroup();
+}
+
+bool FirstConfigure::defaultSetup() const
+{
+ return this->mStartCompilerSetupPage->defaultSetup();
+}
+
+bool FirstConfigure::compilerSetup() const
+{
+ return this->mStartCompilerSetupPage->compilerSetup();
+}
+
+bool FirstConfigure::crossCompilerSetup() const
+{
+ return this->mStartCompilerSetupPage->crossCompilerSetup();
+}
+
+bool FirstConfigure::crossCompilerToolChainFile() const
+{
+ return this->mStartCompilerSetupPage->crossCompilerToolChainFile();
+}
+
+QString FirstConfigure::getCrossCompilerToolChainFile() const
+{
+ return this->mToolchainCompilerSetupPage->toolchainFile();
+}
+
+QString FirstConfigure::getSystemName() const
+{
+ return this->mCrossCompilerSetupPage->getSystem();
+}
+
+QString FirstConfigure::getCCompiler() const
+{
+ if(this->compilerSetup())
+ {
+ return this->mNativeCompilerSetupPage->getCCompiler();
+ }
+ else if(this->crossCompilerSetup())
+ {
+ return this->mCrossCompilerSetupPage->getCCompiler();
+ }
+ return QString();
+}
+
+QString FirstConfigure::getCXXCompiler() const
+{
+ if(this->compilerSetup())
+ {
+ return this->mNativeCompilerSetupPage->getCXXCompiler();
+ }
+ else if(this->crossCompilerSetup())
+ {
+ return this->mCrossCompilerSetupPage->getCXXCompiler();
+ }
+ return QString();
+}
+
+QString FirstConfigure::getFortranCompiler() const
+{
+ if(this->compilerSetup())
+ {
+ return this->mNativeCompilerSetupPage->getFortranCompiler();
+ }
+ else if(this->crossCompilerSetup())
+ {
+ return this->mCrossCompilerSetupPage->getFortranCompiler();
+ }
+ return QString();
+}
+
+
+QString FirstConfigure::getSystemVersion() const
+{
+ return this->mCrossCompilerSetupPage->getVersion();
+}
+
+QString FirstConfigure::getSystemProcessor() const
+{
+ return this->mCrossCompilerSetupPage->getProcessor();
+}
+
+QString FirstConfigure::getCrossRoot() const
+{
+ return this->mCrossCompilerSetupPage->getFindRoot();
+}
+
+const QString CrossModes[] =
+{
+ "BOTH",
+ "ONLY",
+ "NEVER"
+};
+
+QString FirstConfigure::getCrossProgramMode() const
+{
+ return CrossModes[this->mCrossCompilerSetupPage->getProgramMode()];
+}
+
+QString FirstConfigure::getCrossLibraryMode() const
+{
+ return CrossModes[this->mCrossCompilerSetupPage->getLibraryMode()];
+}
+
+QString FirstConfigure::getCrossIncludeMode() const
+{
+ return CrossModes[this->mCrossCompilerSetupPage->getIncludeMode()];
+}
+
diff --git a/Source/QtDialog/FirstConfigure.h b/Source/QtDialog/FirstConfigure.h
new file mode 100644
index 000000000..f4e368bfc
--- /dev/null
+++ b/Source/QtDialog/FirstConfigure.h
@@ -0,0 +1,177 @@
+
+#ifndef FirstConfigure_h
+#define FirstConfigure_h
+
+#include <QWizard>
+#include <QWizardPage>
+#include "ui_Compilers.h"
+#include "ui_CrossCompiler.h"
+
+class QRadioButton;
+class QComboBox;
+
+//! the wizard pages we'll use for the first configure of a build
+enum FirstConfigurePages
+{
+ Start,
+ NativeSetup,
+ ToolchainSetup,
+ CrossSetup,
+ Done
+};
+
+//! the first page that gives basic options for what compilers setup to choose from
+class StartCompilerSetup : public QWizardPage
+{
+ Q_OBJECT
+ public:
+ StartCompilerSetup(QWidget* p);
+ ~StartCompilerSetup();
+ void setGenerators(const QStringList& gens);
+ void setCurrentGenerator(const QString& gen);
+ QString getGenerator() const;
+
+ bool defaultSetup() const;
+ bool compilerSetup() const;
+ bool crossCompilerSetup() const;
+ bool crossCompilerToolChainFile() const;
+
+ int nextId() const;
+
+ signals:
+ void selectionChanged();
+
+ protected slots:
+ void onSelectionChanged(bool);
+
+ protected:
+ QComboBox* GeneratorOptions;
+ QRadioButton* CompilerSetupOptions[4];
+};
+
+//! the page that gives basic options for native compilers
+class NativeCompilerSetup : public QWizardPage, protected Ui::Compilers
+{
+ Q_OBJECT
+ public:
+ NativeCompilerSetup(QWidget* p);
+ ~NativeCompilerSetup();
+
+ QString getCCompiler() const;
+ void setCCompiler(const QString&);
+
+ QString getCXXCompiler() const;
+ void setCXXCompiler(const QString&);
+
+ QString getFortranCompiler() const;
+ void setFortranCompiler(const QString&);
+
+ int nextId() const { return -1; }
+};
+
+//! the page that gives options for cross compilers
+class CrossCompilerSetup : public QWizardPage, protected Ui::CrossCompiler
+{
+ Q_OBJECT
+ public:
+ CrossCompilerSetup(QWidget* p);
+ ~CrossCompilerSetup();
+
+ QString getSystem() const;
+ void setSystem(const QString&);
+
+ QString getVersion() const;
+ void setVersion(const QString&);
+
+ QString getProcessor() const;
+ void setProcessor(const QString&);
+
+ QString getCCompiler() const;
+ void setCCompiler(const QString&);
+
+ QString getCXXCompiler() const;
+ void setCXXCompiler(const QString&);
+
+ QString getFortranCompiler() const;
+ void setFortranCompiler(const QString&);
+
+ QString getFindRoot() const;
+ void setFindRoot(const QString&);
+
+ enum CrossMode
+ {
+ BOTH,
+ ONLY,
+ NEVER
+ };
+
+ int getProgramMode() const;
+ void setProgramMode(int);
+ int getLibraryMode() const;
+ void setLibraryMode(int);
+ int getIncludeMode() const;
+ void setIncludeMode(int);
+
+ int nextId() const { return -1; }
+};
+
+//! the page that gives options for a toolchain file
+class ToolchainCompilerSetup : public QWizardPage
+{
+ Q_OBJECT
+ public:
+ ToolchainCompilerSetup(QWidget* p);
+ ~ToolchainCompilerSetup();
+
+ QString toolchainFile() const;
+ void setToolchainFile(const QString&);
+
+ int nextId() const { return -1; }
+
+ protected:
+ QCMakeFilePathEditor* ToolchainFile;
+};
+
+//! the wizard with the pages
+class FirstConfigure : public QWizard
+{
+ Q_OBJECT
+public:
+ FirstConfigure();
+ ~FirstConfigure();
+
+ void setGenerators(const QStringList& gens);
+ QString getGenerator() const;
+
+ bool defaultSetup() const;
+ bool compilerSetup() const;
+ bool crossCompilerSetup() const;
+ bool crossCompilerToolChainFile() const;
+
+ QString getCCompiler() const;
+ QString getCXXCompiler() const;
+ QString getFortranCompiler() const;
+
+ QString getSystemName() const;
+ QString getSystemVersion() const;
+ QString getSystemProcessor() const;
+ QString getCrossRoot() const;
+ QString getCrossProgramMode() const;
+ QString getCrossLibraryMode() const;
+ QString getCrossIncludeMode() const;
+
+ QString getCrossCompilerToolChainFile() const;
+
+ void loadFromSettings();
+ void saveToSettings();
+
+protected:
+ StartCompilerSetup* mStartCompilerSetupPage;
+ NativeCompilerSetup* mNativeCompilerSetupPage;
+ CrossCompilerSetup* mCrossCompilerSetupPage;
+ ToolchainCompilerSetup* mToolchainCompilerSetupPage;
+
+};
+
+#endif // FirstConfigure_h
+
diff --git a/Source/QtDialog/MacInstallDialog.ui b/Source/QtDialog/MacInstallDialog.ui
new file mode 100644
index 000000000..c7e31dbbe
--- /dev/null
+++ b/Source/QtDialog/MacInstallDialog.ui
@@ -0,0 +1,103 @@
+<ui version="4.0" >
+ <class>Dialog</class>
+ <widget class="QDialog" name="Dialog" >
+ <property name="geometry" >
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>470</width>
+ <height>159</height>
+ </rect>
+ </property>
+ <property name="windowTitle" >
+ <string>Install Command Line Tools</string>
+ </property>
+ <layout class="QGridLayout" >
+ <property name="margin" >
+ <number>9</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item row="3" column="1" >
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Vertical</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>20</width>
+ <height>40</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item row="2" column="0" colspan="3" >
+ <layout class="QHBoxLayout" >
+ <property name="margin" >
+ <number>0</number>
+ </property>
+ <property name="spacing" >
+ <number>6</number>
+ </property>
+ <item>
+ <spacer>
+ <property name="orientation" >
+ <enum>Qt::Horizontal</enum>
+ </property>
+ <property name="sizeHint" >
+ <size>
+ <width>40</width>
+ <height>20</height>
+ </size>
+ </property>
+ </spacer>
+ </item>
+ <item>
+ <widget class="QPushButton" name="skipInstallButton" >
+ <property name="text" >
+ <string>Skip Install Command Line </string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QPushButton" name="doInstallButton" >
+ <property name="text" >
+ <string>Install Command Line Links</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="0" column="2" >
+ <widget class="QPushButton" name="choosePathButton" >
+ <property name="text" >
+ <string>Choose...</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="0" >
+ <widget class="QLabel" name="label" >
+ <property name="text" >
+ <string>Install Folder:</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1" >
+ <widget class="QLineEdit" name="InstallPrefix" />
+ </item>
+ <item row="1" column="0" colspan="3" >
+ <widget class="QLabel" name="label_2" >
+ <property name="text" >
+ <string>This will create symbolic links to the command line tools of cmake into the specified install folder.</string>
+ </property>
+ <property name="wordWrap" >
+ <bool>true</bool>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/Source/QtDialog/Plus16.png b/Source/QtDialog/Plus16.png
new file mode 100644
index 000000000..552f6f004
--- /dev/null
+++ b/Source/QtDialog/Plus16.png
Binary files differ
diff --git a/Source/QtDialog/QCMake.cxx b/Source/QtDialog/QCMake.cxx
new file mode 100644
index 000000000..8554ff894
--- /dev/null
+++ b/Source/QtDialog/QCMake.cxx
@@ -0,0 +1,448 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "QCMake.h"
+
+#include <QDir>
+#include <QCoreApplication>
+
+#include "cmake.h"
+#include "cmCacheManager.h"
+#include "cmSystemTools.h"
+#include "cmExternalMakefileProjectGenerator.h"
+
+#ifdef Q_OS_WIN
+#include "qt_windows.h" // For SetErrorMode
+#endif
+
+QCMake::QCMake(QObject* p)
+ : QObject(p)
+{
+ this->SuppressDevWarnings = false;
+ this->WarnUninitializedMode = false;
+ this->WarnUnusedMode = false;
+ qRegisterMetaType<QCMakeProperty>();
+ qRegisterMetaType<QCMakePropertyList>();
+
+ QDir execDir(QCoreApplication::applicationDirPath());
+
+#if defined(Q_OS_MAC)
+ if(execDir.exists("../bin/cmake"))
+ {
+ execDir.cd("../bin");
+ }
+ else
+ {
+ execDir.cd("../../../"); // path to cmake in build directory (need to fix for deployment)
+ }
+#endif
+
+ QString cmakeCommand = QString("cmake")+QString::fromLocal8Bit(cmSystemTools::GetExecutableExtension());
+ cmakeCommand = execDir.filePath(cmakeCommand);
+
+ cmSystemTools::DisableRunCommandOutput();
+ cmSystemTools::SetRunCommandHideConsole(true);
+ cmSystemTools::SetErrorCallback(QCMake::errorCallback, this);
+ cmSystemTools::FindExecutableDirectory(cmakeCommand.toLocal8Bit().data());
+
+ this->CMakeInstance = new cmake;
+ this->CMakeInstance->SetCMakeCommand(cmakeCommand.toLocal8Bit().data());
+#if defined(Q_OS_MAC)
+ this->CMakeInstance->SetCMakeEditCommand("cmake-gui.app/Contents/MacOS/cmake-gui");
+#else
+ this->CMakeInstance->SetCMakeEditCommand("cmake-gui");
+#endif
+ this->CMakeInstance->SetProgressCallback(QCMake::progressCallback, this);
+
+ cmSystemTools::SetInterruptCallback(QCMake::interruptCallback, this);
+
+ std::vector<std::string> generators;
+ this->CMakeInstance->GetRegisteredGenerators(generators);
+ std::vector<std::string>::iterator iter;
+ for(iter = generators.begin(); iter != generators.end(); ++iter)
+ {
+ // Skip the generator "KDevelop3", since there is also
+ // "KDevelop3 - Unix Makefiles", which is the full and official name.
+ // The short name is actually only still there since this was the name
+ // in CMake 2.4, to keep "command line argument compatibility", but
+ // this is not necessary in the GUI.
+ if (*iter == "KDevelop3")
+ {
+ continue;
+ }
+ this->AvailableGenerators.append(QString::fromLocal8Bit(iter->c_str()));
+ }
+}
+
+QCMake::~QCMake()
+{
+ delete this->CMakeInstance;
+ //cmDynamicLoader::FlushCache();
+}
+
+void QCMake::loadCache(const QString& dir)
+{
+ this->setBinaryDirectory(dir);
+}
+
+void QCMake::setSourceDirectory(const QString& _dir)
+{
+ QString dir =
+ QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str());
+ if(this->SourceDirectory != dir)
+ {
+ this->SourceDirectory = QDir::fromNativeSeparators(dir);
+ emit this->sourceDirChanged(this->SourceDirectory);
+ }
+}
+
+void QCMake::setBinaryDirectory(const QString& _dir)
+{
+ QString dir =
+ QString::fromLocal8Bit(cmSystemTools::GetActualCaseForPath(_dir.toLocal8Bit().data()).c_str());
+ if(this->BinaryDirectory != dir)
+ {
+ this->BinaryDirectory = QDir::fromNativeSeparators(dir);
+ emit this->binaryDirChanged(this->BinaryDirectory);
+ cmCacheManager *cachem = this->CMakeInstance->GetCacheManager();
+ this->setGenerator(QString());
+ if(!this->CMakeInstance->GetCacheManager()->LoadCache(
+ this->BinaryDirectory.toLocal8Bit().data()))
+ {
+ QDir testDir(this->BinaryDirectory);
+ if(testDir.exists("CMakeCache.txt"))
+ {
+ cmSystemTools::Error("There is a CMakeCache.txt file for the current binary "
+ "tree but cmake does not have permission to read it. "
+ "Please check the permissions of the directory you are trying to run CMake on.");
+ }
+ }
+
+ QCMakePropertyList props = this->properties();
+ emit this->propertiesChanged(props);
+ cmCacheManager::CacheIterator itm = cachem->NewIterator();
+ if ( itm.Find("CMAKE_HOME_DIRECTORY"))
+ {
+ setSourceDirectory(QString::fromLocal8Bit(itm.GetValue()));
+ }
+ if ( itm.Find("CMAKE_GENERATOR"))
+ {
+ const char* extraGen = cachem->GetCacheValue("CMAKE_EXTRA_GENERATOR");
+ std::string curGen = cmExternalMakefileProjectGenerator::
+ CreateFullGeneratorName(itm.GetValue(), extraGen);
+ this->setGenerator(QString::fromLocal8Bit(curGen.c_str()));
+ }
+ }
+}
+
+
+void QCMake::setGenerator(const QString& gen)
+{
+ if(this->Generator != gen)
+ {
+ this->Generator = gen;
+ emit this->generatorChanged(this->Generator);
+ }
+}
+
+void QCMake::configure()
+{
+#ifdef Q_OS_WIN
+ UINT lastErrorMode = SetErrorMode(0);
+#endif
+
+ this->CMakeInstance->SetHomeDirectory(this->SourceDirectory.toLocal8Bit().data());
+ this->CMakeInstance->SetStartDirectory(this->SourceDirectory.toLocal8Bit().data());
+ this->CMakeInstance->SetHomeOutputDirectory(this->BinaryDirectory.toLocal8Bit().data());
+ this->CMakeInstance->SetStartOutputDirectory(this->BinaryDirectory.toLocal8Bit().data());
+ this->CMakeInstance->SetGlobalGenerator(
+ this->CMakeInstance->CreateGlobalGenerator(this->Generator.toLocal8Bit().data()));
+ this->CMakeInstance->LoadCache();
+ this->CMakeInstance->SetSuppressDevWarnings(this->SuppressDevWarnings);
+ this->CMakeInstance->SetWarnUninitialized(this->WarnUninitializedMode);
+ this->CMakeInstance->SetWarnUnused(this->WarnUnusedMode);
+ this->CMakeInstance->PreLoadCMakeFiles();
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ int err = this->CMakeInstance->Configure();
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->propertiesChanged(this->properties());
+ emit this->configureDone(err);
+}
+
+void QCMake::generate()
+{
+#ifdef Q_OS_WIN
+ UINT lastErrorMode = SetErrorMode(0);
+#endif
+
+ InterruptFlag = 0;
+ cmSystemTools::ResetErrorOccuredFlag();
+
+ int err = this->CMakeInstance->Generate();
+
+#ifdef Q_OS_WIN
+ SetErrorMode(lastErrorMode);
+#endif
+
+ emit this->generateDone(err);
+}
+
+void QCMake::setProperties(const QCMakePropertyList& newProps)
+{
+ QCMakePropertyList props = newProps;
+
+ QStringList toremove;
+
+ // set the value of properties
+ 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;
+ }
+
+ QCMakeProperty prop;
+ prop.Key = QString::fromLocal8Bit(i.GetName());
+ int idx = props.indexOf(prop);
+ if(idx == -1)
+ {
+ toremove.append(QString::fromLocal8Bit(i.GetName()));
+ }
+ else
+ {
+ prop = props[idx];
+ if(prop.Value.type() == QVariant::Bool)
+ {
+ i.SetValue(prop.Value.toBool() ? "ON" : "OFF");
+ }
+ else
+ {
+ i.SetValue(prop.Value.toString().toLocal8Bit().data());
+ }
+ props.removeAt(idx);
+ }
+
+ }
+
+ // remove some properites
+ foreach(QString s, toremove)
+ {
+ this->CMakeInstance->UnwatchUnusedCli(s.toLocal8Bit().data());
+
+ cachem->RemoveCacheEntry(s.toLocal8Bit().data());
+ }
+
+ // add some new properites
+ foreach(QCMakeProperty s, props)
+ {
+ this->CMakeInstance->WatchUnusedCli(s.Key.toLocal8Bit().data());
+
+ if(s.Type == QCMakeProperty::BOOL)
+ {
+ this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
+ s.Value.toBool() ? "ON" : "OFF",
+ s.Help.toLocal8Bit().data(),
+ cmCacheManager::BOOL);
+ }
+ else if(s.Type == QCMakeProperty::STRING)
+ {
+ this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
+ s.Value.toString().toLocal8Bit().data(),
+ s.Help.toLocal8Bit().data(),
+ cmCacheManager::STRING);
+ }
+ else if(s.Type == QCMakeProperty::PATH)
+ {
+ this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
+ s.Value.toString().toLocal8Bit().data(),
+ s.Help.toLocal8Bit().data(),
+ cmCacheManager::PATH);
+ }
+ else if(s.Type == QCMakeProperty::FILEPATH)
+ {
+ this->CMakeInstance->AddCacheEntry(s.Key.toLocal8Bit().data(),
+ s.Value.toString().toLocal8Bit().data(),
+ s.Help.toLocal8Bit().data(),
+ cmCacheManager::FILEPATH);
+ }
+ }
+
+ cachem->SaveCache(this->BinaryDirectory.toLocal8Bit().data());
+}
+
+QCMakePropertyList QCMake::properties() const
+{
+ QCMakePropertyList 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 ||
+ i.GetType() == cmCacheManager::UNINITIALIZED)
+ {
+ continue;
+ }
+
+ QCMakeProperty prop;
+ prop.Key = QString::fromLocal8Bit(i.GetName());
+ prop.Help = QString::fromLocal8Bit(i.GetProperty("HELPSTRING"));
+ prop.Value = QString::fromLocal8Bit(i.GetValue());
+ prop.Advanced = i.GetPropertyAsBool("ADVANCED");
+
+ if(i.GetType() == cmCacheManager::BOOL)
+ {
+ prop.Type = QCMakeProperty::BOOL;
+ prop.Value = cmSystemTools::IsOn(i.GetValue());
+ }
+ else if(i.GetType() == cmCacheManager::PATH)
+ {
+ prop.Type = QCMakeProperty::PATH;
+ }
+ else if(i.GetType() == cmCacheManager::FILEPATH)
+ {
+ prop.Type = QCMakeProperty::FILEPATH;
+ }
+ else if(i.GetType() == cmCacheManager::STRING)
+ {
+ prop.Type = QCMakeProperty::STRING;
+ if (i.PropertyExists("STRINGS"))
+ {
+ prop.Strings = QString::fromLocal8Bit(i.GetProperty("STRINGS")).split(";");
+ }
+ }
+
+ ret.append(prop);
+ }
+
+ return ret;
+}
+
+void QCMake::interrupt()
+{
+ this->InterruptFlag.ref();
+}
+
+bool QCMake::interruptCallback(void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ return self->InterruptFlag;
+}
+
+void QCMake::progressCallback(const char* msg, float percent, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ if(percent >= 0)
+ {
+ emit self->progressChanged(QString::fromLocal8Bit(msg), percent);
+ }
+ else
+ {
+ emit self->outputMessage(QString::fromLocal8Bit(msg));
+ }
+ QCoreApplication::processEvents();
+}
+
+void QCMake::errorCallback(const char* msg, const char* /*title*/,
+ bool& /*stop*/, void* cd)
+{
+ QCMake* self = reinterpret_cast<QCMake*>(cd);
+ emit self->errorMessage(QString::fromLocal8Bit(msg));
+ QCoreApplication::processEvents();
+}
+
+QString QCMake::binaryDirectory() const
+{
+ return this->BinaryDirectory;
+}
+
+QString QCMake::sourceDirectory() const
+{
+ return this->SourceDirectory;
+}
+
+QString QCMake::generator() const
+{
+ return this->Generator;
+}
+
+QStringList QCMake::availableGenerators() const
+{
+ return this->AvailableGenerators;
+}
+
+void QCMake::deleteCache()
+{
+ // delete cache
+ this->CMakeInstance->GetCacheManager()->DeleteCache(this->BinaryDirectory.toLocal8Bit().data());
+ // reload to make our cache empty
+ this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ // emit no generator and no properties
+ this->setGenerator(QString());
+ QCMakePropertyList props = this->properties();
+ emit this->propertiesChanged(props);
+}
+
+void QCMake::reloadCache()
+{
+ // emit that the cache was cleaned out
+ QCMakePropertyList props;
+ emit this->propertiesChanged(props);
+ // reload
+ this->CMakeInstance->GetCacheManager()->LoadCache(this->BinaryDirectory.toLocal8Bit().data());
+ // emit new cache properties
+ props = this->properties();
+ emit this->propertiesChanged(props);
+}
+
+void QCMake::setDebugOutput(bool flag)
+{
+ if(flag != this->CMakeInstance->GetDebugOutput())
+ {
+ this->CMakeInstance->SetDebugOutputOn(flag);
+ emit this->debugOutputChanged(flag);
+ }
+}
+
+bool QCMake::getDebugOutput() const
+{
+ return this->CMakeInstance->GetDebugOutput();
+}
+
+
+void QCMake::setSuppressDevWarnings(bool value)
+{
+ this->SuppressDevWarnings = value;
+}
+
+void QCMake::setWarnUninitializedMode(bool value)
+{
+ this->WarnUninitializedMode = value;
+}
+
+void QCMake::setWarnUnusedMode(bool value)
+{
+ this->WarnUnusedMode = value;
+}
diff --git a/Source/QtDialog/QCMake.h b/Source/QtDialog/QCMake.h
new file mode 100644
index 000000000..0d68586f2
--- /dev/null
+++ b/Source/QtDialog/QCMake.h
@@ -0,0 +1,154 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef __QCMake_h
+#define __QCMake_h
+#ifdef _MSC_VER
+#pragma warning ( disable : 4127 )
+#pragma warning ( disable : 4512 )
+#endif
+
+#include <QObject>
+#include <QString>
+#include <QVariant>
+#include <QList>
+#include <QStringList>
+#include <QMetaType>
+#include <QAtomicInt>
+
+class cmake;
+
+/// struct to represent cmake properties in Qt
+/// Value is of type String or Bool
+struct QCMakeProperty
+{
+ enum PropertyType { BOOL, PATH, FILEPATH, STRING };
+ QString Key;
+ QVariant Value;
+ QStringList Strings;
+ QString Help;
+ PropertyType Type;
+ bool Advanced;
+ bool operator==(const QCMakeProperty& other) const
+ {
+ return this->Key == other.Key;
+ }
+ bool operator<(const QCMakeProperty& other) const
+ {
+ return this->Key < other.Key;
+ }
+};
+
+// list of properties
+typedef QList<QCMakeProperty> QCMakePropertyList;
+
+// allow QVariant to be a property or list of properties
+Q_DECLARE_METATYPE(QCMakeProperty)
+Q_DECLARE_METATYPE(QCMakePropertyList)
+
+/// 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:
+ /// 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 QCMakePropertyList&);
+ /// interrupt the configure or generate process (if connecting, make a direct connection)
+ void interrupt();
+ /// delete the cache in binary directory
+ void deleteCache();
+ /// reload the cache in binary directory
+ void reloadCache();
+ /// set whether to do debug output
+ void setDebugOutput(bool);
+ /// set whether to do suppress dev warnings
+ void setSuppressDevWarnings(bool value);
+ /// set whether to run cmake with warnings about uninitialized variables
+ void setWarnUninitializedMode(bool value);
+ /// set whether to run cmake with warnings about unused variables
+ void setWarnUnusedMode(bool value);
+
+public:
+ /// get the list of cache properties
+ QCMakePropertyList properties() const;
+ /// get the current binary directory
+ QString binaryDirectory() const;
+ /// get the current source directory
+ QString sourceDirectory() const;
+ /// get the current generator
+ QString generator() const;
+ /// get the available generators
+ QStringList availableGenerators() const;
+ /// get whether to do debug output
+ bool getDebugOutput() const;
+
+signals:
+ /// signal when properties change (during read from disk or configure process)
+ void propertiesChanged(const QCMakePropertyList& vars);
+ /// signal when the generator changes
+ void generatorChanged(const QString& gen);
+ /// signal when the source directory changes (binary directory already
+ /// containing a CMakeCache.txt file)
+ void sourceDirChanged(const QString& dir);
+ /// signal when the binary directory changes
+ void binaryDirChanged(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);
+ /// signal when there is an output message
+ void outputMessage(const QString& msg);
+ /// signal when there is an error message
+ void errorMessage(const QString& msg);
+ /// signal when debug output changes
+ void debugOutputChanged(bool);
+
+protected:
+ cmake* CMakeInstance;
+
+ static bool interruptCallback(void*);
+ static void progressCallback(const char* msg, float percent, void* cd);
+ static void errorCallback(const char* msg, const char* title,
+ bool&, void* cd);
+ bool SuppressDevWarnings;
+ bool WarnUninitializedMode;
+ bool WarnUnusedMode;
+ bool WarnUnusedAllMode;
+ QString SourceDirectory;
+ QString BinaryDirectory;
+ QString Generator;
+ QStringList AvailableGenerators;
+ QString CMakeExecutable;
+ QAtomicInt InterruptFlag;
+};
+
+#endif // __QCMake_h
+
diff --git a/Source/QtDialog/QCMakeCacheView.cxx b/Source/QtDialog/QCMakeCacheView.cxx
new file mode 100644
index 000000000..72e9b2464
--- /dev/null
+++ b/Source/QtDialog/QCMakeCacheView.cxx
@@ -0,0 +1,735 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "QCMakeCacheView.h"
+
+#include <QHBoxLayout>
+#include <QHeaderView>
+#include <QEvent>
+#include <QStyle>
+#include <QKeyEvent>
+#include <QSortFilterProxyModel>
+#include <QMetaProperty>
+#include <QApplication>
+
+#include "QCMakeWidgets.h"
+
+// filter for searches
+class QCMakeSearchFilter : public QSortFilterProxyModel
+{
+public:
+ QCMakeSearchFilter(QObject* o) : QSortFilterProxyModel(o) {}
+protected:
+ bool filterAcceptsRow(int row, const QModelIndex& p) const
+ {
+ QStringList strs;
+ const QAbstractItemModel* m = this->sourceModel();
+ QModelIndex idx = m->index(row, 0, p);
+
+ // if there are no children, get strings for column 0 and 1
+ if(!m->hasChildren(idx))
+ {
+ strs.append(m->data(idx).toString());
+ idx = m->index(row, 1, p);
+ strs.append(m->data(idx).toString());
+ }
+ else
+ {
+ // get strings for children entries to compare with
+ // instead of comparing with the parent
+ int num = m->rowCount(idx);
+ for(int i=0; i<num; i++)
+ {
+ QModelIndex tmpidx = m->index(i, 0, idx);
+ strs.append(m->data(tmpidx).toString());
+ tmpidx = m->index(i, 1, idx);
+ strs.append(m->data(tmpidx).toString());
+ }
+ }
+
+ // check all strings for a match
+ foreach(QString str, strs)
+ {
+ if(str.contains(this->filterRegExp()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+};
+
+// filter for searches
+class QCMakeAdvancedFilter : public QSortFilterProxyModel
+{
+public:
+ QCMakeAdvancedFilter(QObject* o)
+ : QSortFilterProxyModel(o), ShowAdvanced(false) {}
+
+ void setShowAdvanced(bool f)
+ {
+ this->ShowAdvanced = f;
+ this->invalidate();
+ }
+ bool showAdvanced() const { return this->ShowAdvanced; }
+
+protected:
+
+ bool ShowAdvanced;
+
+ bool filterAcceptsRow(int row, const QModelIndex& p) const
+ {
+ const QAbstractItemModel* m = this->sourceModel();
+ QModelIndex idx = m->index(row, 0, p);
+
+ // if there are no children
+ if(!m->hasChildren(idx))
+ {
+ bool adv = m->data(idx, QCMakeCacheModel::AdvancedRole).toBool();
+ if(!adv || (adv && this->ShowAdvanced))
+ {
+ return true;
+ }
+ return false;
+ }
+
+ // check children
+ int num = m->rowCount(idx);
+ for(int i=0; i<num; i++)
+ {
+ bool accept = this->filterAcceptsRow(i, idx);
+ if(accept)
+ {
+ return true;
+ }
+ }
+ return false;
+ }
+};
+
+QCMakeCacheView::QCMakeCacheView(QWidget* p)
+ : QTreeView(p)
+{
+ // hook up our model and search/filter proxies
+ this->CacheModel = new QCMakeCacheModel(this);
+ this->AdvancedFilter = new QCMakeAdvancedFilter(this);
+ this->AdvancedFilter->setSourceModel(this->CacheModel);
+ this->AdvancedFilter->setDynamicSortFilter(true);
+ this->SearchFilter = new QCMakeSearchFilter(this);
+ this->SearchFilter->setSourceModel(this->AdvancedFilter);
+ this->SearchFilter->setFilterCaseSensitivity(Qt::CaseInsensitive);
+ this->SearchFilter->setDynamicSortFilter(true);
+ this->setModel(this->SearchFilter);
+
+ // our delegate for creating our editors
+ QCMakeCacheModelDelegate* delegate = new QCMakeCacheModelDelegate(this);
+ this->setItemDelegate(delegate);
+
+ this->setUniformRowHeights(true);
+
+ this->setEditTriggers(QAbstractItemView::AllEditTriggers);
+
+ // tab, backtab doesn't step through items
+ this->setTabKeyNavigation(false);
+
+ this->setRootIsDecorated(false);
+}
+
+bool QCMakeCacheView::event(QEvent* e)
+{
+ if(e->type() == QEvent::Show)
+ {
+ this->header()->setDefaultSectionSize(this->viewport()->width()/2);
+ }
+ return QTreeView::event(e);
+}
+
+QCMakeCacheModel* QCMakeCacheView::cacheModel() const
+{
+ return this->CacheModel;
+}
+
+QModelIndex QCMakeCacheView::moveCursor(CursorAction act,
+ Qt::KeyboardModifiers mod)
+{
+ // want home/end to go to begin/end of rows, not columns
+ if(act == MoveHome)
+ {
+ return this->model()->index(0, 1);
+ }
+ else if(act == MoveEnd)
+ {
+ return this->model()->index(this->model()->rowCount()-1, 1);
+ }
+ return QTreeView::moveCursor(act, mod);
+}
+
+void QCMakeCacheView::setShowAdvanced(bool s)
+{
+#if QT_VERSION >= 040300
+ // new 4.3 api that needs to be called. what about an older Qt?
+ this->SearchFilter->invalidate();
+#endif
+
+ this->AdvancedFilter->setShowAdvanced(s);
+}
+
+bool QCMakeCacheView::showAdvanced() const
+{
+ return this->AdvancedFilter->showAdvanced();
+}
+
+void QCMakeCacheView::setSearchFilter(const QString& s)
+{
+ this->SearchFilter->setFilterFixedString(s);
+}
+
+QCMakeCacheModel::QCMakeCacheModel(QObject* p)
+ : QStandardItemModel(p),
+ EditEnabled(true),
+ NewPropertyCount(0),
+ View(FlatView)
+{
+ this->ShowNewProperties = true;
+ QStringList labels;
+ labels << tr("Name") << tr("Value");
+ this->setHorizontalHeaderLabels(labels);
+}
+
+QCMakeCacheModel::~QCMakeCacheModel()
+{
+}
+
+static uint qHash(const QCMakeProperty& p)
+{
+ return qHash(p.Key);
+}
+
+void QCMakeCacheModel::setShowNewProperties(bool f)
+{
+ this->ShowNewProperties = f;
+}
+
+void QCMakeCacheModel::clear()
+{
+ this->QStandardItemModel::clear();
+ this->NewPropertyCount = 0;
+
+ QStringList labels;
+ labels << tr("Name") << tr("Value");
+ this->setHorizontalHeaderLabels(labels);
+}
+
+void QCMakeCacheModel::setProperties(const QCMakePropertyList& props)
+{
+ QSet<QCMakeProperty> newProps, newProps2;
+
+ if(this->ShowNewProperties)
+ {
+ newProps = props.toSet();
+ newProps2 = newProps;
+ QSet<QCMakeProperty> oldProps = this->properties().toSet();
+ oldProps.intersect(newProps);
+ newProps.subtract(oldProps);
+ newProps2.subtract(newProps);
+ }
+ else
+ {
+ newProps2 = props.toSet();
+ }
+
+ bool b = this->blockSignals(true);
+
+ this->clear();
+ this->NewPropertyCount = newProps.size();
+
+ if(View == FlatView)
+ {
+ QCMakePropertyList newP = newProps.toList();
+ QCMakePropertyList newP2 = newProps2.toList();
+ qSort(newP);
+ qSort(newP2);
+ int row_count = 0;
+ foreach(QCMakeProperty p, newP)
+ {
+ this->insertRow(row_count);
+ this->setPropertyData(this->index(row_count, 0), p, true);
+ row_count++;
+ }
+ foreach(QCMakeProperty p, newP2)
+ {
+ this->insertRow(row_count);
+ this->setPropertyData(this->index(row_count, 0), p, false);
+ row_count++;
+ }
+ }
+ else if(this->View == GroupView)
+ {
+ QMap<QString, QCMakePropertyList> newPropsTree;
+ this->breakProperties(newProps, newPropsTree);
+ QMap<QString, QCMakePropertyList> newPropsTree2;
+ this->breakProperties(newProps2, newPropsTree2);
+
+ QStandardItem* root = this->invisibleRootItem();
+
+ foreach(QString key, newPropsTree.keys())
+ {
+ QCMakePropertyList props2 = newPropsTree[key];
+
+ QList<QStandardItem*> parentItems;
+ parentItems.append(
+ new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key)
+ );
+ parentItems.append(new QStandardItem());
+ parentItems[0]->setData(QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ parentItems[1]->setData(QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ parentItems[0]->setData(1, GroupRole);
+ parentItems[1]->setData(1, GroupRole);
+ root->appendRow(parentItems);
+
+ int num = props2.size();
+ for(int i=0; i<num; i++)
+ {
+ QCMakeProperty prop = props2[i];
+ QList<QStandardItem*> items;
+ items.append(new QStandardItem());
+ items.append(new QStandardItem());
+ parentItems[0]->appendRow(items);
+ this->setPropertyData(this->indexFromItem(items[0]), prop, true);
+ }
+ }
+
+ foreach(QString key, newPropsTree2.keys())
+ {
+ QCMakePropertyList props2 = newPropsTree2[key];
+
+ QStandardItem* parentItem =
+ new QStandardItem(key.isEmpty() ? tr("Ungrouped Entries") : key);
+ root->appendRow(parentItem);
+ parentItem->setData(1, GroupRole);
+
+ int num = props2.size();
+ for(int i=0; i<num; i++)
+ {
+ QCMakeProperty prop = props2[i];
+ QList<QStandardItem*> items;
+ items.append(new QStandardItem());
+ items.append(new QStandardItem());
+ parentItem->appendRow(items);
+ this->setPropertyData(this->indexFromItem(items[0]), prop, false);
+ }
+ }
+ }
+
+ this->blockSignals(b);
+ this->reset();
+}
+
+QCMakeCacheModel::ViewType QCMakeCacheModel::viewType() const
+{
+ return this->View;
+}
+
+void QCMakeCacheModel::setViewType(QCMakeCacheModel::ViewType t)
+{
+ this->View = t;
+
+ QCMakePropertyList props = this->properties();
+ QCMakePropertyList oldProps;
+ int numNew = this->NewPropertyCount;
+ int numTotal = props.count();
+ for(int i=numNew; i<numTotal; i++)
+ {
+ oldProps.append(props[i]);
+ }
+
+ bool b = this->blockSignals(true);
+ this->clear();
+ this->setProperties(oldProps);
+ this->setProperties(props);
+ this->blockSignals(b);
+ this->reset();
+}
+
+void QCMakeCacheModel::setPropertyData(const QModelIndex& idx1,
+ const QCMakeProperty& prop, bool isNew)
+{
+ QModelIndex idx2 = idx1.sibling(idx1.row(), 1);
+
+ this->setData(idx1, prop.Key, Qt::DisplayRole);
+ this->setData(idx1, prop.Help, QCMakeCacheModel::HelpRole);
+ this->setData(idx1, prop.Type, QCMakeCacheModel::TypeRole);
+ this->setData(idx1, prop.Advanced, QCMakeCacheModel::AdvancedRole);
+
+ if(prop.Type == QCMakeProperty::BOOL)
+ {
+ int check = prop.Value.toBool() ? Qt::Checked : Qt::Unchecked;
+ this->setData(idx2, check, Qt::CheckStateRole);
+ }
+ else
+ {
+ this->setData(idx2, prop.Value, Qt::DisplayRole);
+ }
+ this->setData(idx2, prop.Help, QCMakeCacheModel::HelpRole);
+
+ if (!prop.Strings.isEmpty())
+ {
+ this->setData(idx1, prop.Strings, QCMakeCacheModel::StringsRole);
+ }
+
+ if(isNew)
+ {
+ this->setData(idx1, QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ this->setData(idx2, QBrush(QColor(255,100,100)), Qt::BackgroundColorRole);
+ }
+}
+
+void QCMakeCacheModel::getPropertyData(const QModelIndex& idx1,
+ QCMakeProperty& prop) const
+{
+ QModelIndex idx2 = idx1.sibling(idx1.row(), 1);
+
+ prop.Key = this->data(idx1, Qt::DisplayRole).toString();
+ prop.Help = this->data(idx1, HelpRole).toString();
+ prop.Type = static_cast<QCMakeProperty::PropertyType>(this->data(idx1, TypeRole).toInt());
+ prop.Advanced = this->data(idx1, AdvancedRole).toBool();
+ prop.Strings = this->data(idx1, QCMakeCacheModel::StringsRole).toStringList();
+ if(prop.Type == QCMakeProperty::BOOL)
+ {
+ int check = this->data(idx2, Qt::CheckStateRole).toInt();
+ prop.Value = check == Qt::Checked;
+ }
+ else
+ {
+ prop.Value = this->data(idx2, Qt::DisplayRole).toString();
+ }
+}
+
+QString QCMakeCacheModel::prefix(const QString& s)
+{
+ QString prefix = s.section('_', 0, 0);
+ if(prefix == s)
+ {
+ prefix = QString();
+ }
+ return prefix;
+}
+
+void QCMakeCacheModel::breakProperties(const QSet<QCMakeProperty>& props,
+ QMap<QString, QCMakePropertyList>& result)
+{
+ QMap<QString, QCMakePropertyList> tmp;
+ // return a map of properties grouped by prefixes, and sorted
+ foreach(QCMakeProperty p, props)
+ {
+ QString prefix = QCMakeCacheModel::prefix(p.Key);
+ tmp[prefix].append(p);
+ }
+ // sort it and re-org any properties with only one sub item
+ QCMakePropertyList reorgProps;
+ QMap<QString, QCMakePropertyList>::iterator iter;
+ for(iter = tmp.begin(); iter != tmp.end();)
+ {
+ if(iter->count() == 1)
+ {
+ reorgProps.append((*iter)[0]);
+ iter = tmp.erase(iter);
+ }
+ else
+ {
+ qSort(*iter);
+ ++iter;
+ }
+ }
+ if(reorgProps.count())
+ {
+ tmp[QString()] += reorgProps;
+ }
+ result = tmp;
+}
+
+QCMakePropertyList QCMakeCacheModel::properties() const
+{
+ QCMakePropertyList props;
+
+ if(!this->rowCount())
+ {
+ return props;
+ }
+
+ QList<QModelIndex> idxs;
+ idxs.append(this->index(0,0));
+
+ // walk the entire model for property entries
+ // this works regardless of a flat view or a tree view
+ while(!idxs.isEmpty())
+ {
+ QModelIndex idx = idxs.last();
+ if(this->hasChildren(idx) && this->rowCount(idx))
+ {
+ idxs.append(this->index(0,0, idx));
+ }
+ else
+ {
+ if(!data(idx, GroupRole).toInt())
+ {
+ // get data
+ QCMakeProperty prop;
+ this->getPropertyData(idx, prop);
+ props.append(prop);
+ }
+
+ // go to the next in the tree
+ while(!idxs.isEmpty() && !idxs.last().sibling(idxs.last().row()+1, 0).isValid())
+ {
+ idxs.removeLast();
+ }
+ if(!idxs.isEmpty())
+ {
+ idxs.last() = idxs.last().sibling(idxs.last().row()+1, 0);
+ }
+ }
+ }
+
+ return props;
+}
+
+bool QCMakeCacheModel::insertProperty(QCMakeProperty::PropertyType t,
+ const QString& name, const QString& description,
+ const QVariant& value, bool advanced)
+{
+ QCMakeProperty prop;
+ prop.Key = name;
+ prop.Value = value;
+ prop.Help = description;
+ prop.Type = t;
+ prop.Advanced = advanced;
+
+ //insert at beginning
+ this->insertRow(0);
+ this->setPropertyData(this->index(0,0), prop, true);
+ this->NewPropertyCount++;
+ return true;
+}
+
+void QCMakeCacheModel::setEditEnabled(bool e)
+{
+ this->EditEnabled = e;
+}
+
+bool QCMakeCacheModel::editEnabled() const
+{
+ return this->EditEnabled;
+}
+
+int QCMakeCacheModel::newPropertyCount() const
+{
+ return this->NewPropertyCount;
+}
+
+Qt::ItemFlags QCMakeCacheModel::flags (const QModelIndex& idx) const
+{
+ Qt::ItemFlags f = QStandardItemModel::flags(idx);
+ if(!this->EditEnabled)
+ {
+ f &= ~Qt::ItemIsEditable;
+ return f;
+ }
+ if(QCMakeProperty::BOOL == this->data(idx, TypeRole).toInt())
+ {
+ f |= Qt::ItemIsUserCheckable;
+ }
+ return f;
+}
+
+QModelIndex QCMakeCacheModel::buddy(const QModelIndex& idx) const
+{
+ if(!this->hasChildren(idx) &&
+ this->data(idx, TypeRole).toInt() != QCMakeProperty::BOOL)
+ {
+ return this->index(idx.row(), 1, idx.parent());
+ }
+ return idx;
+}
+
+QCMakeCacheModelDelegate::QCMakeCacheModelDelegate(QObject* p)
+ : QItemDelegate(p), FileDialogFlag(false)
+{
+}
+
+void QCMakeCacheModelDelegate::setFileDialogFlag(bool f)
+{
+ this->FileDialogFlag = f;
+}
+
+QWidget* QCMakeCacheModelDelegate::createEditor(QWidget* p,
+ const QStyleOptionViewItem&, const QModelIndex& idx) const
+{
+ QModelIndex var = idx.sibling(idx.row(), 0);
+ int type = var.data(QCMakeCacheModel::TypeRole).toInt();
+ if(type == QCMakeProperty::BOOL)
+ {
+ return NULL;
+ }
+ else if(type == QCMakeProperty::PATH)
+ {
+ QCMakePathEditor* editor =
+ new QCMakePathEditor(p,
+ var.data(Qt::DisplayRole).toString());
+ QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this,
+ SLOT(setFileDialogFlag(bool)));
+ return editor;
+ }
+ else if(type == QCMakeProperty::FILEPATH)
+ {
+ QCMakeFilePathEditor* editor =
+ new QCMakeFilePathEditor(p,
+ var.data(Qt::DisplayRole).toString());
+ QObject::connect(editor, SIGNAL(fileDialogExists(bool)), this,
+ SLOT(setFileDialogFlag(bool)));
+ return editor;
+ }
+ else if(type == QCMakeProperty::STRING &&
+ var.data(QCMakeCacheModel::StringsRole).isValid())
+ {
+ QCMakeComboBox* editor =
+ new QCMakeComboBox(p, var.data(QCMakeCacheModel::StringsRole).toStringList());
+ editor->setFrame(false);
+ return editor;
+ }
+
+ QLineEdit* editor = new QLineEdit(p);
+ editor->setFrame(false);
+ return editor;
+}
+
+bool QCMakeCacheModelDelegate::editorEvent(QEvent* e, QAbstractItemModel* model,
+ const QStyleOptionViewItem& option, const QModelIndex& index)
+{
+ Qt::ItemFlags flags = model->flags(index);
+ if (!(flags & Qt::ItemIsUserCheckable) || !(option.state & QStyle::State_Enabled)
+ || !(flags & Qt::ItemIsEnabled))
+ {
+ return false;
+ }
+
+ QVariant value = index.data(Qt::CheckStateRole);
+ if (!value.isValid())
+ {
+ return false;
+ }
+
+ if ((e->type() == QEvent::MouseButtonRelease)
+ || (e->type() == QEvent::MouseButtonDblClick))
+ {
+ // eat the double click events inside the check rect
+ if (e->type() == QEvent::MouseButtonDblClick)
+ {
+ return true;
+ }
+ }
+ else if (e->type() == QEvent::KeyPress)
+ {
+ if(static_cast<QKeyEvent*>(e)->key() != Qt::Key_Space &&
+ static_cast<QKeyEvent*>(e)->key() != Qt::Key_Select)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ return false;
+ }
+
+ Qt::CheckState state = (static_cast<Qt::CheckState>(value.toInt()) == Qt::Checked
+ ? Qt::Unchecked : Qt::Checked);
+ bool success = model->setData(index, state, Qt::CheckStateRole);
+ if(success)
+ {
+ this->recordChange(model, index);
+ }
+ return success;
+}
+
+// Issue 205903 fixed in Qt 4.5.0.
+// Can remove this function and FileDialogFlag when minimum Qt version is 4.5
+bool QCMakeCacheModelDelegate::eventFilter(QObject* object, QEvent* evt)
+{
+ // workaround for what looks like a bug in Qt on Mac OS X
+ // where it doesn't create a QWidget wrapper for the native file dialog
+ // so the Qt library ends up assuming the focus was lost to something else
+
+ if(evt->type() == QEvent::FocusOut && this->FileDialogFlag)
+ {
+ return false;
+ }
+ return QItemDelegate::eventFilter(object, evt);
+}
+
+void QCMakeCacheModelDelegate::setModelData(QWidget* editor,
+ QAbstractItemModel* model, const QModelIndex& index ) const
+{
+ QItemDelegate::setModelData(editor, model, index);
+ const_cast<QCMakeCacheModelDelegate*>(this)->recordChange(model, index);
+}
+
+QSize QCMakeCacheModelDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const
+{
+ QSize sz = QItemDelegate::sizeHint(option, index);
+ QStyle *style = QApplication::style();
+
+ // increase to checkbox size
+ QStyleOptionButton opt;
+ opt.QStyleOption::operator=(option);
+ sz = sz.expandedTo(style->subElementRect(QStyle::SE_ViewItemCheckIndicator, &opt, NULL).size());
+
+ return sz;
+}
+
+QSet<QCMakeProperty> QCMakeCacheModelDelegate::changes() const
+{
+ return mChanges;
+}
+
+void QCMakeCacheModelDelegate::clearChanges()
+{
+ mChanges.clear();
+}
+
+void QCMakeCacheModelDelegate::recordChange(QAbstractItemModel* model, const QModelIndex& index)
+{
+ QModelIndex idx = index;
+ QAbstractItemModel* mymodel = model;
+ while(qobject_cast<QAbstractProxyModel*>(mymodel))
+ {
+ idx = static_cast<QAbstractProxyModel*>(mymodel)->mapToSource(idx);
+ mymodel = static_cast<QAbstractProxyModel*>(mymodel)->sourceModel();
+ }
+ QCMakeCacheModel* cache_model = qobject_cast<QCMakeCacheModel*>(mymodel);
+ if(cache_model && idx.isValid())
+ {
+ QCMakeProperty prop;
+ idx = idx.sibling(idx.row(), 0);
+ cache_model->getPropertyData(idx, prop);
+
+ // clean out an old one
+ QSet<QCMakeProperty>::iterator iter = mChanges.find(prop);
+ if(iter != mChanges.end())
+ {
+ mChanges.erase(iter);
+ }
+ // now add the new item
+ mChanges.insert(prop);
+ }
+}
+
diff --git a/Source/QtDialog/QCMakeCacheView.h b/Source/QtDialog/QCMakeCacheView.h
new file mode 100644
index 000000000..0a628b90a
--- /dev/null
+++ b/Source/QtDialog/QCMakeCacheView.h
@@ -0,0 +1,172 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef QCMakeCacheView_h
+#define QCMakeCacheView_h
+
+#include "QCMake.h"
+#include <QTreeView>
+#include <QSet>
+#include <QStandardItemModel>
+#include <QItemDelegate>
+
+class QSortFilterProxyModel;
+class QCMakeCacheModel;
+class QCMakeAdvancedFilter;
+
+/// Qt view class for cache properties
+class QCMakeCacheView : public QTreeView
+{
+ Q_OBJECT
+public:
+ QCMakeCacheView(QWidget* p);
+
+ // retrieve the QCMakeCacheModel storing all the pointers
+ // this isn't necessarily the model one would get from model()
+ QCMakeCacheModel* cacheModel() const;
+
+ // get whether to show advanced entries
+ bool showAdvanced() const;
+
+ QSize sizeHint() const { return QSize(200,200); }
+
+public slots:
+ // set whether to show advanced entries
+ void setShowAdvanced(bool);
+ // set the search filter string. any property key or value not matching will
+ // be filtered out
+ void setSearchFilter(const QString&);
+
+protected:
+ QModelIndex moveCursor(CursorAction, Qt::KeyboardModifiers);
+ bool event(QEvent* e);
+ QCMakeCacheModel* CacheModel;
+ QCMakeAdvancedFilter* AdvancedFilter;
+ QSortFilterProxyModel* SearchFilter;
+};
+
+/// Qt model class for cache properties
+class QCMakeCacheModel : public QStandardItemModel
+{
+ Q_OBJECT
+public:
+ QCMakeCacheModel(QObject* parent);
+ ~QCMakeCacheModel();
+
+ // roles used to retrieve extra data such has help strings, types of
+ // properties, and the advanced flag
+ enum { HelpRole = Qt::ToolTipRole,
+ TypeRole = Qt::UserRole,
+ AdvancedRole,
+ StringsRole,
+ GroupRole
+ };
+
+ enum ViewType { FlatView, GroupView };
+
+public slots:
+ // set a list of properties. This list will be sorted and grouped according
+ // to prefix. Any property that existed already and which is found in this
+ // list of properties to set will become an old property. All others will
+ // become new properties and be marked red.
+ void setProperties(const QCMakePropertyList& props);
+
+ // set whether to show new properties in red
+ void setShowNewProperties(bool);
+
+ // clear everything from the model
+ void clear();
+
+ // set flag whether the model can currently be edited.
+ void setEditEnabled(bool);
+
+ // insert a new property at a row specifying all the information about the
+ // property
+ bool insertProperty(QCMakeProperty::PropertyType t,
+ const QString& name, const QString& description,
+ const QVariant& value, bool advanced);
+
+ // set the view type
+ void setViewType(ViewType t);
+ ViewType viewType() const;
+
+public:
+ // get the properties
+ QCMakePropertyList properties() const;
+
+ // editing enabled
+ bool editEnabled() const;
+
+ // returns how many new properties there are
+ int newPropertyCount() const;
+
+ // return flags (overloaded to modify flag based on EditEnabled flag)
+ Qt::ItemFlags flags (const QModelIndex& index) const;
+ QModelIndex buddy(const QModelIndex& idx) const;
+
+ // get the data in the model for this property
+ void getPropertyData(const QModelIndex& idx1,
+ QCMakeProperty& prop) const;
+
+protected:
+ bool EditEnabled;
+ int NewPropertyCount;
+ bool ShowNewProperties;
+ ViewType View;
+
+ // set the data in the model for this property
+ void setPropertyData(const QModelIndex& idx1,
+ const QCMakeProperty& p, bool isNew);
+
+ // breaks up he property list into groups
+ // where each group has the same prefix up to the first underscore
+ static void breakProperties(const QSet<QCMakeProperty>& props,
+ QMap<QString, QCMakePropertyList>& result);
+
+ // gets the prefix of a string up to the first _
+ static QString prefix(const QString& s);
+
+};
+
+/// Qt delegate class for interaction (or other customization)
+/// with cache properties
+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;
+ bool editorEvent (QEvent* event, QAbstractItemModel* model,
+ const QStyleOptionViewItem& option, const QModelIndex& index);
+ bool eventFilter(QObject* object, QEvent* event);
+ void setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index ) const;
+ QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const;
+
+ QSet<QCMakeProperty> changes() const;
+ void clearChanges();
+
+protected slots:
+ void setFileDialogFlag(bool);
+protected:
+ bool FileDialogFlag;
+ // record a change to an item in the model.
+ // this simply saves the item in the set of changes
+ void recordChange(QAbstractItemModel* model, const QModelIndex& index);
+
+ // properties changed by user via this delegate
+ QSet<QCMakeProperty> mChanges;
+};
+
+#endif
+
diff --git a/Source/QtDialog/QCMakeWidgets.cxx b/Source/QtDialog/QCMakeWidgets.cxx
new file mode 100644
index 000000000..144e1f32e
--- /dev/null
+++ b/Source/QtDialog/QCMakeWidgets.cxx
@@ -0,0 +1,134 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#include "QCMakeWidgets.h"
+
+#include <QDirModel>
+#include <QFileInfo>
+#include <QFileDialog>
+#include <QToolButton>
+#include <QResizeEvent>
+
+QCMakeFileEditor::QCMakeFileEditor(QWidget* p, const QString& var)
+ : QLineEdit(p), Variable(var)
+{
+ this->ToolButton = new QToolButton(this);
+ this->ToolButton->setText("...");
+ this->ToolButton->setCursor(QCursor(Qt::ArrowCursor));
+ QObject::connect(this->ToolButton, SIGNAL(clicked(bool)),
+ this, SLOT(chooseFile()));
+}
+
+QCMakeFilePathEditor::QCMakeFilePathEditor(QWidget* p, const QString& var)
+ : QCMakeFileEditor(p, var)
+{
+ this->setCompleter(new QCMakeFileCompleter(this, false));
+}
+
+QCMakePathEditor::QCMakePathEditor(QWidget* p, const QString& var)
+ : QCMakeFileEditor(p, var)
+{
+ this->setCompleter(new QCMakeFileCompleter(this, true));
+}
+
+void QCMakeFileEditor::resizeEvent(QResizeEvent* e)
+{
+ // make the tool button fit on the right side
+ int h = e->size().height();
+ // move the line edit to make room for the tool button
+ this->setContentsMargins(0, 0, h, 0);
+ // put the tool button in its place
+ this->ToolButton->resize(h, h);
+ this->ToolButton->move(this->width() - h, 0);
+}
+
+void QCMakeFilePathEditor::chooseFile()
+{
+ // choose a file and set it
+ QString path;
+ QFileInfo info(this->text());
+ QString title;
+ if(this->Variable.isEmpty())
+ {
+ title = tr("Select File");
+ }
+ else
+ {
+ title = tr("Select File for %1");
+ title = title.arg(this->Variable);
+ }
+ this->fileDialogExists(true);
+ path = QFileDialog::getOpenFileName(this, title, info.absolutePath());
+ this->fileDialogExists(false);
+
+ if(!path.isEmpty())
+ {
+ this->setText(QDir::fromNativeSeparators(path));
+ }
+}
+
+void QCMakePathEditor::chooseFile()
+{
+ // choose a file and set it
+ QString path;
+ QString title;
+ if(this->Variable.isEmpty())
+ {
+ title = tr("Select Path");
+ }
+ else
+ {
+ title = tr("Select Path for %1");
+ title = title.arg(this->Variable);
+ }
+ this->fileDialogExists(true);
+ path = QFileDialog::getExistingDirectory(this, title, this->text());
+ this->fileDialogExists(false);
+ if(!path.isEmpty())
+ {
+ this->setText(QDir::fromNativeSeparators(path));
+ }
+}
+
+// use same QDirModel for all completers
+static QDirModel* fileDirModel()
+{
+ static QDirModel* m = NULL;
+ if(!m)
+ {
+ m = new QDirModel();
+ }
+ return m;
+}
+static QDirModel* pathDirModel()
+{
+ static QDirModel* m = NULL;
+ if(!m)
+ {
+ m = new QDirModel();
+ m->setFilter(QDir::AllDirs | QDir::Drives | QDir::NoDotAndDotDot);
+ }
+ return m;
+}
+
+QCMakeFileCompleter::QCMakeFileCompleter(QObject* o, bool dirs)
+ : QCompleter(o)
+{
+ QDirModel* m = dirs ? pathDirModel() : fileDirModel();
+ this->setModel(m);
+}
+
+QString QCMakeFileCompleter::pathFromIndex(const QModelIndex& idx) const
+{
+ return QDir::fromNativeSeparators(QCompleter::pathFromIndex(idx));
+}
+
diff --git a/Source/QtDialog/QCMakeWidgets.h b/Source/QtDialog/QCMakeWidgets.h
new file mode 100644
index 000000000..8f58df2bb
--- /dev/null
+++ b/Source/QtDialog/QCMakeWidgets.h
@@ -0,0 +1,87 @@
+/*============================================================================
+ CMake - Cross Platform Makefile Generator
+ Copyright 2000-2009 Kitware, Inc., Insight Software Consortium
+
+ Distributed under the OSI-approved BSD License (the "License");
+ see accompanying file Copyright.txt for details.
+
+ This software is distributed WITHOUT ANY WARRANTY; without even the
+ implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ See the License for more information.
+============================================================================*/
+
+#ifndef QCMakeWidgets_h
+#define QCMakeWidgets_h
+
+#include <QLineEdit>
+#include <QComboBox>
+#include <QCompleter>
+class QToolButton;
+
+// common widgets for Qt based CMake
+
+/// Editor widget for editing paths or file paths
+class QCMakeFileEditor : public QLineEdit
+{
+ Q_OBJECT
+public:
+ QCMakeFileEditor(QWidget* p, const QString& var);
+protected slots:
+ virtual void chooseFile() = 0;
+signals:
+ void fileDialogExists(bool);
+protected:
+ void resizeEvent(QResizeEvent* e);
+ QToolButton* ToolButton;
+ QString Variable;
+};
+
+/// editor widget for editing files
+class QCMakePathEditor : public QCMakeFileEditor
+{
+ Q_OBJECT
+public:
+ QCMakePathEditor(QWidget* p = NULL, const QString& var = QString());
+ void chooseFile();
+};
+
+/// editor widget for editing paths
+class QCMakeFilePathEditor : public QCMakeFileEditor
+{
+ Q_OBJECT
+public:
+ QCMakeFilePathEditor(QWidget* p = NULL, const QString& var = QString());
+ void chooseFile();
+};
+
+/// completer class that returns native cmake paths
+class QCMakeFileCompleter : public QCompleter
+{
+ Q_OBJECT
+public:
+ QCMakeFileCompleter(QObject* o, bool dirs);
+ virtual QString pathFromIndex(const QModelIndex& idx) const;
+};
+
+// editor for strings
+class QCMakeComboBox : public QComboBox
+{
+ Q_OBJECT
+ Q_PROPERTY(QString value READ currentText WRITE setValue USER true);
+public:
+ QCMakeComboBox(QWidget* p, QStringList strings) : QComboBox(p)
+ {
+ this->addItems(strings);
+ }
+ void setValue(const QString& v)
+ {
+ int i = this->findText(v);
+ if(i != -1)
+ {
+ this->setCurrentIndex(i);
+ }
+ }
+};
+
+#endif
+
diff --git a/Source/QtDialog/QMacInstallDialog.cxx b/Source/QtDialog/QMacInstallDialog.cxx
new file mode 100644
index 000000000..6eb053b21
--- /dev/null
+++ b/Source/QtDialog/QMacInstallDialog.cxx
@@ -0,0 +1,121 @@
+#include "QMacInstallDialog.h"
+#include <QMessageBox>
+#include "cmSystemTools.h"
+#include <iostream>
+#include <QFileDialog>
+#include "ui_MacInstallDialog.h"
+
+class QMacInstallDialog::QMacInstallDialogInternals : public Ui::Dialog
+{
+public:
+};
+
+QMacInstallDialog::QMacInstallDialog(QWidget*w)
+ :QDialog(w)
+{
+ this->Internals = new QMacInstallDialogInternals;
+ this->Internals->setupUi(this);
+ QObject::connect(this->Internals->choosePathButton, SIGNAL(pressed()),
+ this, SLOT(ShowBrowser()));
+ QObject::connect(this->Internals->skipInstallButton, SIGNAL(pressed()),
+ this, SLOT(SkipInstall()));
+ QObject::connect(this->Internals->doInstallButton, SIGNAL(pressed()),
+ this, SLOT(DoInstall()));
+ this->Internals->InstallPrefix->setText("/usr/bin/");
+
+}
+
+QMacInstallDialog::~QMacInstallDialog()
+{
+ delete this->Internals;
+}
+
+void QMacInstallDialog::DoInstall()
+{
+ QDir installDir(this->Internals->InstallPrefix->text());
+ QString installTo = installDir.path();
+ if(!cmSystemTools::FileExists(installTo.toLocal8Bit().data()))
+ {
+ QString message = tr("Build install does not exist, "
+ "should I create it?\n\n"
+ "Directory: ");
+ message += installDir.path();
+ QString title = tr("Create Directory");
+ QMessageBox::StandardButton btn;
+ btn = QMessageBox::information(this, title, message,
+ QMessageBox::Yes | QMessageBox::No);
+ if(btn == QMessageBox::Yes)
+ {
+ cmSystemTools::MakeDirectory(installTo.toLocal8Bit().data());
+ }
+ }
+ QDir cmExecDir(QApplication::applicationDirPath());
+ cmExecDir.cd("../bin");
+ QFileInfoList list = cmExecDir.entryInfoList();
+ for (int i = 0; i < list.size(); ++i)
+ {
+ QFileInfo fileInfo = list.at(i);
+ QString filename = fileInfo.fileName();
+ if(filename.size() && filename[0] == '.')
+ {
+ continue;
+ }
+ QString file = fileInfo.absoluteFilePath();
+ QString newName = installTo;
+ newName += "/";
+ newName += filename;
+ // Remove the old files
+ if(cmSystemTools::FileExists(newName.toLocal8Bit().data()))
+ {
+ std::cout << "rm [" << newName.toLocal8Bit().data() << "]\n";
+ if(!cmSystemTools::RemoveFile(newName.toLocal8Bit().data()))
+ {
+ QString message = tr("Failed to remove file "
+ "installation may be incomplete: ");
+ message += newName;
+ QString title = tr("Error Removing file");
+ QMessageBox::StandardButton btn =
+ QMessageBox::critical(this, title, message,
+ QMessageBox::Ok|QMessageBox::Abort);
+ if(btn == QMessageBox::Abort)
+ {
+ return;
+ }
+ }
+ }
+ std::cout << "ln -s [" << file.toLocal8Bit().data() << "] [";
+ std::cout << newName.toLocal8Bit().data() << "]\n";
+ if(!cmSystemTools::CreateSymlink(file.toLocal8Bit().data(),
+ newName.toLocal8Bit().data()))
+ {
+ QString message = tr("Failed create symlink "
+ "installation may be incomplete: ");
+ message += newName;
+ QString title = tr("Error Creating Symlink");
+ QMessageBox::StandardButton btn =
+ QMessageBox::critical(this, title, message,
+ QMessageBox::Ok|QMessageBox::Abort);
+ if(btn == QMessageBox::Abort)
+ {
+ return;
+ }
+ }
+ }
+ this->done(0);
+}
+
+void QMacInstallDialog::SkipInstall()
+{
+ this->done(0);
+}
+
+
+void QMacInstallDialog::ShowBrowser()
+{
+ QString dir = QFileDialog::getExistingDirectory(this,
+ tr("Enter Install Prefix"), this->Internals->InstallPrefix->text());
+ if(!dir.isEmpty())
+ {
+ this->Internals->InstallPrefix->setText(dir);
+ }
+}
diff --git a/Source/QtDialog/QMacInstallDialog.h b/Source/QtDialog/QMacInstallDialog.h
new file mode 100644
index 000000000..efe67dfaf
--- /dev/null
+++ b/Source/QtDialog/QMacInstallDialog.h
@@ -0,0 +1,20 @@
+#ifndef QMacInstallDialog_h
+#define QMacInstallDialog_h
+#include <QDialog>
+
+class QMacInstallDialog : public QDialog
+{
+ Q_OBJECT;
+public:
+ QMacInstallDialog(QWidget*w);
+ ~QMacInstallDialog();
+private slots:
+ void ShowBrowser();
+ void SkipInstall();
+ void DoInstall();
+private:
+ class QMacInstallDialogInternals;
+ QMacInstallDialogInternals* Internals;
+};
+
+#endif
diff --git a/Source/QtDialog/QtDialogCPack.cmake.in b/Source/QtDialog/QtDialogCPack.cmake.in
new file mode 100644
index 000000000..701991b7a
--- /dev/null
+++ b/Source/QtDialog/QtDialogCPack.cmake.in
@@ -0,0 +1,18 @@
+SET(IS_APPLE @APPLE@)
+SET(CMAKE_PACKAGE_QTGUI @CMAKE_PACKAGE_QTGUI@)
+
+IF(CMAKE_PACKAGE_QTGUI)
+ SET(CPACK_PACKAGE_EXECUTABLES "cmake-gui" "CMake (cmake-gui)" ${CPACK_PACKAGE_EXECUTABLES})
+ SET(CPACK_CREATE_DESKTOP_LINKS "cmake-gui" ${CPACK_CREATE_DESKTOP_LINKS})
+ IF(IS_APPLE)
+ # for apple install we set the install prefix to
+ # / and then install
+ # cmake into the bundle for cmake-gui and must use DESTDIR
+ SET(CPACK_SET_DESTDIR TRUE)
+ # we also want to run post install stuff to setup command line
+ SET(CPACK_POSTFLIGHT_SCRIPT "@CMAKE_POSTFLIGHT_SCRIPT@")
+ SET(CPACK_POSTUPGRADE_SCRIPT "@CMAKE_POSTUPGRADE_SCRIPT@")
+ ENDIF(IS_APPLE)
+ENDIF(CMAKE_PACKAGE_QTGUI)
+
+
diff --git a/Source/QtDialog/cmakecache.xml b/Source/QtDialog/cmakecache.xml
new file mode 100644
index 000000000..a13b5b19c
--- /dev/null
+++ b/Source/QtDialog/cmakecache.xml
@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<mime-info xmlns="http://www.freedesktop.org/standards/shared-mime-info">
+ <mime-type type="application/x-cmakecache">
+ <comment>CMake cache file</comment>
+ <glob pattern="CMakeCache.txt"/>
+ <sub-class-of type="text/plain"/>
+ </mime-type>
+</mime-info>
diff --git a/Source/QtDialog/postflight.sh.in b/Source/QtDialog/postflight.sh.in
new file mode 100755
index 000000000..33be35206
--- /dev/null
+++ b/Source/QtDialog/postflight.sh.in
@@ -0,0 +1,3 @@
+#!/bin/bash
+"$2@CMAKE_INSTALL_SUBDIR@/@CMAKE_BUNDLE_NAME@.app/Contents/MacOS/@CMAKE_BUNDLE_NAME@" --mac-install
+exit 0
diff --git a/Source/QtDialog/postupgrade.sh.in b/Source/QtDialog/postupgrade.sh.in
new file mode 100755
index 000000000..06bd98656
--- /dev/null
+++ b/Source/QtDialog/postupgrade.sh.in
@@ -0,0 +1,2 @@
+#!/bin/bash
+exit 0