Commit c4d12742 authored by Tobias Hunger's avatar Tobias Hunger
Browse files

Update build steps related panels

 * Merge BuildSettingsWidget and BuildSettingsSubWidgets. I don't
   see much need for this separation and it makes the indention harder
   to do.
 * Override contentsmargins set by the ProjectsWindow.
   This enables the toolwidget to be displayed properly.
 * Add a remove button to the toolwidget of the buildsteps. Remove the
   global one.
 * Simplify code a bit by using QSignalMapper instead of mapping signals
   manually.

Reviewed-by: dt
parent 7ebf60dc
......@@ -37,18 +37,21 @@
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <QtCore/QPair>
#include <QtCore/QMargins>
#include <QtCore/QTimer>
#include <QtGui/QApplication>
#include <QtGui/QComboBox>
#include <QtGui/QInputDialog>
#include <QtGui/QLabel>
#include <QtGui/QVBoxLayout>
#include <QtGui/QMenu>
#include <QtGui/QPushButton>
#include <QtGui/QVBoxLayout>
using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;
///
/// BuildSettingsPanelFactory
// BuildSettingsPanelFactory
///
bool BuildSettingsPanelFactory::supports(Project *project)
......@@ -62,7 +65,7 @@ IPropertiesPanel *BuildSettingsPanelFactory::createPanel(Project *project)
}
///
/// BuildSettingsPanel
// BuildSettingsPanel
///
BuildSettingsPanel::BuildSettingsPanel(Project *project) :
......@@ -92,74 +95,36 @@ QIcon BuildSettingsPanel::icon() const
}
///
// BuildSettingsSubWidgets
// BuildSettingsWidget
///
BuildSettingsSubWidgets::~BuildSettingsSubWidgets()
BuildSettingsWidget::~BuildSettingsWidget()
{
clear();
}
void BuildSettingsSubWidgets::addWidget(const QString &name, QWidget *widget)
BuildSettingsWidget::BuildSettingsWidget(Project *project) :
m_project(project),
m_buildConfiguration(0),
m_leftMargin(0)
{
QSpacerItem *item = new QSpacerItem(1, 10, QSizePolicy::Fixed, QSizePolicy::Fixed);
QLabel *label = new QLabel(this);
label->setText(name);
QFont f = label->font();
f.setBold(true);
f.setPointSizeF(f.pointSizeF() *1.2);
label->setFont(f);
layout()->addItem(item);
layout()->addWidget(label);
layout()->addWidget(widget);
m_spacerItems.append(item);
m_labels.append(label);
m_widgets.append(widget);
// Provide some time for our contentsmargins to get updated:
QTimer::singleShot(0, this, SLOT(init()));
}
void BuildSettingsSubWidgets::clear()
void BuildSettingsWidget::init()
{
foreach(QSpacerItem *item, m_spacerItems)
layout()->removeItem(item);
qDeleteAll(m_spacerItems);
qDeleteAll(m_widgets);
qDeleteAll(m_labels);
m_widgets.clear();
m_labels.clear();
m_spacerItems.clear();
}
QList<QWidget *> BuildSettingsSubWidgets::widgets() const
{
return m_widgets;
}
QMargins margins(contentsMargins());
m_leftMargin = margins.left();
margins.setLeft(0);
setContentsMargins(margins);
BuildSettingsSubWidgets::BuildSettingsSubWidgets(QWidget *parent)
: QWidget(parent)
{
new QVBoxLayout(this);
layout()->setMargin(0);
}
///
/// BuildSettingsWidget
///
BuildSettingsWidget::~BuildSettingsWidget()
{
}
BuildSettingsWidget::BuildSettingsWidget(Project *project)
: m_project(project), m_buildConfiguration(0)
{
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->setContentsMargins(0, -1, 0, -1);
vbox->setContentsMargins(0, 0, 0, 0);
{ // Edit Build Configuration row
QHBoxLayout *hbox = new QHBoxLayout();
hbox->setContentsMargins(m_leftMargin, 0, 0, 0);
hbox->addWidget(new QLabel(tr("Edit Build Configuration:"), this));
m_buildConfigurationComboBox = new QComboBox(this);
m_buildConfigurationComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
......@@ -169,6 +134,8 @@ BuildSettingsWidget::BuildSettingsWidget(Project *project)
m_addButton->setText(tr("Add"));
m_addButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
hbox->addWidget(m_addButton);
m_addButtonMenu = new QMenu(this);
m_addButton->setMenu(m_addButtonMenu);
m_removeButton = new QPushButton(this);
m_removeButton->setText(tr("Remove"));
......@@ -182,13 +149,6 @@ BuildSettingsWidget::BuildSettingsWidget(Project *project)
m_makeActiveLabel->setVisible(false);
vbox->addWidget(m_makeActiveLabel);
m_subWidgets = new BuildSettingsSubWidgets(this);
vbox->addWidget(m_subWidgets);
m_addButtonMenu = new QMenu(this);
m_addButton->setMenu(m_addButtonMenu);
updateAddButtonMenu();
m_buildConfiguration = m_project->activeBuildConfiguration();
connect(m_makeActiveLabel, SIGNAL(linkActivated(QString)),
......@@ -201,6 +161,8 @@ BuildSettingsWidget::BuildSettingsWidget(Project *project)
this, SLOT(deleteConfiguration()));
// TODO update on displayNameChange
// connect(m_project, SIGNAL(buildConfigurationDisplayNameChanged(const QString &)),
// this, SLOT(buildConfigurationDisplayNameChanged(const QString &)));
connect(m_project, SIGNAL(activeBuildConfigurationChanged()),
this, SLOT(checkMakeActiveLabel()));
......@@ -208,9 +170,44 @@ BuildSettingsWidget::BuildSettingsWidget(Project *project)
if (m_project->buildConfigurationFactory())
connect(m_project->buildConfigurationFactory(), SIGNAL(availableCreationTypesChanged()), SLOT(updateAddButtonMenu()));
updateAddButtonMenu();
updateBuildSettings();
}
void BuildSettingsWidget::addSubWidget(const QString &name, QWidget *widget)
{
widget->setContentsMargins(m_leftMargin, 10, 0, 0);
QLabel *label = new QLabel(this);
label->setText(name);
QFont f = label->font();
f.setBold(true);
f.setPointSizeF(f.pointSizeF() * 1.2);
label->setFont(f);
label->setContentsMargins(m_leftMargin, 10, 0, 0);
layout()->addWidget(label);
layout()->addWidget(widget);
m_labels.append(label);
m_subWidgets.append(widget);
}
void BuildSettingsWidget::clear()
{
qDeleteAll(m_subWidgets);
m_subWidgets.clear();
qDeleteAll(m_labels);
m_labels.clear();
}
QList<QWidget *> BuildSettingsWidget::subWidgets() const
{
return m_subWidgets;
}
void BuildSettingsWidget::makeActive()
{
m_project->setActiveBuildConfiguration(m_buildConfiguration);
......@@ -220,7 +217,7 @@ void BuildSettingsWidget::updateAddButtonMenu()
{
m_addButtonMenu->clear();
m_addButtonMenu->addAction(tr("&Clone Selected"),
this, SLOT(cloneConfiguration()));
this, SLOT(cloneConfiguration()));
IBuildConfigurationFactory *factory = m_project->buildConfigurationFactory();
if (factory) {
foreach (const QString &type, factory->availableCreationTypes()) {
......@@ -237,25 +234,25 @@ void BuildSettingsWidget::updateBuildSettings()
// Delete old tree items
bool blocked = m_buildConfigurationComboBox->blockSignals(true);
m_buildConfigurationComboBox->clear();
m_subWidgets->clear();
clear();
// update buttons
m_removeButton->setEnabled(m_project->buildConfigurations().size() > 1);
// Add pages
BuildConfigWidget *generalConfigWidget = m_project->createConfigWidget();
m_subWidgets->addWidget(generalConfigWidget->displayName(), generalConfigWidget);
addSubWidget(generalConfigWidget->displayName(), generalConfigWidget);
m_subWidgets->addWidget(tr("Build Steps"), new BuildStepsPage(m_project));
m_subWidgets->addWidget(tr("Clean Steps"), new BuildStepsPage(m_project, true));
addSubWidget(tr("Build Steps"), new BuildStepsPage(m_project, false));
addSubWidget(tr("Clean Steps"), new BuildStepsPage(m_project, true));
QList<BuildConfigWidget *> subConfigWidgets = m_project->subConfigWidgets();
foreach (BuildConfigWidget *subConfigWidget, subConfigWidgets)
m_subWidgets->addWidget(subConfigWidget->displayName(), subConfigWidget);
addSubWidget(subConfigWidget->displayName(), subConfigWidget);
// Add tree items
foreach (BuildConfiguration *bc, m_project->buildConfigurations()) {
m_buildConfigurationComboBox->addItem(bc->displayName(), QVariant::fromValue(bc));
m_buildConfigurationComboBox->addItem(bc->displayName(), QVariant::fromValue<BuildConfiguration *>(bc));
if (bc == m_buildConfiguration)
m_buildConfigurationComboBox->setCurrentIndex(m_buildConfigurationComboBox->count() - 1);
}
......@@ -264,12 +261,13 @@ void BuildSettingsWidget::updateBuildSettings()
// TODO Restore position, entry from combbox
// TODO? select entry from combobox ?
activeBuildConfigurationChanged();
}
void BuildSettingsWidget::currentIndexChanged(int index)
{
m_buildConfiguration = (BuildConfiguration *) m_buildConfigurationComboBox->itemData(index).value<BuildConfiguration *>();
m_buildConfiguration = m_buildConfigurationComboBox->itemData(index).value<BuildConfiguration *>();
activeBuildConfigurationChanged();
}
......@@ -281,7 +279,7 @@ void BuildSettingsWidget::activeBuildConfigurationChanged()
break;
}
}
foreach (QWidget *widget, m_subWidgets->widgets()) {
foreach (QWidget *widget, subWidgets()) {
if (BuildConfigWidget *buildStepWidget = qobject_cast<BuildConfigWidget*>(widget)) {
buildStepWidget->init(m_buildConfiguration);
}
......@@ -311,14 +309,14 @@ void BuildSettingsWidget::createConfiguration()
void BuildSettingsWidget::cloneConfiguration()
{
int index = m_buildConfigurationComboBox->currentIndex();
const int index = m_buildConfigurationComboBox->currentIndex();
BuildConfiguration *bc = m_buildConfigurationComboBox->itemData(index).value<BuildConfiguration *>();
cloneConfiguration(bc);
}
void BuildSettingsWidget::deleteConfiguration()
{
int index = m_buildConfigurationComboBox->currentIndex();
const int index = m_buildConfigurationComboBox->currentIndex();
BuildConfiguration *bc = m_buildConfigurationComboBox->itemData(index).value<BuildConfiguration *>();
deleteConfiguration(bc);
}
......@@ -328,7 +326,7 @@ void BuildSettingsWidget::cloneConfiguration(BuildConfiguration *sourceConfigura
if (!sourceConfiguration)
return;
QString newDisplayName = QInputDialog::getText(this, tr("Clone configuration"), tr("New Configuration Name:"));
QString newDisplayName(QInputDialog::getText(this, tr("Clone configuration"), tr("New Configuration Name:")));
if (newDisplayName.isEmpty())
return;
......
......@@ -32,35 +32,22 @@
#include "iprojectproperties.h"
#include <QtCore/QHash>
#include <QtGui/QComboBox>
#include <QtGui/QPushButton>
#include <QtGui/QLabel>
#include <QtGui/QGroupBox>
#include <QtGui/QSpacerItem>
#include <QtGui/QWidget>
QT_BEGIN_NAMESPACE
class QComboBox;
class QLabel;
class QMenu;
class QPushButton;
QT_END_NAMESPACE
namespace ProjectExplorer {
class IBuildStepFactory;
class BuildConfiguration;
class IBuildStepFactory;
namespace Internal {
class BuildSettingsSubWidgets : public QWidget
{
Q_OBJECT
public:
BuildSettingsSubWidgets(QWidget *parent);
~BuildSettingsSubWidgets();
void clear();
void addWidget(const QString &name, QWidget *widget);
QList<QWidget *> widgets() const;
private:
QList<QWidget *> m_widgets;
QList<QLabel *> m_labels;
QList<QSpacerItem *> m_spacerItems;
};
class BuildSettingsPanelFactory : public IPanelFactory
{
public:
......@@ -93,6 +80,10 @@ public:
BuildSettingsWidget(Project *project);
~BuildSettingsWidget();
void clear();
void addSubWidget(const QString &name, QWidget *widget);
QList<QWidget *> subWidgets() const;
private slots:
void updateBuildSettings();
void currentIndexChanged(int index);
......@@ -105,18 +96,25 @@ private slots:
void checkMakeActiveLabel();
void makeActive();
void init();
private:
void cloneConfiguration(ProjectExplorer::BuildConfiguration *toClone);
void deleteConfiguration(ProjectExplorer::BuildConfiguration *toDelete);
void cloneConfiguration(BuildConfiguration *toClone);
void deleteConfiguration(BuildConfiguration *toDelete);
Project *m_project;
BuildConfiguration *m_buildConfiguration;
QPushButton *m_addButton;
QPushButton *m_removeButton;
QComboBox *m_buildConfigurationComboBox;
BuildSettingsSubWidgets *m_subWidgets;
BuildConfiguration *m_buildConfiguration;
QMenu *m_addButtonMenu;
QLabel *m_makeActiveLabel;
QList<QWidget *> m_subWidgets;
QList<QLabel *> m_labels;
int m_leftMargin;
};
} // namespace Internal
......
......@@ -28,13 +28,14 @@
**************************************************************************/
#include "buildstepspage.h"
#include "project.h"
#include "buildconfiguration.h"
#include <coreplugin/coreconstants.h>
#include <extensionsystem/pluginmanager.h>
#include <utils/qtcassert.h>
#include <QtCore/QSignalMapper>
#include <QtGui/QLabel>
#include <QtGui/QPushButton>
#include <QtGui/QMenu>
......@@ -47,40 +48,11 @@ using namespace ProjectExplorer::Internal;
BuildStepsPage::BuildStepsPage(Project *project, bool clean) :
BuildConfigWidget(),
m_clean(clean)
m_clean(clean),
m_addButton(0),
m_leftMargin(-1)
{
Q_UNUSED(project)
m_vbox = new QVBoxLayout(this);
m_vbox->setContentsMargins(0, 0, 0, 0);
m_vbox->setSpacing(0);
m_noStepsLabel = new QLabel(tr("No Build Steps"), this);
m_vbox->addWidget(m_noStepsLabel);
QHBoxLayout *hboxLayout = new QHBoxLayout();
m_addButton = new QPushButton(this);
m_addButton->setText(clean ? tr("Add clean step") : tr("Add build step"));
m_addButton->setMenu(new QMenu(this));
hboxLayout->addWidget(m_addButton);
m_removeButton = new QPushButton(this);
m_removeButton->setText(clean ? tr("Remove clean step") : tr("Remove build step"));
m_removeButton->setMenu(new QMenu(this));
hboxLayout->addWidget(m_removeButton);
hboxLayout->addStretch(10);
#ifdef Q_OS_MAC
m_addButton->setAttribute(Qt::WA_MacSmallSize);
m_removeButton->setAttribute(Qt::WA_MacSmallSize);
#endif
m_vbox->addLayout(hboxLayout);
connect(m_addButton->menu(), SIGNAL(aboutToShow()),
this, SLOT(updateAddBuildStepMenu()));
connect(m_removeButton->menu(), SIGNAL(aboutToShow()),
this, SLOT(updateRemoveBuildStepMenu()));
Q_UNUSED(project);
}
BuildStepsPage::~BuildStepsPage()
......@@ -112,6 +84,10 @@ QString BuildStepsPage::displayName() const
void BuildStepsPage::init(BuildConfiguration *bc)
{
QTC_ASSERT(bc, return);
setupUi();
foreach(BuildStepsWidgetStruct s, m_buildSteps) {
delete s.widget;
delete s.detailsWidget;
......@@ -120,7 +96,7 @@ void BuildStepsPage::init(BuildConfiguration *bc)
m_configuration = bc;
const QList<BuildStep *> &steps = m_clean ? bc->cleanSteps() : bc->buildSteps();
const QList<BuildStep *> &steps = m_clean ? m_configuration->cleanSteps() : m_configuration->buildSteps();
int i = 0;
foreach (BuildStep *bs, steps) {
addBuildStepWidget(i, bs);
......@@ -128,7 +104,6 @@ void BuildStepsPage::init(BuildConfiguration *bc)
}
m_noStepsLabel->setVisible(steps.isEmpty());
m_removeButton->setEnabled(!steps.isEmpty());
// make sure widget is updated
foreach(BuildStepsWidgetStruct s, m_buildSteps) {
......@@ -143,7 +118,7 @@ void BuildStepsPage::updateAddBuildStepMenu()
QMap<QString, QPair<QString, IBuildStepFactory *> > map;
//Build up a list of possible steps and save map the display names to the (internal) name and factories.
QList<IBuildStepFactory *> factories = ExtensionSystem::PluginManager::instance()->getObjects<IBuildStepFactory>();
foreach (IBuildStepFactory * factory, factories) {
foreach (IBuildStepFactory *factory, factories) {
QStringList names = factory->canCreateForBuildConfiguration(m_configuration);
foreach (const QString &name, names) {
map.insert(factory->displayNameForName(name), QPair<QString, IBuildStepFactory *>(name, factory));
......@@ -188,136 +163,144 @@ void BuildStepsPage::addBuildStepWidget(int pos, BuildStep *step)
s.upButton->setIconSize(QSize(10, 10));
s.downButton->setIconSize(QSize(10, 10));
#endif
s.removeButton = new QPushButton(this);
s.removeButton->setText(QChar('X'));
s.removeButton->setMaximumHeight(22);
s.removeButton->setMaximumWidth(22);
// layout
QWidget *toolWidget = new QWidget(s.detailsWidget);
toolWidget->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
s.hbox = new QHBoxLayout(toolWidget);
s.hbox->setMargin(0);
s.hbox->setSpacing(0);
s.hbox->addWidget(s.upButton);
s.hbox->addWidget(s.downButton);
QHBoxLayout *hbox = new QHBoxLayout();
toolWidget->setLayout(hbox);
hbox->setMargin(0);
hbox->setSpacing(0);
hbox->addWidget(s.upButton);
hbox->addWidget(s.downButton);
hbox->addWidget(s.removeButton);
s.detailsWidget->setToolWidget(toolWidget);
const int leftMargin(qMax(m_leftMargin - toolWidget->width(), 0));
s.detailsWidget->setContentsMargins(leftMargin, 0, 0, 1);
m_buildSteps.insert(pos, s);
m_vbox->insertWidget(pos, s.detailsWidget);
connect(s.widget, SIGNAL(updateSummary()),
this, SLOT(updateSummary()));
connect(s.upButton, SIGNAL(clicked()),
this, SLOT(upBuildStep()));
m_upMapper, SLOT(map()));
connect(s.downButton, SIGNAL(clicked()),
this, SLOT(downBuildStep()));
m_downMapper, SLOT(map()));
connect(s.removeButton, SIGNAL(clicked()),
m_removeMapper, SLOT(map()));
}
void BuildStepsPage::addBuildStep()
{
if (QAction *action = qobject_cast<QAction *>(sender())) {
BuildConfiguration *bc = m_configuration;
QPair<QString, IBuildStepFactory *> pair = m_addBuildStepHash.value(action);
BuildStep *newStep = pair.second->create(bc, pair.first);
int pos = m_clean ? bc->cleanSteps().count() : bc->buildSteps().count();
m_clean ? bc->insertCleanStep(pos, newStep) : bc->insertBuildStep(pos, newStep);
BuildStep *newStep = pair.second->create(m_configuration, pair.first);
int pos = m_clean ? m_configuration->cleanSteps().count() : m_configuration->buildSteps().count();
m_clean ? m_configuration->insertCleanStep(pos, newStep) : m_configuration->insertBuildStep(pos, newStep);
addBuildStepWidget(pos, newStep);
const BuildStepsWidgetStruct s = m_buildSteps.at(pos);
s.widget->init();
s.detailsWidget->setSummaryText(s.widget->summaryText());
s.detailsWidget->setExpanded(true);
}
updateBuildStepButtonsState();
}
void BuildStepsPage::updateRemoveBuildStepMenu()
void BuildStepsPage::stepMoveUp(int pos)
{
QMenu *menu = m_removeButton->menu();
menu->clear();
const QList<BuildStep *> &steps = m_clean ? m_configuration->cleanSteps() : m_configuration->buildSteps();
foreach(BuildStep *step, steps) {
QAction *action = menu->addAction(step->displayName());
if (step->immutable())
action->setEnabled(false);
connect(action, SIGNAL(triggered()),
this, SLOT(removeBuildStep()));
}
}
m_clean ? m_configuration->moveCleanStepUp(pos) : m_configuration->moveBuildStepUp(pos);
m_vbox->insertWidget(pos - 1, m_buildSteps.at(pos).detailsWidget);
m_buildSteps.swap(pos - 1, pos);
void BuildStepsPage::removeBuildStep()
{
QAction *action = qobject_cast<QAction *>(sender());
if (action) {
int pos = m_removeButton->menu()->actions().indexOf(action);
const QList<BuildStep *> &steps = m_clean ? m_configuration->cleanSteps() : m_configuration->buildSteps();
if (steps.at(pos)->immutable())
return;
BuildStepsWidgetStruct s = m_buildSteps.at(pos);
delete s.widget;
delete s.detailsWidget;
m_buildSteps.removeAt(pos);
m_clean ? m_configuration->removeCleanStep(pos) : m_configuration->removeBuildStep(pos);
}
updateBuildStepButtonsState();
}
void BuildStepsPage::upBuildStep()
void BuildStepsPage::stepMoveDown(int pos)
{
int pos = -1;
QToolButton *tb = qobject_cast<QToolButton *>(sender());
if (!tb)
return;
stepMoveUp(pos + 1);
}
for (int i=0; i<m_buildSteps.count(); ++i) {
if (m_buildSteps.at(i).upButton == tb) {
pos = i;
break;
}
}
if (pos == -1)
return;
void BuildStepsPage::stepRemove(int pos)
{