Merge branch 'master' of git@scm.dev.nokia.troll.no:creator/mainline

This commit is contained in:
hjk
2009-01-23 17:21:36 +01:00
15 changed files with 510 additions and 62 deletions

View File

@@ -11,7 +11,7 @@
Development Environment (IDE) to develop Qt projects. It is available for Development Environment (IDE) to develop Qt projects. It is available for
the Linux, Mac OS X and Windows platforms. the Linux, Mac OS X and Windows platforms.
\note The current version of Qt Creator is 0.9.1 (Beta). It is \note The current version of Qt Creator is 0.9.2 (Beta). It is
possible to edit source code, compile, run and debug applications; other possible to edit source code, compile, run and debug applications; other
features are still under development. Please send bug reports and features are still under development. Please send bug reports and
suggestions to qt-creator@trolltech.com. To subscribe, send a suggestions to qt-creator@trolltech.com. To subscribe, send a

View File

@@ -17,15 +17,15 @@ sources.fileextensions = "qtcreator.qdoc"
qhp.projects = QtCreator qhp.projects = QtCreator
qhp.QtCreator.file = qtcreator.qhp qhp.QtCreator.file = qtcreator.qhp
qhp.QtCreator.namespace = com.nokia.qtcreator.091 qhp.QtCreator.namespace = com.nokia.qtcreator.092
qhp.QtCreator.virtualFolder = doc qhp.QtCreator.virtualFolder = doc
qhp.QtCreator.indexTitle = Qt Creator qhp.QtCreator.indexTitle = Qt Creator
qhp.QtCreator.indexRoot = qhp.QtCreator.indexRoot =
qhp.QtCreator.extraFiles = classic.css \ qhp.QtCreator.extraFiles = classic.css \
images/qt-logo.png images/qt-logo.png
qhp.QtCreator.filterAttributes = qtcreator 0.9.1 qhp.QtCreator.filterAttributes = qtcreator 0.9.2
qhp.QtCreator.customFilters.QtCreator.name = Qt Creator 0.9.1 qhp.QtCreator.customFilters.QtCreator.name = Qt Creator 0.9.2
qhp.QtCreator.customFilters.QtCreator.filterAttributes = qtcreator 0.9.1 qhp.QtCreator.customFilters.QtCreator.filterAttributes = qtcreator 0.9.2
# macros.qdocconf # macros.qdocconf
@@ -201,5 +201,5 @@ HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
"<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
"<td width=\"30%\" align=\"left\">Copyright &copy; 2008 Nokia</td>\n" \ "<td width=\"30%\" align=\"left\">Copyright &copy; 2008 Nokia</td>\n" \
"<td width=\"40%\" align=\"center\">&nbsp;</td>\n" \ "<td width=\"40%\" align=\"center\">&nbsp;</td>\n" \
"<td width=\"30%\" align=\"right\"><div align=\"right\">Qt Creator 0.9.1</div></td>\n" \ "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt Creator 0.9.2</div></td>\n" \
"</tr></table></div></address>" "</tr></table></div></address>"

View File

