targetsettingspanel.cpp 10.9 KB
Newer Older
Tobias Hunger's avatar
Tobias Hunger committed
1
2
3
4
/**************************************************************************
**
** This file is part of Qt Creator
**
hjk's avatar
hjk committed
5
** Copyright (c) 2012 Nokia Corporation and/or its subsidiary(-ies).
Tobias Hunger's avatar
Tobias Hunger committed
6
**
7
** Contact: Nokia Corporation (qt-info@nokia.com)
Tobias Hunger's avatar
Tobias Hunger committed
8
9
10
11
**
**
** GNU Lesser General Public License Usage
**
hjk's avatar
hjk committed
12
13
14
15
16
17
** 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.
Tobias Hunger's avatar
Tobias Hunger committed
18
**
con's avatar
con committed
19
** In addition, as a special exception, Nokia gives you certain additional
hjk's avatar
hjk committed
20
** rights. These rights are described in the Nokia Qt LGPL Exception
con's avatar
con committed
21
22
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
hjk's avatar
hjk committed
23
24
25
26
27
** Other Usage
**
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
con's avatar
con committed
28
** If you have questions regarding the use of this file, please contact
29
** Nokia at qt-info@nokia.com.
Tobias Hunger's avatar
Tobias Hunger committed
30
31
32
33
34
35
36
37
38
39
40
41
42
**
**************************************************************************/

#include "targetsettingspanel.h"

#include "buildsettingspropertiespage.h"
#include "project.h"
#include "projectwindow.h"
#include "runsettingspropertiespage.h"
#include "target.h"
#include "targetsettingswidget.h"

#include <extensionsystem/pluginmanager.h>
Daniel Teske's avatar
Daniel Teske committed
43
44
#include <projectexplorer/projectexplorer.h>
#include <projectexplorer/buildmanager.h>
Tobias Hunger's avatar
Tobias Hunger committed
45

46
47
48
49
50
51
52
#include <QCoreApplication>
#include <QLabel>
#include <QMenu>
#include <QMessageBox>
#include <QVBoxLayout>
#include <QStackedWidget>
#include <QPushButton>
Tobias Hunger's avatar
Tobias Hunger committed
53
54
55
56
57
58
59
60
61
62

using namespace ProjectExplorer;
using namespace ProjectExplorer::Internal;


///
// TargetSettingsWidget
///

TargetSettingsPanelWidget::TargetSettingsPanelWidget(Project *project) :
63
    m_currentTarget(0),
Tobias Hunger's avatar
Tobias Hunger committed
64
65
66
67
    m_project(project),
    m_selector(0),
    m_centralWidget(0)
{
68
69
    Q_ASSERT(m_project);

Tobias Hunger's avatar
Tobias Hunger committed
70
71
72
    m_panelWidgets[0] = 0;
    m_panelWidgets[1] = 0;

73
74
    m_addMenu = new QMenu(this);

75
76
    setFocusPolicy(Qt::NoFocus);

Tobias Hunger's avatar
Tobias Hunger committed
77
78
79
80
    setupUi();

    connect(m_project, SIGNAL(addedTarget(ProjectExplorer::Target*)),
            this, SLOT(targetAdded(ProjectExplorer::Target*)));
81
82
83
    connect(m_project, SIGNAL(removedTarget(ProjectExplorer::Target*)),
            this, SLOT(removedTarget(ProjectExplorer::Target*)));

Tobias Hunger's avatar
Tobias Hunger committed
84
85
    connect(m_project, SIGNAL(activeTargetChanged(ProjectExplorer::Target*)),
            this, SLOT(activeTargetChanged(ProjectExplorer::Target*)));
86
87
88
89
90
91
92
93

    QList<ITargetFactory *> factories =
            ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();

    foreach (ITargetFactory *fac, factories) {
        connect(fac, SIGNAL(supportedTargetIdsChanged()),
                this, SLOT(updateTargetAddAndRemoveButtons()));
    }
Tobias Hunger's avatar
Tobias Hunger committed
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
}

TargetSettingsPanelWidget::~TargetSettingsPanelWidget()
{
}

