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 "kitchooser.h"
27 
28 #include "kitinformation.h"
29 #include "kitmanager.h"
30 #include "project.h"
31 #include "projectexplorerconstants.h"
32 #include "session.h"
33 #include "target.h"
34 
35 #include <coreplugin/icore.h>
36 
37 #include <QComboBox>
38 #include <QHBoxLayout>
39 #include <QPushButton>
40 #include <QSettings>
41 
42 using namespace Core;
43 using namespace Utils;
44 
45 namespace ProjectExplorer {
46 
47 const char lastKitKey[] = "LastSelectedKit";
48 
KitChooser(QWidget * parent)49 KitChooser::KitChooser(QWidget *parent) :
50     QWidget(parent),
51     m_kitPredicate([](const Kit *k) { return k->isValid(); })
52 {
53     m_chooser = new QComboBox(this);
54     m_chooser->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed);
55     m_manageButton = new QPushButton(KitAspectWidget::msgManage(), this);
56 
57     auto layout = new QHBoxLayout(this);
58     layout->setContentsMargins(0, 0, 0, 0);
59     layout->addWidget(m_chooser);
60     layout->addWidget(m_manageButton);
61     setFocusProxy(m_manageButton);
62 
63     connect(m_chooser, QOverload<int>::of(&QComboBox::currentIndexChanged),
64             this, &KitChooser::onCurrentIndexChanged);
65     connect(m_chooser, QOverload<int>::of(&QComboBox::activated),
66             this, &KitChooser::onActivated);
67     connect(m_manageButton, &QAbstractButton::clicked, this, &KitChooser::onManageButtonClicked);
68     connect(KitManager::instance(), &KitManager::kitsChanged, this, &KitChooser::populate);
69 }
70 
onManageButtonClicked()71 void KitChooser::onManageButtonClicked()
72 {
73     Core::ICore::showOptionsDialog(Constants::KITS_SETTINGS_PAGE_ID, this);
74 }
75 
setShowIcons(bool showIcons)76 void KitChooser::setShowIcons(bool showIcons)
77 {
78     m_showIcons = showIcons;
79 }
80 
onCurrentIndexChanged()81 void KitChooser::onCurrentIndexChanged()
82 {
83     const Id id = Id::fromSetting(m_chooser->currentData());
84     Kit *kit = KitManager::kit(id);
85     setToolTip(kit ? kitToolTip(kit) : QString());
86     emit currentIndexChanged();
87 }
88 
onActivated()89 void KitChooser::onActivated()
90 {
91     // Active user interaction.
92     Id id = Id::fromSetting(m_chooser->currentData());
93     if (m_hasStartupKit && m_chooser->currentIndex() == 0)
94         id = Id(); // Special value to indicate startup kit.
95     ICore::settings()->setValueWithDefault(lastKitKey, id.toSetting(), Id().toSetting());
96     emit activated();
97 }
98 
kitText(const Kit * k) const99 QString KitChooser::kitText(const Kit *k) const
100 {
101     return k->displayName();
102 }
103 
kitToolTip(Kit * k) const104 QString KitChooser::kitToolTip(Kit *k) const
105 {
106     return k->toHtml();
107 }
108 
populate()109 void KitChooser::populate()
110 {
111     m_chooser->clear();
112 
113     const Id lastKit = Id::fromSetting(ICore::settings()->value(lastKitKey));
114     bool didActivate = false;
115 
116     if (Target *target = SessionManager::startupTarget()) {
117         Kit *kit = target->kit();
118         if (m_kitPredicate(kit)) {
119             QString display = tr("Kit of Active Project: %1").arg(kitText(kit));
120             m_chooser->addItem(display, kit->id().toSetting());
121             m_chooser->setItemData(0, kitToolTip(kit), Qt::ToolTipRole);
122             if (!lastKit.isValid()) {
123                 m_chooser->setCurrentIndex(0);
124                 didActivate = true;
125             }
126             m_chooser->insertSeparator(1);
127             m_hasStartupKit = true;
128         }
129     }
130 
131     foreach (Kit *kit, KitManager::sortKits(KitManager::kits())) {
132         if (m_kitPredicate(kit)) {
133             m_chooser->addItem(kitText(kit), kit->id().toSetting());
134             const int pos = m_chooser->count() - 1;
135             m_chooser->setItemData(pos, kitToolTip(kit), Qt::ToolTipRole);
136             if (m_showIcons)
137                 m_chooser->setItemData(pos, kit->displayIcon(), Qt::DecorationRole);
138             if (!didActivate && kit->id() == lastKit) {
139                 m_chooser->setCurrentIndex(pos);
140                 didActivate = true;
141             }
142         }
143     }
144 
145     const int n = m_chooser->count();
146     m_chooser->setEnabled(n > 1);
147 
148     if (n > 1)
149         setFocusProxy(m_chooser);
150     else
151         setFocusProxy(m_manageButton);
152 
153 }
154 
currentKit() const155 Kit *KitChooser::currentKit() const
156 {
157     const Id id = Id::fromSetting(m_chooser->currentData());
158     return KitManager::kit(id);
159 }
160 
setCurrentKitId(Utils::Id id)161 void KitChooser::setCurrentKitId(Utils::Id id)
162 {
163     QVariant v = id.toSetting();
164     for (int i = 0, n = m_chooser->count(); i != n; ++i) {
165         if (m_chooser->itemData(i) == v) {
166             m_chooser->setCurrentIndex(i);
167             break;
168         }
169     }
170 }
171 
currentKitId() const172 Utils::Id KitChooser::currentKitId() const
173 {
174     Kit *kit = currentKit();
175     return kit ? kit->id() : Utils::Id();
176 }
177 
setKitPredicate(const Kit::Predicate & predicate)178 void KitChooser::setKitPredicate(const Kit::Predicate &predicate)
179 {
180     m_kitPredicate = predicate;
181     populate();
182 }
183 
184 } // namespace ProjectExplorer
185