@@ -25,6 +25,12 @@ NEW_MINOR=`sed 's/^[0-9]\+\.\([0-9]\+\)\.[0-9]\+$/\1/' <<<"$2"`
OLD_RELEASE=`sed 's/^[0-9]\+\.[0-9]\+\.\([0-9]\+\)$/\1/' <<<"$1"` OLD_RELEASE=`sed 's/^[0-9]\+\.[0-9]\+\.\([0-9]\+\)$/\1/' <<<"$1"`
NEW_RELEASE=`sed 's/^[0-9]\+\.[0-9]\+\.\([0-9]\+\)$/\1/' <<<"$2"` NEW_RELEASE=`sed 's/^[0-9]\+\.[0-9]\+\.\([0-9]\+\)$/\1/' <<<"$2"`
OLD_THREE="${OLD_MAJOR}${OLD_MINOR}${OLD_RELEASE}"
NEW_THREE="${NEW_MAJOR}${NEW_MINOR}${NEW_RELEASE}"
OLD_DOT_THREE="${OLD_MAJOR}\\.${OLD_MINOR}\\.${OLD_RELEASE}"
NEW_DOT_THREE="${NEW_MAJOR}\\.${NEW_MINOR}\\.${NEW_RELEASE}"
OLD_DOT_FOUR="${OLD_MAJOR}\\.${OLD_MINOR}\\.${OLD_RELEASE}\\.0" OLD_DOT_FOUR="${OLD_MAJOR}\\.${OLD_MINOR}\\.${OLD_RELEASE}\\.0"
NEW_DOT_FOUR="${NEW_MAJOR}\\.${NEW_MINOR}\\.${NEW_RELEASE}\\.0" NEW_DOT_FOUR="${NEW_MAJOR}\\.${NEW_MINOR}\\.${NEW_RELEASE}\\.0"
@@ -38,8 +44,10 @@ echo "# Major '${OLD_MAJOR}' -> '${NEW_MAJOR}'"
echo "# Minor '${OLD_MINOR}' -> '${NEW_MINOR}'" echo "# Minor '${OLD_MINOR}' -> '${NEW_MINOR}'"
echo "# Release '${OLD_RELEASE}' -> '${NEW_RELEASE}'" echo "# Release '${OLD_RELEASE}' -> '${NEW_RELEASE}'"
echo "#-----------------------------------------------" echo "#-----------------------------------------------"
echo "# Dots '${OLD_DOT_FOUR}' -> '${NEW_DOT_FOUR}'" echo "# 3 '${OLD_THREE}' -> '${NEW_THREE}'"
echo "# Comma '${OLD_COMMA_FOUR}' -> '${NEW_COMMA_FOUR}'" echo "# Dot 3 '${OLD_DOT_THREE}' -> '${NEW_DOT_THREE}'"
echo "# Dot 4 '${OLD_DOT_FOUR}' -> '${NEW_DOT_FOUR}'"
echo "# Comma 4 '${OLD_COMMA_FOUR}' -> '${NEW_COMMA_FOUR}'"
echo "#===============================================" echo "#==============================================="
echo echo
@@ -85,7 +93,7 @@ sed \
mv -f "${TMPFILE}" "${INSTALLER_RC}" mv -f "${TMPFILE}" "${INSTALLER_RC}"
## Patch installer.rc ## Patch Info.plist
TMPFILE=`mktemp` TMPFILE=`mktemp`
INFO_PLIST="${SCRIPT_DIR}/src/app/Info.plist" INFO_PLIST="${SCRIPT_DIR}/src/app/Info.plist"
echo "Patching \`${INFO_PLIST}'" echo "Patching \`${INFO_PLIST}'"
@@ -95,6 +103,27 @@ sed \
mv -f "${TMPFILE}" "${INFO_PLIST}" mv -f "${TMPFILE}" "${INFO_PLIST}"
## Patch qtcreator.qdocconf
TMPFILE=`mktemp`
QDOCCONF="${SCRIPT_DIR}/doc/qtcreator.qdocconf"
echo "Patching \`${QDOCCONF}'"
sed \
-e "s/"${OLD_DOT_THREE}"/"${NEW_DOT_THREE}"/" \
-e "s/"${OLD_THREE}"/"${NEW_THREE}"/" \
"${QDOCCONF}" > "${TMPFILE}"
mv -f "${TMPFILE}" "${QDOCCONF}"
## Patch qtcreator.qdoc
TMPFILE=`mktemp`
QDOC="${SCRIPT_DIR}/doc/qtcreator.qdoc"
echo "Patching \`${QDOC}'"
sed \
-e 's/\(The current version of Qt Creator is \)'${OLD_DOT_THREE}'/\1'${NEW_DOT_THREE}'/' \
"${QDOC}" > "${TMPFILE}"
mv -f "${TMPFILE}" "${QDOC}"
## Go back to original $PWD ## Go back to original $PWD
echo "Leaving directory \`${SCRIPT_DIR}'" echo "Leaving directory \`${SCRIPT_DIR}'"
popd &>/dev/null || exit 1 popd &>/dev/null || exit 1

View File

