buildsettingspropertiespage.cpp 10.8 KB
Newer Older
1
/**************************************************************************
con's avatar
con committed
2
3
4
**
** This file is part of Qt Creator
**
5
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
con's avatar
con committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
con's avatar
con committed
8
**
9
** Commercial Usage
10
**
11
12
13
14
** Licensees holding valid Qt Commercial licenses may use this file in
** accordance with the Qt Commercial License Agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and Nokia.
15
**
16
** GNU Lesser General Public License Usage
17
**
18
19
20
21
22
23
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24
**
25
** If you are unsure which license is appropriate for your use, please
hjk's avatar
hjk committed
26
** contact the sales department at http://qt.nokia.com/contact.
con's avatar
con committed
27
**
28
**************************************************************************/
hjk's avatar
hjk committed
29

con's avatar
con committed
30
31
32
33
#include "buildsettingspropertiespage.h"
#include "buildstep.h"
#include "buildstepspage.h"
#include "project.h"
34
#include "buildconfiguration.h"
con's avatar
con committed
35

36
#include <coreplugin/coreconstants.h>
con's avatar
con committed
37
38
39
40
41
42
#include <extensionsystem/pluginmanager.h>

#include <QtCore/QDebug>
#include <QtCore/QPair>
#include <QtGui/QInputDialog>
#include <QtGui/QLabel>
dt's avatar
dt committed
43
#include <QtGui/QVBoxLayout>
44
#include <QtGui/QMenu>
con's avatar
con committed
45
46
47
48
49
50
51
52

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;

///
/// BuildSettingsPanelFactory
///

53
bool BuildSettingsPanelFactory::supports(Project *project)
con's avatar
con committed
54
{
55
    return project->hasBuildSettings();
con's avatar
con committed
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
}

PropertiesPanel *BuildSettingsPanelFactory::createPanel(Project *project)
{
    return new BuildSettingsPanel(project);
}

///
/// BuildSettingsPanel
///

BuildSettingsPanel::BuildSettingsPanel(Project *project)
        : PropertiesPanel(),
          m_widget(new BuildSettingsWidget(project))
{
}

BuildSettingsPanel::~BuildSettingsPanel()
{
    delete m_widget;
}

QString BuildSettingsPanel::name() const
{
    return tr("Build Settings");
}

QWidget *BuildSettingsPanel::widget()
{
    return m_widget;
}

dt's avatar
dt committed
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
///
// BuildSettingsSubWidgets
///

BuildSettingsSubWidgets::~BuildSettingsSubWidgets()
{
    clear();
}

void BuildSettingsSubWidgets::addWidget(const QString &name, QWidget *widget)
{
    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()->addWidget(label);
    layout()->addWidget(widget);

    m_labels.append(label);
    m_widgets.append(widget);
}

void BuildSettingsSubWidgets::clear()
{
    qDeleteAll(m_widgets);
    qDeleteAll(m_labels);
117
118
    m_widgets.clear();
    m_labels.clear();
dt's avatar
dt committed
119
120
121
122
123
124
125
126
}

QList<QWidget *> BuildSettingsSubWidgets::widgets() const
{
    return m_widgets;
}

BuildSettingsSubWidgets::BuildSettingsSubWidgets(QWidget *parent)
dt's avatar
dt committed
127
    : QWidget(parent)
dt's avatar
dt committed
128
129
{
    new QVBoxLayout(this);
130
    layout()->setMargin(0);
dt's avatar
dt committed
131
132
}

con's avatar
con committed
133
134
135
136
137
138
139
140
141
142
143
///
/// BuildSettingsWidget
///

BuildSettingsWidget::~BuildSettingsWidget()
{
}

BuildSettingsWidget::BuildSettingsWidget(Project *project)
    : m_project(project)
{
dt's avatar
dt committed
144
    QVBoxLayout *vbox = new QVBoxLayout(this);
con's avatar
con committed
145
    vbox->setContentsMargins(0, -1, 0, -1);
dt's avatar
dt committed
146
    QHBoxLayout *hbox = new QHBoxLayout();
dt's avatar
dt committed
147
    hbox->addWidget(new QLabel(tr("Edit Build Configuration:"), this));
dt's avatar
dt committed
148
    m_buildConfigurationComboBox = new QComboBox(this);
149
    m_buildConfigurationComboBox->setSizeAdjustPolicy(QComboBox::AdjustToContents);
dt's avatar
dt committed
150
151
152
    hbox->addWidget(m_buildConfigurationComboBox);

    m_addButton = new QPushButton(this);
153
    m_addButton->setText(tr("Add"));
dt's avatar
dt committed
154
155
156
157
    m_addButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    hbox->addWidget(m_addButton);

    m_removeButton = new QPushButton(this);
158
    m_removeButton->setText(tr("Remove"));
dt's avatar
dt committed
159
160
161
162
163
164
165
    m_removeButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    hbox->addWidget(m_removeButton);
    hbox->addSpacerItem(new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Fixed));
    vbox->addLayout(hbox);

    m_subWidgets = new BuildSettingsSubWidgets(this);
    vbox->addWidget(m_subWidgets);
