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