Qt 6.x
The Qt SDK
Loading...
Searching...
No Matches
qfontcombobox.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 "qfontcombobox.h"
5
6#include <qstringlistmodel.h>
7#include <qitemdelegate.h>
8#include <qlistview.h>
9#include <qpainter.h>
10#include <qevent.h>
11#include <qapplication.h>
12#include <private/qcombobox_p.h>
13#include <qdebug.h>
14
16
17using namespace Qt::StringLiterals;
18
20{
21 switch (script) {
57 return QFontDatabase::Lao;
83 return QFontDatabase::Nko;
84 default:
85 return QFontDatabase::Any;
86 }
87}
88
90{
91 QStringList uiLanguages = QLocale::system().uiLanguages();
92 QLocale::Script script;
93 if (!uiLanguages.isEmpty())
94 script = QLocale(uiLanguages.at(0)).script();
95 else
96 script = QLocale::system().script();
97
98 return writingSystemFromScript(script);
99}
100
102{
104// qDebug() << font.families().first() << writingSystems;
105
106 // this just confuses the algorithm below. Vietnamese is Latin with lots of special chars
107 writingSystems.removeOne(QFontDatabase::Vietnamese);
108 *hasLatin = writingSystems.removeOne(QFontDatabase::Latin);
109
110 if (writingSystems.isEmpty())
111 return QFontDatabase::Any;
112
114
115 if (writingSystems.contains(system))
116 return system;
117
119 && writingSystems.contains(QFontDatabase::SimplifiedChinese)) {
121 }
122
124 && writingSystems.contains(QFontDatabase::TraditionalChinese)) {
126 }
127
128 system = writingSystems.constLast();
129
130 if (!*hasLatin) {
131 // we need to show something
132 return system;
133 }
134
135 if (writingSystems.size() == 1 && system > QFontDatabase::Cyrillic)
136 return system;
137
138 if (writingSystems.size() <= 2 && system > QFontDatabase::Armenian && system < QFontDatabase::Vietnamese)
139 return system;
140
141 if (writingSystems.size() <= 5 && system >= QFontDatabase::SimplifiedChinese && system <= QFontDatabase::Korean)
142 return system;
143
144 return QFontDatabase::Any;
145}
146
148{
149public:
151
152 QFontComboBox::FontFilters filters;
157
158 void _q_updateModel();
159 void _q_currentChanged(const QString &);
160
161 Q_DECLARE_PUBLIC(QFontComboBox)
162};
163
165{
167public:
169
170 // painting
171 void paint(QPainter *painter,
172 const QStyleOptionViewItem &option,
173 const QModelIndex &index) const override;
174
175 QSize sizeHint(const QStyleOptionViewItem &option,
176 const QModelIndex &index) const override;
177
182};
183
186 truetype(QStringLiteral(":/qt-project.org/styles/commonstyle/images/fonttruetype-16.png")),
187 bitmap(QStringLiteral(":/qt-project.org/styles/commonstyle/images/fontbitmap-16.png")),
188 writingSystem(QFontDatabase::Any),
189 comboPrivate(comboP)
190{
191}
192
194 const QStyleOptionViewItem &option,
195 const QModelIndex &index) const
196{
197 QString text = index.data(Qt::DisplayRole).toString();
198 QFont font(option.font);
199 font.setPointSize(QFontInfo(font).pointSize() * 3 / 2);
200 QFont font2 = font;
202
203 bool hasLatin;
204 QFontDatabase::WritingSystem system = writingSystemForFont(font2, &hasLatin);
205 if (hasLatin)
206 font = font2;
207
209
210 QRect r = option.rect;
211
212 if (option.state & QStyle::State_Selected) {
213 painter->save();
214 painter->setBrush(option.palette.highlight());
216 painter->drawRect(option.rect);
217 painter->setPen(QPen(option.palette.highlightedText(), 0));
218 }
219
220 const QIcon *icon = &bitmap;
222 icon = &truetype;
223 }
224 const QSize actualSize = icon->actualSize(r.size());
225 const QRect iconRect = QStyle::alignedRect(option.direction, option.displayAlignment,
226 actualSize, r);
228 if (option.direction == Qt::RightToLeft)
229 r.setRight(r.right() - actualSize.width() - 4);
230 else
231 r.setLeft(r.left() + actualSize.width() + 4);
232
233 QFont old = painter->font();
235
236 const Qt::Alignment textAlign = QStyle::visualAlignment(option.direction, option.displayAlignment);
237 // If the ascent of the font is larger than the height of the rect,
238 // we will clip the text, so it's better to align the tight bounding rect in this case
239 // This is specifically for fonts where the ascent is very large compared to
240 // the descent, like certain of the Stix family.
242 if (fontMetrics.ascent() > r.height()) {
243 QRectF tbr = fontMetrics.tightBoundingRect(text);
245 textRect.setHeight(textRect.height() + (r.height() - tbr.height()));
247 } else {
249 }
250
252 system = writingSystem;
253
255 if (system != QFontDatabase::Any || !sampleText.isEmpty()) {
256 int w = painter->fontMetrics().horizontalAdvance(text + " "_L1);
257 painter->setFont(font2);
258 const QString sample = !sampleText.isEmpty() ? sampleText : QFontDatabase::writingSystemSample(system);
259 if (option.direction == Qt::RightToLeft)
260 r.setRight(r.right() - w);
261 else
262 r.setLeft(r.left() + w);
264 }
265 painter->setFont(old);
266
267 if (option.state & QStyle::State_Selected)
268 painter->restore();
269
270}
271
272QSize QFontFamilyDelegate::sizeHint(const QStyleOptionViewItem &option,
273 const QModelIndex &index) const
274{
275 QString text = index.data(Qt::DisplayRole).toString();
276 QFont font(option.font);
277// font.setFamilies(QStringList{text});
278 font.setPointSize(QFontInfo(font).pointSize() * 3/2);
280 return QSize(fontMetrics.horizontalAdvance(text), fontMetrics.height());
281}
282
283
285{
286 Q_Q(QFontComboBox);
287
289 return;
290
293
294 QStringListModel *m = qobject_cast<QStringListModel *>(q->model());
295 if (!m)
296 return;
297 QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(q->view()->itemDelegate());
298 QFontDatabase::WritingSystem system = delegate ? delegate->writingSystem : QFontDatabase::Any;
299
302
303 int offset = 0;
305
306 for (int i = 0; i < list.size(); ++i) {
308 continue;
309
310 if ((filters & scalableMask) && (filters & scalableMask) != scalableMask) {
312 continue;
313 }
314 if ((filters & spacingMask) && (filters & spacingMask) != spacingMask) {
316 continue;
317 }
318 result += list.at(i);
319 if (list.at(i) == fi.family() || list.at(i).startsWith(fi.family() + " ["_L1))
320 offset = result.size() - 1;
321 }
322 list = result;
323
324 //we need to block the signals so that the model doesn't emit reset
325 //this prevents the current index from changing
326 //it will be updated just after this
328 {
329 const QSignalBlocker blocker(m);
330 m->setStringList(list);
331 }
332
333 if (list.isEmpty()) {
334 if (currentFont != QFont()) {
335 currentFont = QFont();
336 emit q->currentFontChanged(currentFont);
337 }
338 } else {
339 q->setCurrentIndex(offset);
340 }
341}
342
343
345{
346 Q_Q(QFontComboBox);
347 QStringList families = currentFont.families();
348 if (families.isEmpty() || families.first() != text) {
350 emit q->currentFontChanged(currentFont);
351 }
352}
353
392{
393 Q_D(QFontComboBox);
394 d->currentFont = font();
395 setEditable(true);
396
398 setModel(m);
400 QListView *lview = qobject_cast<QListView*>(view());
401 if (lview)
402 lview->setUniformItemSizes(true);
404
406 this, SLOT(_q_currentChanged(QString)));
407
408 connect(qApp, SIGNAL(fontDatabaseChanged()),
409 this, SLOT(_q_updateModel()));
410}
411
412
417{
418}
419
431{
432 Q_D(QFontComboBox);
433 QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(view()->itemDelegate());
434 if (delegate)
435 delegate->writingSystem = script;
436 d->_q_updateModel();
437}
438
440{
441 QFontFamilyDelegate *delegate = qobject_cast<QFontFamilyDelegate *>(view()->itemDelegate());
442 if (delegate)
443 return delegate->writingSystem;
444 return QFontDatabase::Any;
445}
446
447
469{
470 Q_D(QFontComboBox);
471 d->filters = filters;
472 d->_q_updateModel();
473}
474
475QFontComboBox::FontFilters QFontComboBox::fontFilters() const
476{
477 Q_D(const QFontComboBox);
478 return d->filters;
479}
480
488{
489 Q_D(const QFontComboBox);
490 return d->currentFont;
491}
492
494{
495 Q_D(QFontComboBox);
496 if (font != d->currentFont) {
497 d->currentFont = font;
498 d->_q_updateModel();
499 if (d->currentFont == font) { //else the signal has already be emitted by _q_updateModel
500 emit currentFontChanged(d->currentFont);
501 }
502 }
503}
504
518{
519 if (e->type() == QEvent::Resize) {
520 QListView *lview = qobject_cast<QListView*>(view());
521 if (lview) {
522 lview->window()->setFixedWidth(qMin(width() * 5 / 3,
524 }
525 }
526 return QComboBox::event(e);
527}
528
533{
535 QFontMetrics fm(font());
536 sz.setWidth(fm.horizontalAdvance(u'm') * 14);
537 return sz;
538}
539
548{
549 Q_D(QFontComboBox);
550 d->sampleTextForWritingSystem[writingSystem] = sampleText;
551}
552
553
560{
561 Q_D(const QFontComboBox);
562 return d->sampleTextForWritingSystem.value(writingSystem);
563}
564
572void QFontComboBox::setSampleTextForFont(const QString &fontFamily, const QString &sampleText)
573{
574 Q_D(QFontComboBox);
575 d->sampleTextForFontFamily[fontFamily] = sampleText;
576}
577
584{
585 Q_D(const QFontComboBox);
586 return d->sampleTextForFontFamily.value(fontFamily);
587}
588
594void QFontComboBox::setDisplayFont(const QString &fontFamily, const QFont &font)
595{
596 Q_D(QFontComboBox);
597 d->displayFontForFontFamily[fontFamily] = font;
598}
599
605std::optional<QFont> QFontComboBox::displayFont(const QString &fontFamily) const
606{
607 Q_D(const QFontComboBox);
608 return d->displayFontForFontFamily.value(fontFamily, {});
609}
610
612
613#include "qfontcombobox.moc"
614#include "moc_qfontcombobox.cpp"
The QAbstractItemDelegate class is used to display and edit data items from a model.
The QComboBox widget is a combined button and popup list.
Definition qcombobox.h:24
QAbstractItemView * view() const
Returns the list view used for the combobox popup.
void setItemDelegate(QAbstractItemDelegate *delegate)
Sets the item delegate for the popup list view.
bool event(QEvent *event) override
\reimp
void currentTextChanged(const QString &)
QAbstractItemDelegate * itemDelegate() const
Returns the item delegate used by the popup list view.
virtual void setModel(QAbstractItemModel *model)
Sets the model to be model.
QSize sizeHint() const override
\reimp
void setEditable(bool editable)
static bool closingDown()
Returns true if the application objects are being destroyed; otherwise returns false.
\inmodule QtCore
Definition qcoreevent.h:45
QHash< QString, QFont > displayFontForFontFamily
QFontComboBox::FontFilters filters
void _q_currentChanged(const QString &)
QHash< QString, QString > sampleTextForFontFamily
QHash< QFontDatabase::WritingSystem, QString > sampleTextForWritingSystem
The QFontComboBox widget is a combobox that lets the user select a font family.
void setDisplayFont(const QString &fontFamily, const QFont &font)
Sets the font to be used to display a given fontFamily (when the combo is open).
QFontComboBox(QWidget *parent=nullptr)
Constructs a font combobox with the given parent.
QFont currentFont
the currently selected font
bool event(QEvent *e) override
\reimp
QSize sizeHint() const override
\reimp
~QFontComboBox()
Destroys the combobox.
QString sampleTextForSystem(QFontDatabase::WritingSystem writingSystem) const
Returns the sample text to show after the font name (when the combo is open) for a given writingSyste...
QString sampleTextForFont(const QString &fontFamily) const
Returns the sample text to show after the font name (when the combo is open) for a given fontFamily.
std::optional< QFont > displayFont(const QString &fontFamily) const
Returns the font (if set) to be used to display a given fontFamily (when the combo is open).
void setFontFilters(FontFilters filters)
void currentFontChanged(const QFont &f)
This signal is emitted whenever the current font changes, with the new font.
void setSampleTextForSystem(QFontDatabase::WritingSystem writingSystem, const QString &sampleText)
Sets the sampleText to show after the font name (when the combo is open) for a given writingSystem.
void setWritingSystem(QFontDatabase::WritingSystem)
QFontDatabase::WritingSystem writingSystem
the writing system that serves as a filter for the combobox
FontFilters fontFilters
the filter for the combobox
void setCurrentFont(const QFont &f)
void setSampleTextForFont(const QString &fontFamily, const QString &sampleText)
Sets the sampleText to show after the font name (when the combo is open) for a given fontFamily.
\threadsafe \inmodule QtGui
WritingSystem
\value Any \value Latin \value Greek \value Cyrillic \value Armenian \value Hebrew \value Arabic \val...
static bool isSmoothlyScalable(const QString &family, const QString &style=QString())
Returns true if the font that has family family and style style is smoothly scalable; otherwise retur...
static bool isPrivateFamily(const QString &family)
static QString writingSystemSample(WritingSystem writingSystem)
Returns a string with sample characters from writingSystem.
static QStringList families(WritingSystem writingSystem=Any)
Returns a sorted list of the available font families which support the writingSystem.
static QList< WritingSystem > writingSystems()
Returns a sorted list of the available writing systems.
static bool isFixedPitch(const QString &family, const QString &style=QString())
Returns true if the font that has family family and style style is fixed pitch; otherwise returns fal...
void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override
This pure abstract function must be reimplemented if you want to provide custom rendering.
QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override
This pure abstract function must be reimplemented if you want to provide custom rendering.
QFontComboBoxPrivate * comboPrivate
QFontFamilyDelegate(QObject *parent, QFontComboBoxPrivate *comboP)
QFontDatabase::WritingSystem writingSystem
\reentrant
Definition qfontinfo.h:14
\reentrant \inmodule QtGui
\reentrant \inmodule QtGui
int horizontalAdvance(const QString &, int len=-1) const
Returns the horizontal advance in pixels of the first len characters of text.
\reentrant
Definition qfont.h:20
void setPointSize(int)
Sets the point size to pointSize.
Definition qfont.cpp:970
void setFamilies(const QStringList &)
Definition qfont.cpp:2491
QStringList families() const
Definition qfont.cpp:2469
\inmodule QtCore
Definition qhash.h:818
T value(const Key &key) const noexcept
Definition qhash.h:1044
The QIcon class provides scalable icons in different modes and states.
Definition qicon.h:20
void paint(QPainter *painter, const QRect &rect, Qt::Alignment alignment=Qt::AlignCenter, Mode mode=Normal, State state=Off) const
Uses the painter to paint the icon with specified alignment, required mode, and state into the rectan...
Definition qicon.cpp:931
QSize actualSize(const QSize &size, Mode mode=Normal, State state=Off) const
Returns the actual size of the icon for the requested size, mode, and state.
Definition qicon.cpp:880
The QListView class provides a list or icon view onto a model.
Definition qlistview.h:17
void setUniformItemSizes(bool enable)
Definition qlist.h:74
qsizetype size() const noexcept
Definition qlist.h:386
bool isEmpty() const noexcept
Definition qlist.h:390
const T & constLast() const noexcept
Definition qlist.h:633
bool removeOne(const AT &t)
Definition qlist.h:581
const_reference at(qsizetype i) const noexcept
Definition qlist.h:429
QStringList uiLanguages() const
List of locale names for use in selecting translations.
Definition qlocale.cpp:4580
@ JapaneseScript
Definition qlocale.h:457
@ OghamScript
Definition qlocale.h:496
@ OriyaScript
Definition qlocale.h:549
@ TibetanScript
Definition qlocale.h:538
@ GurmukhiScript
Definition qlocale.h:445
@ ThaiScript
Definition qlocale.h:537
@ SimplifiedHanScript
Definition qlocale.h:522
@ LaoScript
Definition qlocale.h:469
@ GujaratiScript
Definition qlocale.h:444
@ KoreanScript
Definition qlocale.h:467
@ NkoScript
Definition qlocale.h:494
@ GreekScript
Definition qlocale.h:443
@ KhmerScript
Definition qlocale.h:464
@ MalayalamScript
Definition qlocale.h:478
@ RunicScript
Definition qlocale.h:515
@ ThaanaScript
Definition qlocale.h:536
@ CyrillicScript
Definition qlocale.h:431
@ TamilScript
Definition qlocale.h:533
@ TeluguScript
Definition qlocale.h:535
@ ArmenianScript
Definition qlocale.h:409
@ SinhalaScript
Definition qlocale.h:523
@ HebrewScript
Definition qlocale.h:451
@ TraditionalHanScript
Definition qlocale.h:541
@ DevanagariScript
Definition qlocale.h:433
@ BengaliScript
Definition qlocale.h:547
@ SyriacScript
Definition qlocale.h:527
@ MyanmarScript
Definition qlocale.h:490
@ KannadaScript
Definition qlocale.h:460
@ GeorgianScript
Definition qlocale.h:439
@ LatinScript
Definition qlocale.h:470
@ ArabicScript
Definition qlocale.h:408
Script script() const
Definition qlocale.cpp:1291
static QLocale system()
Returns a QLocale object initialized to the system locale.
Definition qlocale.cpp:2742
\inmodule QtCore
\inmodule QtCore
Definition qobject.h:90
QObject * parent() const
Returns a pointer to the parent object.
Definition qobject.h:311
static QMetaObject::Connection connect(const QObject *sender, const char *signal, const QObject *receiver, const char *member, Qt::ConnectionType=Qt::AutoConnection)
\threadsafe
Definition qobject.cpp:2823
The QPainter class performs low-level painting on widgets and other paint devices.
Definition qpainter.h:46
void drawRect(const QRectF &rect)
Draws the current rectangle with the current pen and brush.
Definition qpainter.h:519
void setPen(const QColor &color)
This is an overloaded member function, provided for convenience. It differs from the above function o...
const QFont & font() const
Returns the currently set font used for drawing text.
void restore()
Restores the current painter state (pops a saved state off the stack).
QFontMetrics fontMetrics() const
Returns the font metrics for the painter if the painter is active.
void save()
Saves the current painter state (pushes the state onto a stack).
void setFont(const QFont &f)
Sets the painter's font to the given font.
void drawText(const QPointF &p, const QString &s)
Draws the given text with the currently defined text direction, beginning at the given position.
void setBrush(const QBrush &brush)
Sets the painter's brush to the given brush.
\inmodule QtGui
Definition qpen.h:25
\inmodule QtCore\reentrant
Definition qrect.h:483
constexpr qreal height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:718
\inmodule QtCore\reentrant
Definition qrect.h:30
constexpr int height() const noexcept
Returns the height of the rectangle.
Definition qrect.h:238
constexpr void setHeight(int h) noexcept
Sets the height of the rectangle to the given height.
Definition qrect.h:383
Exception-safe wrapper around QObject::blockSignals().
Definition qobject.h:443
\inmodule QtCore
Definition qsize.h:25
constexpr int width() const noexcept
Returns the width.
Definition qsize.h:129
constexpr void setWidth(int w) noexcept
Sets the width to the given width.
Definition qsize.h:135
\inmodule QtCore
\inmodule QtCore
\macro QT_RESTRICTED_CAST_FROM_ASCII
Definition qstring.h:127
bool isEmpty() const
Returns true if the string has no characters; otherwise returns false.
Definition qstring.h:1083
QChar * data()
Returns a pointer to the data stored in the QString.
Definition qstring.h:1095
@ State_Selected
Definition qstyle.h:82
static Qt::Alignment visualAlignment(Qt::LayoutDirection direction, Qt::Alignment alignment)
Transforms an alignment of Qt::AlignLeft or Qt::AlignRight without Qt::AlignAbsolute into Qt::AlignLe...
Definition qstyle.cpp:2203
static QRect alignedRect(Qt::LayoutDirection direction, Qt::Alignment alignment, const QSize &size, const QRect &rectangle)
Returns a new rectangle of the specified size that is aligned to the given rectangle according to the...
Definition qstyle.cpp:2174
static QRect availableScreenGeometry(const QWidget *widget)
Definition qwidget_p.h:468
The QWidget class is the base class of all user interface objects.
Definition qwidget.h:99
int width
the width of the widget excluding any window frame
Definition qwidget.h:114
QFont font
the font currently set for the widget
Definition qwidget.h:133
QPainter paint
QString text
double e
fontMetrics
QRect textRect
Combined button and popup list for selecting options.
@ AlignBottom
Definition qnamespace.h:153
@ AlignVCenter
Definition qnamespace.h:154
@ AlignLeft
Definition qnamespace.h:143
@ RightToLeft
@ TextSingleLine
Definition qnamespace.h:169
@ NoPen
@ DisplayRole
#define qApp
static QFontDatabase::WritingSystem writingSystemFromLocale()
static QFontDatabase::WritingSystem writingSystemFromScript(QLocale::Script script)
static QFontDatabase::WritingSystem writingSystemForFont(const QFont &font, bool *hasLatin)
constexpr const T & qMin(const T &a, const T &b)
Definition qminmax.h:40
#define SLOT(a)
Definition qobjectdefs.h:51
#define SIGNAL(a)
Definition qobjectdefs.h:52
const GLfloat * m
GLfloat GLfloat GLfloat w
[0]
GLuint index
[2]
GLboolean r
[2]
GLenum GLuint GLintptr offset
GLsizei GLfixed GLfixed GLfixed GLfixed const GLubyte * bitmap
GLdouble GLdouble GLdouble GLdouble q
Definition qopenglext.h:259
GLuint64EXT * result
[6]
GLuint GLenum option
#define QStringLiteral(str)
#define Q_OBJECT
#define emit
QList< int > list
[14]
QFileInfo fi("c:/temp/foo")
[newstuff]
const QStringList filters({"Image files (*.png *.xpm *.jpg)", "Text files (*.txt)", "Any files (*)" })
[6]
QPainter painter(this)
[7]
bool contains(const AT &t) const noexcept
Definition qlist.h:44
IUIAutomationTreeWalker __RPC__deref_out_opt IUIAutomationElement ** parent