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 "qmakekitinformation.h"
27
28 #include "qmakeprojectmanagerconstants.h"
29
30 #include <projectexplorer/projectexplorerconstants.h>
31 #include <projectexplorer/toolchain.h>
32 #include <projectexplorer/toolchainmanager.h>
33
34 #include <qtsupport/qtkitinformation.h>
35
36 #include <utils/algorithm.h>
37 #include <utils/layoutbuilder.h>
38 #include <utils/qtcassert.h>
39
40 #include <QDir>
41 #include <QLineEdit>
42
43 using namespace ProjectExplorer;
44 using namespace Utils;
45
46 namespace QmakeProjectManager {
47 namespace Internal {
48
49 class QmakeKitAspectWidget final : public KitAspectWidget
50 {
51 Q_DECLARE_TR_FUNCTIONS(QmakeProjectManager::Internal::QmakeKitAspect)
52
53 public:
QmakeKitAspectWidget(Kit * k,const KitAspect * ki)54 QmakeKitAspectWidget(Kit *k, const KitAspect *ki)
55 : KitAspectWidget(k, ki), m_lineEdit(createSubWidget<QLineEdit>())
56 {
57 refresh(); // set up everything according to kit
58 m_lineEdit->setToolTip(ki->description());
59 connect(m_lineEdit, &QLineEdit::textEdited, this, &QmakeKitAspectWidget::mkspecWasChanged);
60 }
61
~QmakeKitAspectWidget()62 ~QmakeKitAspectWidget() override { delete m_lineEdit; }
63
64 private:
addToLayout(LayoutBuilder & builder)65 void addToLayout(LayoutBuilder &builder) override
66 {
67 addMutableAction(m_lineEdit);
68 builder.addItem(m_lineEdit);
69 }
70
makeReadOnly()71 void makeReadOnly() override { m_lineEdit->setEnabled(false); }
72
refresh()73 void refresh() override
74 {
75 if (!m_ignoreChange)
76 m_lineEdit->setText(QDir::toNativeSeparators(QmakeKitAspect::mkspec(m_kit)));
77 }
78
mkspecWasChanged(const QString & text)79 void mkspecWasChanged(const QString &text)
80 {
81 m_ignoreChange = true;
82 QmakeKitAspect::setMkspec(m_kit, text, QmakeKitAspect::MkspecSource::User);
83 m_ignoreChange = false;
84 }
85
86 QLineEdit *m_lineEdit = nullptr;
87 bool m_ignoreChange = false;
88 };
89
90
QmakeKitAspect()91 QmakeKitAspect::QmakeKitAspect()
92 {
93 setObjectName(QLatin1String("QmakeKitAspect"));
94 setId(QmakeKitAspect::id());
95 setDisplayName(tr("Qt mkspec"));
96 setDescription(tr("The mkspec to use when building the project with qmake.<br>"
97 "This setting is ignored when using other build systems."));
98 setPriority(24000);
99 }
100
validate(const Kit * k) const101 Tasks QmakeKitAspect::validate(const Kit *k) const
102 {
103 Tasks result;
104 QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k);
105
106 const QString mkspec = QmakeKitAspect::mkspec(k);
107 if (!version && !mkspec.isEmpty())
108 result << BuildSystemTask(Task::Warning, tr("No Qt version set, so mkspec is ignored."));
109 if (version && !version->hasMkspec(mkspec))
110 result << BuildSystemTask(Task::Error, tr("Mkspec not found for Qt version."));
111
112 return result;
113 }
114
createConfigWidget(Kit * k) const115 KitAspectWidget *QmakeKitAspect::createConfigWidget(Kit *k) const
116 {
117 return new Internal::QmakeKitAspectWidget(k, this);
118 }
119
toUserOutput(const Kit * k) const120 KitAspect::ItemList QmakeKitAspect::toUserOutput(const Kit *k) const
121 {
122 return {qMakePair(tr("mkspec"), QDir::toNativeSeparators(mkspec(k)))};
123 }
124
addToMacroExpander(Kit * kit,MacroExpander * expander) const125 void QmakeKitAspect::addToMacroExpander(Kit *kit, MacroExpander *expander) const
126 {
127 expander->registerVariable("Qmake:mkspec", tr("Mkspec configured for qmake by the kit."),
128 [kit]() -> QString {
129 return QDir::toNativeSeparators(mkspec(kit));
130 });
131 }
132
id()133 Utils::Id QmakeKitAspect::id()
134 {
135 return Constants::KIT_INFORMATION_ID;
136 }
137
mkspec(const Kit * k)138 QString QmakeKitAspect::mkspec(const Kit *k)
139 {
140 if (!k)
141 return {};
142 return k->value(QmakeKitAspect::id()).toString();
143 }
144
effectiveMkspec(const Kit * k)145 QString QmakeKitAspect::effectiveMkspec(const Kit *k)
146 {
147 if (!k)
148 return {};
149 const QString spec = mkspec(k);
150 if (spec.isEmpty())
151 return defaultMkspec(k);
152 return spec;
153 }
154
setMkspec(Kit * k,const QString & mkspec,MkspecSource source)155 void QmakeKitAspect::setMkspec(Kit *k, const QString &mkspec, MkspecSource source)
156 {
157 QTC_ASSERT(k, return);
158 k->setValue(QmakeKitAspect::id(), source == MkspecSource::Code && mkspec == defaultMkspec(k)
159 ? QString() : mkspec);
160 }
161
defaultMkspec(const Kit * k)162 QString QmakeKitAspect::defaultMkspec(const Kit *k)
163 {
164 QtSupport::BaseQtVersion *version = QtSupport::QtKitAspect::qtVersion(k);
165 if (!version) // No version, so no qmake
166 return {};
167
168 return version->mkspecFor(ToolChainKitAspect::cxxToolChain(k));
169 }
170
171 } // namespace Internal
172 } // namespace QmakeProjectManager
173