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