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
qquickfontdialogimpl.cpp
Go to the documentation of this file.
1// Copyright (C) 2021 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
7
8#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h>
9#include <private/qfontdatabase_p.h>
10
11#include <QRegularExpression>
12
14
15Q_STATIC_LOGGING_CATEGORY(lcAttachedProperty, "qt.quick.dialogs.quickfontdialogimpl.attachedOrWarn")
16
17QQuickFontDialogImplPrivate::QQuickFontDialogImplPrivate()
18{
19}
20
21QQuickFontDialogImplAttached *QQuickFontDialogImplPrivate::attachedOrWarn()
22{
23 Q_Q(QQuickFontDialogImpl);
24 QQuickFontDialogImplAttached *attached = static_cast<QQuickFontDialogImplAttached *>(
25 qmlAttachedPropertiesObject<QQuickFontDialogImpl>(q));
26 if (!attached) {
27 qCWarning(lcAttachedProperty)
28 << "Expected FontDialogImpl attached object to be present on" << this;
29 }
30 return attached;
31}
32
34
35void QQuickFontDialogImplPrivate::handleClick(QQuickAbstractButton *button)
36{
37 Q_Q(QQuickFontDialogImpl);
38 if (buttonRole(button) == QPlatformDialogHelper::AcceptRole) {
39 q->accept();
40 QQuickDialogPrivate::handleClick(button);
41 }
42}
43
44QQuickFontDialogImpl::QQuickFontDialogImpl(QObject *parent)
45 : QQuickDialog(*(new QQuickFontDialogImplPrivate), parent)
46{
47}
48
49QQuickFontDialogImplAttached *QQuickFontDialogImpl::qmlAttachedProperties(QObject *object)
50{
51 return new QQuickFontDialogImplAttached(object);
52}
53
54QSharedPointer<QFontDialogOptions> QQuickFontDialogImpl::options() const
55{
56 Q_D(const QQuickFontDialogImpl);
57
58 return d->options;
59}
60
61void QQuickFontDialogImpl::setOptions(const QSharedPointer<QFontDialogOptions> &options)
62{
63 Q_D(QQuickFontDialogImpl);
64
65 if (options == d->options)
66 return;
67
68 d->options = options;
69
70 emit optionsChanged();
71}
72
73QFont QQuickFontDialogImpl::currentFont() const
74{
75 Q_D(const QQuickFontDialogImpl);
76 return d->currentFont;
77}
78
79void QQuickFontDialogImpl::setCurrentFont(const QFont &font, bool selectInListViews)
80{
81 Q_D(QQuickFontDialogImpl);
82
83 if (font == d->currentFont)
84 return;
85
86 d->currentFont = font;
87
88 emit currentFontChanged(font);
89
90 if (!selectInListViews)
91 return;
92
93 QQuickFontDialogImplAttached *attached = d->attachedOrWarn();
94 if (!attached)
95 return;
96
97 if (!attached->familyListView()->model().isValid()) {
98 const QSignalBlocker blocker(attached->sampleEdit());
99 attached->updateFamilies();
100 }
101
102 attached->selectFontInListViews(font);
103}
104
105void QQuickFontDialogImpl::init()
106{
107 Q_D(QQuickFontDialogImpl);
108 QQuickFontDialogImplAttached *attached = d->attachedOrWarn();
109 if (!attached)
110 return;
111
112 if (!attached->familyListView()->model().isValid())
113 attached->updateFamilies();
114
115 attached->buttonBox()->setVisible(!(options()->options() & QFontDialogOptions::NoButtons));
116}
117
118void QQuickFontDialogImpl::keyReleaseEvent(QKeyEvent *event)
119{
120 Q_D(QQuickFontDialogImpl);
121
122 QQuickDialog::keyReleaseEvent(event);
123
124 QQuickFontDialogImplAttached *attached = d->attachedOrWarn();
125 if (!attached)
126 return;
127
128 // The family and style text edits are read-only so that they
129 // can show the current selection but also allow key input to "search".
130 // This is why we handle just the release event, and don't accept it.
131 if (attached->familyEdit()->hasFocus())
132 attached->searchFamily(event->text());
133 else if (attached->styleEdit()->hasFocus())
134 attached->searchStyle(event->text());
135}
136
137void QQuickFontDialogImpl::focusOutEvent(QFocusEvent *event)
138{
139 Q_D(QQuickFontDialogImpl);
140
141 QQuickDialog::focusOutEvent(event);
142
143 QQuickFontDialogImplAttached *attached = d->attachedOrWarn();
144 if (!attached)
145 return;
146
147 attached->clearSearch();
148}
149
150void QQuickFontDialogImpl::itemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &data)
151{
152 Q_D(QQuickFontDialogImpl);
153 QQuickDialog::itemChange(change, data);
154
155 if (change != QQuickItem::ItemVisibleHasChanged || !isComponentComplete() || !data.boolValue)
156 return;
157
158 if (QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); attached && attached->buttonBox())
159 attached->buttonBox()->forceActiveFocus(Qt::OtherFocusReason);
160}
161
162QQuickFontDialogImplAttached::QQuickFontDialogImplAttached(QObject *parent)
163 : QObject(*(new QQuickFontDialogImplAttachedPrivate), parent),
164 m_writingSystem(QFontDatabase::Any),
165 m_selectedSize(-1),
166 m_smoothlyScalable(false),
167 m_ignoreFamilyUpdate(false),
168 m_ignoreStyleUpdate(false)
169{
170 if (!qobject_cast<QQuickFontDialogImpl *>(parent)) {
171 qmlWarning(this) << "FontDialogImpl attached properties should only be "
172 << "accessed through the root FileDialogImpl instance";
173 }
174}
175
176QQuickListView *QQuickFontDialogImplAttached::familyListView() const
177{
178 Q_D(const QQuickFontDialogImplAttached);
179 return d->familyListView;
180}
181
182void QQuickFontDialogImplAttached::setFamilyListView(QQuickListView *familyListView)
183{
184 Q_D(QQuickFontDialogImplAttached);
185 if (d->familyListView == familyListView)
186 return;
187
188 if (d->familyListView) {
189 disconnect(d->familyListView, &QQuickListView::currentIndexChanged,
190 this, &QQuickFontDialogImplAttached::_q_familyChanged);
191 }
192
193 d->familyListView = familyListView;
194
195 if (familyListView) {
196 connect(d->familyListView, &QQuickListView::currentIndexChanged,
197 this, &QQuickFontDialogImplAttached::_q_familyChanged);
198 }
199
200 emit familyListViewChanged();
201}
202
203QQuickListView *QQuickFontDialogImplAttached::styleListView() const
204{
205 Q_D(const QQuickFontDialogImplAttached);
206 return d->styleListView;
207}
208
209void QQuickFontDialogImplAttached::setStyleListView(QQuickListView *styleListView)
210{
211 Q_D(QQuickFontDialogImplAttached);
212 if (d->styleListView == styleListView)
213 return;
214
215 if (d->styleListView) {
216 disconnect(d->styleListView, &QQuickListView::currentIndexChanged,
217 this, &QQuickFontDialogImplAttached::_q_styleChanged);
218 }
219
220 d->styleListView = styleListView;
221
222 if (styleListView) {
223 connect(d->styleListView, &QQuickListView::currentIndexChanged,
224 this, &QQuickFontDialogImplAttached::_q_styleChanged);
225 }
226
227 emit styleListViewChanged();
228}
229
230QQuickListView *QQuickFontDialogImplAttached::sizeListView() const
231{
232 Q_D(const QQuickFontDialogImplAttached);
233 return d->sizeListView;
234}
235
236void QQuickFontDialogImplAttached::setSizeListView(QQuickListView *sizeListView)
237{
238 Q_D(QQuickFontDialogImplAttached);
239 if (d->sizeListView == sizeListView)
240 return;
241
242 if (d->sizeListView) {
243 disconnect(d->sizeListView, &QQuickListView::currentIndexChanged,
244 this, &QQuickFontDialogImplAttached::_q_sizeChanged);
245 }
246
247 d->sizeListView = sizeListView;
248
249 if (d->sizeListView) {
250 connect(d->sizeListView, &QQuickListView::currentIndexChanged,
251 this, &QQuickFontDialogImplAttached::_q_sizeChanged);
252 }
253
254 emit sizeListViewChanged();
255}
256
257QQuickTextEdit *QQuickFontDialogImplAttached::sampleEdit() const
258{
259 Q_D(const QQuickFontDialogImplAttached);
260 return d->sampleEdit;
261}
262
263void QQuickFontDialogImplAttached::setSampleEdit(QQuickTextEdit *sampleEdit)
264{
265 Q_D(QQuickFontDialogImplAttached);
266
267 if (d->sampleEdit == sampleEdit)
268 return;
269
270 if (d->sampleEdit) {
271 QObjectPrivate::disconnect(d->sampleEdit, &QQuickTextEdit::fontChanged,
272 d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged);
273 }
274
275 d->sampleEdit = sampleEdit;
276
277 if (d->sampleEdit) {
278 QObjectPrivate::connect(d->sampleEdit, &QQuickTextEdit::fontChanged,
279 d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged);
280
281 d->sampleEdit->setText(QFontDatabase::writingSystemSample(m_writingSystem));
282 }
283
284 emit sampleEditChanged();
285}
286
287QQuickDialogButtonBox *QQuickFontDialogImplAttached::buttonBox() const
288{
289 Q_D(const QQuickFontDialogImplAttached);
290 return d->buttonBox;
291}
292
293void QQuickFontDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox)
294{
295 Q_D(QQuickFontDialogImplAttached);
296 if (buttonBox == d->buttonBox)
297 return;
298
299 if (d->buttonBox) {
300 QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent());
301 if (fontDialogImpl) {
302 auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl);
303 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted,
304 dialogPrivate, &QQuickDialogPrivate::handleAccept);
305 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected,
306 dialogPrivate, &QQuickDialogPrivate::handleReject);
307 QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate,
308 &QQuickDialogPrivate::handleClick);
309 }
310 }
311
312 d->buttonBox = buttonBox;
313
314 if (buttonBox) {
315 QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent());
316 if (fontDialogImpl) {
317 auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl);
318 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted, dialogPrivate,
319 &QQuickDialogPrivate::handleAccept);
320 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected, dialogPrivate,
321 &QQuickDialogPrivate::handleReject);
322 QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate,
323 &QQuickDialogPrivate::handleClick);
324 }
325 }
326
327 emit buttonBoxChanged();
328}
329
330QQuickComboBox *QQuickFontDialogImplAttached::writingSystemComboBox() const
331{
332 Q_D(const QQuickFontDialogImplAttached);
333 return d->writingSystemComboBox;
334}
335
336void QQuickFontDialogImplAttached::setWritingSystemComboBox(QQuickComboBox *writingSystemComboBox)
337{
338 Q_D(QQuickFontDialogImplAttached);
339
340 if (d->writingSystemComboBox == writingSystemComboBox)
341 return;
342
343 if (d->writingSystemComboBox) {
344 disconnect(d->writingSystemComboBox, &QQuickComboBox::activated,
345 this, &QQuickFontDialogImplAttached::_q_writingSystemChanged);
346 }
347
348 d->writingSystemComboBox = writingSystemComboBox;
349
350 if (d->writingSystemComboBox) {
351 QStringList writingSystemModel;
352 for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) {
353 QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i);
354 QString wsName = QFontDatabase::writingSystemName(ws);
355 if (wsName.isEmpty())
356 break;
357 writingSystemModel.append(wsName);
358 }
359
360 d->writingSystemComboBox->setModel(writingSystemModel);
361
362 connect(d->writingSystemComboBox, &QQuickComboBox::activated,
363 this, &QQuickFontDialogImplAttached::_q_writingSystemChanged);
364 }
365
366 emit writingSystemComboBoxChanged();
367}
368
369QQuickCheckBox *QQuickFontDialogImplAttached::underlineCheckBox() const
370{
371 Q_D(const QQuickFontDialogImplAttached);
372 return d->underlineCheckBox;
373}
374
375void QQuickFontDialogImplAttached::setUnderlineCheckBox(QQuickCheckBox *underlineCheckBox)
376{
377 Q_D(QQuickFontDialogImplAttached);
378
379 if (d->underlineCheckBox == underlineCheckBox)
380 return;
381
382 if (d->underlineCheckBox) {
383 disconnect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged,
384 this, &QQuickFontDialogImplAttached::_q_updateSample);
385 }
386
387 d->underlineCheckBox = underlineCheckBox;
388
389 if (d->underlineCheckBox) {
390 connect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged,
391 this, &QQuickFontDialogImplAttached::_q_updateSample);
392 }
393
394 emit underlineCheckBoxChanged();
395}
396
397QQuickCheckBox *QQuickFontDialogImplAttached::strikeoutCheckBox() const
398{
399 Q_D(const QQuickFontDialogImplAttached);
400 return d->strikeoutCheckBox;
401}
402
403void QQuickFontDialogImplAttached::setStrikeoutCheckBox(QQuickCheckBox *strikeoutCheckBox)
404{
405 Q_D(QQuickFontDialogImplAttached);
406
407 if (d->strikeoutCheckBox == strikeoutCheckBox)
408 return;
409
410 if (d->strikeoutCheckBox) {
411 disconnect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged,
412 this, &QQuickFontDialogImplAttached::_q_updateSample);
413 }
414
415 d->strikeoutCheckBox = strikeoutCheckBox;
416
417 if (d->strikeoutCheckBox) {
418 connect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged,
419 this, &QQuickFontDialogImplAttached::_q_updateSample);
420 }
421
422 emit strikeoutCheckBoxChanged();
423}
424
425QQuickTextField *QQuickFontDialogImplAttached::familyEdit() const
426{
427 Q_D(const QQuickFontDialogImplAttached);
428 return d->familyEdit;
429}
430
431void QQuickFontDialogImplAttached::setFamilyEdit(QQuickTextField *familyEdit)
432{
433 Q_D(QQuickFontDialogImplAttached);
434
435 if (d->familyEdit == familyEdit)
436 return;
437
438 d->familyEdit = familyEdit;
439
440 emit familyEditChanged();
441}
442
443QQuickTextField *QQuickFontDialogImplAttached::styleEdit() const
444{
445 Q_D(const QQuickFontDialogImplAttached);
446 return d->styleEdit;
447}
448
449void QQuickFontDialogImplAttached::setStyleEdit(QQuickTextField *styleEdit)
450{
451 Q_D(QQuickFontDialogImplAttached);
452
453 if (d->styleEdit == styleEdit)
454 return;
455
456 d->styleEdit = styleEdit;
457
458 emit styleEditChanged();
459}
460
461QQuickTextField *QQuickFontDialogImplAttached::sizeEdit() const
462{
463 Q_D(const QQuickFontDialogImplAttached);
464 return d->sizeEdit;
465}
466
467void QQuickFontDialogImplAttached::setSizeEdit(QQuickTextField *sizeEdit)
468{
469 Q_D(QQuickFontDialogImplAttached);
470
471 if (d->sizeEdit == sizeEdit)
472 return;
473
474 if (d->sizeEdit) {
475 disconnect(d->sizeEdit, &QQuickTextField::textChanged,
476 this, &QQuickFontDialogImplAttached::_q_sizeEdited);
477 }
478
479 d->sizeEdit = sizeEdit;
480
481 if (d->sizeEdit) {
482 connect(d->sizeEdit, &QQuickTextField::textChanged,
483 this, &QQuickFontDialogImplAttached::_q_sizeEdited);
484 }
485
486 emit sizeEditChanged();
487}
488
489static int findFamilyInModel(const QString &selectedFamily, const QStringList &model)
490{
491 enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 };
492 QString foundryName1, familyName1, foundryName2, familyName2;
493 int bestFamilyMatch = -1;
494 match_t bestFamilyType = MATCH_NONE;
495 const QFont f;
496
497 QFontDatabasePrivate::parseFontName(selectedFamily, foundryName1, familyName1);
498
499 int i = 0;
500 for (auto it = model.constBegin(); it != model.constEnd(); ++it, ++i) {
501 QFontDatabasePrivate::parseFontName(*it, foundryName2, familyName2);
502
503 if (familyName1 == familyName2) {
504 bestFamilyType = MATCH_FAMILY;
505 if (foundryName1 == foundryName2)
506 return i;
507 else
508 bestFamilyMatch = i;
509 }
510
511 // fallbacks
512 match_t type = MATCH_NONE;
513 if (bestFamilyType <= MATCH_NONE && familyName2 == QStringLiteral("helvetica"))
514 type = MATCH_LAST_RESORT;
515 if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.families().constFirst())
516 type = MATCH_APP;
517 if (type != MATCH_NONE) {
518 bestFamilyType = type;
519 bestFamilyMatch = i;
520 }
521 }
522
523 return bestFamilyMatch;
524}
525
526static int findStyleInModel(const QString &selectedStyle, const QStringList &model)
527{
528 if (model.isEmpty())
529 return -1;
530
531 if (!selectedStyle.isEmpty()) {
532 const int idx = model.indexOf(QRegularExpression(QRegularExpression::escape(selectedStyle), QRegularExpression::CaseInsensitiveOption));
533 if (idx >= 0)
534 return idx;
535
536 enum class StyleClass {Unknown, Normal, Italic};
537 auto classifyStyleFallback = [](const QString & style) {
538 if (style.toLower() == QLatin1String("italic") || style.toLower() == QLatin1String("oblique"))
539 return StyleClass::Italic;
540 if (style.toLower() == QLatin1String("normal") || style.toLower() == QLatin1String("regular"))
541 return StyleClass::Normal;
542 return StyleClass::Unknown;
543 };
544
545 auto styleClass = classifyStyleFallback(selectedStyle);
546
547 if (styleClass != StyleClass::Unknown)
548 for (int i = 0; i < model.size(); ++i)
549 if (classifyStyleFallback(model.at(i)) == styleClass)
550 return i;
551 }
552 return 0;
553}
554
555/*!
556 \internal
557
558 Updates the model for the family list view, and attempt
559 to reselect the previously selected font family.
560 */
561void QQuickFontDialogImplAttached::updateFamilies()
562{
563 const QFontDialogOptions::FontDialogOptions scalableMask(
564 QFontDialogOptions::ScalableFonts | QFontDialogOptions::NonScalableFonts);
565
566 const QFontDialogOptions::FontDialogOptions spacingMask(QFontDialogOptions::ProportionalFonts
567 | QFontDialogOptions::MonospacedFonts);
568
569 const auto p = qobject_cast<QQuickFontDialogImpl *>(parent());
570
571 const auto options = p->options()->options();
572
573 QStringList familyNames;
574 const auto families = QFontDatabase::families(m_writingSystem);
575 for (const auto &family : families) {
576 if (QFontDatabase::isPrivateFamily(family))
577 continue;
578
579 if ((options & scalableMask) && (options & scalableMask) != scalableMask) {
580 if (bool(options & QFontDialogOptions::ScalableFonts)
581 != QFontDatabase::isSmoothlyScalable(family))
582 continue;
583 }
584
585 if ((options & spacingMask) && (options & scalableMask) != spacingMask) {
586 if (bool(options & QFontDialogOptions::MonospacedFonts)
587 != QFontDatabase::isFixedPitch(family))
588 continue;
589 }
590
591 familyNames << family;
592 }
593
594 auto listView = familyListView();
595
596 // Index will be set to -1 on empty model, and 0 for non empty models.
597 m_ignoreFamilyUpdate = !m_selectedFamily.isEmpty();
598 listView->setModel(familyNames);
599 m_ignoreFamilyUpdate = false;
600
601 // Will overwrite selectedFamily and selectedStyle
602 listView->setCurrentIndex(findFamilyInModel(m_selectedFamily, familyNames));
603
604 if (familyNames.isEmpty())
605 _q_familyChanged();
606}
607
608/*!
609 \internal
610
611 Updates the model for the style list view, and
612 attempt to reselect the style that was previously selected.
613
614 Calls updateSizes()
615 */
616void QQuickFontDialogImplAttached::updateStyles()
617{
618 const QString family = familyListView()->currentIndex() >= 0 ? m_selectedFamily : QString();
619 const QStringList styles = QFontDatabase::styles(family);
620
621 auto listView = styleListView();
622
623 m_ignoreStyleUpdate = !m_selectedStyle.isEmpty();
624 listView->setModel(styles);
625
626 if (styles.isEmpty()) {
627 styleEdit()->clear();
628 m_smoothlyScalable = false;
629 } else {
630 int newIndex = findStyleInModel(m_selectedStyle, styles);
631
632 listView->setCurrentIndex(newIndex);
633
634 m_selectedStyle = styles.at(newIndex);
635 styleEdit()->setText(m_selectedStyle);
636
637 m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle);
638 }
639
640 m_ignoreStyleUpdate = false;
641
642 updateSizes();
643}
644
645/*!
646 \internal
647
648 Updates the model for the size list view,
649 and attempts to reselect the size that was previously selected
650 */
651void QQuickFontDialogImplAttached::updateSizes()
652{
653 if (!m_selectedFamily.isEmpty()) {
654 const QList<int> sizes = QFontDatabase::pointSizes(m_selectedFamily, m_selectedStyle);
655
656 QStringList str_sizes;
657
658 str_sizes.reserve(sizes.size());
659
660 int idx = 0, current = -1;
661 for (QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); it++) {
662 str_sizes.append(QString::number(*it));
663 if (current == -1 && m_selectedSize == *it) {
664 current = idx;
665 }
666 ++idx;
667 }
668
669 auto listView = sizeListView();
670
671 // only select the first element in the model when this function is first called and the new model isn't empty
672 listView->setModel(str_sizes);
673
674 if (current != -1)
675 listView->setCurrentIndex(current);
676
677 sizeEdit()->setText(!m_smoothlyScalable && listView->currentIndex() > 0
678 ? str_sizes.at(listView->currentIndex())
679 : QString::number(m_selectedSize));
680 } else {
681 qCWarning(lcAttachedProperty) << "Warning! selectedFamily is empty";
682 sizeEdit()->clear();
683 }
684
685 _q_updateSample();
686}
687
688void QQuickFontDialogImplAttached::_q_updateSample()
689{
690 if (m_selectedFamily.isEmpty())
691 return;
692
693 const int pSize = sizeEdit()->text().toInt();
694
695 QFont newFont = QFontDatabase::font(m_selectedFamily, m_selectedStyle, pSize);
696
697 newFont.setUnderline(underlineCheckBox()->isChecked());
698 newFont.setStrikeOut(strikeoutCheckBox()->isChecked());
699
700 sampleEdit()->setFont(newFont);
701}
702
703void QQuickFontDialogImplAttached::_q_writingSystemChanged(int index)
704{
705 m_writingSystem = QFontDatabase::WritingSystem(index);
706 sampleEdit()->setText(QFontDatabase::writingSystemSample(m_writingSystem));
707
708 updateFamilies();
709}
710
711void QQuickFontDialogImplAttached::searchListView(const QString &s, QQuickListView *listView)
712{
713 if (s.isEmpty())
714 return;
715
716 const QStringList model = listView->model().toStringList();
717
718 bool redo = false;
719
720 do {
721 m_search.append(s);
722
723 for (int i = 0; i < model.size(); ++i) {
724 if (model.at(i).startsWith(m_search, Qt::CaseInsensitive)) {
725 listView->setCurrentIndex(i);
726 return;
727 }
728 }
729
730 clearSearch();
731
732 redo = !redo;
733 } while (redo);
734}
735
736void QQuickFontDialogImplAttached::clearSearch()
737{
738 m_search.clear();
739}
740
741void QQuickFontDialogImplAttached::_q_familyChanged()
742{
743 if (m_ignoreFamilyUpdate)
744 return;
745
746 const int index = familyListView()->currentIndex();
747
748 if (index < 0) {
749 familyEdit()->clear();
750 } else {
751 m_selectedFamily = familyListView()->model().toStringList().at(index);
752 familyEdit()->setText(m_selectedFamily);
753 }
754
755 updateStyles();
756}
757
758void QQuickFontDialogImplAttached::_q_styleChanged()
759{
760 if (m_ignoreStyleUpdate)
761 return;
762
763 const int index = styleListView()->currentIndex();
764
765 if (index < 0) {
766 qCWarning(lcAttachedProperty) << "currentIndex changed to -1";
767 return;
768 }
769
770 m_selectedStyle = styleListView()->model().toStringList().at(index);
771 styleEdit()->setText(m_selectedStyle);
772 m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle);
773
774 updateSizes();
775}
776
777void QQuickFontDialogImplAttached::_q_sizeEdited()
778{
779 const int size = qAbs(sizeEdit()->text().toInt());
780
781 if (size == m_selectedSize)
782 return;
783
784 m_selectedSize = size;
785
786 if (sizeListView()->count()) {
787 auto model = sizeListView()->model().toStringList();
788
789 int i;
790 for (i = 0; i < model.size() - 1; ++i) {
791 if (model.at(i).toInt() >= size)
792 break;
793 }
794
795 QSignalBlocker blocker(sizeListView());
796 if (model.at(i).toInt() == size)
797 sizeListView()->setCurrentIndex(i);
798 else
799 sizeListView()->setCurrentIndex(-1);
800 }
801
802 _q_updateSample();
803}
804
805void QQuickFontDialogImplAttached::_q_sizeChanged()
806{
807 const int index = sizeListView()->currentIndex();
808
809 if (index < 0) {
810 qCWarning(lcAttachedProperty) << "currentIndex changed to -1";
811 return;
812 }
813
814 const QString s = sizeListView()->model().toStringList().at(index);
815 m_selectedSize = s.toInt();
816
817 sizeEdit()->setText(s);
818
819 _q_updateSample();
820}
821
822void QQuickFontDialogImplAttachedPrivate::currentFontChanged(const QFont &font)
823{
824 auto fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent);
825
826 if (!fontDialogImpl) {
827 return;
828 }
829
830 fontDialogImpl->setCurrentFont(font);
831}
832
833void QQuickFontDialogImplAttached::selectFontInListViews(const QFont &font)
834{
835 {
836 QSignalBlocker blocker(sampleEdit());
837 familyListView()->setCurrentIndex(findFamilyInModel(font.families().constFirst(), familyListView()->model().toStringList()));
838 styleListView()->setCurrentIndex(findStyleInModel(QFontDatabase::styleString(font), styleListView()->model().toStringList()));
839 sizeEdit()->setText(QString::number(font.pointSize()));
840
841 underlineCheckBox()->setChecked(font.underline());
842 strikeoutCheckBox()->setChecked(font.strikeOut());
843 }
844
845 _q_updateSample();
846}
847
848QT_END_NAMESPACE
849
850#include "moc_qquickfontdialogimpl_p.cpp"
void handleClick(QQuickAbstractButton *button) override
QQuickFontDialogImplAttached * attachedOrWarn()
Combined button and popup list for selecting options.
static int findFamilyInModel(const QString &selectedFamily, const QStringList &model)
static int findStyleInModel(const QString &selectedStyle, const QStringList &model)