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
5
6#include <QtDesigner/abstractformeditor.h>
7#include <widgetfactory_p.h>
8#include <qdesigner_utils_p.h>
9
10#include <QtWidgets/qapplication.h>
11#include <QtGui/qfont.h>
12#include <QtWidgets/qstyle.h>
13#include <QtWidgets/qstylefactory.h>
14#include <QtWidgets/qapplication.h>
15
16#include <QtGui/qscreen.h>
17
18#include <QtCore/qshareddata.h>
19#include <QtCore/qtextstream.h>
20
21#include <QtCore/qxmlstream.h>
22
23
24static const char dpiXPropertyC[] = "_q_customDpiX";
25static const char dpiYPropertyC[] = "_q_customDpiY";
26
27QT_BEGIN_NAMESPACE
28
29using namespace Qt::StringLiterals;
30
31namespace qdesigner_internal {
32
33// XML serialization
34static const char *xmlVersionC="1.0";
35static const char *rootElementC="deviceprofile";
36static constexpr auto nameElementC = "name"_L1;
37static constexpr auto fontFamilyElementC = "fontfamily"_L1;
38static constexpr auto fontPointSizeElementC = "fontpointsize"_L1;
39static constexpr auto dPIXElementC = "dpix"_L1;
40static constexpr auto dPIYElementC = "dpiy"_L1;
41static constexpr auto styleElementC = "style"_L1;
42
43/* DeviceProfile:
44 * For preview purposes (preview, widget box, new form dialog), the
45 * QDesignerFormBuilder applies the settings to the form main container
46 * (Point being here that the DPI must be set directly for size calculations
47 * to be correct).
48 * For editing purposes, FormWindow applies the settings to the form container
49 * as not to interfere with the font settings of the form main container.
50 * In addition, the widgetfactory maintains the system settings style
51 * and applies it when creating widgets. */
52
53// ---------------- DeviceProfileData
55public:
56 DeviceProfileData() = default;
57 void fromSystem();
58 void clear();
59
64 int m_dpiX = -1;
65 int m_dpiY = -1;
66};
67
69{
70 m_fontPointSize = -1;
71 m_dpiX = 0;
72 m_dpiY = 0;
73 m_name.clear();
74 m_style.clear();
75}
76
78{
79 const QFont appFont = QApplication::font();
80 m_fontFamily = appFont.family();
81 m_fontPointSize = appFont.pointSize();
82 DeviceProfile::systemResolution(&m_dpiX, &m_dpiY);
83 m_style.clear();
84}
85
86// ---------------- DeviceProfile
91
97
99{
100 m_d.operator=(o.m_d);
101 return *this;
102}
103
104DeviceProfile::~DeviceProfile() = default;
105
107{
108 m_d->clear();
109}
110
112{
113 return m_d->m_name.isEmpty();
114}
115
117{
118 return m_d->m_fontFamily;
119}
120
122{
123 m_d->m_fontFamily = f;
124}
125
127{
128 return m_d->m_fontPointSize;
129}
130
135
137{
138 return m_d->m_style;
139}
140
142{
143 m_d->m_style = s;
144}
145
146int DeviceProfile::dpiX() const
147{
148 return m_d->m_dpiX;
149}
150
152{
153 m_d->m_dpiX = d;
154}
155
156int DeviceProfile::dpiY() const
157{
158 return m_d->m_dpiY;
159}
160
162{
163 m_d->m_dpiY = d;
164}
165
167{
168 m_d->fromSystem();
169}
170
172{
173 return m_d->m_name;
174}
175
177{
178 m_d->m_name = n;
179}
180
182{
183 auto s = qApp->primaryScreen();
186}
187
188class FriendlyWidget : public QWidget {
189 friend class DeviceProfile;
190};
191
193{
194 const FriendlyWidget *fw = static_cast<const FriendlyWidget*>(w);
197}
198
200{
201 const DeviceProfileData &d = *m_d;
202 QString rc;
203 QTextStream(&rc) << "DeviceProfile:name=" << d.m_name << " Font=" << d.m_fontFamily << ' '
204 << d.m_fontPointSize << " Style=" << d.m_style << " DPI=" << d.m_dpiX << ',' << d.m_dpiY;
205 return rc;
206}
207
208// Apply font to widget
209static void applyFont(const QString &family, int size, DeviceProfile::ApplyMode am, QWidget *widget)
210{
211 QFont currentFont = widget->font();
212 if (currentFont.pointSize() == size && currentFont.family() == family)
213 return;
214 switch (am) {
215 case DeviceProfile::ApplyFormParent:
216 // Invisible form parent: Apply all
217 widget->setFont(QFont(family, size));
218 break;
219 case DeviceProfile::ApplyPreview: {
220 // Preview: Apply only subproperties that have not been changed by designer properties
221 bool apply = false;
222 const uint resolve = currentFont.resolveMask();
223 if (!(resolve & QFont::FamilyResolved)) {
224 currentFont.setFamily(family);
225 apply = true;
226 }
227 if (!(resolve & QFont::SizeResolved)) {
228 currentFont.setPointSize(size);
229 apply = true;
230 }
231 if (apply)
232 widget->setFont(currentFont);
233 }
234 break;
235 }
236}
237
239{
240 int sysDPIX, sysDPIY; // Set dynamic variables in case values are different from system DPI
242 if (dpiX != sysDPIX && dpiY != sysDPIY) {
245 }
246}
247
265
266bool comparesEqual(const DeviceProfile &lhs, const DeviceProfile &rhs) noexcept
267{
268 const DeviceProfileData &d = *lhs.m_d;
269 const DeviceProfileData &rhs_d = *rhs.m_d;
270 return d.m_fontPointSize == rhs_d.m_fontPointSize &&
271 d.m_dpiX == rhs_d.m_dpiX && d.m_dpiY == rhs_d.m_dpiY && d.m_fontFamily == rhs_d.m_fontFamily &&
272 d.m_style == rhs_d.m_style && d.m_name == rhs_d.m_name;
273}
274
275static inline void writeElement(QXmlStreamWriter &writer, const QString &element, const QString &cdata)
276{
277 writer.writeStartElement(element);
278 writer.writeCharacters(cdata);
279 writer.writeEndElement();
280}
281
306
307/* Switch stages when encountering a start element (state table) */
311
312static ParseStage nextStage(ParseStage currentStage, QStringView startElement)
313{
314 switch (currentStage) {
315 case ParseBeginning:
316 if (startElement == QLatin1StringView(rootElementC))
317 return ParseWithinRoot;
318 break;
319 case ParseWithinRoot:
320 case ParseName:
321 case ParseFontFamily:
323 case ParseDPIX:
324 case ParseDPIY:
325 case ParseStyle:
326 if (startElement == nameElementC)
327 return ParseName;
328 if (startElement == fontFamilyElementC)
329 return ParseFontFamily;
330 if (startElement == fontPointSizeElementC)
331 return ParseFontPointSize;
332 if (startElement == dPIXElementC)
333 return ParseDPIX;
334 if (startElement == dPIYElementC)
335 return ParseDPIY;
336 if (startElement == styleElementC)
337 return ParseStyle;
338 break;
339 case ParseError:
340 break;
341 }
342 return ParseError;
343}
344
345static bool readIntegerElement(QXmlStreamReader &reader, int *v)
346{
347 const QString e = reader.readElementText();
348 bool ok;
349 *v = e.toInt(&ok);
350 //: Reading a number for an embedded device profile
351 if (!ok)
352 reader.raiseError(QApplication::translate("DeviceProfile", "'%1' is not a number.").arg(e));
353 return ok;
354}
355
357{
359 d.fromSystem();
360
362
365 int iv = 0;
366 do {
367 tt = reader.readNext();
369 ps = nextStage(ps, reader.name());
370 switch (ps) {
371 case ParseBeginning:
372 case ParseWithinRoot:
373 break;
374 case ParseError:
375 reader.raiseError(QApplication::translate("DeviceProfile", "An invalid tag <%1> was encountered.").arg(reader.name().toString()));
377 break;
378 case ParseName:
380 break;
381 case ParseFontFamily:
383 break;
387 } else {
389 }
390 break;
391 case ParseDPIX:
393 d.m_dpiX = iv;
394 } else {
396 }
397 break;
398 case ParseDPIY:
400 d.m_dpiY = iv;
401 } else {
403 }
404 break;
405 case ParseStyle:
407 break;
408 }
409 }
411
412 if (reader.hasError()) {
414 return false;
415 }
416
417 return true;
418}
419}
420
421QT_END_NAMESPACE
friend class QWidget
Definition qpainter.h:421
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