con's avatar
con committed
166

con's avatar
con committed
167
168
169
    m_addButtonMenu = new QMenu(this);
    m_addButton->setMenu(m_addButtonMenu);
    updateAddButtonMenu();
con's avatar
con committed
170

171
    m_buildConfiguration = m_project->activeBuildConfiguration()->name();
dt's avatar
dt committed
172

dt's avatar
dt committed
173
174
    connect(m_buildConfigurationComboBox, SIGNAL(currentIndexChanged(int)),
            this, SLOT(currentIndexChanged(int)));
con's avatar
con committed
175

dt's avatar
dt committed
176
    connect(m_removeButton, SIGNAL(clicked()),
con's avatar
con committed
177
            this, SLOT(deleteConfiguration()));
dt's avatar
dt committed
178

con's avatar
con committed
179
180
    connect(m_project, SIGNAL(buildConfigurationDisplayNameChanged(const QString &)),
            this, SLOT(buildConfigurationDisplayNameChanged(const QString &)));
con's avatar
con committed
181
182
    if (m_project->buildConfigurationFactory())
        connect(m_project->buildConfigurationFactory(), SIGNAL(availableCreationTypesChanged()), SLOT(updateAddButtonMenu()));
con's avatar
con committed
183
184
185
186

    updateBuildSettings();
}

con's avatar
con committed
187
void BuildSettingsWidget::updateAddButtonMenu()
188
{
con's avatar
con committed
189
190
    m_addButtonMenu->clear();
    m_addButtonMenu->addAction(tr("&Clone Selected"),
191
192
193
194
                             this, SLOT(cloneConfiguration()));
    IBuildConfigurationFactory *factory = m_project->buildConfigurationFactory();
    if (factory) {
        foreach (const QString &type, factory->availableCreationTypes()) {
con's avatar
con committed
195
            QAction *action = m_addButtonMenu->addAction(factory->displayNameForType(type), this, SLOT(createConfiguration()));
196
197
198
199
200
            action->setData(type);
        }
    }
}

con's avatar
con committed
201
202
void BuildSettingsWidget::buildConfigurationDisplayNameChanged(const QString &buildConfiguration)
{
dt's avatar
dt committed
203
204
    for (int i=0; i<m_buildConfigurationComboBox->count(); ++i) {
        if (m_buildConfigurationComboBox->itemData(i).toString() == buildConfiguration) {
205
            m_buildConfigurationComboBox->setItemText(i, m_project->buildConfiguration(buildConfiguration)->displayName());
dt's avatar
dt committed
206
            break;
con's avatar
con committed
207
208
209
210
211
212
213
        }
    }
}


void BuildSettingsWidget::updateBuildSettings()
{
dt's avatar
dt committed
214
    // TODO save position, entry from combbox
con's avatar
con committed
215
216

    // Delete old tree items
dt's avatar
dt committed
217
    m_buildConfigurationComboBox->blockSignals(true);
dt's avatar
dt committed
218
219
    m_buildConfigurationComboBox->clear();
    m_subWidgets->clear();
con's avatar
con committed
220

dt's avatar
dt committed
221
222
    // update buttons
    m_removeButton->setEnabled(m_project->buildConfigurations().size() > 1);
con's avatar
con committed
223
224

    // Add pages
dt's avatar
dt committed
225
    BuildConfigWidget *generalConfigWidget = m_project->createConfigWidget();
dt's avatar
dt committed
226
227
228
229
    m_subWidgets->addWidget(generalConfigWidget->displayName(), generalConfigWidget);

    m_subWidgets->addWidget(tr("Build Steps"), new BuildStepsPage(m_project));
    m_subWidgets->addWidget(tr("Clean Steps"), new BuildStepsPage(m_project, true));
con's avatar
con committed
230

dt's avatar
dt committed
231
232
    QList<BuildConfigWidget *> subConfigWidgets = m_project->subConfigWidgets();
    foreach (BuildConfigWidget *subConfigWidget, subConfigWidgets)
dt's avatar
dt committed
233
        m_subWidgets->addWidget(subConfigWidget->displayName(), subConfigWidget);
con's avatar
con committed
234
235

    // Add tree items
236
237
238
    foreach (const BuildConfiguration *bc, m_project->buildConfigurations()) {
        m_buildConfigurationComboBox->addItem(bc->displayName(), bc->name());
        if (bc->name() == m_buildConfiguration)
dt's avatar
dt committed
239
            m_buildConfigurationComboBox->setCurrentIndex(m_buildConfigurationComboBox->count() - 1);
con's avatar
con committed
240
241
    }

dt's avatar
dt committed
242
    m_buildConfigurationComboBox->blockSignals(false);
con's avatar
con committed
243

dt's avatar
dt committed
244
245
246
    // TODO Restore position, entry from combbox
    // TODO? select entry from combobox ?
    activeBuildConfigurationChanged();
con's avatar
con committed
247
248
}

