diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp index 68d3479050ec3be3a9edf90f6e4de93974e996d6..35769432c98e8ff97c2004719b3319406ba5c16f 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.cpp @@ -193,6 +193,16 @@ QStringList QbsBuildConfiguration::changedFiles() const return m_changedFiles; } +void QbsBuildConfiguration::setProducts(const QStringList &products) +{ + m_products = products; +} + +QStringList QbsBuildConfiguration::products() const +{ + return m_products; +} + QbsBuildConfiguration *QbsBuildConfiguration::setup(ProjectExplorer::Target *t, const QString &defaultDisplayName, const QString &displayName, diff --git a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h index 8a0749c2259bdc2281bff7974346269ea0addd86..6304bf7adcc69267fb9b4c14b1be0d213b2c2320 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h +++ b/src/plugins/qbsprojectmanager/qbsbuildconfiguration.h @@ -73,6 +73,9 @@ public: void setChangedFiles(const QStringList &files); QStringList changedFiles() const; + void setProducts(const QStringList &products); + QStringList products() const; + signals: void qbsConfigurationChanged(); @@ -96,6 +99,7 @@ private: bool m_parsingError; Utils::FileName m_buildDirectory; QStringList m_changedFiles; + QStringList m_products; friend class QbsBuildConfigurationFactory; friend class QbsBuildConfigurationWidget; diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp index 93a5d304f7e7851b72801622416030063eb0e445..68d23c1c261b2a1428b957d95ae280f63257e941 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.cpp +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.cpp @@ -102,6 +102,7 @@ bool QbsBuildStep::init() m_parser->appendOutputParser(parser); m_changedFiles = bc->changedFiles(); + m_products = bc->products(); connect(m_parser, SIGNAL(addOutput(QString,ProjectExplorer::BuildStep::OutputFormat)), this, SIGNAL(addOutput(QString,ProjectExplorer::BuildStep::OutputFormat))); @@ -119,7 +120,7 @@ void QbsBuildStep::run(QFutureInterface<bool> &fi) qbs::BuildOptions options(m_qbsBuildOptions); options.setChangedFiles(m_changedFiles); - m_job = pro->build(options); + m_job = pro->build(options, m_products); if (!m_job) { m_fi->reportResult(false); diff --git a/src/plugins/qbsprojectmanager/qbsbuildstep.h b/src/plugins/qbsprojectmanager/qbsbuildstep.h index a916b9d91cb685270e105b3e9d2787216b4f4517..433d2478b19cb20899a331b0b1201bd83d4a54e1 100644 --- a/src/plugins/qbsprojectmanager/qbsbuildstep.h +++ b/src/plugins/qbsprojectmanager/qbsbuildstep.h @@ -96,6 +96,7 @@ private: QVariantMap m_qbsConfiguration; qbs::BuildOptions m_qbsBuildOptions; QStringList m_changedFiles; + QStringList m_products; QFutureInterface<bool> *m_fi; qbs::BuildJob *m_job; diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 6fc2f8519071fc9e2f76d3422d7620696c5c4034..2ff1460bb22cd59b88f88bb600989204dcb5b157 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -179,11 +179,29 @@ void QbsProject::invalidate() prepareForParsing(); } -qbs::BuildJob *QbsProject::build(const qbs::BuildOptions &opts) +qbs::BuildJob *QbsProject::build(const qbs::BuildOptions &opts, QStringList productNames) { if (!qbsProject() || isParsing()) return 0; - return qbsProject()->buildAllProducts(opts); + if (productNames.isEmpty()) { + return qbsProject()->buildAllProducts(opts); + } else { + QList<qbs::ProductData> products; + foreach (const QString &productName, productNames) { + bool found = false; + foreach (const qbs::ProductData &data, qbsProjectData()->products()) { + if (data.name() == productName) { + found = true; + products.append(data); + break; + } + } + if (!found) + return 0; + } + + return qbsProject()->buildSomeProducts(products, opts); + } } qbs::CleanJob *QbsProject::clean(const qbs::CleanOptions &opts) diff --git a/src/plugins/qbsprojectmanager/qbsproject.h b/src/plugins/qbsprojectmanager/qbsproject.h index 823f5fbb355c05a8233e3c4d13a98504a22b48ea..49419e004c57a7cbc52e6022ad5dcb11e2054c81 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.h +++ b/src/plugins/qbsprojectmanager/qbsproject.h @@ -79,7 +79,7 @@ public: QStringList files(FilesMode fileMode) const; - qbs::BuildJob *build(const qbs::BuildOptions &opts); + qbs::BuildJob *build(const qbs::BuildOptions &opts, QStringList products = QStringList()); qbs::CleanJob *clean(const qbs::CleanOptions &opts); qbs::InstallJob *install(const qbs::InstallOptions &opts); diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h index 6d7428f1ab58d39d949867591670175d621dec2b..32e8f7962a7d78d8f75c73ea93e60951c5665998 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerconstants.h @@ -49,6 +49,8 @@ const char ACTION_REPARSE_QBS[] = "Qbs.Reparse"; const char ACTION_REPARSE_QBS_CONTEXT[] = "Qbs.ReparseCtx"; const char ACTION_BUILD_FILE_CONTEXT[] = "Qbs.BuildFileCtx"; const char ACTION_BUILD_FILE[] = "Qbs.BuildFile"; +const char ACTION_BUILD_PRODUCT_CONTEXT[] = "Qbs.BuildProductCtx"; +const char ACTION_BUILD_PRODUCT[] = "Qbs.BuildProduct"; // Ids: const char QBS_BUILDSTEP_ID[] = "Qbs.BuildStep"; diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp index 1453d18a0026b2c074a4ade55c274e520eedde01..d6ea41010012cfba3523076ac1da2f7ae322a3db 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp @@ -77,6 +77,7 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString * m_manager = new QbsManager(this); m_projectExplorer = ProjectExplorer::ProjectExplorerPlugin::instance(); const Core::Context projectContext(::QbsProjectManager::Constants::PROJECT_ID); + const Core::Context globalcontext(Core::Constants::C_GLOBAL); Q_UNUSED(arguments); @@ -100,10 +101,8 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString * // PE Context menu for projects Core::ActionContainer *mproject = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_PROJECTCONTEXT); - // <debug> - // Core::ActionContainer *msubproject = - // Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_SUBPROJECTCONTEXT); - // </debug> + Core::ActionContainer *msubproject = + Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_SUBPROJECTCONTEXT); Core::ActionContainer *mfile = Core::ActionManager::actionContainer(ProjectExplorer::Constants::M_FILECONTEXT); @@ -129,7 +128,6 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString * mfile->addAction(command, ProjectExplorer::Constants::G_FILE_OTHER); connect(m_buildFileContextMenu, SIGNAL(triggered()), this, SLOT(buildFileContextMenu())); - const Core::Context globalcontext(Core::Constants::C_GLOBAL); m_buildFile = new Utils::ParameterAction(tr("Build File"), tr("Build File \"%1\""), Utils::ParameterAction::AlwaysEnabled, this); command = Core::ActionManager::registerAction(m_buildFile, Constants::ACTION_BUILD_FILE, globalcontext); @@ -140,6 +138,22 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString * mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); connect(m_buildFile, SIGNAL(triggered()), this, SLOT(buildFile())); + m_buildProductContextMenu = new QAction(tr("Build"), this); + command = Core::ActionManager::registerAction(m_buildProductContextMenu, Constants::ACTION_BUILD_PRODUCT_CONTEXT, projectContext); + command->setAttribute(Core::Command::CA_Hide); + msubproject->addAction(command, ProjectExplorer::Constants::G_PROJECT_BUILD); + connect(m_buildProductContextMenu, SIGNAL(triggered()), this, SLOT(buildProductContextMenu())); + + m_buildProduct = new Utils::ParameterAction(tr("Build Product"), tr("Build Product \"%1\""), + Utils::ParameterAction::AlwaysEnabled, this); + command = Core::ActionManager::registerAction(m_buildProduct, Constants::ACTION_BUILD_PRODUCT, globalcontext); + command->setAttribute(Core::Command::CA_Hide); + command->setAttribute(Core::Command::CA_UpdateText); + command->setDescription(m_buildFile->text()); + command->setDefaultKeySequence(QKeySequence(tr("Ctrl+Alt+Shift+B"))); + mbuild->addAction(command, ProjectExplorer::Constants::G_BUILD_BUILD); + connect(m_buildProduct, SIGNAL(triggered()), this, SLOT(buildProduct())); + // Connect connect(m_projectExplorer, SIGNAL(currentNodeChanged(ProjectExplorer::Node*,ProjectExplorer::Project*)), this, SLOT(updateContextActions(ProjectExplorer::Node*,ProjectExplorer::Project*))); @@ -148,12 +162,12 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString * this, SLOT(buildStateChanged(ProjectExplorer::Project*))); connect(Core::EditorManager::instance(), SIGNAL(currentEditorChanged(Core::IEditor*)), - this, SLOT(updateBuildFileAction())); + this, SLOT(updateBuildActions())); // Run initial setup routines updateContextActions(0, 0); updateReparseQbsAction(); - updateBuildFileAction(); + updateBuildActions(); return true; } @@ -187,10 +201,12 @@ void QbsProjectManagerPlugin::updateContextActions(ProjectExplorer::Node *node, bool isBuilding = m_projectExplorer->buildManager()->isBuilding(project); bool isFile = m_currentProject && node && (node->nodeType() == ProjectExplorer::FileNodeType); + bool isProduct = m_currentProject && node && qobject_cast<QbsProductNode *>(node->projectNode()); bool isFileEnabled = isFile && node->isEnabled(); m_reparseQbsCtx->setEnabled(!isBuilding && m_currentProject && !m_currentProject->isParsing()); m_buildFileContextMenu->setEnabled(isFileEnabled); + m_buildProductContextMenu->setEnabled(isProduct); } void QbsProjectManagerPlugin::updateReparseQbsAction() @@ -200,12 +216,15 @@ void QbsProjectManagerPlugin::updateReparseQbsAction() && !m_currentProject->isParsing()); } -void QbsProjectManagerPlugin::updateBuildFileAction() +void QbsProjectManagerPlugin::updateBuildActions() { - bool visible = false; - bool enabled = false; + bool fileVisible = false; + bool fileEnabled = false; + bool productVisible = false; + bool productEnabled = false; QString file; + if (Core::IEditor *currentEditor = Core::EditorManager::currentEditor()) { file = currentEditor->document()->fileName(); ProjectExplorer::SessionManager *session = m_projectExplorer->session(); @@ -214,14 +233,22 @@ void QbsProjectManagerPlugin::updateBuildFileAction() = qobject_cast<QbsProject *>(session->projectForFile(file)); m_buildFile->setParameter(QFileInfo(file).fileName()); - visible = project && node && qobject_cast<QbsBaseProjectNode *>(node->projectNode()); - - enabled = !m_projectExplorer->buildManager()->isBuilding(project) + fileVisible = project && node && qobject_cast<QbsBaseProjectNode *>(node->projectNode()); + fileEnabled = !m_projectExplorer->buildManager()->isBuilding(project) && m_currentProject && !m_currentProject->isParsing(); + + if (QbsProductNode *productNode = qobject_cast<QbsProductNode *>(node->projectNode())) { + productEnabled = true; + productVisible = true; + m_buildProduct->setParameter(productNode->displayName()); + } } - m_buildFile->setEnabled(enabled); - m_buildFile->setVisible(visible); + m_buildFile->setEnabled(fileEnabled); + m_buildFile->setVisible(fileVisible); + + m_buildProduct->setEnabled(productEnabled); + m_buildProduct->setVisible(productVisible); } void QbsProjectManagerPlugin::activeTargetChanged() @@ -244,7 +271,7 @@ void QbsProjectManagerPlugin::buildStateChanged(ProjectExplorer::Project *projec if (project == m_currentProject) { updateReparseQbsAction(); updateContextActions(m_currentNode, m_currentProject); - updateBuildFileAction(); + updateBuildActions(); } } @@ -279,6 +306,32 @@ void QbsProjectManagerPlugin::buildFile() buildFiles(project, QStringList(file)); } +void QbsProjectManagerPlugin::buildProductContextMenu() +{ + QTC_ASSERT(m_currentNode, return); + QTC_ASSERT(m_currentProject, return); + + buildProducts(m_currentProject, QStringList(m_currentNode->displayName())); +} + +void QbsProjectManagerPlugin::buildProduct() +{ + QbsProject *project = 0; + QbsProductNode *product = 0; + if (Core::IEditor *currentEditor = Core::EditorManager::currentEditor()) { + const QString file = currentEditor->document()->fileName(); + ProjectExplorer::SessionManager *session = m_projectExplorer->session(); + + project = qobject_cast<QbsProject *>(session->projectForFile(file)); + product = qobject_cast<QbsProductNode *>(session->nodeForFile(file)->projectNode()); + } + + if (!project || !product) + return; + + buildProducts(project, QStringList(product->displayName())); +} + void QbsProjectManagerPlugin::buildFiles(QbsProject *project, const QStringList &files) { QTC_ASSERT(project, return); @@ -296,6 +349,7 @@ void QbsProjectManagerPlugin::buildFiles(QbsProject *project, const QStringList return; bc->setChangedFiles(files); + bc->setProducts(QStringList()); const Core::Id buildStep = Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD); @@ -305,6 +359,33 @@ void QbsProjectManagerPlugin::buildFiles(QbsProject *project, const QStringList bc->setChangedFiles(QStringList()); } +void QbsProjectManagerPlugin::buildProducts(QbsProject *project, const QStringList &products) +{ + QTC_ASSERT(project, return); + QTC_ASSERT(!products.isEmpty(), return); + + ProjectExplorer::Target *t = project->activeTarget(); + if (!t) + return; + QbsBuildConfiguration *bc = qobject_cast<QbsBuildConfiguration *>(t->activeBuildConfiguration()); + if (!bc) + return; + + ProjectExplorer::ProjectExplorerPlugin *pe = ProjectExplorer::ProjectExplorerPlugin::instance(); + if (!pe->saveModifiedFiles()) + return; + + bc->setChangedFiles(QStringList()); + bc->setProducts(products); + + const Core::Id buildStep = Core::Id(ProjectExplorer::Constants::BUILDSTEPS_BUILD); + + const QString name = ProjectExplorer::ProjectExplorerPlugin::displayNameForStepId(buildStep); + pe->buildManager()->buildList(bc->stepList(buildStep), name); + + bc->setProducts(QStringList()); +} + void QbsProjectManagerPlugin::reparseCurrentProject() { if (m_currentProject) diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h index 27317940a3f396c666f26e2ef92a84c01e9fcb94..9e91e3da8db4dbe0544dbd3883abb8453a45d7c1 100644 --- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h +++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.h @@ -68,17 +68,20 @@ public: private slots: void updateContextActions(ProjectExplorer::Node *node, ProjectExplorer::Project *project); void updateReparseQbsAction(); - void updateBuildFileAction(); + void updateBuildActions(); void activeTargetChanged(); void buildStateChanged(ProjectExplorer::Project *project); void parsingStateChanged(); void buildFileContextMenu(); void buildFile(); + void buildProductContextMenu(); + void buildProduct(); void reparseCurrentProject(); private: void buildFiles(QbsProject *project, const QStringList &files); + void buildProducts(QbsProject *project, const QStringList &products); QbsManager *m_manager; ProjectExplorer::ProjectExplorerPlugin *m_projectExplorer; @@ -86,7 +89,9 @@ private: QAction *m_reparseQbs; QAction *m_reparseQbsCtx; QAction *m_buildFileContextMenu; + QAction *m_buildProductContextMenu; Utils::ParameterAction *m_buildFile; + Utils::ParameterAction *m_buildProduct; Internal::QbsProject *m_currentProject; ProjectExplorer::Target *m_currentTarget;