void TargetSettingsPanelWidget::setupUi()
{
    QVBoxLayout *viewLayout = new QVBoxLayout(this);
    viewLayout->setMargin(0);
    viewLayout->setSpacing(0);

    m_selector = new TargetSettingsWidget(this);
    viewLayout->addWidget(m_selector);

    // Setup our container for the contents:
    m_centralWidget = new QStackedWidget(this);
    m_selector->setCentralWidget(m_centralWidget);

113
    // no target label:
Tobias Hunger's avatar
Tobias Hunger committed
114
    m_noTargetLabel = new QWidget;
115
    QVBoxLayout *noTargetLayout = new QVBoxLayout(m_noTargetLabel);
Tobias Hunger's avatar
Tobias Hunger committed
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
    noTargetLayout->setMargin(0);
    QLabel *label = new QLabel(m_noTargetLabel);
    label->setText(tr("No target defined."));
    {
        QFont f = label->font();
        f.setPointSizeF(f.pointSizeF() * 1.4);
        f.setBold(true);
        label->setFont(f);
    }
    label->setMargin(10);
    label->setAlignment(Qt::AlignTop);
    noTargetLayout->addWidget(label);
    noTargetLayout->addStretch(10);
    m_centralWidget->addWidget(m_noTargetLabel);

    foreach (Target *t, m_project->targets())
        targetAdded(t);

dt's avatar
dt committed
134
135
136
137
138
139
140
141
142
143
    // Now set the correct target
    int index = m_targets.indexOf(m_project->activeTarget());
    m_selector->setCurrentIndex(index);
    m_selector->setCurrentSubIndex(0);

    currentTargetChanged(index, 0);

    connect(m_selector, SIGNAL(currentChanged(int,int)),
            this, SLOT(currentTargetChanged(int,int)));

144
145
    connect(m_selector, SIGNAL(removeButtonClicked()),
            this, SLOT(removeTarget()));
Tobias Hunger's avatar
Tobias Hunger committed
146

147
148
149
150
    m_selector->setAddButtonMenu(m_addMenu);
    connect(m_addMenu, SIGNAL(triggered(QAction*)),
            this, SLOT(addTarget(QAction*)));

151
    updateTargetAddAndRemoveButtons();
Tobias Hunger's avatar
Tobias Hunger committed
152
153
}

154
void TargetSettingsPanelWidget::currentTargetChanged(int targetIndex, int subIndex)
Tobias Hunger's avatar
Tobias Hunger committed
155
{
156
    if (targetIndex < -1 || targetIndex >= m_targets.count())
Tobias Hunger's avatar
Tobias Hunger committed
157
158
159
160
        return;
    if (subIndex < -1 || subIndex >= 2)
        return;

161
162
163
164
165
166
167
168
169
170
    if (targetIndex == -1 || subIndex == -1) { // no more targets!
        delete m_panelWidgets[0];
        m_panelWidgets[0] = 0;
        delete m_panelWidgets[1];
        m_panelWidgets[1] = 0;

        m_centralWidget->setCurrentWidget(m_noTargetLabel);
        return;
    }

171
    Target *target = m_targets.at(targetIndex);
Tobias Hunger's avatar
Tobias Hunger committed
172
173

    // Target was not actually changed:
174
    if (m_currentTarget == target) {
175
176
177
178
        if (m_panelWidgets[subIndex])
            m_centralWidget->setCurrentWidget(m_panelWidgets[subIndex]);
        else
            m_centralWidget->setCurrentWidget(m_noTargetLabel);
Tobias Hunger's avatar
Tobias Hunger committed
179
180
181
        return;
    }

182
    // Target has changed:
183
    m_currentTarget = target;
Tobias Hunger's avatar
Tobias Hunger committed
184

185
186
    PanelsWidget *buildPanel = new PanelsWidget(m_centralWidget);
    PanelsWidget *runPanel = new PanelsWidget(m_centralWidget);
Tobias Hunger's avatar
Tobias Hunger committed
187

188
    foreach (ITargetPanelFactory *panelFactory, ExtensionSystem::PluginManager::instance()->getObjects<ITargetPanelFactory>()) {
Tobias Hunger's avatar
Tobias Hunger committed
189
        if (panelFactory->id() == QLatin1String(BUILDSETTINGS_PANEL_ID)) {
190
            PropertiesPanel *panel = panelFactory->createPanel(target);
Tobias Hunger's avatar
Tobias Hunger committed
191
192
193
194
            buildPanel->addPropertiesPanel(panel);
            continue;
        }
        if (panelFactory->id() == QLatin1String(RUNSETTINGS_PANEL_ID)) {
195
            PropertiesPanel *panel = panelFactory->createPanel(target);
Tobias Hunger's avatar
Tobias Hunger committed
196
197
198
199
200
201
202
            runPanel->addPropertiesPanel(panel);
            continue;
        }
    }
    m_centralWidget->addWidget(buildPanel);
    m_centralWidget->addWidget(runPanel);

203
204
205
    m_centralWidget->setCurrentWidget(subIndex == 0 ? buildPanel : runPanel);

    delete m_panelWidgets[0];
Tobias Hunger's avatar
Tobias Hunger committed
206
    m_panelWidgets[0] = buildPanel;
207
    delete m_panelWidgets[1];
Tobias Hunger's avatar
Tobias Hunger committed
208
    m_panelWidgets[1] = runPanel;
209
210
211


    m_project->setActiveTarget(target);
Tobias Hunger's avatar
Tobias Hunger committed
212
213
}

214
void TargetSettingsPanelWidget::addTarget(QAction *action)
Tobias Hunger's avatar
Tobias Hunger committed
215
{
216
    QString id = action->data().toString();
217
    Q_ASSERT(!m_project->target(id));
218
219
220
221
222
223
224
225
226
227
228
    QList<ITargetFactory *> factories =
            ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();

    Target *target = 0;
    foreach (ITargetFactory *fac, factories) {
        if (fac->canCreate(m_project, id)) {
            target = fac->create(m_project, id);
            break;
        }
    }

229
230
231
    if (!target)
        return;
    m_project->addTarget(target);
Tobias Hunger's avatar
Tobias Hunger committed
232
233
}