@@ -0,0 +1,90 @@
#include "cmakeconfigurewidget.h"
#include "cmakeprojectmanager.h"
#include <projectexplorer/environment.h>
#include <QtGui/QVBoxLayout>
#include <QtGui/QLineEdit>
#include <QtGui/QSpacerItem>
using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal;
CMakeConfigureWidget::CMakeConfigureWidget(QWidget *parent, CMakeManager *manager, const QString &sourceDirectory)
: QWidget(parent), m_configureSucceded(false), m_cmakeManager(manager), m_sourceDirectory(sourceDirectory)
{
m_ui.setupUi(this);
m_ui.buildDirectoryLineEdit->setPath(sourceDirectory + "/qtcreator-build");
connect(m_ui.configureButton, SIGNAL(clicked()), this, SLOT(runCMake()));
// TODO make the configure button do stuff
// TODO set initial settings
// TODO note if there's already a build in that directory
// detect which generators we have
// let the user select generator
}
QString CMakeConfigureWidget::buildDirectory()
{
return m_ui.buildDirectoryLineEdit->path();
}
QStringList CMakeConfigureWidget::arguments()
{
return ProjectExplorer::Environment::parseCombinedArgString(m_ui.cmakeArgumentsLineEdit->text());
}
bool CMakeConfigureWidget::configureSucceded()
{
return m_configureSucceded;
}
void CMakeConfigureWidget::runCMake()
{
// TODO run project createCbp()
// get output and display it
// TODO analyse wheter this worked out
m_ui.cmakeOutput->setPlainText(tr("Waiting for cmake..."));
QString string = m_cmakeManager->createXmlFile(arguments(), m_sourceDirectory, buildDirectory());
m_ui.cmakeOutput->setPlainText(string);
}
//////
// CMakeConfigureDialog
/////
CMakeConfigureDialog::CMakeConfigureDialog(QWidget *parent, CMakeManager *manager, const QString &sourceDirectory)
: QDialog(parent)
{
QVBoxLayout *vbox = new QVBoxLayout(this);
setLayout(vbox);
m_cmakeConfigureWidget = new CMakeConfigureWidget(this, manager, sourceDirectory);
vbox->addWidget(m_cmakeConfigureWidget);
QHBoxLayout *hboxlayout = new QHBoxLayout(this);
hboxlayout->addSpacerItem(new QSpacerItem(20, 20, QSizePolicy::Expanding, QSizePolicy::Fixed));
QPushButton *okButton = new QPushButton(this);
okButton->setText(tr("Ok"));
okButton->setDefault(true);
connect(okButton, SIGNAL(clicked()), this, SLOT(accept()));
hboxlayout->addWidget(okButton);
vbox->addLayout(hboxlayout);
}
QString CMakeConfigureDialog::buildDirectory()
{
return m_cmakeConfigureWidget->buildDirectory();
}
QStringList CMakeConfigureDialog::arguments()
{
return m_cmakeConfigureWidget->arguments();
}
bool CMakeConfigureDialog::configureSucceded()
{
return m_cmakeConfigureWidget->configureSucceded();
}

View File

@@ -0,0 +1,48 @@
#ifndef CMAKECONFIGUREWIDGET_H
#define CMAKECONFIGUREWIDGET_H
#include "ui_cmakeconfigurewidget.h"
#include <QtGui/QWidget>
#include <QtGui/QDialog>
namespace CMakeProjectManager {
namespace Internal {
class CMakeManager;
class CMakeConfigureWidget : public QWidget
{
Q_OBJECT
public:
CMakeConfigureWidget(QWidget *parent, CMakeManager *manager, const QString &sourceDirectory);
Ui::CMakeConfigureWidget m_ui;
QString buildDirectory();
QStringList arguments();
bool configureSucceded();
private slots:
void runCMake();
private:
bool m_configureSucceded;
CMakeManager *m_cmakeManager;
QString m_sourceDirectory;
};
class CMakeConfigureDialog : public QDialog
{
public:
CMakeConfigureDialog(QWidget *parent, CMakeManager *manager, const QString &sourceDirectory);
QString buildDirectory();
QStringList arguments();
bool configureSucceded();
private:
CMakeConfigureWidget *m_cmakeConfigureWidget;
};
}
}
#endif // CMAKECONFIGUREWIDGET_H

View File

