diff options
| author | Oliver Eftevaag <oliver.eftevaag@qt.io> | 2021-09-28 14:58:53 +0200 |
|---|---|---|
| committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2021-11-03 13:04:13 +0000 |
| commit | bedcd11944e90d828ea3036e52944d1d5c67bda5 (patch) | |
| tree | 2bd8ce3ac1d0ff1a623c05c66db227c07185b7bf /src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp | |
| parent | e8ec692c776b0d524598b498a9758dec816cface (diff) | |
QuickFontDialog: make setCurrentFont() update listview indexes
For the non-native implementation of the QQuickFontDialog, when the qml
user assigns a new font to the currentFont property, the list view
indexes should be changed to point the family, style and pointSize of the
new font.
In cases where the family, style or size of the new font exists in
the model for the representing listview, the index for that listview should
be updated to the new value, or 0 if the value isn't found, or -1 if the model
is empty.
Fixes: QTBUG-96934
Change-Id: Ia7bb11d01c4a0807d0df742f34bd8aefb00104f6
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
(cherry picked from commit 3c15f90fc6b4f2b5689eaa8b70fb5ca76237540d)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
Diffstat (limited to 'src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp')
| -rw-r--r-- | src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp | 217 |
1 files changed, 122 insertions, 95 deletions
diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp index 3263b73ba9..74e5f1fb48 100644 --- a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp @@ -40,6 +40,8 @@ #include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> #include <private/qfontdatabase_p.h> +#include <QRegularExpression> + QT_BEGIN_NAMESPACE Q_LOGGING_CATEGORY(lcAttachedProperty, "qt.quick.dialogs.quickfontdialogimpl.attachedOrWarn") @@ -106,7 +108,7 @@ QFont QQuickFontDialogImpl::currentFont() const return d->currentFont; } -void QQuickFontDialogImpl::setCurrentFont(const QFont &font) +void QQuickFontDialogImpl::setCurrentFont(const QFont &font, bool selectInListViews) { Q_D(QQuickFontDialogImpl); @@ -116,16 +118,26 @@ void QQuickFontDialogImpl::setCurrentFont(const QFont &font) d->currentFont = font; emit currentFontChanged(font); + + if (!selectInListViews) + return; + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->selectFontInListViews(font); } -void QQuickFontDialogImpl::updateListViews() +void QQuickFontDialogImpl::init() { Q_D(QQuickFontDialogImpl); QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); if (!attached) return; - attached->updateFamilies(); + if (!attached->familyListView()->model().isValid()) + attached->updateFamilies(); attached->buttonBox()->setVisible(!(options()->options() & QFontDialogOptions::NoButtons)); } @@ -167,7 +179,8 @@ QQuickFontDialogImplAttached::QQuickFontDialogImplAttached(QObject *parent) m_writingSystem(QFontDatabase::Any), m_selectedSize(-1), m_smoothlyScalable(false), - m_isUpdatingStyles(false) + m_ignoreFamilyUpdate(false), + m_ignoreStyleUpdate(false) { if (!qobject_cast<QQuickFontDialogImpl *>(parent)) { qmlWarning(this) << "FontDialogImpl attached properties should only be " @@ -488,18 +501,80 @@ void QQuickFontDialogImplAttached::setSizeEdit(QQuickTextField *sizeEdit) emit sizeEditChanged(); } +static int findFamilyInModel(const QString &selectedFamily, const QStringList &model) +{ + enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; + QString foundryName1, familyName1, foundryName2, familyName2; + int bestFamilyMatch = -1; + match_t bestFamilyType = MATCH_NONE; + const QFont f; + + QFontDatabasePrivate::parseFontName(selectedFamily, foundryName1, familyName1); + + int i = 0; + for (auto it = model.constBegin(); it != model.constEnd(); ++it, ++i) { + QFontDatabasePrivate::parseFontName(*it, foundryName2, familyName2); + + if (familyName1 == familyName2) { + bestFamilyType = MATCH_FAMILY; + if (foundryName1 == foundryName2) + return i; + else + bestFamilyMatch = i; + } + + // fallbacks + match_t type = MATCH_NONE; + if (bestFamilyType <= MATCH_NONE && familyName2 == QStringLiteral("helvetica")) + type = MATCH_LAST_RESORT; + if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.families().constFirst()) + type = MATCH_APP; + if (type != MATCH_NONE) { + bestFamilyType = type; + bestFamilyMatch = i; + } + } + + return bestFamilyMatch; +} + +static int findStyleInModel(const QString &selectedStyle, const QStringList &model) +{ + if (model.isEmpty()) + return -1; + + if (!selectedStyle.isEmpty()) { + const int idx = model.indexOf(QRegularExpression(QRegularExpression::escape(selectedStyle), QRegularExpression::CaseInsensitiveOption)); + if (idx >= 0) + return idx; + + enum class StyleClass {Unknown, Normal, Italic}; + auto classifyStyleFallback = [](const QString & style) { + if (style.toLower() == QLatin1String("italic") || style.toLower() == QLatin1String("oblique")) + return StyleClass::Italic; + if (style.toLower() == QLatin1String("normal") || style.toLower() == QLatin1String("regular")) + return StyleClass::Normal; + return StyleClass::Unknown; + }; + + auto styleClass = classifyStyleFallback(selectedStyle); + + if (styleClass != StyleClass::Unknown) + for (int i = 0; i < model.count(); ++i) + if (classifyStyleFallback(model.at(i)) == styleClass) + return i; + } + return 0; +} + /*! \internal Updates the model for the family list view, and attempt to reselect the previously selected font family. - - Calls updateStyles() */ void QQuickFontDialogImplAttached::updateFamilies() { - enum match_t { MATCH_NONE = 0, MATCH_LAST_RESORT = 1, MATCH_APP = 2, MATCH_FAMILY = 3 }; - const QFontDialogOptions::FontDialogOptions scalableMask( QFontDialogOptions::ScalableFonts | QFontDialogOptions::NonScalableFonts); @@ -534,49 +609,15 @@ void QQuickFontDialogImplAttached::updateFamilies() auto listView = familyListView(); // Index will be set to -1 on empty model, and 0 for non empty models. - // Will overwrite selectedFamily and selectedStyle + m_ignoreFamilyUpdate = !m_selectedFamily.isEmpty(); listView->setModel(familyNames); + m_ignoreFamilyUpdate = false; - QString foundryName1, familyName1, foundryName2, familyName2; - int bestFamilyMatch = -1; - match_t bestFamilyType = MATCH_NONE; - const QFont f; - - QFontDatabasePrivate::parseFontName(m_selectedFamily, foundryName1, familyName1); - - int i = 0; - for (auto it = familyNames.constBegin(); it != familyNames.constEnd(); ++it, ++i) { - QFontDatabasePrivate::parseFontName(*it, foundryName2, familyName2); - - if (familyName1 == familyName2) { - bestFamilyType = MATCH_FAMILY; - if (foundryName1 == foundryName2) { - bestFamilyMatch = i; - break; - } - if (bestFamilyMatch < MATCH_FAMILY) { - bestFamilyMatch = i; - } - } - - match_t type = MATCH_NONE; - if (bestFamilyType <= MATCH_NONE && familyName2 == QStringLiteral("helvetica")) - type = MATCH_LAST_RESORT; - if (bestFamilyType <= MATCH_LAST_RESORT && familyName2 == f.families().constFirst()) - type = MATCH_APP; - if (type != MATCH_NONE) { - bestFamilyType = type; - bestFamilyMatch = i; - } - } - - if (!familyNames.isEmpty() && bestFamilyType != MATCH_NONE) { - listView->setCurrentIndex(bestFamilyMatch); - } else { - listView->setCurrentIndex(-1); - } + // Will overwrite selectedFamily and selectedStyle + listView->setCurrentIndex(findFamilyInModel(m_selectedFamily, familyNames)); - updateStyles(); + if (familyNames.isEmpty()) + _q_familyChanged(); } /*! @@ -594,48 +635,14 @@ void QQuickFontDialogImplAttached::updateStyles() auto listView = styleListView(); - m_isUpdatingStyles = true; - + m_ignoreStyleUpdate = !m_selectedStyle.isEmpty(); listView->setModel(styles); if (styles.isEmpty()) { styleEdit()->clear(); m_smoothlyScalable = false; } else { - int newIndex = 0; - - if (!m_selectedStyle.isEmpty()) { - bool redo = true, found = false; - QString cstyle = m_selectedStyle; - do { - for (int i = 0; i < styles.count(); ++i) { - if (cstyle.toLower() == styles.at(i).toLower()) { - newIndex = i; - found = true; - break; - } - } - - if (!found && redo) { - redo = false; - - if (cstyle.contains(QLatin1String("Italic"))) { - cstyle.replace(QLatin1String("Italic"), QLatin1String("Oblique")); - continue; - } else if (cstyle.contains(QLatin1String("Oblique"))) { - cstyle.replace(QLatin1String("Oblique"), QLatin1String("Italic")); - continue; - } else if (cstyle.contains(QLatin1String("Regular"))) { - cstyle.replace(QLatin1String("Regular"), QLatin1String("Normal")); - continue; - } else if (cstyle.contains(QLatin1String("Normal"))) { - cstyle.replace(QLatin1String("Normal"), QLatin1String("Regular")); - continue; - } - } - - } while (!found && redo); - } + int newIndex = findStyleInModel(m_selectedStyle, styles); listView->setCurrentIndex(newIndex); @@ -645,7 +652,7 @@ void QQuickFontDialogImplAttached::updateStyles() m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle); } - m_isUpdatingStyles = false; + m_ignoreStyleUpdate = false; updateSizes(); } @@ -676,7 +683,9 @@ void QQuickFontDialogImplAttached::updateSizes() auto listView = sizeListView(); + // only select the first element in the model when this function is first called and the new model isn't empty listView->setModel(str_sizes); + if (current != -1) listView->setCurrentIndex(current); @@ -693,6 +702,9 @@ void QQuickFontDialogImplAttached::updateSizes() void QQuickFontDialogImplAttached::_q_updateSample() { + if (m_selectedFamily.isEmpty()) + return; + const int pSize = sizeEdit()->text().toInt(); QFont newFont = QFontDatabase::font(m_selectedFamily, m_selectedStyle, pSize); @@ -700,9 +712,7 @@ void QQuickFontDialogImplAttached::_q_updateSample() newFont.setUnderline(underlineCheckBox()->isChecked()); newFont.setStrikeOut(strikeoutCheckBox()->isChecked()); - if (!m_selectedFamily.isEmpty()) { - sampleEdit()->setFont(newFont); - } + sampleEdit()->setFont(newFont); } void QQuickFontDialogImplAttached::_q_writingSystemChanged(int index) @@ -742,22 +752,24 @@ void QQuickFontDialogImplAttached::clearSearch() void QQuickFontDialogImplAttached::_q_familyChanged() { + if (m_ignoreFamilyUpdate) + return; + const int index = familyListView()->currentIndex(); if (index < 0) { familyEdit()->clear(); - return; + } else { + m_selectedFamily = familyListView()->model().toStringList().at(index); + familyEdit()->setText(m_selectedFamily); } - m_selectedFamily = familyListView()->model().toStringList().at(index); - familyEdit()->setText(m_selectedFamily); - updateStyles(); } void QQuickFontDialogImplAttached::_q_styleChanged() { - if (m_isUpdatingStyles) + if (m_ignoreStyleUpdate) return; const int index = styleListView()->currentIndex(); @@ -769,13 +781,14 @@ void QQuickFontDialogImplAttached::_q_styleChanged() m_selectedStyle = styleListView()->model().toStringList().at(index); styleEdit()->setText(m_selectedStyle); + m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle); updateSizes(); } void QQuickFontDialogImplAttached::_q_sizeEdited() { - const int size = sizeEdit()->text().toInt(); + const int size = qAbs(sizeEdit()->text().toInt()); if (size == m_selectedSize) return; @@ -820,7 +833,6 @@ void QQuickFontDialogImplAttached::_q_sizeChanged() void QQuickFontDialogImplAttachedPrivate::currentFontChanged(const QFont &font) { - auto fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent); if (!fontDialogImpl) { @@ -833,4 +845,19 @@ void QQuickFontDialogImplAttachedPrivate::currentFontChanged(const QFont &font) emit fontDialogImpl->fontSelected(font); } +void QQuickFontDialogImplAttached::selectFontInListViews(const QFont &font) +{ + { + QSignalBlocker blocker(sampleEdit()); + familyListView()->setCurrentIndex(findFamilyInModel(font.families().constFirst(), familyListView()->model().toStringList())); + styleListView()->setCurrentIndex(findStyleInModel(QFontDatabase::styleString(font), styleListView()->model().toStringList())); + sizeEdit()->setText(QString::number(font.pointSize())); + + underlineCheckBox()->setChecked(font.underline()); + strikeoutCheckBox()->setChecked(font.strikeOut()); + } + + _q_updateSample(); +} + QT_END_NAMESPACE |
