Qt
Internal/Contributor docs for the Qt SDK. Note: These are NOT official API docs; those are found at https://doc.qt.io/
Loading...
Searching...
No Matches
deviceprofile.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
3// Qt-Security score:significant reason:default
4
6
7#include <QtDesigner/abstractformeditor.h>
8#include <widgetfactory_p.h>
9#include <qdesigner_utils_p.h>
10
11#include <QtWidgets/qapplication.h>
12#include <QtGui/qfont.h>
13#include <QtWidgets/qstyle.h>
14#include <QtWidgets/qstylefactory.h>
15#include <QtWidgets/qapplication.h>
16
17#include <QtGui/qscreen.h>
18
19#include <QtCore/qshareddata.h>
20#include <QtCore/qtextstream.h>
21
22#include <QtCore/qxmlstream.h>
23
24
25static const char dpiXPropertyC[] = "_q_customDpiX";
26static const char dpiYPropertyC[] = "_q_customDpiY";
27
28QT_BEGIN_NAMESPACE
29
30using namespace Qt::StringLiterals;
31
32namespace qdesigner_internal {
33
34// XML serialization
35static const char *xmlVersionC="1.0";
36static const char *rootElementC="deviceprofile";
37static constexpr auto nameElementC = "name"_L1;
38static constexpr auto fontFamilyElementC = "fontfamily"_L1;
39static constexpr auto fontPointSizeElementC = "fontpointsize"_L1;
40static constexpr auto dPIXElementC = "dpix"_L1;
41static constexpr auto dPIYElementC = "dpiy"_L1;
42static constexpr auto styleElementC = "style"_L1;
43
44/* DeviceProfile:
45 * For preview purposes (preview, widget box, new form dialog), the
46 * QDesignerFormBuilder applies the settings to the form main container
47 * (Point being here that the DPI must be set directly for size calculations
48 * to be correct).
49 * For editing purposes, FormWindow applies the settings to the form container
50 * as not to interfere with the font settings of the form main container.
51 * In addition, the widgetfactory maintains the system settings style
52 * and applies it when creating widgets. */
53
54// ---------------- DeviceProfileData
56public:
57 DeviceProfileData() = default;
58 void fromSystem();
59 void clear();
60
65 int m_dpiX = -1;
66 int m_dpiY = -1;
67};
68
70{
71 m_fontPointSize = -1;
72 m_dpiX = 0;
73 m_dpiY = 0;
74 m_name.clear();
75 m_style.clear();
76}
77
79{
80 const QFont appFont = QApplication::font();
81 m_fontFamily = appFont.family();
82 m_fontPointSize = appFont.pointSize();
83 DeviceProfile::systemResolution(&m_dpiX, &m_dpiY);
84 m_style.clear();
85}
86
87// ---------------- DeviceProfile
92
98
100{
101 m_d.operator=(o.m_d);
102 return *this;
103}
104
105DeviceProfile::~DeviceProfile() = default;
106
108{
109 m_d->clear();
110}
111
113{
114 return m_d->m_name.isEmpty();
115}
116
118{
119 return m_d->m_fontFamily;
120}
121
123{
124 m_d->m_fontFamily = f;
125}
126
128{
129 return m_d->m_fontPointSize;
130}
131
136
138{
139 return m_d->m_style;
140}
141
143{
144 m_d->m_style = s;
145}
146
147int DeviceProfile::dpiX() const
148{
149 return m_d->m_dpiX;
150}
151
153{
154 m_d->m_dpiX = d;
155}
156
157int DeviceProfile::dpiY() const
158{
159 return m_d->m_dpiY;
160}
161
163{
164 m_d->m_dpiY = d;
165}
166
168{
169 m_d->fromSystem();
170}
171
173{
174 return m_d->m_name;
175}
176
178{
179 m_d->m_name = n;
180}
181
183{
184 auto s = qApp->primaryScreen();
187}
188
189class FriendlyWidget : public QWidget {
190 friend class DeviceProfile;
191};
192
194{
195 const FriendlyWidget *fw = static_cast<const FriendlyWidget*>(w);
198}
199
201{
202 const DeviceProfileData &d = *m_d;
203 QString rc;
204 QTextStream(&rc) << "DeviceProfile:name=" << d.m_name << " Font=" << d.m_fontFamily << ' '
205 << d.m_fontPointSize << " Style=" << d.m_style << " DPI=" << d.m_dpiX << ',' << d.m_dpiY;
206 return rc;
207}
208
209// Apply font to widget
210static void applyFont(const QString &family, int size, DeviceProfile::ApplyMode am, QWidget *widget)
211{
212 QFont currentFont = widget->font();
213 if (currentFont.pointSize() == size && currentFont.family() == family)
214 return;
215 switch (am) {
216 case DeviceProfile::ApplyFormParent:
217 // Invisible form parent: Apply all
218 widget->setFont(QFont(family, size));
219 break;
220 case DeviceProfile::ApplyPreview: {
221 // Preview: Apply only subproperties that have not been changed by designer properties
222 bool apply = false;
223 const uint resolve = currentFont.resolveMask();
224 if (!(resolve & QFont::FamilyResolved)) {
225 currentFont.setFamily(family);
226 apply = true;
227 }
228 if (!(resolve & QFont::SizeResolved)) {
229 currentFont.setPointSize(size);
230 apply = true;
231 }
232 if (apply)
233 widget->setFont(currentFont);
234 }
235 break;
236 }
237}
238
240{
241 int sysDPIX, sysDPIY; // Set dynamic variables in case values are different from system DPI
243 if (dpiX != sysDPIX && dpiY != sysDPIY) {
246 }
247}
248
266
267bool comparesEqual(const DeviceProfile &lhs, const DeviceProfile &rhs) noexcept
268{
269 const DeviceProfileData &d = *lhs.m_d;
270 const DeviceProfileData &rhs_d = *rhs.m_d;
271 return d.m_fontPointSize == rhs_d.m_fontPointSize &&
272 d.m_dpiX == rhs_d.m_dpiX && d.m_dpiY == rhs_d.m_dpiY && d.m_fontFamily == rhs_d.m_fontFamily &&
273 d.m_style == rhs_d.m_style && d.m_name == rhs_d.m_name;
274}
275
276static inline void writeElement(QXmlStreamWriter &writer, const QString &element, const QString &cdata)
277{
278 writer.writeStartElement(element);
279 writer.writeCharacters(cdata);
280 writer.writeEndElement();
281}
282
307
308/* Switch stages when encountering a start element (state table) */
312
313static ParseStage nextStage(ParseStage currentStage, QStringView startElement)
314{
315 switch (currentStage) {
316 case ParseBeginning:
317 if (startElement == QLatin1StringView(rootElementC))
318 return ParseWithinRoot;
319 break;
320 case ParseWithinRoot:
321 case ParseName:
322 case ParseFontFamily:
324 case ParseDPIX:
325 case ParseDPIY:
326 case ParseStyle:
327 if (startElement == nameElementC)
328 return ParseName;
329 if (startElement == fontFamilyElementC)
330 return ParseFontFamily;
331 if (startElement == fontPointSizeElementC)
332 return ParseFontPointSize;
333 if (startElement == dPIXElementC)
334 return ParseDPIX;
335 if (startElement == dPIYElementC)
336 return ParseDPIY;
337 if (startElement == styleElementC)
338 return ParseStyle;
339 break;
340 case ParseError:
341 break;
342 }
343 return ParseError;
344}
345
346static bool readIntegerElement(QXmlStreamReader &reader, int *v)
347{
348 const QString e = reader.readElementText();
349 bool ok;
350 *v = e.toInt(&ok);
351 //: Reading a number for an embedded device profile
352 if (!ok)
353 reader.raiseError(QApplication::translate("DeviceProfile", "'%1' is not a number.").arg(e));
354 return ok;
355}
356
358{
360 d.fromSystem();
361
363
366 int iv = 0;
367 do {
368 tt = reader.readNext();
370 ps = nextStage(ps, reader.name());
371 switch (ps) {
372 case ParseBeginning:
373 case ParseWithinRoot:
374 break;
375 case ParseError:
376 reader.raiseError(QApplication::translate("DeviceProfile", "An invalid tag <%1> was encountered.").arg(reader.name().toString()));
378 break;
379 case ParseName:
381 break;
382 case ParseFontFamily:
384 break;
388 } else {
390 }
391 break;
392 case ParseDPIX:
394 d.m_dpiX = iv;
395 } else {
397 }
398 break;
399 case ParseDPIY:
401 d.m_dpiY = iv;
402 } else {
404 }
405 break;
406 case ParseStyle:
408 break;
409 }
410 }
412
413 if (reader.hasError()) {
415 return false;
416 }
417
418 return true;
419}
420}
421
422QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:432
static const char dpiYPropertyC[]
static const char dpiXPropertyC[]
Auxiliary methods to store/retrieve settings.
static void writeElement(QXmlStreamWriter &writer, const QString &element, const QString &cdata)
static bool readIntegerElement(QXmlStreamReader &reader, int *v)
static const char * rootElementC
static constexpr auto styleElementC
static constexpr auto fontPointSizeElementC
static constexpr auto dPIYElementC
static const char * xmlVersionC
static constexpr auto dPIXElementC
static constexpr auto fontFamilyElementC
static void applyFont(const QString &family, int size, DeviceProfile::ApplyMode am, QWidget *widget)
static ParseStage nextStage(ParseStage currentStage, QStringView startElement)
static constexpr auto nameElementC
bool comparesEqual(const DeviceProfile &lhs, const DeviceProfile &rhs) noexcept