aboutsummaryrefslogtreecommitdiffstats
path: root/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp
diff options
context:
space:
mode:
authorOliver Eftevaag <oliver.eftevaag@qt.io>2021-09-28 14:58:53 +0200
committerQt Cherry-pick Bot <cherrypick_bot@qt-project.org>2021-11-03 13:04:13 +0000
commitbedcd11944e90d828ea3036e52944d1d5c67bda5 (patch)
tree2bd8ce3ac1d0ff1a623c05c66db227c07185b7bf /src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp
parente8ec692c776b0d524598b498a9758dec816cface (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.cpp217
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