@@ -32,21 +32,24 @@
***************************************************************************/ ***************************************************************************/
#include "cmakeproject.h" #include "cmakeproject.h"
#include "ui_cmakeconfigurewidget.h"
#include "cmakeconfigurewidget.h"
#include "cmakeprojectconstants.h" #include "cmakeprojectconstants.h"
#include "cmakeprojectnodes.h" #include "cmakeprojectnodes.h"
#include "cmakerunconfiguration.h" #include "cmakerunconfiguration.h"
#include "cmakestep.h" #include "cmakestep.h"
#include "makestep.h" #include "makestep.h"
#include <extensionsystem/pluginmanager.h>
#include <cpptools/cppmodelmanagerinterface.h> #include <cpptools/cppmodelmanagerinterface.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <coreplugin/icore.h>
#include <QtCore/QDebug> #include <QtCore/QDebug>
#include <QtCore/QDir> #include <QtCore/QDir>
#include <QtCore/QProcess> #include <QtCore/QProcess>
#include <QtGui/QFormLayout> #include <QtGui/QFormLayout>
#include <QtGui/QMainWindow>
using namespace CMakeProjectManager; using namespace CMakeProjectManager;
using namespace CMakeProjectManager::Internal; using namespace CMakeProjectManager::Internal;
@@ -67,8 +70,6 @@ CMakeProject::CMakeProject(CMakeManager *manager, const QString &fileName)
: m_manager(manager), m_fileName(fileName), m_rootNode(new CMakeProjectNode(m_fileName)) : m_manager(manager), m_fileName(fileName), m_rootNode(new CMakeProjectNode(m_fileName))
{ {
m_file = new CMakeFile(this, fileName); m_file = new CMakeFile(this, fileName);
QDir dir = QFileInfo(m_fileName).absoluteDir();
parseCMakeLists(dir);
} }
CMakeProject::~CMakeProject() CMakeProject::~CMakeProject()
@@ -78,12 +79,12 @@ CMakeProject::~CMakeProject()
// TODO also call this method if the CMakeLists.txt file changed, which is also called if the CMakeList.txt is updated // TODO also call this method if the CMakeLists.txt file changed, which is also called if the CMakeList.txt is updated
// TODO make this function work even if it is reparsing // TODO make this function work even if it is reparsing
void CMakeProject::parseCMakeLists(const QDir &directory) void CMakeProject::parseCMakeLists()
{ {
createCbpFile(buildDirectory(QString())); QString sourceDirectory = QFileInfo(m_fileName).absolutePath();
m_manager->createXmlFile(cmakeStep()->userArguments(activeBuildConfiguration()), sourceDirectory, buildDirectory(activeBuildConfiguration()));
QString cbpFile = findCbpFile(buildDirectory(QString()));
QString cbpFile = findCbpFile(buildDirectory(activeBuildConfiguration()));
CMakeCbpParser cbpparser; CMakeCbpParser cbpparser;
qDebug()<<"Parsing file "<<cbpFile; qDebug()<<"Parsing file "<<cbpFile;
if (cbpparser.parseCbpFile(cbpFile)) { if (cbpparser.parseCbpFile(cbpFile)) {
@@ -142,24 +143,6 @@ QString CMakeProject::findCbpFile(const QDir &directory)
return QString::null; return QString::null;
} }
void CMakeProject::createCbpFile(const QDir &directory)
{
// We create a cbp file, only if we didn't find a cbp file in the base directory
// Yet that can still override cbp files in subdirectories
// And we are creating tons of files in the source directories
// All of that is not really nice.
// The mid term plan is to move away from the CodeBlocks Generator and use our own
// QtCreator generator, which actually can be very similar to the CodeBlock Generator
// TODO we need to pass on the same paremeters as the cmakestep
qDebug()<<"Creating cbp file";
directory.mkpath(directory.absolutePath());
QProcess cmake;
cmake.setWorkingDirectory(directory.absolutePath());
cmake.start("cmake", QStringList() << ".." << "-GCodeBlocks - Unix Makefiles");
cmake.waitForFinished(-1);
qDebug()<<"cmake output: \n"<<cmake.readAll();
}
void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list) void CMakeProject::buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list)
{ {
@@ -300,8 +283,20 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader
{ {
// TODO // TODO
Project::restoreSettingsImpl(reader); Project::restoreSettingsImpl(reader);
if (buildConfigurations().isEmpty()) { bool hasUserFile = !buildConfigurations().isEmpty();
// No build configuration, adding those if (!hasUserFile) {
// Ask the user for where he wants to build it
// and the cmake command line
// TODO check wheter there's already a CMakeCache.txt in the src directory,
// then we don't need to ask, we simply need to build in the src directory
CMakeConfigureDialog ccd(Core::ICore::instance()->mainWindow(), m_manager, QFileInfo(m_fileName).absolutePath());
ccd.exec();
qDebug()<<"ccd.buildDirectory()"<<ccd.buildDirectory();
// Now create a standard build configuration
CMakeStep *cmakeStep = new CMakeStep(this); CMakeStep *cmakeStep = new CMakeStep(this);
MakeStep *makeStep = new MakeStep(this); MakeStep *makeStep = new MakeStep(this);
@@ -311,7 +306,14 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader
addBuildConfiguration("all"); addBuildConfiguration("all");
setActiveBuildConfiguration("all"); setActiveBuildConfiguration("all");
makeStep->setBuildTarget("all", "all", true); makeStep->setBuildTarget("all", "all", true);
if (!ccd.buildDirectory().isEmpty())
setValue("all", "buildDirectory", ccd.buildDirectory());
cmakeStep->setUserArguments("all", ccd.arguments());
}
parseCMakeLists(); // Gets the directory from the active buildconfiguration
if (!hasUserFile) {
// Create run configurations for m_targets // Create run configurations for m_targets
qDebug()<<"Create run configurations of m_targets"; qDebug()<<"Create run configurations of m_targets";
bool setActive = false; bool setActive = false;
@@ -328,7 +330,6 @@ void CMakeProject::restoreSettingsImpl(ProjectExplorer::PersistentSettingsReader
} }
} }
// Restoring is fine
} }

View File

