1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25
26 #include "targetsetuppage.h"
27 #include "buildconfiguration.h"
28 #include "buildinfo.h"
29 #include "importwidget.h"
30 #include "kit.h"
31 #include "kitmanager.h"
32 #include "project.h"
33 #include "projectexplorerconstants.h"
34 #include "session.h"
35 #include "target.h"
36 #include "targetsetupwidget.h"
37 #include "task.h"
38
39 #include <coreplugin/icore.h>
40
41 #include <projectexplorer/ipotentialkit.h>
42
43 #include <utils/qtcassert.h>
44 #include <utils/qtcprocess.h>
45 #include <utils/wizard.h>
46 #include <utils/algorithm.h>
47 #include <utils/fancylineedit.h>
48
49 #include <QFileInfo>
50 #include <QLabel>
51 #include <QMessageBox>
52 #include <QScrollArea>
53 #include <QVBoxLayout>
54 #include <QCheckBox>
55
56 using namespace Utils;
57
58 namespace ProjectExplorer {
59
60 static QList<IPotentialKit *> g_potentialKits;
61
IPotentialKit()62 IPotentialKit::IPotentialKit()
63 {
64 g_potentialKits.append(this);
65 }
66
~IPotentialKit()67 IPotentialKit::~IPotentialKit()
68 {
69 g_potentialKits.removeOne(this);
70 }
71
72 namespace Internal {
importDirectory(const FilePath & projectPath)73 static FilePath importDirectory(const FilePath &projectPath)
74 {
75 // Setup import widget:
76 auto path = projectPath;
77 path = path.parentDir(); // base dir
78 path = path.parentDir(); // parent dir
79
80 return path;
81 }
82
83 class TargetSetupPageUi
84 {
85 public:
86 QWidget *centralWidget;
87 QWidget *scrollAreaWidget;
88 QScrollArea *scrollArea;
89 QLabel *headerLabel;
90 QLabel *noValidKitLabel;
91 QCheckBox *allKitsCheckBox;
92 FancyLineEdit *kitFilterLineEdit;
93
setupUi(TargetSetupPage * q)94 void setupUi(TargetSetupPage *q)
95 {
96 auto setupTargetPage = new QWidget(q);
97
98 headerLabel = new QLabel(setupTargetPage);
99 headerLabel->setWordWrap(true);
100 headerLabel->setVisible(false);
101
102 noValidKitLabel = new QLabel(setupTargetPage);
103 noValidKitLabel->setWordWrap(true);
104 noValidKitLabel->setText("<span style=\" font-weight:600;\">"
105 + TargetSetupPage::tr("No suitable kits found.") + "</span><br/>"
106 + TargetSetupPage::tr("Add a kit in the <a href=\"buildandrun\">"
107 "options</a> or via the maintenance tool of"
108 " the SDK."));
109 noValidKitLabel->setTextInteractionFlags(Qt::TextBrowserInteraction);
110 noValidKitLabel->setVisible(false);
111
112 allKitsCheckBox = new QCheckBox(setupTargetPage);
113 allKitsCheckBox->setTristate(true);
114 allKitsCheckBox->setText(TargetSetupPage::tr("Select all kits"));
115
116 kitFilterLineEdit = new FancyLineEdit(setupTargetPage);
117 kitFilterLineEdit->setFiltering(true);
118 kitFilterLineEdit->setPlaceholderText(TargetSetupPage::tr("Type to filter kits by name..."));
119
120 centralWidget = new QWidget(setupTargetPage);
121 QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Fixed);
122 policy.setHorizontalStretch(0);
123 policy.setVerticalStretch(0);
124 policy.setHeightForWidth(centralWidget->sizePolicy().hasHeightForWidth());
125 centralWidget->setSizePolicy(policy);
126
127 scrollAreaWidget = new QWidget(setupTargetPage);
128 scrollArea = new QScrollArea(scrollAreaWidget);
129 scrollArea->setWidgetResizable(true);
130
131 auto scrollAreaWidgetContents = new QWidget();
132 scrollAreaWidgetContents->setGeometry(QRect(0, 0, 230, 81));
133 scrollArea->setWidget(scrollAreaWidgetContents);
134
135 auto verticalLayout = new QVBoxLayout(scrollAreaWidget);
136 verticalLayout->setSpacing(0);
137 verticalLayout->setContentsMargins(0, 0, 0, 0);
138 verticalLayout->addWidget(scrollArea);
139
140 auto verticalLayout_2 = new QVBoxLayout(setupTargetPage);
141 verticalLayout_2->addWidget(headerLabel);
142 verticalLayout_2->addWidget(kitFilterLineEdit);
143 verticalLayout_2->addWidget(noValidKitLabel);
144 verticalLayout_2->addWidget(allKitsCheckBox);
145 verticalLayout_2->addWidget(centralWidget);
146 verticalLayout_2->addWidget(scrollAreaWidget);
147
148 auto verticalLayout_3 = new QVBoxLayout(q);
149 verticalLayout_3->setContentsMargins(0, 0, 0, -1);
150 verticalLayout_3->addWidget(setupTargetPage);
151
152 QObject::connect(noValidKitLabel, &QLabel::linkActivated,
153 q, &TargetSetupPage::openOptions);
154
155 QObject::connect(allKitsCheckBox, &QAbstractButton::clicked,
156 q, &TargetSetupPage::changeAllKitsSelections);
157
158 QObject::connect(kitFilterLineEdit, &FancyLineEdit::filterChanged,
159 q, &TargetSetupPage::kitFilterChanged);
160 }
161 };
162
163 } // namespace Internal
164
defaultTasksGenerator(const TasksGenerator & childGenerator)165 static TasksGenerator defaultTasksGenerator(const TasksGenerator &childGenerator)
166 {
167 return [childGenerator](const Kit *k) -> Tasks {
168 if (!k->isValid())
169 return {
170 CompileTask(Task::Error,
171 QCoreApplication::translate("ProjectExplorer", "Kit is not valid."))};
172 if (childGenerator)
173 return childGenerator(k);
174 return {};
175 };
176 }
177
178 using namespace Internal;
179
TargetSetupPage(QWidget * parent)180 TargetSetupPage::TargetSetupPage(QWidget *parent)
181 : WizardPage(parent)
182 , m_tasksGenerator(defaultTasksGenerator({}))
183 , m_ui(new TargetSetupPageUi)
184 , m_importWidget(new ImportWidget(this))
185 , m_spacer(new QSpacerItem(0, 0, QSizePolicy::Minimum, QSizePolicy::MinimumExpanding))
186 {
187 m_importWidget->setVisible(false);
188
189 setObjectName(QLatin1String("TargetSetupPage"));
190 setWindowTitle(tr("Select Kits for Your Project"));
191 m_ui->setupUi(this);
192
193 QSizePolicy policy(QSizePolicy::Preferred, QSizePolicy::Preferred);
194 policy.setHorizontalStretch(0);
195 policy.setVerticalStretch(0);
196 policy.setHeightForWidth(sizePolicy().hasHeightForWidth());
197 setSizePolicy(policy);
198
199 auto centralWidget = new QWidget(this);
200 m_ui->scrollArea->setWidget(centralWidget);
201 centralWidget->setLayout(new QVBoxLayout);
202 m_ui->centralWidget->setLayout(new QVBoxLayout);
203 m_ui->centralWidget->layout()->setContentsMargins(0, 0, 0, 0);
204
205 setTitle(tr("Kit Selection"));
206
207 for (IPotentialKit *pk : qAsConst(g_potentialKits))
208 if (pk->isEnabled())
209 m_potentialWidgets.append(pk->createWidget(this));
210
211 setUseScrollArea(true);
212
213 KitManager *km = KitManager::instance();
214 // do note that those slots are triggered once *per* targetsetuppage
215 // thus the same slot can be triggered multiple times on different instances!
216 connect(km, &KitManager::kitAdded, this, &TargetSetupPage::handleKitAddition);
217 connect(km, &KitManager::kitRemoved, this, &TargetSetupPage::handleKitRemoval);
218 connect(km, &KitManager::kitUpdated, this, &TargetSetupPage::handleKitUpdate);
219 connect(m_importWidget, &ImportWidget::importFrom,
__anond4c89d290202(const FilePath &dir) 220 this, [this](const FilePath &dir) { import(dir); });
221 connect(KitManager::instance(), &KitManager::kitsChanged,
222 this, &TargetSetupPage::updateVisibility);
223
224 setProperty(SHORT_TITLE_PROPERTY, tr("Kits"));
225 }
226
initializePage()227 void TargetSetupPage::initializePage()
228 {
229 if (KitManager::isLoaded()) {
230 doInitializePage();
231 } else {
232 connect(KitManager::instance(), &KitManager::kitsLoaded,
233 this, &TargetSetupPage::doInitializePage);
234 }
235 }
236
setTasksGenerator(const TasksGenerator & tasksGenerator)237 void TargetSetupPage::setTasksGenerator(const TasksGenerator &tasksGenerator)
238 {
239 m_tasksGenerator = defaultTasksGenerator(tasksGenerator);
240 }
241
selectedKits() const242 QList<Utils::Id> TargetSetupPage::selectedKits() const
243 {
244 QList<Utils::Id> result;
245 for (TargetSetupWidget *w : m_widgets) {
246 if (w->isKitSelected())
247 result.append(w->kit()->id());
248 }
249 return result;
250 }
251
~TargetSetupPage()252 TargetSetupPage::~TargetSetupPage()
253 {
254 disconnect();
255 reset();
256 delete m_spacer;
257 delete m_ui;
258 }
259
isComplete() const260 bool TargetSetupPage::isComplete() const
261 {
262 return anyOf(m_widgets, [](const TargetSetupWidget *w) {
263 return w->isKitSelected();
264 });
265 }
266
setupWidgets(const QString & filterText)267 void TargetSetupPage::setupWidgets(const QString &filterText)
268 {
269 const auto kitList = KitManager::sortKits(KitManager::kits());
270 for (Kit *k : kitList) {
271 if (!filterText.isEmpty() && !k->displayName().contains(filterText, Qt::CaseInsensitive))
272 continue;
273 const auto widget = new TargetSetupWidget(k, m_projectPath);
274 connect(widget, &TargetSetupWidget::selectedToggled,
275 this, &TargetSetupPage::kitSelectionChanged);
276 connect(widget, &TargetSetupWidget::selectedToggled, this, &QWizardPage::completeChanged);
277 updateWidget(widget);
278 m_widgets.push_back(widget);
279 m_baseLayout->addWidget(widget);
280 }
281 addAdditionalWidgets();
282
283 // Setup import widget:
284 m_importWidget->setCurrentDirectory(Internal::importDirectory(m_projectPath));
285
286 kitSelectionChanged();
287 updateVisibility();
288 }
289
reset()290 void TargetSetupPage::reset()
291 {
292 removeAdditionalWidgets();
293 while (m_widgets.size() > 0) {
294 TargetSetupWidget *w = m_widgets.back();
295
296 Kit *k = w->kit();
297 if (k && m_importer)
298 m_importer->removeProject(k);
299
300 removeWidget(w);
301 }
302
303 m_ui->allKitsCheckBox->setChecked(false);
304 }
305
widget(const Utils::Id kitId,TargetSetupWidget * fallback) const306 TargetSetupWidget *TargetSetupPage::widget(const Utils::Id kitId,
307 TargetSetupWidget *fallback) const
308 {
309 return findOr(m_widgets, fallback, [kitId](const TargetSetupWidget *w) {
310 return w->kit() && w->kit()->id() == kitId;
311 });
312 }
313
setProjectPath(const FilePath & path)314 void TargetSetupPage::setProjectPath(const FilePath &path)
315 {
316 m_projectPath = path;
317 if (!m_projectPath.isEmpty()) {
318 QFileInfo fileInfo(QDir::cleanPath(path.toString()));
319 QStringList subDirsList = fileInfo.absolutePath().split('/');
320 m_ui->headerLabel->setText(tr("The following kits can be used for project <b>%1</b>:",
321 "%1: Project name").arg(subDirsList.last()));
322 }
323 m_ui->headerLabel->setVisible(!m_projectPath.isEmpty());
324
325 if (m_widgetsWereSetUp)
326 initializePage();
327 }
328
setProjectImporter(ProjectImporter * importer)329 void TargetSetupPage::setProjectImporter(ProjectImporter *importer)
330 {
331 if (importer == m_importer)
332 return;
333
334 if (m_widgetsWereSetUp)
335 reset(); // Reset before changing the importer!
336
337 m_importer = importer;
338 m_importWidget->setVisible(m_importer);
339
340 if (m_widgetsWereSetUp)
341 initializePage();
342 }
343
importLineEditHasFocus() const344 bool TargetSetupPage::importLineEditHasFocus() const
345 {
346 return m_importWidget->ownsReturnKey();
347 }
348
setupImports()349 void TargetSetupPage::setupImports()
350 {
351 if (!m_importer || m_projectPath.isEmpty())
352 return;
353
354 const QStringList toImport = m_importer->importCandidates();
355 for (const QString &path : toImport)
356 import(FilePath::fromString(path), true);
357 }
358
handleKitAddition(Kit * k)359 void TargetSetupPage::handleKitAddition(Kit *k)
360 {
361 if (isUpdating())
362 return;
363
364 Q_ASSERT(!widget(k));
365 addWidget(k);
366 kitSelectionChanged();
367 updateVisibility();
368 }
369
handleKitRemoval(Kit * k)370 void TargetSetupPage::handleKitRemoval(Kit *k)
371 {
372 if (isUpdating())
373 return;
374
375 if (m_importer)
376 m_importer->cleanupKit(k);
377
378 removeWidget(k);
379 kitSelectionChanged();
380 updateVisibility();
381 }
382
handleKitUpdate(Kit * k)383 void TargetSetupPage::handleKitUpdate(Kit *k)
384 {
385 if (isUpdating())
386 return;
387
388 if (m_importer)
389 m_importer->makePersistent(k);
390
391 const auto newWidgetList = sortedWidgetList();
392 if (newWidgetList != m_widgets) { // Sorting has changed.
393 m_widgets = newWidgetList;
394 reLayout();
395 }
396 updateWidget(widget(k));
397 kitSelectionChanged();
398 updateVisibility();
399 }
400
selectAtLeastOneEnabledKit()401 void TargetSetupPage::selectAtLeastOneEnabledKit()
402 {
403 if (anyOf(m_widgets, [](const TargetSetupWidget *w) { return w->isKitSelected(); })) {
404 // Something is already selected, we are done.
405 return;
406 }
407
408 TargetSetupWidget *toCheckWidget = nullptr;
409
410 const Kit *defaultKit = KitManager::defaultKit();
411
412 auto isPreferred = [this](const TargetSetupWidget *w) {
413 const Tasks tasks = m_tasksGenerator(w->kit());
414 return w->isEnabled() && tasks.isEmpty();
415 };
416
417 // Use default kit if that is preferred:
418 toCheckWidget = findOrDefault(m_widgets, [defaultKit, isPreferred](const TargetSetupWidget *w) {
419 return isPreferred(w) && w->kit() == defaultKit;
420 });
421
422 if (!toCheckWidget) {
423 // Use the first preferred widget:
424 toCheckWidget = findOrDefault(m_widgets, isPreferred);
425 }
426
427 if (!toCheckWidget) {
428 // Use default kit if it is enabled:
429 toCheckWidget = findOrDefault(m_widgets, [defaultKit](const TargetSetupWidget *w) {
430 return w->isEnabled() && w->kit() == defaultKit;
431 });
432 }
433
434 if (!toCheckWidget) {
435 // Use the first enabled widget:
436 toCheckWidget = findOrDefault(m_widgets,
437 [](const TargetSetupWidget *w) { return w->isEnabled(); });
438 }
439
440 if (toCheckWidget) {
441 toCheckWidget->setKitSelected(true);
442
443 emit completeChanged(); // Is this necessary?
444 }
445 }
446
updateVisibility()447 void TargetSetupPage::updateVisibility()
448 {
449 // Always show the widgets, the import widget always makes sense to show.
450 m_ui->scrollAreaWidget->setVisible(m_baseLayout == m_ui->scrollArea->widget()->layout());
451 m_ui->centralWidget->setVisible(m_baseLayout == m_ui->centralWidget->layout());
452
453 const bool hasUsableKits = KitManager::kit([this](const Kit *k) { return isUsable(k); });
454 m_ui->noValidKitLabel->setVisible(!hasUsableKits);
455 m_ui->allKitsCheckBox->setVisible(hasUsableKits);
456
457 emit completeChanged();
458 }
459
reLayout()460 void TargetSetupPage::reLayout()
461 {
462 removeAdditionalWidgets();
463 for (TargetSetupWidget * const w : qAsConst(m_widgets))
464 m_baseLayout->removeWidget(w);
465 for (TargetSetupWidget * const w : qAsConst(m_widgets))
466 m_baseLayout->addWidget(w);
467 addAdditionalWidgets();
468 }
469
compareKits(const Kit * k1,const Kit * k2)470 bool TargetSetupPage::compareKits(const Kit *k1, const Kit *k2)
471 {
472 const QString name1 = k1->displayName();
473 const QString name2 = k2->displayName();
474 if (name1 < name2)
475 return true;
476 if (name1 > name2)
477 return false;
478 return k1 < k2;
479 }
480
sortedWidgetList() const481 std::vector<TargetSetupWidget *> TargetSetupPage::sortedWidgetList() const
482 {
483 std::vector<TargetSetupWidget *> list = m_widgets;
484 sort(list, [](const TargetSetupWidget *w1, const TargetSetupWidget *w2) {
485 return compareKits(w1->kit(), w2->kit());
486 });
487 return list;
488 }
489
openOptions()490 void TargetSetupPage::openOptions()
491 {
492 Core::ICore::showOptionsDialog(Constants::KITS_SETTINGS_PAGE_ID, this);
493 }
494
kitSelectionChanged()495 void TargetSetupPage::kitSelectionChanged()
496 {
497 int selected = 0;
498 int deselected = 0;
499 for (const TargetSetupWidget *widget : m_widgets) {
500 if (widget->isKitSelected())
501 ++selected;
502 else
503 ++deselected;
504 }
505 if (selected > 0 && deselected > 0)
506 m_ui->allKitsCheckBox->setCheckState(Qt::PartiallyChecked);
507 else if (selected > 0 && deselected == 0)
508 m_ui->allKitsCheckBox->setCheckState(Qt::Checked);
509 else
510 m_ui->allKitsCheckBox->setCheckState(Qt::Unchecked);
511 }
512
kitFilterChanged(const QString & filterText)513 void TargetSetupPage::kitFilterChanged(const QString &filterText)
514 {
515 // Remember selected kits:
516 const std::vector<TargetSetupWidget *> selectedWidgets
517 = filtered(m_widgets, &TargetSetupWidget::isKitSelected);
518 const QVector<Utils::Id> selectedKitIds = transform<QVector>(selectedWidgets,
519 [](const TargetSetupWidget *w) {
520 return w->kit()->id();
521 });
522
523 // Reset currently shown kits
524 reset();
525 setupWidgets(filterText);
526
527 // Re-select kits:
528 for (TargetSetupWidget *w : qAsConst(m_widgets))
529 w->setKitSelected(selectedKitIds.contains(w->kit()->id()));
530 }
531
doInitializePage()532 void TargetSetupPage::doInitializePage()
533 {
534 reset();
535 setupWidgets();
536 setupImports();
537
538 selectAtLeastOneEnabledKit();
539
540 updateVisibility();
541 }
542
showEvent(QShowEvent * event)543 void TargetSetupPage::showEvent(QShowEvent *event)
544 {
545 WizardPage::showEvent(event);
546 setFocus(); // Ensure "Configure Project" gets triggered on <Return>
547 }
548
changeAllKitsSelections()549 void TargetSetupPage::changeAllKitsSelections()
550 {
551 if (m_ui->allKitsCheckBox->checkState() == Qt::PartiallyChecked)
552 m_ui->allKitsCheckBox->setCheckState(Qt::Checked);
553 bool checked = m_ui->allKitsCheckBox->isChecked();
554 for (TargetSetupWidget *widget : m_widgets)
555 widget->setKitSelected(checked);
556 emit completeChanged();
557 }
558
isUpdating() const559 bool TargetSetupPage::isUpdating() const
560 {
561 return m_importer && m_importer->isUpdating();
562 }
563
import(const FilePath & path,bool silent)564 void TargetSetupPage::import(const FilePath &path, bool silent)
565 {
566 if (!m_importer)
567 return;
568
569 for (const BuildInfo &info : m_importer->import(path, silent)) {
570 TargetSetupWidget *w = widget(info.kitId);
571 if (!w) {
572 Kit *k = KitManager::kit(info.kitId);
573 Q_ASSERT(k);
574 addWidget(k);
575 }
576 w = widget(info.kitId);
577 if (!w)
578 continue;
579
580 w->addBuildInfo(info, true);
581 w->setKitSelected(true);
582 w->expandWidget();
583 kitSelectionChanged();
584 }
585 emit completeChanged();
586 }
587
removeWidget(TargetSetupWidget * w)588 void TargetSetupPage::removeWidget(TargetSetupWidget *w)
589 {
590 if (!w)
591 return;
592 w->deleteLater();
593 w->clearKit();
594 m_widgets.erase(std::find(m_widgets.begin(), m_widgets.end(), w));
595 }
596
addWidget(Kit * k)597 TargetSetupWidget *TargetSetupPage::addWidget(Kit *k)
598 {
599 const auto widget = new TargetSetupWidget(k, m_projectPath);
600 updateWidget(widget);
601 connect(widget, &TargetSetupWidget::selectedToggled,
602 this, &TargetSetupPage::kitSelectionChanged);
603 connect(widget, &TargetSetupWidget::selectedToggled, this, &QWizardPage::completeChanged);
604
605
606 // Insert widget, sorted.
607 const auto insertionPos = std::find_if(m_widgets.begin(), m_widgets.end(),
608 [k](const TargetSetupWidget *w) {
609 return compareKits(k, w->kit());
610 });
611 const bool addedToEnd = insertionPos == m_widgets.end();
612 m_widgets.insert(insertionPos, widget);
613 if (addedToEnd) {
614 removeAdditionalWidgets();
615 m_baseLayout->addWidget(widget);
616 addAdditionalWidgets();
617 } else {
618 reLayout();
619 }
620
621 return widget;
622 }
623
addAdditionalWidgets()624 void TargetSetupPage::addAdditionalWidgets()
625 {
626 m_baseLayout->addWidget(m_importWidget);
627 for (QWidget * const widget : qAsConst(m_potentialWidgets))
628 m_baseLayout->addWidget(widget);
629 m_baseLayout->addItem(m_spacer);
630 }
631
removeAdditionalWidgets(QLayout * layout)632 void TargetSetupPage::removeAdditionalWidgets(QLayout *layout)
633 {
634 layout->removeWidget(m_importWidget);
635 for (QWidget * const potentialWidget : qAsConst(m_potentialWidgets))
636 layout->removeWidget(potentialWidget);
637 layout->removeItem(m_spacer);
638 }
639
updateWidget(TargetSetupWidget * widget)640 void TargetSetupPage::updateWidget(TargetSetupWidget *widget)
641 {
642 QTC_ASSERT(widget, return );
643 widget->update(m_tasksGenerator);
644 }
645
isUsable(const Kit * kit) const646 bool TargetSetupPage::isUsable(const Kit *kit) const
647 {
648 return !containsType(m_tasksGenerator(kit), Task::Error);
649 }
650
setupProject(Project * project)651 bool TargetSetupPage::setupProject(Project *project)
652 {
653 QList<BuildInfo> toSetUp;
654 for (TargetSetupWidget *widget : m_widgets) {
655 if (!widget->isKitSelected())
656 continue;
657
658 Kit *k = widget->kit();
659
660 if (k && m_importer)
661 m_importer->makePersistent(k);
662 toSetUp << widget->selectedBuildInfoList();
663 widget->clearKit();
664 }
665
666 project->setup(toSetUp);
667 toSetUp.clear();
668
669 // Only reset now that toSetUp has been cleared!
670 reset();
671
672 Target *activeTarget = nullptr;
673 if (m_importer)
674 activeTarget = m_importer->preferredTarget(project->targets());
675 if (activeTarget)
676 SessionManager::setActiveTarget(project, activeTarget, SetActive::NoCascade);
677
678 return true;
679 }
680
setUseScrollArea(bool b)681 void TargetSetupPage::setUseScrollArea(bool b)
682 {
683 QLayout *oldBaseLayout = m_baseLayout;
684 m_baseLayout = b ? m_ui->scrollArea->widget()->layout() : m_ui->centralWidget->layout();
685 if (oldBaseLayout == m_baseLayout)
686 return;
687 m_ui->scrollAreaWidget->setVisible(b);
688 m_ui->centralWidget->setVisible(!b);
689
690 if (oldBaseLayout)
691 removeAdditionalWidgets(oldBaseLayout);
692 addAdditionalWidgets();
693 }
694
695 } // namespace ProjectExplorer
696