diff options
author | Radovan Zivkovic <pivonroll@gmail.com> | 2012-12-06 22:16:25 +0100 |
---|---|---|
committer | Oswald Buddenhagen <oswald.buddenhagen@digia.com> | 2014-03-11 19:54:51 +0100 |
commit | e207a126b32e1989ddc21f6107d2da3b13596387 (patch) | |
tree | 015d00d2dc9e9ab44a1d336cd6233d8b6e09bb3b | |
parent | 169921274f17c46b32b6ef5a32c7778ee4c37c08 (diff) |
Added Visual Studio settings page and choice for MS Build command.
Change-Id: Ia5a3b089d92cbd00ce15a03ebcfa2a67cf351dc0
Reviewed-by: Bojan Petrovic <bojan85@gmail.com>
-rw-r--r-- | src/plugins/vcprojectmanager/vcmakestep.cpp | 126 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcmakestep.h | 22 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcproject.cpp | 1 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcprojectbuildconfiguration.cpp | 1 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcprojectbuildoptionspage.cpp | 417 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcprojectbuildoptionspage.h | 121 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcprojectmanager.cpp | 16 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcprojectmanager.h | 8 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcprojectmanagerconstants.h | 9 | ||||
-rw-r--r-- | src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp | 5 |
10 files changed, 710 insertions, 16 deletions
diff --git a/src/plugins/vcprojectmanager/vcmakestep.cpp b/src/plugins/vcprojectmanager/vcmakestep.cpp index 424bae0c60..4a0f4c9187 100644 --- a/src/plugins/vcprojectmanager/vcmakestep.cpp +++ b/src/plugins/vcprojectmanager/vcmakestep.cpp @@ -1,9 +1,12 @@ #include "vcmakestep.h" #include "vcprojectbuildconfiguration.h" +#include "vcprojectbuildoptionspage.h" #include "vcprojectfile.h" +#include "vcprojectmanager.h" #include "vcprojectmanagerconstants.h" +#include <coreplugin/icore.h> #include <projectexplorer/buildsteplist.h> #include <projectexplorer/project.h> #include <projectexplorer/projectconfiguration.h> @@ -11,8 +14,10 @@ #include <projectexplorer/target.h> #include <projectexplorer/task.h> +#include <QComboBox> #include <QFormLayout> #include <QLabel> +#include <QSettings> namespace VcProjectManager { namespace Internal { @@ -33,7 +38,7 @@ bool VcMakeStep::init() { VcProjectBuildConfiguration *bc = vcProjectBuildConfiguration(); - if (!bc) { + if (!bc || m_msBuildCommand.isEmpty()) { m_tasks.append(ProjectExplorer::Task(ProjectExplorer::Task::Error, tr("Qt Creator didn't detected any proper build tool for .vcproj files."), Utils::FileName(), -1, @@ -41,15 +46,16 @@ bool VcMakeStep::init() return true; } - ProjectExplorer::ProcessParameters *pp = processParameters(); - pp->setMacroExpander(bc->macroExpander()); - pp->setEnvironment(bc->environment()); - pp->setWorkingDirectory(bc->buildDirectory()); - pp->setCommand(QString("C:/Windows/Microsoft.NET/Framework/v3.5/MSBuild.exe")); + m_processParams = processParameters(); + m_processParams->setCommand(m_msBuildCommand); + m_processParams->setMacroExpander(bc->macroExpander()); + m_processParams->setEnvironment(bc->environment()); + m_processParams->setWorkingDirectory(bc->buildDirectory()); + ProjectExplorer::Project *project = bc->target()->project(); VcProjectFile* document = static_cast<VcProjectFile *>(project->document()); + m_processParams->setArguments(document->filePath()); - pp->setArguments(document->filePath()); return AbstractProcessStep::init(); } @@ -91,6 +97,16 @@ VcProjectBuildConfiguration *VcMakeStep::vcProjectBuildConfiguration() const return static_cast<VcProjectBuildConfiguration *>(buildConfiguration()); } +QString VcMakeStep::msBuildCommand() const +{ + return m_msBuildCommand; +} + +void VcMakeStep::setMsBuildCommand(const QString &msBuild) +{ + m_msBuildCommand = msBuild; +} + QVariantMap VcMakeStep::toMap() const { return BuildStep::toMap(); @@ -115,9 +131,46 @@ VcMakeStepConfigWidget::VcMakeStepConfigWidget(VcMakeStep *makeStep) : QFormLayout *mainLayout = new QFormLayout(this); mainLayout->setMargin(0); mainLayout->setFieldGrowthPolicy(QFormLayout::ExpandingFieldsGrow); - QLabel *label = new QLabel("C:/Windows/Microsoft.NET/Framework/v3.5/MSBuild.exe"); - mainLayout->addRow(tr("Command:"), label); + + m_msBuildComboBox = new QComboBox(); + m_msBuildPath = new QLabel(); + mainLayout->addRow(tr("Command:"), m_msBuildPath); + mainLayout->addRow(tr("MS Build:"), m_msBuildComboBox); setLayout(mainLayout); + + if (m_makeStep) { + VcProjectBuildConfiguration *bc = m_makeStep->vcProjectBuildConfiguration(); + ProjectExplorer::Project *project = bc->target()->project(); + VcManager *vcManager = static_cast<VcManager *>(project->projectManager()); + QVector<MsBuildInformation *> msBuildInfos = vcManager->buildOptionsPage()->msBuilds(); + + if (msBuildInfos.size()) { + foreach (const MsBuildInformation *msBuild, msBuildInfos) { + if (!msBuild->m_executable.isEmpty()) { + QFileInfo fileInfo(msBuild->m_executable); + QString buildName = fileInfo.fileName() + QLatin1Char(' ') + msBuild->m_version; + m_msBuildComboBox->addItem(buildName, msBuild->m_executable); + } + } + } + else { + m_msBuildPath->setText(tr("No Ms Build tools found.")); + m_msBuildComboBox->setEnabled(false); + } + + // NOTE(Radovan): place Ms Build settings read from our .user file for selected MS Build for this project + // and setting that ms build as ms build command in this make step + if (m_makeStep->msBuildCommand().isEmpty() && m_msBuildComboBox->count()) { + m_msBuildComboBox->setCurrentIndex(0); + onMsBuildSelectionChanged(0); + } + + connect(m_msBuildComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(onMsBuildSelectionChanged(int))); + + connect(vcManager->buildOptionsPage(), SIGNAL(msBuildInfomationsUpdated()), + this, SLOT(onMsBuildInformationsUpdated())); + } } QString VcMakeStepConfigWidget::displayName() const @@ -130,6 +183,60 @@ QString VcMakeStepConfigWidget::summaryText() const return tr("This is Vc Project's build step configuration widget."); } +void VcMakeStepConfigWidget::onMsBuildSelectionChanged(int index) +{ + if (m_makeStep && m_msBuildComboBox && 0 <= index && index < m_msBuildComboBox->count()) { + m_makeStep->setMsBuildCommand(m_msBuildComboBox->itemData(index).toString()); + m_msBuildPath->setText(m_makeStep->msBuildCommand()); + } +} + +void VcMakeStepConfigWidget::onMsBuildInformationsUpdated() +{ + disconnect(m_msBuildComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(onMsBuildSelectionChanged(int))); + + m_msBuildComboBox->clear(); + VcProjectBuildConfiguration *bc = m_makeStep->vcProjectBuildConfiguration(); + ProjectExplorer::Project *project = bc->target()->project(); + VcManager *vcManager = static_cast<VcManager *>(project->projectManager()); + QVector<MsBuildInformation *> msBuildInfos = vcManager->buildOptionsPage()->msBuilds(); + bool msBuildExists = false; + + foreach (const MsBuildInformation *msBuild, msBuildInfos) { + if (!msBuild->m_executable.isEmpty()) { + QFileInfo fileInfo(msBuild->m_executable); + QString buildName = fileInfo.fileName() + QLatin1Char(' ') + msBuild->m_version; + QVariant msBuildFullPath(msBuild->m_executable); + m_msBuildComboBox->addItem(buildName, msBuildFullPath); + + if (!m_makeStep->msBuildCommand().isEmpty() && msBuildFullPath == m_makeStep->msBuildCommand()) { + m_msBuildComboBox->setCurrentIndex(m_msBuildComboBox->count() - 1); + msBuildExists = true; + } + } + } + + if (!msBuildExists) { + if (m_msBuildComboBox->count()) { + onMsBuildSelectionChanged(m_msBuildComboBox->currentIndex()); + + if (!m_msBuildComboBox->isEnabled()) + m_msBuildComboBox->setEnabled(true); + } + + else { + QString msBuildCommand; + m_makeStep->setMsBuildCommand(msBuildCommand); + m_msBuildPath->setText(tr("No Ms Build tools found.")); + m_msBuildComboBox->setEnabled(false); + } + } + + connect(m_msBuildComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(onMsBuildSelectionChanged(int))); +} + //////////////////// // VcMakeStepFactory //////////////////// @@ -144,7 +251,6 @@ VcMakeStepFactory::~VcMakeStepFactory() bool VcMakeStepFactory::canCreate(ProjectExplorer::BuildStepList *parent, const Core::Id id) const { - qDebug() << "VcMakeStepFactory::canCreate()"; if (parent->target()->project()->id() == Constants::VC_PROJECT_ID) return id == MS_ID; return false; diff --git a/src/plugins/vcprojectmanager/vcmakestep.h b/src/plugins/vcprojectmanager/vcmakestep.h index 606301563e..1e019d3ac7 100644 --- a/src/plugins/vcprojectmanager/vcmakestep.h +++ b/src/plugins/vcprojectmanager/vcmakestep.h @@ -3,10 +3,14 @@ #include <projectexplorer/abstractprocessstep.h> +class QComboBox; +class QLabel; + namespace VcProjectManager { namespace Internal { class VcProjectBuildConfiguration; +struct MsBuildInformation; class VcMakeStep : public ProjectExplorer::AbstractProcessStep { @@ -22,14 +26,19 @@ public: bool immutable() const; VcProjectBuildConfiguration *vcProjectBuildConfiguration() const; + QString msBuildCommand() const; + void setMsBuildCommand(const QString &msBuild); QVariantMap toMap() const; bool fromMap(const QVariantMap &map); + private: explicit VcMakeStep(ProjectExplorer::BuildStepList *parent, VcMakeStep *vcMakeStep); QList<ProjectExplorer::Task> m_tasks; QFutureInterface<bool> *m_futureInterface; + ProjectExplorer::ProcessParameters *m_processParams; + QString m_msBuildCommand; }; class VcMakeStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget @@ -37,10 +46,17 @@ class VcMakeStepConfigWidget : public ProjectExplorer::BuildStepConfigWidget Q_OBJECT public: VcMakeStepConfigWidget(VcMakeStep *makeStep); - virtual QString displayName() const; - virtual QString summaryText() const; + QString displayName() const; + QString summaryText() const; + +private slots: + void onMsBuildSelectionChanged(int index); + void onMsBuildInformationsUpdated(); + private: VcMakeStep *m_makeStep; + QComboBox *m_msBuildComboBox; + QLabel *m_msBuildPath; }; class VcMakeStepFactory : public ProjectExplorer::IBuildStepFactory @@ -49,7 +65,7 @@ class VcMakeStepFactory : public ProjectExplorer::IBuildStepFactory public: explicit VcMakeStepFactory(QObject *parent = 0); - virtual ~VcMakeStepFactory(); + ~VcMakeStepFactory(); bool canCreate(ProjectExplorer::BuildStepList *parent, const Core::Id id) const; ProjectExplorer::BuildStep *create(ProjectExplorer::BuildStepList *parent, const Core::Id id); diff --git a/src/plugins/vcprojectmanager/vcproject.cpp b/src/plugins/vcprojectmanager/vcproject.cpp index c93a00c9da..8687f7ee60 100644 --- a/src/plugins/vcprojectmanager/vcproject.cpp +++ b/src/plugins/vcprojectmanager/vcproject.cpp @@ -119,6 +119,7 @@ bool VcProject::fromMap(const QVariantMap &map) qDebug() << "VcProject::fromMap() defaultKit:" << defaultKit->displayName(); Target *target = new Target(this, defaultKit); VcProjectBuildConfiguration *bc = new VcProjectBuildConfiguration(target); + bc->setDefaultDisplayName(tr("vcproj")); ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); VcMakeStep *makeStep = new VcMakeStep(buildSteps); buildSteps->insertStep(0, makeStep); diff --git a/src/plugins/vcprojectmanager/vcprojectbuildconfiguration.cpp b/src/plugins/vcprojectmanager/vcprojectbuildconfiguration.cpp index ef8afa29a6..ac03fc5c03 100644 --- a/src/plugins/vcprojectmanager/vcprojectbuildconfiguration.cpp +++ b/src/plugins/vcprojectmanager/vcprojectbuildconfiguration.cpp @@ -111,6 +111,7 @@ VcProjectBuildConfiguration *VcProjectBuildConfigurationFactory::create(ProjectE VcProjectBuildConfiguration *bc = new VcProjectBuildConfiguration(parent); bc->setDisplayName(buildConfigName); + bc->setDefaultDisplayName(buildConfigName); ProjectExplorer::BuildStepList *buildSteps = bc->stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); diff --git a/src/plugins/vcprojectmanager/vcprojectbuildoptionspage.cpp b/src/plugins/vcprojectmanager/vcprojectbuildoptionspage.cpp new file mode 100644 index 0000000000..48ef7fe553 --- /dev/null +++ b/src/plugins/vcprojectmanager/vcprojectbuildoptionspage.cpp @@ -0,0 +1,417 @@ +#include "vcprojectbuildoptionspage.h" + +#include "vcprojectmanagerconstants.h" + +#include <coreplugin/icore.h> +#include <projectexplorer/projectexplorerconstants.h> + +#include <QDialogButtonBox> +#include <QCoreApplication> +#include <QFileDialog> +#include <QFormLayout> +#include <QHBoxLayout> +#include <QHeaderView> +#include <QLabel> +#include <QLineEdit> +#include <QMessageBox> +#include <QProcess> +#include <QPushButton> +#include <QSettings> +#include <QTableWidget> +#include <QVBoxLayout> + +namespace VcProjectManager { +namespace Internal { + +VcProjectEditMsBuildDialog::VcProjectEditMsBuildDialog(QWidget *parent) : + QDialog(parent) +{ + QVBoxLayout *mainLayout = new QVBoxLayout(this); + QHBoxLayout *filePathLayout = new QHBoxLayout; + m_pathChooser = new QLineEdit; + QDialogButtonBox *buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel); + m_browseButton = new QPushButton(tr("Browse...")); + filePathLayout->addWidget(m_pathChooser); + filePathLayout->addWidget(m_browseButton); + filePathLayout->setStretch(0, 1); + mainLayout->addLayout(filePathLayout); + mainLayout->addWidget(buttonBox); + + connect(buttonBox->button(QDialogButtonBox::Ok), SIGNAL(clicked()), + this, SLOT(accept())); + connect(buttonBox->button(QDialogButtonBox::Cancel), SIGNAL(clicked()), + this, SLOT(reject())); + connect(m_browseButton, SIGNAL(clicked()), this, SLOT(showBrowseFileDialog())); +} + +VcProjectEditMsBuildDialog::~VcProjectEditMsBuildDialog() +{ +} + +QString VcProjectEditMsBuildDialog::path() const +{ + return m_pathChooser->text(); +} + +void VcProjectEditMsBuildDialog::setPath(const QString &path) +{ + m_pathChooser->setText(path); +} + +void VcProjectEditMsBuildDialog::showBrowseFileDialog() +{ + m_pathChooser->setText(QFileDialog::getOpenFileName(0, tr("Select Ms Build"), QString(), QString("*.exe"))); +} + +VcProjectBuildOptionsWidget::VcProjectBuildOptionsWidget(QWidget *parent) : + QWidget(parent) +{ + QHBoxLayout *mainLayout = new QHBoxLayout(this); + + QVBoxLayout *buttonLayout = new QVBoxLayout; + m_addMsBuildButton = new QPushButton(tr("Add...")); + m_editBuildButton = new QPushButton(tr("Edit...")); + m_editBuildButton->setEnabled(false); + m_deleteBuildButton = new QPushButton(tr("Delete")); + m_deleteBuildButton->setEnabled(false); + buttonLayout->addWidget(m_addMsBuildButton); + buttonLayout->addWidget(m_editBuildButton); + buttonLayout->addWidget(m_deleteBuildButton); + buttonLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding)); + + QVBoxLayout *tableLayout = new QVBoxLayout; + m_buildTableWidget = new QTableWidget(); + m_buildTableWidget->setColumnCount(2); + QStringList horizontalHeaderLabels; + horizontalHeaderLabels << tr("Executable") << tr("Version"); + m_buildTableWidget->setHorizontalHeaderLabels(horizontalHeaderLabels); + m_buildTableWidget->horizontalHeader()->setResizeMode(QHeaderView::Stretch); + m_buildTableWidget->horizontalHeader()->setClickable(false); + m_buildTableWidget->horizontalHeader()->setMovable(false); + m_buildTableWidget->horizontalHeader()->setSelectionMode(QAbstractItemView::NoSelection); + m_buildTableWidget->verticalHeader()->hide(); + m_buildTableWidget->setSelectionBehavior(QAbstractItemView::SelectRows); + tableLayout->addWidget(m_buildTableWidget); + + tableLayout->addItem(new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::MinimumExpanding)); + + mainLayout->addLayout(tableLayout); + mainLayout->addLayout(buttonLayout); + + connect(m_addMsBuildButton, SIGNAL(clicked()), this, SIGNAL(addNewButtonClicked())); + connect(m_editBuildButton, SIGNAL(clicked()), this, SIGNAL(editButtonClicked())); + connect(m_deleteBuildButton, SIGNAL(clicked()), this, SIGNAL(deleteButtonClicked())); + connect(m_buildTableWidget, SIGNAL(cellClicked(int, int)), this, SLOT(onTableRowIndexChange(int))); +} + +VcProjectBuildOptionsWidget::~VcProjectBuildOptionsWidget() +{ +} + +MsBuildInformation VcProjectBuildOptionsWidget::build(int index) +{ + MsBuildInformation msBuild; + QString exePath; + QString version; + + if (0 <= index && index < m_buildTableWidget->rowCount()) { + exePath = m_buildTableWidget->item(index, 0)->text(); + version = m_buildTableWidget->item(index, 1)->text(); + } + + msBuild.m_version = version; + msBuild.m_executable = exePath; + return msBuild; +} + +int VcProjectBuildOptionsWidget::buildCount() +{ + return m_buildTableWidget->rowCount(); +} + +MsBuildInformation VcProjectBuildOptionsWidget::currentSelectedBuild() const +{ + QModelIndex currentIndex = m_buildTableWidget->selectionModel()->currentIndex(); + if (currentIndex.isValid()) { + MsBuildInformation msBuild; + msBuild.m_executable = m_buildTableWidget->item(currentIndex.row(), 0)->text(); + msBuild.m_version = m_buildTableWidget->item(currentIndex.row(), 1)->text(); + return msBuild; + } + + return MsBuildInformation(); +} + +int VcProjectBuildOptionsWidget::currentSelectedRow() const +{ + if (m_buildTableWidget->selectionModel()->currentIndex().isValid()) + return m_buildTableWidget->selectionModel()->currentIndex().row(); + return -1; +} + +bool VcProjectBuildOptionsWidget::exists(const QString &exePath) +{ + for (int i = 0; i < m_buildTableWidget->rowCount(); ++i) { + QTableWidgetItem *item = m_buildTableWidget->item(i, 0); + + if (item->text() == exePath) + return true; + } + + return false; +} + +void VcProjectBuildOptionsWidget::insertMSBuild(const MsBuildInformation &info) +{ + QTableWidgetItem *exeTableItem = new QTableWidgetItem(); + exeTableItem->setText(info.m_executable); + + QTableWidgetItem *versionTableItem = new QTableWidgetItem(); + versionTableItem->setText(info.m_version); + + m_buildTableWidget->insertRow(m_buildTableWidget->rowCount()); + m_buildTableWidget->setItem(m_buildTableWidget->rowCount() - 1, 0, exeTableItem); + m_buildTableWidget->setItem(m_buildTableWidget->rowCount() - 1, 1, versionTableItem); + + if (!m_buildTableWidget->selectionModel()->currentIndex().isValid()) + m_buildTableWidget->selectRow(0); + + if (!m_editBuildButton->isEnabled()) + m_editBuildButton->setEnabled(true); + + if (!m_deleteBuildButton->isEnabled()) + m_deleteBuildButton->setEnabled(true); +} + +void VcProjectBuildOptionsWidget::removeBuild(int index) +{ + if (0 <= index && index < m_buildTableWidget->rowCount()) + m_buildTableWidget->removeRow(index); + + if (m_buildTableWidget->rowCount() <= 0) { + m_editBuildButton->setEnabled(false); + m_deleteBuildButton->setEnabled(false); + } +} + +void VcProjectBuildOptionsWidget::updateMsBuild(const QString &exePath, const MsBuildInformation &newMsBuildInfo) +{ + for (int i = 0; i < m_buildTableWidget->rowCount(); ++i) { + QTableWidgetItem *item = m_buildTableWidget->item(i, 0); + + if (item->text() == exePath) { + item->setText(newMsBuildInfo.m_executable); + + // update version column item + item = m_buildTableWidget->item(i, 1); + item->setText(newMsBuildInfo.m_version); + break; + } + } +} + +void VcProjectBuildOptionsWidget::onTableRowIndexChange(int index) +{ + if (0 <= index && index < m_buildTableWidget->rowCount()) { + m_editBuildButton->setEnabled(true); + m_deleteBuildButton->setEnabled(true); + } + + else { + m_editBuildButton->setEnabled(false); + m_deleteBuildButton->setEnabled(false); + } + + emit currentBuildSelectionChanged(index); +} + +VcProjectBuildOptionsPage::VcProjectBuildOptionsPage() : + m_optionsWidget(0) +{ + setId(QLatin1String("VcProject.MSBuild")); + setDisplayName(tr("MS Build")); + setCategory(QLatin1String(VcProjectManager::Constants::VC_PROJECT_SETTINGS_CATEGORY)); + setDisplayCategory(QCoreApplication::translate("ProjectExplorer", + VcProjectManager::Constants::VC_PROJECT_SETTINGS_TR_CATEGORY)); + + // TODO(Radovan): create and set proper icon + setCategoryIcon(QLatin1String(ProjectExplorer::Constants::PROJECTEXPLORER_SETTINGS_CATEGORY_ICON)); + loadSettings(); +} + +VcProjectBuildOptionsPage::~VcProjectBuildOptionsPage() +{ +} + +QWidget *VcProjectBuildOptionsPage::createPage(QWidget *parent) +{ + m_optionsWidget = new VcProjectBuildOptionsWidget(parent); + + foreach (const MsBuildInformation *msBuildInfo, m_msBuildInformations) + m_optionsWidget->insertMSBuild(*msBuildInfo); + + connect(m_optionsWidget, SIGNAL(addNewButtonClicked()), this, SLOT(addNewMsBuild())); + connect(m_optionsWidget, SIGNAL(editButtonClicked()), this, SLOT(editMsBuild())); + connect(m_optionsWidget, SIGNAL(deleteButtonClicked()), this, SLOT(deleteMsBuild())); + return m_optionsWidget; +} + +void VcProjectBuildOptionsPage::apply() +{ + if (!m_optionsWidget || (m_optionsWidget && m_optionsWidget->buildCount() < 0)) + return; + + saveSettings(); +} + +void VcProjectBuildOptionsPage::finish() +{ +} + +QVector<MsBuildInformation *> VcProjectBuildOptionsPage::msBuilds() const +{ + return m_msBuildInformations; +} + +void VcProjectBuildOptionsPage::loadSettings() +{ + QSettings *settings = Core::ICore::settings(); + settings->beginGroup(QLatin1String(VcProjectManager::Constants::VC_PROJECT_SETTINGS_GROUP)); + QString msBuildInformationData = settings->value(QLatin1String(VcProjectManager::Constants::VC_PROJECT_MS_BUILD_INFORMATIONS)).toString(); + settings->endGroup(); + + foreach (MsBuildInformation *msBuild, m_msBuildInformations) + delete msBuild; + + m_msBuildInformations.clear(); + + if (!msBuildInformationData.isEmpty()) { + QStringList msBuildInformations = msBuildInformationData.split(QLatin1Char(';')); + + foreach (QString msBuildInfo, msBuildInformations) { + QStringList msBuildData = msBuildInfo.split(QLatin1Char(',')); + MsBuildInformation *msBuild = new MsBuildInformation(); + msBuild->m_executable = msBuildData.first(); + msBuild->m_version = msBuildData.last(); + m_msBuildInformations.append(msBuild); + } + } +} + +void VcProjectBuildOptionsPage::saveSettings() +{ + if (m_optionsWidget) { + QString msBuildInformations; + + for (int i = 0; i < m_optionsWidget->buildCount(); ++i) { + MsBuildInformation msBuildInfo = m_optionsWidget->build(i); + msBuildInformations += msBuildInfo.m_executable + QLatin1Char(',') + msBuildInfo.m_version; + + if (i != m_optionsWidget->buildCount() - 1) + msBuildInformations += QLatin1Char(';'); + } + + QSettings *settings = Core::ICore::settings(); + settings->beginGroup(QLatin1String(VcProjectManager::Constants::VC_PROJECT_SETTINGS_GROUP)); + settings->setValue(QLatin1String(VcProjectManager::Constants::VC_PROJECT_MS_BUILD_INFORMATIONS), msBuildInformations); + settings->endGroup(); + + loadSettings(); + emit msBuildInfomationsUpdated(); + } +} + +void VcProjectBuildOptionsPage::startVersionCheck() +{ + if (m_validator.m_executable.isEmpty()) { + return; + } + + m_validator.m_process = new QProcess(); + connect(m_validator.m_process, SIGNAL(finished(int)), + this, SLOT(versionCheckFinished())); + + m_validator.m_process->start(m_validator.m_executable, QStringList(QLatin1String("/version"))); + m_validator.m_process->waitForStarted(); +} + +void VcProjectBuildOptionsPage::addNewMsBuild() +{ + QString newMsBuild = QFileDialog::getOpenFileName(0, tr("Select Ms Build"), QString(), QString("*.exe")); + + if (m_optionsWidget && !newMsBuild.isEmpty()) { + if (m_optionsWidget->exists(newMsBuild)) { + QMessageBox::information(0, tr("Ms Build already present"), tr("Selected MSBuild.exe is already present in the list.")); + return; + } + + m_validator.m_executable = newMsBuild; + m_validator.m_requestType = VcProjectValidator::ValidationRequest_Add; + startVersionCheck(); + } +} + +void VcProjectBuildOptionsPage::editMsBuild() +{ + if (m_optionsWidget && m_optionsWidget->currentSelectedRow() != -1) { + MsBuildInformation currentSelectedMsBuild = m_optionsWidget->currentSelectedBuild(); + m_validator.m_originalExecutable = currentSelectedMsBuild.m_executable; + + VcProjectEditMsBuildDialog editDialog; + editDialog.setPath(m_validator.m_originalExecutable); + + if (editDialog.exec() == QDialog::Accepted) { + if (editDialog.path() == m_validator.m_originalExecutable) + return; + + m_validator.m_requestType = VcProjectValidator::ValidationRequest_Edit; + m_validator.m_executable = editDialog.path(); + startVersionCheck(); + } + } +} + +void VcProjectBuildOptionsPage::deleteMsBuild() +{ + if (m_optionsWidget && m_optionsWidget->buildCount() > 0) + m_optionsWidget->removeBuild(m_optionsWidget->currentSelectedRow()); +} + +void VcProjectBuildOptionsPage::versionCheckFinished() +{ + if (m_validator.m_process) { + QString response = m_validator.m_process->readAll(); + QStringList splitData = response.split(QLatin1Char('\n')); + + if (m_validator.m_requestType == VcProjectValidator::ValidationRequest_Add) { + MsBuildInformation newMsBuild; + newMsBuild.m_executable = m_validator.m_executable; + newMsBuild.m_version = splitData.last(); + + if (m_optionsWidget) + m_optionsWidget->insertMSBuild(newMsBuild); + } + + else if (m_validator.m_requestType == VcProjectValidator::ValidationRequest_Edit) { + foreach (const MsBuildInformation *msBuildInfo, m_msBuildInformations) { + if (msBuildInfo && msBuildInfo->m_executable == m_validator.m_originalExecutable) { + MsBuildInformation newInfo; + newInfo.m_version = splitData.last(); + newInfo.m_executable = m_validator.m_executable; + + // update table data + if (m_optionsWidget) + m_optionsWidget->updateMsBuild(m_validator.m_originalExecutable, newInfo); + + break; + } + } + } + + m_validator.m_process->deleteLater(); + m_validator.m_process = 0; + } +} + +} // namespace Internal +} // namespace VcProjectManager diff --git a/src/plugins/vcprojectmanager/vcprojectbuildoptionspage.h b/src/plugins/vcprojectmanager/vcprojectbuildoptionspage.h new file mode 100644 index 0000000000..8dbf161d5a --- /dev/null +++ b/src/plugins/vcprojectmanager/vcprojectbuildoptionspage.h @@ -0,0 +1,121 @@ +#ifndef VCPROJECTBUILDOPTIONSPAGE_H +#define VCPROJECTBUILDOPTIONSPAGE_H + +#include <coreplugin/dialogs/ioptionspage.h> + +#include <QDialog> + +class QLabel; +class QLineEdit; +class QProcess; +class QPushButton; +class QTableWidget; + +namespace VcProjectManager { +namespace Internal { + +struct VcProjectValidator { + enum ValidationRequest { + ValidationRequest_Add, + ValidationRequest_Edit + }; + + QString m_originalExecutable; // used only for ValidationRequest_Edit + QString m_executable; + QProcess *m_process; + ValidationRequest m_requestType; +}; + +struct MsBuildInformation { + QString m_executable; + QString m_version; +}; + +class VcProjectEditMsBuildDialog : public QDialog +{ + Q_OBJECT + +public: + VcProjectEditMsBuildDialog(QWidget *parent = 0); + ~VcProjectEditMsBuildDialog(); + + QString path() const; + void setPath(const QString &path); + +private slots: + void showBrowseFileDialog(); + +private: + QLineEdit *m_pathChooser; + QPushButton *m_browseButton; +}; + +class VcProjectBuildOptionsWidget : public QWidget +{ + Q_OBJECT + +public: + VcProjectBuildOptionsWidget(QWidget *parent = 0); + ~VcProjectBuildOptionsWidget(); + + MsBuildInformation build(int index); + int buildCount(); + MsBuildInformation currentSelectedBuild() const; + int currentSelectedRow() const; + bool exists(const QString &exePath); + void insertMSBuild(const MsBuildInformation &info); + void removeBuild(int index); + void updateMsBuild(const QString &exePath, const MsBuildInformation &newMsBuildInfo); + +private slots: + void onTableRowIndexChange(int index); + +signals: + void addNewButtonClicked(); + void editButtonClicked(); + void deleteButtonClicked(); + void currentBuildSelectionChanged(int); + +private: + QPushButton *m_addMsBuildButton; + QPushButton *m_editBuildButton; + QPushButton *m_deleteBuildButton; + QTableWidget *m_buildTableWidget; +}; + +class VcProjectBuildOptionsPage : public Core::IOptionsPage +{ + Q_OBJECT + +public: + VcProjectBuildOptionsPage(); + ~VcProjectBuildOptionsPage(); + + QWidget *createPage(QWidget *parent); + void apply(); + void finish(); + + QVector<MsBuildInformation *> msBuilds() const; + void loadSettings(); + void saveSettings(); + void startVersionCheck(); + +private slots: + void addNewMsBuild(); + void editMsBuild(); + void deleteMsBuild(); + void versionCheckFinished(); + +signals: + void msBuildInfomationsUpdated(); + +private: + QVector<MsBuildInformation *> m_msBuildInformations; + VcProjectBuildOptionsWidget *m_optionsWidget; + VcProjectValidator m_validator; +}; + +} // namespace Internal +} // namespace VcProjectManager + +#endif // VCPROJECTBUILDOPTIONSPAGE_H diff --git a/src/plugins/vcprojectmanager/vcprojectmanager.cpp b/src/plugins/vcprojectmanager/vcprojectmanager.cpp index 9091a2ce00..0e36184f19 100644 --- a/src/plugins/vcprojectmanager/vcprojectmanager.cpp +++ b/src/plugins/vcprojectmanager/vcprojectmanager.cpp @@ -1,6 +1,7 @@ #include "vcprojectmanager.h" #include "vcproject.h" +#include "vcprojectbuildoptionspage.h" #include "vcprojectmanagerconstants.h" #include <coreplugin/actionmanager/actionmanager.h> @@ -18,7 +19,8 @@ using namespace ProjectExplorer; namespace VcProjectManager { namespace Internal { -VcManager::VcManager() +VcManager::VcManager(VcProjectBuildOptionsPage *configPage) : + m_configPage(configPage) { ProjectExplorerPlugin *projectExplorer = ProjectExplorerPlugin::instance(); connect(projectExplorer, SIGNAL(aboutToShowContextMenu(ProjectExplorer::Project*,ProjectExplorer::Node*)), @@ -79,6 +81,18 @@ ProjectExplorer::Project *VcManager::openProject(const QString &fileName, QStrin return new VcProject(this, canonicalFilePath); } +QVector<MsBuildInformation *> VcManager::msBuilds() const +{ + if (!m_configPage) + return QVector<MsBuildInformation *>(); + return m_configPage->msBuilds(); +} + +VcProjectBuildOptionsPage *VcManager::buildOptionsPage() +{ + return m_configPage; +} + void VcManager::reparseActiveProject() { VcProject *project = qobject_cast<VcProject *>(ProjectExplorerPlugin::currentProject()); diff --git a/src/plugins/vcprojectmanager/vcprojectmanager.h b/src/plugins/vcprojectmanager/vcprojectmanager.h index 83d3f26770..052c3f5a62 100644 --- a/src/plugins/vcprojectmanager/vcprojectmanager.h +++ b/src/plugins/vcprojectmanager/vcprojectmanager.h @@ -9,15 +9,20 @@ class QAction; namespace VcProjectManager { namespace Internal { +class VcProjectBuildOptionsPage; +struct MsBuildInformation; + class VcManager : public ProjectExplorer::IProjectManager { Q_OBJECT public: - VcManager(); + VcManager(VcProjectBuildOptionsPage *configPage); QString mimeType() const; ProjectExplorer::Project *openProject(const QString &fileName, QString *errorString); + QVector<MsBuildInformation *> msBuilds() const; + VcProjectBuildOptionsPage *buildOptionsPage(); private slots: void reparseActiveProject(); @@ -28,6 +33,7 @@ private: ProjectExplorer::Project *m_contextProject; QAction *m_reparseAction; QAction *m_reparseContextMenuAction; + VcProjectBuildOptionsPage *m_configPage; }; } // namespace Internal diff --git a/src/plugins/vcprojectmanager/vcprojectmanagerconstants.h b/src/plugins/vcprojectmanager/vcprojectmanagerconstants.h index 6de5e2b67b..14e9d60b73 100644 --- a/src/plugins/vcprojectmanager/vcprojectmanagerconstants.h +++ b/src/plugins/vcprojectmanager/vcprojectmanagerconstants.h @@ -1,6 +1,8 @@ #ifndef VCPROJECTMANAGERCONSTANTS_H #define VCPROJECTMANAGERCONSTANTS_H +#include <qglobal.h> + namespace VcProjectManager { namespace Constants { @@ -9,10 +11,17 @@ const char VC_PROJECT_ID[] = "VcProject.VcProject"; const char VC_PROJECT_CONTEXT[] = "VcProject.ProjectContext"; const char VC_PROJECT_TARGET_ID[] = "VcProject.DefaultVcProjectTarget"; const char VC_PROJECT_BC_ID[] = "VcProject.VcProjectBuildConfiguration"; +const char VC_PROJECT_SETTINGS_CATEGORY[] = "K.VcProjectSettingsCategory"; +const char VC_PROJECT_SETTINGS_TR_CATEGORY[] = QT_TRANSLATE_NOOP("ProjectExplorer", "Visual Studio"); const char REPARSE_ACTION_ID[] = "VcProject.ReparseMenuAction"; const char REPARSE_CONTEXT_MENU_ACTION_ID[] = "VcProject.ReparseContextMenuAction"; +const char VC_PROJECT_SETTINGS_GROUP[] = "VcProjectSettings"; +const char VC_PROJECT_MS_BUILD_INFORMATIONS[] = "VcProject.MsBuildInformations"; +const char VC_PROJECT_MS_BUILD_EXECUTABLE[] = "VcProject.MsBuildExecutable"; +const char VC_PROJECT_MS_BUILD_EXECUTABLE_VERSION[] = "VcProject.MsBuildExecutableVersion"; + //const char ACTION_ID[] = "VcProjectManager.Action"; //const char MENU_ID[] = "VcProjectManager.Menu"; diff --git a/src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp b/src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp index 39b38b6231..4be9b74629 100644 --- a/src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp +++ b/src/plugins/vcprojectmanager/vcprojectmanagerplugin.cpp @@ -3,6 +3,7 @@ #include "vcprojectmanager.h" #include "vcprojectmanagerconstants.h" #include "vcprojectbuildconfiguration.h" +#include "vcprojectbuildoptionspage.h" #include "vcmakestep.h" // TODO: clean up @@ -49,7 +50,9 @@ bool VcProjectManagerPlugin::initialize(const QStringList &arguments, QString *e if (!Core::ICore::mimeDatabase()->addMimeTypes(QLatin1String(":vcproject/VcProject.mimetypes.xml"), errorString)) return false; - addAutoReleasedObject(new VcManager); + VcProjectBuildOptionsPage *confPage = new VcProjectBuildOptionsPage; + addAutoReleasedObject(confPage); + addAutoReleasedObject(new VcManager(confPage)); addAutoReleasedObject(new VcProjectBuildConfigurationFactory); addAutoReleasedObject(new VcMakeStepFactory); |