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
fontpanel.cpp
Go to the documentation of this file.
1// Copyright (C) 2016 The Qt Company Ltd.
2// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR LGPL-3.0-only OR GPL-2.0-only OR GPL-3.0-only
3// Qt-Security score:significant reason:default
4
5#include "fontpanel_p.h"
6
7#include <QtWidgets/qcombobox.h>
8#include <QtWidgets/qfontcombobox.h>
9#include <QtWidgets/qformlayout.h>
10#include <QtWidgets/qlabel.h>
11#include <QtWidgets/qlayoutitem.h>
12#include <QtWidgets/qlineedit.h>
13
14#include <QtCore/qtimer.h>
15
17
18using namespace Qt::StringLiterals;
19
20FontPanel::FontPanel(QWidget *parentWidget) :
21 QGroupBox(parentWidget),
22 m_previewLineEdit(new QLineEdit),
23 m_writingSystemComboBox(new QComboBox),
24 m_familyComboBox(new QFontComboBox),
25 m_styleComboBox(new QComboBox),
26 m_pointSizeComboBox(new QComboBox)
27{
28 setTitle(tr("Font"));
29
30 auto *formLayout = new QFormLayout(this);
31 // writing systems
32 m_writingSystemComboBox->setEditable(false);
33
34 auto writingSystems = QFontDatabase::writingSystems();
35 writingSystems.push_front(QFontDatabase::Any);
36 for (QFontDatabase::WritingSystem ws : std::as_const(writingSystems))
37 m_writingSystemComboBox->addItem(QFontDatabase::writingSystemName(ws), QVariant(ws));
38 connect(m_writingSystemComboBox, &QComboBox::currentIndexChanged,
39 this, &FontPanel::slotWritingSystemChanged);
40 formLayout->addRow(tr("&Writing system"), m_writingSystemComboBox);
41
42 connect(m_familyComboBox, &QFontComboBox::currentFontChanged,
43 this, &FontPanel::slotFamilyChanged);
44 formLayout->addRow(tr("&Family"), m_familyComboBox);
45
46 m_styleComboBox->setEditable(false);
47 connect(m_styleComboBox, &QComboBox::currentIndexChanged,
48 this, &FontPanel::slotStyleChanged);
49 formLayout->addRow(tr("&Style"), m_styleComboBox);
50
51 m_pointSizeComboBox->setEditable(false);
52 connect(m_pointSizeComboBox, &QComboBox::currentIndexChanged,
53 this, &FontPanel::slotPointSizeChanged);
54 formLayout->addRow(tr("&Point size"), m_pointSizeComboBox);
55
56 m_previewLineEdit->setReadOnly(true);
57 formLayout->addRow(m_previewLineEdit);
58
59 setWritingSystem(QFontDatabase::Any);
60}
61
63{
64 QFont rc = m_familyComboBox->currentFont();
65 const QString family = rc.family();
66 rc.setPointSize(pointSize());
67 const QString styleDescription = styleString();
68 if (styleDescription.contains("Italic"_L1))
69 rc.setStyle(QFont::StyleItalic);
70 else if (styleDescription.contains("Oblique"_L1))
71 rc.setStyle(QFont::StyleOblique);
72 else
73 rc.setStyle(QFont::StyleNormal);
74 rc.setBold(QFontDatabase::bold(family, styleDescription));
75 rc.setWeight(QFont::Weight(QFontDatabase::weight(family, styleDescription)));
76 return rc;
77}
78
79void FontPanel::setSelectedFont(const QFont &f)
80{
81 m_familyComboBox->setCurrentFont(f);
82 if (m_familyComboBox->currentIndex() < 0) {
83 // family not in writing system - find the corresponding one?
84 QList<QFontDatabase::WritingSystem> familyWritingSystems = QFontDatabase::writingSystems(f.family());
85 if (familyWritingSystems.isEmpty())
86 return;
87
88 setWritingSystem(familyWritingSystems.constFirst());
89 m_familyComboBox->setCurrentFont(f);
90 }
91
92 updateFamily(family());
93
94 const int pointSizeIndex = closestPointSizeIndex(f.pointSize());
95 m_pointSizeComboBox->setCurrentIndex( pointSizeIndex);
96
97 const QString styleString = QFontDatabase::styleString(f);
98 const int styleIndex = m_styleComboBox->findText(styleString);
99 m_styleComboBox->setCurrentIndex(styleIndex);
100 slotUpdatePreviewFont();
101}
102
103
105{
106 const int currentIndex = m_writingSystemComboBox->currentIndex();
107 if ( currentIndex == -1)
108 return QFontDatabase::Latin;
109 return static_cast<QFontDatabase::WritingSystem>(m_writingSystemComboBox->itemData(currentIndex).toInt());
110}
111
112QString FontPanel::family() const
113{
114 const int currentIndex = m_familyComboBox->currentIndex();
115 return currentIndex != -1 ? m_familyComboBox->currentFont().family() : QString();
116}
117
118int FontPanel::pointSize() const
119{
120 const int currentIndex = m_pointSizeComboBox->currentIndex();
121 return currentIndex != -1 ? m_pointSizeComboBox->itemData(currentIndex).toInt() : 9;
122}
123
124QString FontPanel::styleString() const
125{
126 const int currentIndex = m_styleComboBox->currentIndex();
127 return currentIndex != -1 ? m_styleComboBox->itemText(currentIndex) : QString();
128}
129
130void FontPanel::setWritingSystem(QFontDatabase::WritingSystem ws)
131{
132 m_writingSystemComboBox->setCurrentIndex(m_writingSystemComboBox->findData(QVariant(ws)));
133 updateWritingSystem(ws);
134}
135
136
137void FontPanel::slotWritingSystemChanged(int)
138{
139 updateWritingSystem(writingSystem());
140 delayedPreviewFontUpdate();
141}
142
143void FontPanel::slotFamilyChanged(const QFont &)
144{
145 updateFamily(family());
146 delayedPreviewFontUpdate();
147}
148
149void FontPanel::slotStyleChanged(int)
150{
151 updatePointSizes(family(), styleString());
152 delayedPreviewFontUpdate();
153}
154
155void FontPanel::slotPointSizeChanged(int)
156{
157 delayedPreviewFontUpdate();
158}
159
160void FontPanel::updateWritingSystem(QFontDatabase::WritingSystem ws)
161{
162
163 m_previewLineEdit->setText(QFontDatabase::writingSystemSample(ws));
164 m_familyComboBox->setWritingSystem (ws);
165 // Current font not in WS ... set index 0.
166 if (m_familyComboBox->currentIndex() < 0) {
167 m_familyComboBox->setCurrentIndex(0);
168 updateFamily(family());
169 }
170}
171
172void FontPanel::updateFamily(const QString &family)
173{
174 // Update styles and trigger update of point sizes.
175 // Try to maintain selection or select normal
176 const QString &oldStyleString = styleString();
177
178 const QStringList &styles = QFontDatabase::styles(family);
179 const bool hasStyles = !styles.isEmpty();
180
181 m_styleComboBox->setCurrentIndex(-1);
182 m_styleComboBox->clear();
183 m_styleComboBox->setEnabled(hasStyles);
184
185 int normalIndex = -1;
186 const QString normalStyle = "Normal"_L1;
187
188 if (hasStyles) {
189 for (const QString &style : styles) {
190 // try to maintain selection or select 'normal' preferably
191 const int newIndex = m_styleComboBox->count();
192 m_styleComboBox->addItem(style);
193 if (oldStyleString == style) {
194 m_styleComboBox->setCurrentIndex(newIndex);
195 } else {
196 if (oldStyleString == normalStyle)
197 normalIndex = newIndex;
198 }
199 }
200 if (m_styleComboBox->currentIndex() == -1 && normalIndex != -1)
201 m_styleComboBox->setCurrentIndex(normalIndex);
202 }
203 updatePointSizes(family, styleString());
204}
205
206int FontPanel::closestPointSizeIndex(int desiredPointSize) const
207{
208 // try to maintain selection or select closest.
209 int closestIndex = -1;
210 int closestAbsError = 0xFFFF;
211
212 const int pointSizeCount = m_pointSizeComboBox->count();
213 for (int i = 0; i < pointSizeCount; i++) {
214 const int itemPointSize = m_pointSizeComboBox->itemData(i).toInt();
215 const int absError = qAbs(desiredPointSize - itemPointSize);
216 if (absError < closestAbsError) {
217 closestIndex = i;
218 closestAbsError = absError;
219 if (closestAbsError == 0)
220 break;
221 } else { // past optimum
222 if (absError > closestAbsError) {
223 break;
224 }
225 }
226 }
227 return closestIndex;
228}
229
230
231void FontPanel::updatePointSizes(const QString &family, const QString &styleString)
232{
233 const int oldPointSize = pointSize();
234
235 auto pointSizes = QFontDatabase::pointSizes(family, styleString);
236 if (pointSizes.isEmpty())
237 pointSizes = QFontDatabase::standardSizes();
238
239 const bool hasSizes = !pointSizes.isEmpty();
240 m_pointSizeComboBox->clear();
241 m_pointSizeComboBox->setEnabled(hasSizes);
242 m_pointSizeComboBox->setCurrentIndex(-1);
243
244 // try to maintain selection or select closest.
245 if (hasSizes) {
246 QString n;
247 for (int pointSize : std::as_const(pointSizes))
248 m_pointSizeComboBox->addItem(n.setNum(pointSize), QVariant(pointSize));
249 const int closestIndex = closestPointSizeIndex(oldPointSize);
250 if (closestIndex != -1)
251 m_pointSizeComboBox->setCurrentIndex(closestIndex);
252 }
253}
254
255void FontPanel::slotUpdatePreviewFont()
256{
257 m_previewLineEdit->setFont(selectedFont());
258}
259
260void FontPanel::delayedPreviewFontUpdate()
261{
262 if (!m_previewFontUpdateTimer) {
263 m_previewFontUpdateTimer = new QTimer(this);
264 connect(m_previewFontUpdateTimer, &QTimer::timeout,
265 this, &FontPanel::slotUpdatePreviewFont);
266 m_previewFontUpdateTimer->setInterval(0);
267 m_previewFontUpdateTimer->setSingleShot(true);
268 }
269 if (m_previewFontUpdateTimer->isActive())
270 return;
271 m_previewFontUpdateTimer->start();
272}
273
274QT_END_NAMESPACE
QFont selectedFont() const
Definition fontpanel.cpp:62
void setWritingSystem(QFontDatabase::WritingSystem ws)
QFontDatabase::WritingSystem writingSystem() const
void setSelectedFont(const QFont &)
Definition fontpanel.cpp:79
Combined button and popup list for selecting options.