234
235
236
void TargetSettingsPanelWidget::removeTarget()
{
    int index = m_selector->currentIndex();
237
    Target *t = m_targets.at(index);
Daniel Teske's avatar
Daniel Teske committed
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

    ProjectExplorer::BuildManager *bm = ProjectExplorerPlugin::instance()->buildManager();
    if (bm->isBuilding(t)) {
        QMessageBox box;
        QPushButton *closeAnyway = box.addButton(tr("Cancel Build && Remove Target"), QMessageBox::AcceptRole);
        QPushButton *cancelClose = box.addButton(tr("Do Not Remove"), QMessageBox::RejectRole);
        box.setDefaultButton(cancelClose);
        box.setWindowTitle(tr("Remove Target %1?").arg(t->displayName()));
        box.setText(tr("The target <b>%1</b> is currently being built.").arg(t->displayName()));
        box.setInformativeText(tr("Do you want to cancel the build process and remove the Target anyway?"));
        box.exec();
        if (box.clickedButton() != closeAnyway)
            return;
        bm->cancel();
    } else {
        // We don't show the generic message box on removing the target, if we showed the still building one
        int ret = QMessageBox::warning(this, tr("Qt Creator"),
                                       tr("Do you really want to remove the\n"
                                          "\"%1\" target?").arg(t->displayName()),
                                        QMessageBox::Yes | QMessageBox::No,
                                        QMessageBox::No);
        if (ret != QMessageBox::Yes)
            return;
    }

    m_project->removeTarget(t);

265
266
}

Tobias Hunger's avatar
Tobias Hunger committed
267
268
269
270
271
void TargetSettingsPanelWidget::targetAdded(ProjectExplorer::Target *target)
{
    Q_ASSERT(m_project == target->project());
    Q_ASSERT(m_selector);

272
273
274
275
276
277
278
279
280
    for (int pos = 0; pos <= m_targets.count(); ++pos) {
        if (m_targets.count() == pos ||
            m_targets.at(pos)->displayName() > target->displayName()) {
            m_targets.insert(pos, target);
            m_selector->insertTarget(pos, target->displayName());
            break;
        }
    }

281
    updateTargetAddAndRemoveButtons();
Tobias Hunger's avatar
Tobias Hunger committed
282
283
}

284
void TargetSettingsPanelWidget::removedTarget(ProjectExplorer::Target *target)
Tobias Hunger's avatar
Tobias Hunger committed
285
286
287
288
{
    Q_ASSERT(m_project == target->project());
    Q_ASSERT(m_selector);

289
    int index(m_targets.indexOf(target));
Tobias Hunger's avatar
Tobias Hunger committed
290
291
    if (index < 0)
        return;
292
293
    m_targets.removeAt(index);

Tobias Hunger's avatar
Tobias Hunger committed
294
    m_selector->removeTarget(index);
295
296

    updateTargetAddAndRemoveButtons();
Tobias Hunger's avatar
Tobias Hunger committed
297
298
299
300
301
302
303
}

void TargetSettingsPanelWidget::activeTargetChanged(ProjectExplorer::Target *target)
{
    Q_ASSERT(m_project == target->project());
    Q_ASSERT(m_selector);

304
305
    int index = m_targets.indexOf(target);
    m_selector->setCurrentIndex(index);
Tobias Hunger's avatar
Tobias Hunger committed
306
}
307
308
309
310
311
312

void TargetSettingsPanelWidget::updateTargetAddAndRemoveButtons()
{
    if (!m_selector)
        return;

313
314
    m_addMenu->clear();

315
316
317
    QList<ITargetFactory *> factories =
            ExtensionSystem::PluginManager::instance()->getObjects<ITargetFactory>();

318
319
320
321
322
323
324
325
    foreach (ITargetFactory *fac, factories) {
        foreach (const QString &id, fac->supportedTargetIds(m_project)) {
            if (m_project->target(id))
                continue;
            QString displayName = fac->displayNameForId(id);
            QAction *action = new QAction(displayName, m_addMenu);
            action->setData(QVariant(id));
            bool added = false;
dt's avatar
dt committed
326
            foreach (QAction *existing, m_addMenu->actions()) {
327
328
329
330
                if (existing->text() > action->text()) {
                    m_addMenu->insertAction(existing, action);
                    added = true;
                }
331
332
            }

333
334
            if (!added)
                m_addMenu->addAction(action);
335
336
        }
    }
337

338
    m_selector->setAddButtonEnabled(!m_addMenu->actions().isEmpty());
339
340
    m_selector->setRemoveButtonEnabled(m_project->targets().count() > 1);
}
341
342
343
344
345
346
347
348
349
350

int TargetSettingsPanelWidget::currentSubIndex() const
{
    return m_selector->currentSubIndex();
}

void TargetSettingsPanelWidget::setCurrentSubIndex(int subIndex)
{
    m_selector->setCurrentSubIndex(subIndex);
}