@@ -106,9 +106,8 @@ public:
QStringList targets() const; QStringList targets() const;
private: private:
void parseCMakeLists(const QDir &directory); void parseCMakeLists();
QString findCbpFile(const QDir &); QString findCbpFile(const QDir &);
void createCbpFile(const QDir &);
void buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list); void buildTree(CMakeProjectNode *rootNode, QList<ProjectExplorer::FileNode *> list);
ProjectExplorer::FolderNode *findOrCreateFolder(CMakeProjectNode *rootNode, QString directory); ProjectExplorer::FolderNode *findOrCreateFolder(CMakeProjectNode *rootNode, QString directory);

View File

@@ -36,18 +36,30 @@
#include "cmakeproject.h" #include "cmakeproject.h"
#include "cmakeprojectconstants.h" #include "cmakeprojectconstants.h"
#include <coreplugin/icore.h>
#include <coreplugin/uniqueidmanager.h> #include <coreplugin/uniqueidmanager.h>
#include <projectexplorer/projectexplorerconstants.h> #include <projectexplorer/projectexplorerconstants.h>
#include <projectexplorer/environment.h>
#include <qtconcurrent/QtConcurrentTools>
#include <QtCore/QtConcurrentRun>
#include <QtCore/QSettings>
#include <QtGui/QFormLayout>
using namespace CMakeProjectManager::Internal; using namespace CMakeProjectManager::Internal;
CMakeManager::CMakeManager() CMakeManager::CMakeManager(CMakeSettingsPage *cmakeSettingsPage)
: m_settingsPage(cmakeSettingsPage)
{ {
Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance(); Core::UniqueIDManager *uidm = Core::UniqueIDManager::instance();
m_projectContext = uidm->uniqueIdentifier(CMakeProjectManager::Constants::PROJECTCONTEXT); m_projectContext = uidm->uniqueIdentifier(CMakeProjectManager::Constants::PROJECTCONTEXT);
m_projectLanguage = uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX); m_projectLanguage = uidm->uniqueIdentifier(ProjectExplorer::Constants::LANG_CXX);
} }
CMakeSettingsPage::~CMakeSettingsPage()
{
}
int CMakeManager::projectContext() const int CMakeManager::projectContext() const
{ {
return m_projectContext; return m_projectContext;
@@ -61,6 +73,14 @@ int CMakeManager::projectLanguage() const
ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName) ProjectExplorer::Project *CMakeManager::openProject(const QString &fileName)
{ {
// TODO check wheter this project is already opened // TODO check wheter this project is already opened
// Check that we have a cmake executable first
// Look at the settings first
QString cmakeExecutable = m_settingsPage->cmakeExecutable();
if (cmakeExecutable.isNull())
m_settingsPage->askUserForCMakeExecutable();
cmakeExecutable = m_settingsPage->cmakeExecutable();
if (cmakeExecutable.isNull())
return 0;
return new CMakeProject(this, fileName); return new CMakeProject(this, fileName);
} }
@@ -68,3 +88,204 @@ QString CMakeManager::mimeType() const
{ {
return Constants::CMAKEMIMETYPE; return Constants::CMAKEMIMETYPE;
} }
QString CMakeManager::cmakeExecutable() const
{
return m_settingsPage->cmakeExecutable();
}
// TODO need to refactor this out
// we probably want the process instead of this function
// cmakeproject then could even run the cmake process in the background, adding the files afterwards
// sounds like a plan
QString CMakeManager::createXmlFile(const QStringList &arguments, const QString &sourceDirectory, const QDir &buildDirectory)
{
// We create a cbp file, only if we didn't find a cbp file in the base directory
// Yet that can still override cbp files in subdirectories
// And we are creating tons of files in the source directories
// All of that is not really nice.
// The mid term plan is to move away from the CodeBlocks Generator and use our own
// QtCreator generator, which actually can be very similar to the CodeBlock Generator
// TODO we need to pass on the same paremeters as the cmakestep
QString buildDirectoryPath = buildDirectory.absolutePath();
qDebug()<<"Creating cbp file in"<<buildDirectoryPath;
buildDirectory.mkpath(buildDirectoryPath);
QProcess cmake;
cmake.setWorkingDirectory(buildDirectoryPath);
cmake.start(cmakeExecutable(), QStringList() << sourceDirectory << arguments << "-GCodeBlocks - Unix Makefiles");
qDebug()<<cmakeExecutable()<<sourceDirectory << arguments;
cmake.waitForFinished(-1);
cmake.setProcessChannelMode(QProcess::MergedChannels);
QString output = cmake.readAll();
qDebug()<<"cmake output: \n"<<output;
return output;
}
/////
// CMakeRunner
////
// TODO give a better name, what this class is to update cached information
// about a cmake executable, with qtconcurrent
// The nifty feature of this class is that it does so in a seperate thread,
// not blocking the main thread
CMakeRunner::CMakeRunner()
: m_cacheUpToDate(false)
{
}
void CMakeRunner::run(QFutureInterface<void> &fi)
{
m_mutex.lock();
QString executable = m_executable;
m_mutex.unlock();
QProcess cmake;
cmake.start(executable, QStringList()<<"--help");
cmake.waitForFinished();
QString response = cmake.readAll();
QRegExp versionRegexp("^cmake version ([*\\d\\.]*)-(|patch (\\d*))(|\\r)\\n");
versionRegexp.indexIn(response);
m_mutex.lock();
m_supportsQtCreator = response.contains("QtCreator");
m_version = versionRegexp.cap(1);
if (!versionRegexp.capturedTexts().size()>3)
m_version += "." + versionRegexp.cap(3);
m_cacheUpToDate = true;
m_mutex.unlock();
fi.reportFinished();
}
void CMakeRunner::setExecutable(const QString &executable)
{
waitForUpToDate();
m_mutex.lock();
m_executable = executable;
m_cacheUpToDate = false;
m_mutex.unlock();
m_future = QtConcurrent::run(&CMakeRunner::run, this);
}
QString CMakeRunner::executable() const
{
waitForUpToDate();
m_mutex.lock();
QString result = m_executable;
m_mutex.unlock();
return result;
}
QString CMakeRunner::version() const
{
waitForUpToDate();
m_mutex.lock();
QString result = m_version;
m_mutex.unlock();
return result;
}
bool CMakeRunner::supportsQtCreator() const
{
waitForUpToDate();
m_mutex.lock();
bool result = m_supportsQtCreator;
m_mutex.unlock();
return result;
}
void CMakeRunner::waitForUpToDate() const
{
m_future.waitForFinished();
}
/////
// CMakeSettingsPage
////
CMakeSettingsPage::CMakeSettingsPage()
{
Core::ICore *core = Core::ICore::instance();
QSettings * settings = core->settings();
settings->beginGroup("CMakeSettings");
m_cmakeRunner.setExecutable(settings->value("cmakeExecutable").toString());
settings->endGroup();
}
QString CMakeSettingsPage::findCmakeExecutable() const
{
ProjectExplorer::Environment env = ProjectExplorer::Environment::systemEnvironment();
return env.searchInPath("cmake");
}
QString CMakeSettingsPage::name() const
{
return "CMake";
}
QString CMakeSettingsPage::category() const
{
return "CMake";
}
QString CMakeSettingsPage::trCategory() const
{
return tr("CMake");
}
QWidget *CMakeSettingsPage::createPage(QWidget *parent)
{
QWidget *w = new QWidget(parent);
QFormLayout *fl = new QFormLayout(w);
m_pathchooser = new Core::Utils::PathChooser(w);
m_pathchooser->setExpectedKind(Core::Utils::PathChooser::Command);
fl->addRow("CMake executable", m_pathchooser);
m_pathchooser->setPath(cmakeExecutable());
return w;
}
void CMakeSettingsPage::saveSettings() const
{
QSettings *settings = Core::ICore::instance()->settings();
settings->beginGroup("CMakeSettings");
settings->setValue("cmakeExecutable", m_cmakeRunner.executable());
settings->endGroup();
}
void CMakeSettingsPage::apply()
{
m_cmakeRunner.setExecutable(m_pathchooser->path());
saveSettings();
}
void CMakeSettingsPage::finish()
{
}
QString CMakeSettingsPage::cmakeExecutable() const
{
if (m_cmakeRunner.executable().isEmpty()) {
QString cmakeExecutable = findCmakeExecutable();
if (!cmakeExecutable.isEmpty()) {
m_cmakeRunner.setExecutable(cmakeExecutable);
saveSettings();
}
}
return m_cmakeRunner.executable();
}
void CMakeSettingsPage::askUserForCMakeExecutable()
{
// TODO implement
// That is ideally add a label to the settings page, which says something
// to the effect: please configure the cmake executable
// and show the settings page
// ensure that we rehide the label in the finish() function
// But to test that i need an environment without cmake, e.g. windows
}

View File

@@ -34,27 +34,82 @@
#ifndef CMAKEPROJECTMANAGER_H #ifndef CMAKEPROJECTMANAGER_H
#define CMAKEPROJECTMANAGER_H #define CMAKEPROJECTMANAGER_H
#include <coreplugin/dialogs/ioptionspage.h>
#include <projectexplorer/iprojectmanager.h> #include <projectexplorer/iprojectmanager.h>
#include <utils/pathchooser.h>
#include <QtCore/QFuture>
#include <QtCore/QStringList>
#include <QtCore/QDir>
namespace CMakeProjectManager { namespace CMakeProjectManager {
namespace Internal { namespace Internal {
class CMakeSettingsPage;
class CMakeRunner;
class CMakeManager : public ProjectExplorer::IProjectManager class CMakeManager : public ProjectExplorer::IProjectManager
{ {
Q_OBJECT Q_OBJECT
public: public:
CMakeManager(); CMakeManager(CMakeSettingsPage *cmakeSettingsPage);
virtual int projectContext() const; virtual int projectContext() const;
virtual int projectLanguage() const; virtual int projectLanguage() const;
//virtual bool canOpenProject(const QString &fileName);
virtual ProjectExplorer::Project *openProject(const QString &fileName); virtual ProjectExplorer::Project *openProject(const QString &fileName);
virtual QString mimeType() const; virtual QString mimeType() const;
//virtual QString fileFilter() const; QString cmakeExecutable() const;
QString createXmlFile(const QStringList &arguments, const QString &sourceDirectory, const QDir &buildDirectory);
private: private:
int m_projectContext; int m_projectContext;
int m_projectLanguage; int m_projectLanguage;
CMakeSettingsPage *m_settingsPage;
};
class CMakeRunner
{
public:
CMakeRunner();
void run(QFutureInterface<void> &fi);
void setExecutable(const QString &executable);
QString executable() const;
QString version() const;
bool supportsQtCreator() const;
void waitForUpToDate() const;
private:
QString m_executable;
QString m_version;
bool m_supportsQtCreator;
bool m_cacheUpToDate;
mutable QFuture<void> m_future;
mutable QMutex m_mutex;
};
class CMakeSettingsPage : public Core::IOptionsPage
{
Q_OBJECT
public:
CMakeSettingsPage();
virtual ~CMakeSettingsPage();
virtual QString name() const;
virtual QString category() const;
virtual QString trCategory() const;
virtual QWidget *createPage(QWidget *parent);
virtual void apply();
virtual void finish();
QString cmakeExecutable() const;
void askUserForCMakeExecutable();
private:
void updateCachedInformation() const;
void saveSettings() const;
QString findCmakeExecutable() const;
mutable CMakeRunner m_cmakeRunner;
Core::Utils::PathChooser *m_pathchooser;
}; };
} // namespace Internal } // namespace Internal

View File

@@ -9,12 +9,15 @@ HEADERS = cmakeproject.h \
cmakeprojectnodes.h \ cmakeprojectnodes.h \
cmakestep.h \ cmakestep.h \
makestep.h \ makestep.h \
cmakerunconfiguration.h cmakerunconfiguration.h \
cmakeconfigurewidget.h
SOURCES = cmakeproject.cpp \ SOURCES = cmakeproject.cpp \
cmakeprojectplugin.cpp \ cmakeprojectplugin.cpp \
cmakeprojectmanager.cpp \ cmakeprojectmanager.cpp \
cmakeprojectnodes.cpp \ cmakeprojectnodes.cpp \
cmakestep.cpp \ cmakestep.cpp \
makestep.cpp \ makestep.cpp \
cmakerunconfiguration.cpp cmakerunconfiguration.cpp \
cmakeconfigurewidget.cpp
RESOURCES += cmakeproject.qrc RESOURCES += cmakeproject.qrc
FORMS += cmakeconfigurewidget.ui

View File

@@ -59,7 +59,9 @@ bool CMakeProjectPlugin::initialize(const QStringList & /*arguments*/, QString *
Core::ICore *core = Core::ICore::instance(); Core::ICore *core = Core::ICore::instance();
if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":cmakeproject/CMakeProject.mimetypes.xml"), errorMessage)) if (!core->mimeDatabase()->addMimeTypes(QLatin1String(":cmakeproject/CMakeProject.mimetypes.xml"), errorMessage))
return false; return false;
addAutoReleasedObject(new CMakeManager()); CMakeSettingsPage *cmp = new CMakeSettingsPage();
addAutoReleasedObject(cmp);
addAutoReleasedObject(new CMakeManager(cmp));
addAutoReleasedObject(new CMakeBuildStepFactory()); addAutoReleasedObject(new CMakeBuildStepFactory());
addAutoReleasedObject(new MakeBuildStepFactory()); addAutoReleasedObject(new MakeBuildStepFactory());
addAutoReleasedObject(new CMakeRunConfigurationFactory()); addAutoReleasedObject(new CMakeRunConfigurationFactory());

View File

@@ -36,6 +36,7 @@
#include "cmakeproject.h" #include "cmakeproject.h"
#include "cmakeprojectconstants.h" #include "cmakeprojectconstants.h"
#include <projectexplorer/environment.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <QtGui/QFormLayout> #include <QtGui/QFormLayout>
#include <QtGui/QLineEdit> #include <QtGui/QLineEdit>
@@ -56,7 +57,10 @@ bool CMakeStep::init(const QString &buildConfiguration)
{ {
setEnabled(buildConfiguration, true); setEnabled(buildConfiguration, true);
setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration)); setWorkingDirectory(buildConfiguration, m_pro->buildDirectory(buildConfiguration));
setCommand(buildConfiguration, "cmake"); // TODO give full path here?
CMakeManager *cmakeProjectManager = static_cast<CMakeManager *>(m_pro->projectManager());
setCommand(buildConfiguration, cmakeProjectManager->cmakeExecutable());
QString sourceDir = QFileInfo(m_pro->file()->fileName()).absolutePath(); QString sourceDir = QFileInfo(m_pro->file()->fileName()).absolutePath();
setArguments(buildConfiguration, setArguments(buildConfiguration,
@@ -99,14 +103,14 @@ bool CMakeStep::immutable() const
return true; return true;
} }
QString CMakeStep::userArguments(const QString &buildConfiguration) const QStringList CMakeStep::userArguments(const QString &buildConfiguration) const
{ {
return ProjectExplorer::Environment::joinArgumentList(value(buildConfiguration, "userArguments").toStringList()); return value(buildConfiguration, "userArguments").toStringList();
} }
void CMakeStep::setUserArguments(const QString &buildConfiguration, const QString &arguments) void CMakeStep::setUserArguments(const QString &buildConfiguration, const QStringList &arguments)
{ {
setValue(buildConfiguration, "userArguments", ProjectExplorer::Environment::parseCombinedArgString(arguments)); setValue(buildConfiguration, "userArguments", arguments);
} }
// //
@@ -132,13 +136,13 @@ void CMakeBuildStepConfigWidget::init(const QString &buildConfiguration)
{ {
m_buildConfiguration = buildConfiguration; m_buildConfiguration = buildConfiguration;
disconnect(m_arguments, SIGNAL(textChanged(QString)), this, SLOT(argumentsLineEditChanged())); disconnect(m_arguments, SIGNAL(textChanged(QString)), this, SLOT(argumentsLineEditChanged()));
m_arguments->setText(m_cmakeStep->userArguments(buildConfiguration)); m_arguments->setText(ProjectExplorer::Environment::joinArgumentList(m_cmakeStep->userArguments(buildConfiguration)));
connect(m_arguments, SIGNAL(textChanged(QString)), this, SLOT(argumentsLineEditChanged())); connect(m_arguments, SIGNAL(textChanged(QString)), this, SLOT(argumentsLineEditChanged()));
} }
void CMakeBuildStepConfigWidget::argumentsLineEditChanged() void CMakeBuildStepConfigWidget::argumentsLineEditChanged()
{ {
m_cmakeStep->setUserArguments(m_buildConfiguration, m_arguments->text()); m_cmakeStep->setUserArguments(m_buildConfiguration, ProjectExplorer::Environment::parseCombinedArgString(m_arguments->text()));
} }
// //

View File

@@ -63,8 +63,8 @@ public:
virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget(); virtual ProjectExplorer::BuildStepConfigWidget *createConfigWidget();
virtual bool immutable() const; virtual bool immutable() const;
void setUserArguments(const QString &buildConfiguration, const QString &arguments); void setUserArguments(const QString &buildConfiguration, const QStringList &arguments);
QString userArguments(const QString &buildConfiguration) const; QStringList userArguments(const QString &buildConfiguration) const;
private: private:
CMakeProject *m_pro; CMakeProject *m_pro;
}; };

View File

@@ -183,10 +183,6 @@ void Environment::clear()
m_values.clear(); m_values.clear();
} }
// currently it returns the string that was passed in, except
// under windows and if the executable does not end in .exe
// then it returns executable appended with .exe
// that is clearly wrong
QString Environment::searchInPath(QString executable) QString Environment::searchInPath(QString executable)
{ {
// qDebug()<<"looking for "<<executable<< "in PATH: "<<m_values.value("PATH"); // qDebug()<<"looking for "<<executable<< "in PATH: "<<m_values.value("PATH");

View File

@@ -6,7 +6,7 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>521</width> <width>551</width>
<height>300</height> <height>300</height>
</rect> </rect>
</property> </property>
@@ -35,7 +35,7 @@
<item> <item>
<widget class="QComboBox" name="runConfigurationCombo"> <widget class="QComboBox" name="runConfigurationCombo">
<property name="sizeAdjustPolicy"> <property name="sizeAdjustPolicy">
<enum>QComboBox::AdjustToMinimumContentsLength</enum> <enum>QComboBox::AdjustToContents</enum>
</property> </property>
<property name="minimumContentsLength"> <property name="minimumContentsLength">
<number>30</number> <number>30</number>