dt's avatar
dt committed
249
void BuildSettingsWidget::currentIndexChanged(int index)
con's avatar
con committed
250
{
dt's avatar
dt committed
251
252
    m_buildConfiguration = m_buildConfigurationComboBox->itemData(index).toString();
    activeBuildConfigurationChanged();
con's avatar
con committed
253
254
}

dt's avatar
dt committed
255
void BuildSettingsWidget::activeBuildConfigurationChanged()
con's avatar
con committed
256
{
dt's avatar
dt committed
257
    for (int i = 0; i < m_buildConfigurationComboBox->count(); ++i) {
dt's avatar
dt committed
258
        if (m_buildConfigurationComboBox->itemData(i).toString() == m_buildConfiguration) {
dt's avatar
dt committed
259
260
261
262
263
            m_buildConfigurationComboBox->setCurrentIndex(i);
            break;
        }
    }
    foreach (QWidget *widget, m_subWidgets->widgets()) {
dt's avatar
dt committed
264
        if (BuildConfigWidget *buildStepWidget = qobject_cast<BuildConfigWidget*>(widget)) {
dt's avatar
dt committed
265
            buildStepWidget->init(m_buildConfiguration);
con's avatar
con committed
266
267
268
269
270
271
        }
    }
}

void BuildSettingsWidget::createConfiguration()
{
272
273
    QAction *action = qobject_cast<QAction *>(sender());
    const QString &type = action->data().toString();
274
    if (m_project->buildConfigurationFactory()->create(type)) {
con's avatar
con committed
275
        // TODO switching to last buildconfiguration in list might not be what we want
276
        m_buildConfiguration = m_project->buildConfigurations().last()->name();
277
278
        updateBuildSettings();
    }
con's avatar
con committed
279
280
281
282
}

void BuildSettingsWidget::cloneConfiguration()
{
dt's avatar
dt committed
283
    const QString configuration = m_buildConfigurationComboBox->itemData(m_buildConfigurationComboBox->currentIndex()).toString();
con's avatar
con committed
284
285
286
287
288
    cloneConfiguration(configuration);
}

void BuildSettingsWidget::deleteConfiguration()
{
dt's avatar
dt committed
289
    const QString configuration = m_buildConfigurationComboBox->itemData(m_buildConfigurationComboBox->currentIndex()).toString();
con's avatar
con committed
290
291
292
293
294
    deleteConfiguration(configuration);
}

void BuildSettingsWidget::cloneConfiguration(const QString &sourceConfiguration)
{
hjk's avatar
hjk committed
295
    if (sourceConfiguration.isEmpty())
con's avatar
con committed
296
297
298
        return;

    QString newBuildConfiguration = QInputDialog::getText(this, tr("Clone configuration"), tr("New Configuration Name:"));
hjk's avatar
hjk committed
299
    if (newBuildConfiguration.isEmpty())
con's avatar
con committed
300
301
302
303
        return;

    QString newDisplayName = newBuildConfiguration;
    // Check that the internal name is not taken and use a different one otherwise
304
    if (m_project->buildConfiguration(newBuildConfiguration)) {
con's avatar
con committed
305
        int i = 2;
306
        while (m_project->buildConfiguration(newBuildConfiguration + QString::number(i)))
con's avatar
con committed
307
308
309
310
311
            ++i;
        newBuildConfiguration += QString::number(i);
    }

    m_project->copyBuildConfiguration(sourceConfiguration, newBuildConfiguration);
312
    m_project->setDisplayNameFor(m_project->buildConfiguration(newBuildConfiguration), newDisplayName);
con's avatar
con committed
313

dt's avatar
dt committed
314
    m_buildConfiguration = newBuildConfiguration;
con's avatar
con committed
315
316
317
318
319
320
321
322
    updateBuildSettings();
}

void BuildSettingsWidget::deleteConfiguration(const QString &deleteConfiguration)
{
    if (deleteConfiguration.isEmpty() || m_project->buildConfigurations().size() <= 1)
        return;

323
324
325
326
    if (m_project->activeBuildConfiguration()->name() == deleteConfiguration) {
        foreach (BuildConfiguration *bc, m_project->buildConfigurations()) {
            if (bc->name() != deleteConfiguration) {
                m_project->setActiveBuildConfiguration(bc);
con's avatar
con committed
327
328
329
330
331
                break;
            }
        }
    }

dt's avatar
dt committed
332
    if (m_buildConfiguration == deleteConfiguration) {
333
334
335
        foreach (const BuildConfiguration *bc, m_project->buildConfigurations()) {
            if (bc->name() != deleteConfiguration) {
                m_buildConfiguration = bc->name();
dt's avatar
dt committed
336
337
338
339
340
                break;
            }
        }
    }

341
    m_project->removeBuildConfiguration(m_project->buildConfiguration(deleteConfiguration));
con's avatar
con committed
342
343
344

    updateBuildSettings();
}