diff options
author | Oliver Eftevaag <oliver.eftevaag@qt.io> | 2021-03-15 16:05:11 +0100 |
---|---|---|
committer | Oliver Eftevaag <oliver.eftevaag@qt.io> | 2021-06-04 18:02:30 +0200 |
commit | c830979fbb176e6e48b3ff45c84fa0742aaa186e (patch) | |
tree | b594ec6b742a2155113f766d6eaac76c2f2f6ec6 /src | |
parent | 4ab599b2058949e18ac3fcdf71f9204f307d93ef (diff) |
Add FontDialog to QtQuick.Dialogs
Adding non-native FontDialog to QtQuick.
This is a native FontDialog on platforms
that support it, and a non-native
Qt Quick FontDialog on platforms that don't.
Fixes: QTBUG-87799
Change-Id: I43a59e3668a8a40f1d0c04a3c2506283d552a22b
Reviewed-by: Mitch Curtis <mitch.curtis@qt.io>
Diffstat (limited to 'src')
17 files changed, 2780 insertions, 1 deletions
diff --git a/src/imports/dialogs/doc/images/qtquickdialogs-fontdialog-gtk.png b/src/imports/dialogs/doc/images/qtquickdialogs-fontdialog-gtk.png Binary files differnew file mode 100644 index 00000000..0c6217bd --- /dev/null +++ b/src/imports/dialogs/doc/images/qtquickdialogs-fontdialog-gtk.png diff --git a/src/quickdialogs2/quickdialogs2/CMakeLists.txt b/src/quickdialogs2/quickdialogs2/CMakeLists.txt index 59f671d7..560460d6 100644 --- a/src/quickdialogs2/quickdialogs2/CMakeLists.txt +++ b/src/quickdialogs2/quickdialogs2/CMakeLists.txt @@ -8,6 +8,8 @@ qt_internal_add_module(QuickDialogs2 qquickabstractdialog_p.h qquickfiledialog.cpp qquickfiledialog_p.h + qquickfontdialog.cpp + qquickfontdialog_p.h qtquickdialogs2foreign_p.h qtquickdialogs2global_p.h DEFINES diff --git a/src/quickdialogs2/quickdialogs2/qquickfontdialog.cpp b/src/quickdialogs2/quickdialogs2/qquickfontdialog.cpp new file mode 100644 index 00000000..d4c68bb3 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickfontdialog.cpp @@ -0,0 +1,227 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOG_CPP +#define QQUICKFONTDIALOG_CPP + +#include "qquickfontdialog_p.h" + +#include <QtCore/qloggingcategory.h> + +QT_BEGIN_NAMESPACE + +/*! + \qmltype FontDialog + \inherits Dialog +//! \instantiates QQuickFontDialog + \inqmlmodule QtQuick.Dialogs + \since 6.2 + \brief A font dialog. + + The FontDialog type provides a QML API for font dialogs. + + \image qtquickdialogs-fontdialog-gtk.png + + To show a font dialog, construct an instance of FontDialog, set the + desired properties, and call \l {Dialog::}{open()}. The \l currentFont + property can be used to determine the currently selected font in the + dialog. The \l selectedFont property is updated only after the final selection + has been made by accepting the dialog. + + \code + MenuItem { + text: "Font" + onTriggered: fontDialog.open() + } + + FontDialog { + id: fontDialog + currentFont.family: document.font + } + + MyDocument { + id: document + font: fontDialog.selectedFont + } + \endcode + + \section2 Availability + + A native platform font dialog is currently available on the following platforms: + + \list + \li macOS + \li Linux (when running with the GTK+ platform theme) + \endlist + + \include includes/fallback.qdocinc +*/ + +Q_LOGGING_CATEGORY(lcFontDialog, "qt.quick.dialogs.fontdialog") + +QQuickFontDialog::QQuickFontDialog(QObject *parent) + : QQuickAbstractDialog(QPlatformTheme::FontDialog, parent), + m_options(QFontDialogOptions::create()) +{ +} + +/*! + \qmlproperty font QtQuick.Dialogs::FontDialog::currentFont + + This property holds the currently selected font in the dialog. + + Unlike the \l selectedFont property, the \c currentFont property is updated + while the user is selecting fonts in the dialog, even before the final + selection has been made. + + \sa selectedFont +*/ + +QFont QQuickFontDialog::currentFont() const +{ + if (QPlatformFontDialogHelper *fontDialog = qobject_cast<QPlatformFontDialogHelper *>(handle())) + return fontDialog->currentFont(); + return QFont(); +} + +void QQuickFontDialog::setCurrentFont(const QFont &font) +{ + if (QPlatformFontDialogHelper *fontDialog = + qobject_cast<QPlatformFontDialogHelper *>(handle())) + fontDialog->setCurrentFont(font); +} + +/*! + \qmlproperty font QtQuick.Dialogs::FontDialog::selectedFont + + This property holds the final accepted font. + + Unlike the \l currentFont property, the \c selectedFont property is not updated + while the user is selecting fonts in the dialog, but only after the final + selection has been made. That is, when the user has clicked \uicontrol Open + to accept a font. Alternatively, the \l {Dialog::}{accepted()} signal + can be handled to get the final selection. + + \sa currentFont, {Dialog::}{accepted()} +*/ + +QFont QQuickFontDialog::selectedFont() const +{ + return m_selectedFont; +} + +void QQuickFontDialog::setSelectedFont(const QFont &font) +{ + if (m_selectedFont == font) + return; + + m_selectedFont = font; + emit selectedFontChanged(); +} + +/*! + \qmlproperty flags QtQuick.Dialogs::FontDialog::options + + This property holds the various options that affect the look and feel of the dialog. + + By default, all options are disabled. + + Options should be set before showing the dialog. Setting them while the dialog is + visible is not guaranteed to have an immediate effect on the dialog (depending on + the option and on the platform). + + Available options: + \value FontDialog.ScalableFonts Show scalable fonts. + \value FontDialog.NonScalableFonts Show non-scalable fonts. + \value FontDialog.MonospacedFonts Show monospaced fonts. + \value FontDialog.ProportionalFonts Show proportional fonts. + \value FontDialog.NoButtons Don't display \uicontrol Open and \uicontrol Cancel buttons (useful + for "live dialogs"). +*/ + +QFontDialogOptions::FontDialogOptions QQuickFontDialog::options() const +{ + return m_options->options(); +} + +void QQuickFontDialog::setOptions(QFontDialogOptions::FontDialogOptions options) +{ + if (options == m_options->options()) + return; + + m_options->setOptions(options); + emit optionsChanged(); +} + +void QQuickFontDialog::resetOptions() +{ + setOptions({}); +} + +bool QQuickFontDialog::useNativeDialog() const +{ + return QQuickAbstractDialog::useNativeDialog() + && !(m_options->testOption(QFontDialogOptions::DontUseNativeDialog)); +} + +void QQuickFontDialog::onCreate(QPlatformDialogHelper *dialog) +{ + if (QPlatformFontDialogHelper *fontDialog = qobject_cast<QPlatformFontDialogHelper *>(dialog)) { + connect(fontDialog, &QPlatformFontDialogHelper::currentFontChanged, this, + &QQuickFontDialog::currentFontChanged); + connect(fontDialog, &QPlatformFontDialogHelper::fontSelected, this, + &QQuickFontDialog::setSelectedFont); + fontDialog->setOptions(m_options); + } +} + +void QQuickFontDialog::onShow(QPlatformDialogHelper *dialog) +{ + m_options->setWindowTitle(title()); + if (QPlatformFontDialogHelper *fontDialog = qobject_cast<QPlatformFontDialogHelper *>(dialog)) + fontDialog->setOptions(m_options); // setOptions only assigns a member and isn't virtual +} + +void QQuickFontDialog::accept() +{ + if (auto fontDialog = qobject_cast<QPlatformFontDialogHelper *>(handle())) + setSelectedFont(fontDialog->currentFont()); + QQuickAbstractDialog::accept(); +} + +QT_END_NAMESPACE + +#endif // QQUICKFONTDIALOG_CPP diff --git a/src/quickdialogs2/quickdialogs2/qquickfontdialog_p.h b/src/quickdialogs2/quickdialogs2/qquickfontdialog_p.h new file mode 100644 index 00000000..50350df6 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2/qquickfontdialog_p.h @@ -0,0 +1,101 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOG_P_H +#define QQUICKFONTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include "qquickabstractdialog_p.h" + +#include <QtGui/qfont.h> + +QT_BEGIN_NAMESPACE + +class Q_QUICKDIALOGS2_PRIVATE_EXPORT QQuickFontDialog : public QQuickAbstractDialog +{ + Q_OBJECT + Q_PROPERTY(QFont selectedFont READ selectedFont WRITE setSelectedFont NOTIFY selectedFontChanged) + Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged FINAL) + Q_PROPERTY(QFontDialogOptions::FontDialogOptions options READ options WRITE setOptions + RESET resetOptions NOTIFY optionsChanged) + Q_FLAGS(QFontDialogOptions::FontDialogOptions) + QML_NAMED_ELEMENT(FontDialog) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFontDialog(QObject *parent = nullptr); + + void setCurrentFont(const QFont &font); + QFont currentFont() const; + + void setSelectedFont(const QFont &font); + QFont selectedFont() const; + + QFontDialogOptions::FontDialogOptions options() const; + void setOptions(QFontDialogOptions::FontDialogOptions options); + void resetOptions(); + +Q_SIGNALS: + void selectedFontChanged(); + void currentFontChanged(); + void optionsChanged(); + +protected: + bool useNativeDialog() const override; + void onCreate(QPlatformDialogHelper *dialog) override; + void onShow(QPlatformDialogHelper *dialog) override; + void accept() override; + +private: + QFont m_selectedFont; + QSharedPointer<QFontDialogOptions> m_options; +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFontDialog) + +#endif // QQUICKFONTDIALOG_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt index f5ad89e8..277be0a3 100644 --- a/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt +++ b/src/quickdialogs2/quickdialogs2quickimpl/CMakeLists.txt @@ -16,8 +16,13 @@ qt_internal_add_module(QuickDialogs2QuickImpl qquickfolderbreadcrumbbar_p_p.h qquickplatformfiledialog.cpp qquickplatformfiledialog_p.h + qquickplatformfontdialog_p.h + qquickplatformfontdialog.cpp qtquickdialogs2quickimplforeign_p.h qtquickdialogs2quickimplglobal_p.h + qquickfontdialogimpl_p.h + qquickfontdialogimpl_p_p.h + qquickfontdialogimpl.cpp DEFINES QT_BUILD_QUICKDIALOGS2QUICKIMPL_LIB QT_NO_CAST_FROM_ASCII @@ -99,18 +104,24 @@ set(qtquickdialogs2quickimpl_resource_files "qml/FileDialogDelegate.qml" "qml/FileDialogDelegateLabel.qml" "qml/FolderBreadcrumbBar.qml" + "qml/FontDialog.qml" + "qml/FontDialogContent.qml" "qml/+Fusion/FileDialog.qml" "qml/+Fusion/FileDialogDelegate.qml" "qml/+Fusion/FolderBreadcrumbBar.qml" + "qml/+Fusion/FontDialog.qml" "qml/+Imagine/FileDialog.qml" "qml/+Imagine/FileDialogDelegate.qml" "qml/+Imagine/FolderBreadcrumbBar.qml" + "qml/+Imagine/FontDialog.qml" "qml/+Material/FileDialog.qml" "qml/+Material/FileDialogDelegate.qml" "qml/+Material/FolderBreadcrumbBar.qml" + "qml/+Material/FontDialog.qml" "qml/+Universal/FileDialog.qml" "qml/+Universal/FileDialogDelegate.qml" "qml/+Universal/FolderBreadcrumbBar.qml" + "qml/+Universal/FontDialog.qml" ) qt_internal_add_resource(QuickDialogs2QuickImpl "QuickDialogs2QuickImpl" diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml new file mode 100644 index 00000000..1a5b1d21 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Fusion/FontDialog.qml @@ -0,0 +1,151 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Fusion +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(control.implicitBackgroundWidth + control.leftInset + control.rightInset, + control.contentWidth + control.leftPadding + control.rightPadding, + control.implicitHeaderWidth, + control.implicitFooterWidth) + implicitHeight: Math.max(control.implicitBackgroundHeight + control.topInset + control.bottomInset, + control.contentHeight + control.topPadding + control.bottomPadding + + (control.implicitHeaderHeight > 0 ? control.implicitHeaderHeight + control.spacing : 0) + + (control.implicitFooterHeight > 0 ? control.implicitFooterHeight + control.spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.mid + radius: 2 + + Rectangle { + z: -1 + x: 1 + y: 1 + width: parent.width + height: parent.height + color: control.palette.shadow + opacity: 0.2 + radius: 2 + } + } + + Overlay.modal: Rectangle { + color: Fusion.topShadow + } + + Overlay.modeless: Rectangle { + color: Fusion.topShadow + } + + header: Label { + text: control.title + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + padding: 6 + } + + contentItem: FontDialogContent { + id: content + } + + footer: RowLayout { + id: rowLayout + spacing: 12 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 12 + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 6 + horizontalPadding: 0 + verticalPadding: 0 + background: null + + Layout.rightMargin: 12 + Layout.topMargin: 6 + Layout.bottomMargin: 6 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml new file mode 100644 index 00000000..2bc76091 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Imagine/FontDialog.qml @@ -0,0 +1,166 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Imagine +import QtQuick.Controls.Imagine.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + // Can't set implicitWidth of the NinePatchImage background, so we do it here. + implicitWidth: Math.max(600, + implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(400, + implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + topPadding: background ? background.topPadding : 0 + leftPadding: background ? background.leftPadding : 0 + rightPadding: background ? background.rightPadding : 0 + bottomPadding: background ? background.bottomPadding : 0 + + topInset: background ? -background.topInset || 0 : 0 + leftInset: background ? -background.leftInset || 0 : 0 + rightInset: background ? -background.rightInset || 0 : 0 + bottomInset: background ? -background.bottomInset || 0 : 0 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: NinePatchImage { + source: Imagine.url + "dialog-background" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + + Overlay.modal: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": true} + ] + } + } + + Overlay.modeless: NinePatchImage { + source: Imagine.url + "dialog-overlay" + NinePatchImageSelector on source { + states: [ + {"modal": false} + ] + } + } + + header: Label { + text: control.title + elide: Label.ElideRight + font.bold: true + + leftPadding: 16 + rightPadding: 16 + topPadding: 12 + height: control.title.length > 0 ? implicitHeight : 0 + + background: NinePatchImage { + width: parent.width + height: parent.height + + source: Imagine.url + "dialog-title" + NinePatchImageSelector on source { + states: [ + {"modal": control.modal}, + {"dim": control.dim} + ] + } + } + } + + contentItem: FontDialogContent { + id: content + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + Label { + text: qsTr("Writing System") + Layout.leftMargin: 20 + Layout.bottomMargin: 16 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.bottomMargin: 16 + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + Layout.rightMargin: 20 + Layout.bottomMargin: 16 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml new file mode 100644 index 00000000..b877d2f6 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Material/FontDialog.qml @@ -0,0 +1,138 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Material +import QtQuick.Controls.Material.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + leftPadding: 24 + rightPadding: 24 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + Material.elevation: 24 + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + radius: 2 + color: control.Material.dialogColor + + layer.enabled: control.Material.elevation > 0 + layer.effect: ElevationEffect { + elevation: control.Material.elevation + } + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } + + header: Label { + text: control.title + visible: control.title.length > 0 + elide: Label.ElideRight + font.bold: true + font.pixelSize: 16 + + leftPadding: 24 + rightPadding: 24 + topPadding: 24 + } + + contentItem: FontDialogContent { + id: content + } + + footer: RowLayout { + id: rowLayout + spacing: 20 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 20 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml new file mode 100644 index 00000000..69c90102 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/+Universal/FontDialog.qml @@ -0,0 +1,143 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Controls.Universal +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(implicitBackgroundWidth + leftInset + rightInset, + contentWidth + leftPadding + rightPadding, + implicitHeaderWidth, + implicitFooterWidth) + implicitHeight: Math.max(implicitBackgroundHeight + topInset + bottomInset, + contentHeight + topPadding + bottomPadding + + (implicitHeaderHeight > 0 ? implicitHeaderHeight + spacing : 0) + + (implicitFooterHeight > 0 ? implicitFooterHeight + spacing : 0)) + + padding: 24 + verticalPadding: 18 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.Universal.chromeMediumLowColor + border.color: control.Universal.chromeHighColor + border.width: 1 // FlyoutBorderThemeThickness + } + + Overlay.modal: Rectangle { + color: control.Universal.baseLowColor + } + + Overlay.modeless: Rectangle { + color: control.Universal.baseLowColor + } + + header: Label { + text: control.title + elide: Label.ElideRight + // TODO: QPlatformTheme::TitleBarFont + font.pixelSize: 20 + + leftPadding: 24 + rightPadding: 24 + topPadding: 18 + height: control.title.length > 0 ? implicitHeight : 0 + + background: Rectangle { + x: 1; y: 1 // // FlyoutBorderThemeThickness + color: control.Universal.chromeMediumLowColor + width: parent.width - 2 + height: parent.height - 1 + } + } + + contentItem: FontDialogContent { + id: content + } + + footer: RowLayout { + id: rowLayout + spacing: 24 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 24 + Layout.topMargin: 6 + Layout.bottomMargin: 24 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + Layout.topMargin: 6 + Layout.bottomMargin: 24 + + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + spacing: 12 + horizontalPadding: 0 + + Layout.rightMargin: 24 + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml new file mode 100644 index 00000000..284b7dec --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialog.qml @@ -0,0 +1,146 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts +import QtQuick.Templates as T + +FontDialogImpl { + id: control + + implicitWidth: Math.max(control.implicitBackgroundWidth + control.leftInset + control.rightInset, + control.contentWidth + control.leftPadding + control.rightPadding, + control.implicitHeaderWidth, + control.implicitFooterWidth) + implicitHeight: Math.max(control.implicitBackgroundHeight + control.topInset + control.bottomInset, + control.contentHeight + control.topPadding + control.bottomPadding + + (control.implicitHeaderHeight > 0 ? control.implicitHeaderHeight + control.spacing : 0) + + (control.implicitFooterHeight > 0 ? control.implicitFooterHeight + control.spacing : 0)) + + leftPadding: 20 + rightPadding: 20 + // Ensure that the background's border is visible. + leftInset: -1 + rightInset: -1 + topInset: -1 + bottomInset: -1 + + standardButtons: T.Dialog.Ok | T.Dialog.Cancel + + FontDialogImpl.buttonBox: buttonBox + FontDialogImpl.familyListView: content.familyListView + FontDialogImpl.styleListView: content.styleListView + FontDialogImpl.sizeListView: content.sizeListView + FontDialogImpl.sampleEdit: content.sampleEdit + FontDialogImpl.writingSystemComboBox: writingSystemComboBox + FontDialogImpl.underlineCheckBox: content.underline + FontDialogImpl.strikeoutCheckBox: content.strikeout + FontDialogImpl.familyEdit: content.familyEdit + FontDialogImpl.styleEdit: content.styleEdit + FontDialogImpl.sizeEdit: content.sizeEdit + + background: Rectangle { + implicitWidth: 600 + implicitHeight: 400 + color: control.palette.window + border.color: control.palette.dark + } + + Overlay.modal: Rectangle { + color: Color.transparent(control.palette.shadow, 0.5) + } + + Overlay.modeless: Rectangle { + color: Color.transparent(control.palette.shadow, 0.12) + } + + header: Pane { + palette.window: control.palette.light + padding: 20 + + contentItem: Label { + width: parent.width + text: control.title + visible: control.title.length > 0 + horizontalAlignment: Label.AlignHCenter + elide: Label.ElideRight + font.bold: true + } + } + + contentItem: FontDialogContent { + id: content + } + + footer: Rectangle { + color: control.palette.light + implicitWidth: rowLayout.implicitWidth + implicitHeight: rowLayout.implicitHeight + + RowLayout { + id: rowLayout + width: parent.width + height: parent.height + spacing: 20 + + Label { + text: qsTr("Writing System") + + Layout.leftMargin: 20 + } + ComboBox{ + id: writingSystemComboBox + + Layout.fillWidth: true + } + + DialogButtonBox { + id: buttonBox + standardButtons: control.standardButtons + palette.window: control.palette.light + spacing: 12 + horizontalPadding: 0 + verticalPadding: 20 + + Layout.rightMargin: 20 + } + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml new file mode 100644 index 00000000..817ea75e --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qml/FontDialogContent.qml @@ -0,0 +1,269 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick +import QtQuick.Controls +import QtQuick.Controls.impl +import QtQuick.Dialogs +import QtQuick.Dialogs.quickimpl +import QtQuick.Layouts + +GridLayout { + property alias familyListView: fontFamilyListView + property alias styleListView: fontStyleListView + property alias sizeListView: fontSizeListView + property alias sampleEdit: fontSample + property alias underline: fontUnderline + property alias strikeout: fontStrikeout + property alias familyEdit: fontFamilyEdit + property alias styleEdit: fontStyleEdit + property alias sizeEdit: fontSizeEdit + + columns: 3 + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 50 + Layout.preferredHeight: 80 + + Label { + text: qsTr("Family") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontFamilyEdit + objectName: "familyEdit" + readOnly: true + Layout.fillWidth: true + focus: true + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + color: "white" + } + ListView { + id: fontFamilyListView + objectName: "familyListView" + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontFamilyListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 30 + Layout.preferredHeight: 80 + + Label { + text: qsTr("Style") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontStyleEdit + objectName: "styleEdit" + readOnly: true + Layout.fillWidth: true + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + color: "white" + } + ListView { + id: fontStyleListView + objectName: "styleListView" + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar {} + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontStyleListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + spacing: 0 + + Layout.preferredWidth: 20 + Layout.preferredHeight: 80 + + Label { + text: qsTr("Size") + Layout.alignment: Qt.AlignLeft + } + TextField { + id: fontSizeEdit + objectName: "sizeEdit" + Layout.fillWidth: true + validator: IntValidator { + bottom: 1 + top: 512 + } + } + Frame { + Layout.fillWidth: true + Layout.fillHeight: true + background: Rectangle { + color: "white" + } + ListView { + id: fontSizeListView + objectName: "sizeListView" + anchors.fill: parent + clip: true + + ScrollBar.vertical: ScrollBar { + policy: ScrollBar.AlwaysOn + } + + boundsBehavior: Flickable.StopAtBounds + + highlightMoveVelocity: -1 + highlightMoveDuration: 1 + highlightFollowsCurrentItem: true + keyNavigationEnabled: true + + delegate: ItemDelegate { + width: ListView.view.width + highlighted: ListView.isCurrentItem + onClicked: () => fontSizeListView.currentIndex = index + text: modelData + } + } + } + } + + ColumnLayout { + Layout.preferredHeight: 50 + Layout.preferredWidth: 80 + + GroupBox { + id: effectsGroupBox + title: qsTr("Effects") + + Layout.fillWidth: true + + Layout.fillHeight: true + + label: Label { + anchors.left: effectsGroupBox.left + text: parent.title + } + + ColumnLayout { + anchors.centerIn: parent + CheckBox { + id: fontUnderline + objectName: "underlineEffect" + text: qsTr("Underline") + } + CheckBox{ + id: fontStrikeout + objectName: "strikeoutEffect" + text: qsTr("Strikeout") + } + } + } + } + + GroupBox { + id: sample + padding: label.implicitHeight + title: qsTr("Sample") + + Layout.fillWidth: true + Layout.preferredHeight: 50 + Layout.preferredWidth: 80 + Layout.fillHeight: true + Layout.columnSpan: 2 + clip: true + + background: Rectangle { + y: sample.topPadding - sample.bottomPadding + width: parent.width - sample.leftPadding + sample.rightPadding + height: parent.height - sample.topPadding + sample.bottomPadding + radius: 3 + } + + label: Label { + anchors.left: sample.left + text: sample.title + } + + TextEdit { + id: fontSample + objectName: "sampleEdit" + anchors.centerIn: parent + readOnly: true + } + } +} diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp index f56466e0..1523154b 100644 --- a/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickdialogimplfactory.cpp @@ -39,6 +39,7 @@ #include <QtCore/qloggingcategory.h> #include "qquickplatformfiledialog_p.h" +#include "qquickplatformfontdialog_p.h" QT_BEGIN_NAMESPACE @@ -63,7 +64,17 @@ QPlatformDialogHelper *QQuickDialogImplFactory::createPlatformDialogHelper( } return dialog; - } default: + } + case QPlatformTheme::FontDialog: { + auto dialog = new QQuickPlatformFontDialog(parent); + + if (!dialog->isValid()) { + delete dialog; + return nullptr; + } + return dialog; + } + default: break; } diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp new file mode 100644 index 00000000..bc0108ce --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl.cpp @@ -0,0 +1,836 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickfontdialogimpl_p.h" +#include "qquickfontdialogimpl_p_p.h" + +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p_p.h> +#include <private/qfontdatabase_p.h> + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcAttachedProperty, "qt.quick.dialogs.quickfontdialogimpl.attachedOrWarn") + +QQuickFontDialogImplPrivate::QQuickFontDialogImplPrivate() +{ +} + +QQuickFontDialogImplAttached *QQuickFontDialogImplPrivate::attachedOrWarn() +{ + Q_Q(QQuickFontDialogImpl); + QQuickFontDialogImplAttached *attached = static_cast<QQuickFontDialogImplAttached *>( + qmlAttachedPropertiesObject<QQuickFontDialogImpl>(q)); + if (!attached) { + qCWarning(lcAttachedProperty) + << "Expected FontDialogImpl attached object to be present on" << this; + } + return attached; +} + +void QQuickFontDialogImplPrivate::handleAccept() { } + +void QQuickFontDialogImplPrivate::handleClick(QQuickAbstractButton *button) +{ + Q_Q(QQuickFontDialogImpl); + if (buttonRole(button) == QPlatformDialogHelper::AcceptRole) { + q->accept(); + QQuickDialogPrivate::handleClick(button); + } +} + +QQuickFontDialogImpl::QQuickFontDialogImpl(QObject *parent) + : QQuickDialog(*(new QQuickFontDialogImplPrivate), parent) +{ +} + +QQuickFontDialogImplAttached *QQuickFontDialogImpl::qmlAttachedProperties(QObject *object) +{ + return new QQuickFontDialogImplAttached(object); +} + +QSharedPointer<QFontDialogOptions> QQuickFontDialogImpl::options() const +{ + Q_D(const QQuickFontDialogImpl); + + return d->options; +} + +void QQuickFontDialogImpl::setOptions(const QSharedPointer<QFontDialogOptions> &options) +{ + Q_D(QQuickFontDialogImpl); + + if (options == d->options) + return; + + d->options = options; + + emit optionsChanged(); +} + +QFont QQuickFontDialogImpl::currentFont() const +{ + Q_D(const QQuickFontDialogImpl); + return d->currentFont; +} + +void QQuickFontDialogImpl::setCurrentFont(const QFont &font) +{ + Q_D(QQuickFontDialogImpl); + + if (font == d->currentFont) + return; + + d->currentFont = font; + + emit currentFontChanged(font); +} + +void QQuickFontDialogImpl::updateListViews() +{ + Q_D(QQuickFontDialogImpl); + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->updateFamilies(); + + attached->buttonBox()->setVisible(!(options()->options() & QFontDialogOptions::NoButtons)); +} + +void QQuickFontDialogImpl::keyReleaseEvent(QKeyEvent *event) +{ + Q_D(QQuickFontDialogImpl); + + QQuickDialog::keyReleaseEvent(event); + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + // The family and style text edits are read-only so that they + // can show the current selection but also allow key input to "search". + // This is why we handle just the release event, and don't accept it. + if (window()->activeFocusItem() == attached->familyEdit()) + attached->searchFamily(event->text()); + else if (window()->activeFocusItem() == attached->styleEdit()) + attached->searchStyle(event->text()); +} + +void QQuickFontDialogImpl::focusOutEvent(QFocusEvent *event) +{ + Q_D(QQuickFontDialogImpl); + + QQuickDialog::focusOutEvent(event); + + QQuickFontDialogImplAttached *attached = d->attachedOrWarn(); + if (!attached) + return; + + attached->clearSearch(); +} + +QQuickFontDialogImplAttached::QQuickFontDialogImplAttached(QObject *parent) + : QObject(*(new QQuickFontDialogImplAttachedPrivate), parent), + m_writingSystem(QFontDatabase::Any), + m_selectedSize(-1), + m_smoothlyScalable(false), + m_isUpdatingStyles(false) +{ + if (!qobject_cast<QQuickFontDialogImpl *>(parent)) { + qmlWarning(this) << "FontDialogImpl attached properties should only be " + << "accessed through the root FileDialogImpl instance"; + } +} + +QQuickListView *QQuickFontDialogImplAttached::familyListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->familyListView; +} + +void QQuickFontDialogImplAttached::setFamilyListView(QQuickListView *familyListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->familyListView == familyListView) + return; + + if (d->familyListView) { + disconnect(d->familyListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_familyChanged); + } + + d->familyListView = familyListView; + + if (familyListView) { + connect(d->familyListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_familyChanged); + } + + emit familyListViewChanged(); +} + +QQuickListView *QQuickFontDialogImplAttached::styleListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->styleListView; +} + +void QQuickFontDialogImplAttached::setStyleListView(QQuickListView *styleListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->styleListView == styleListView) + return; + + if (d->styleListView) { + disconnect(d->styleListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_styleChanged); + } + + d->styleListView = styleListView; + + if (styleListView) { + connect(d->styleListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_styleChanged); + } + + emit styleListViewChanged(); +} + +QQuickListView *QQuickFontDialogImplAttached::sizeListView() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sizeListView; +} + +void QQuickFontDialogImplAttached::setSizeListView(QQuickListView *sizeListView) +{ + Q_D(QQuickFontDialogImplAttached); + if (d->sizeListView == sizeListView) + return; + + if (d->sizeListView) { + disconnect(d->sizeListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_sizeChanged); + } + + d->sizeListView = sizeListView; + + if (d->sizeListView) { + connect(d->sizeListView, &QQuickListView::currentIndexChanged, + this, &QQuickFontDialogImplAttached::_q_sizeChanged); + } + + emit sizeListViewChanged(); +} + +QQuickTextEdit *QQuickFontDialogImplAttached::sampleEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sampleEdit; +} + +void QQuickFontDialogImplAttached::setSampleEdit(QQuickTextEdit *sampleEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->sampleEdit == sampleEdit) + return; + + if (d->sampleEdit) { + QObjectPrivate::disconnect(d->sampleEdit, &QQuickTextEdit::fontChanged, + d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged); + } + + d->sampleEdit = sampleEdit; + + if (d->sampleEdit) { + QObjectPrivate::connect(d->sampleEdit, &QQuickTextEdit::fontChanged, + d, &QQuickFontDialogImplAttachedPrivate::currentFontChanged); + + d->sampleEdit->setText(QFontDatabase::writingSystemSample(m_writingSystem)); + } + + emit sampleEditChanged(); +} + +QQuickDialogButtonBox *QQuickFontDialogImplAttached::buttonBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->buttonBox; +} + +void QQuickFontDialogImplAttached::setButtonBox(QQuickDialogButtonBox *buttonBox) +{ + Q_D(QQuickFontDialogImplAttached); + if (buttonBox == d->buttonBox) + return; + + if (d->buttonBox) { + QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent()); + if (fontDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::accepted, + dialogPrivate, &QQuickDialogPrivate::handleAccept); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::rejected, + dialogPrivate, &QQuickDialogPrivate::handleReject); + QObjectPrivate::disconnect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate, + &QQuickDialogPrivate::handleClick); + } + } + + d->buttonBox = buttonBox; + + if (buttonBox) { + QQuickFontDialogImpl *fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent()); + if (fontDialogImpl) { + auto dialogPrivate = QQuickDialogPrivate::get(fontDialogImpl); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::accepted, dialogPrivate, + &QQuickDialogPrivate::handleAccept); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::rejected, dialogPrivate, + &QQuickDialogPrivate::handleReject); + QObjectPrivate::connect(d->buttonBox, &QQuickDialogButtonBox::clicked, dialogPrivate, + &QQuickDialogPrivate::handleClick); + } + } + + emit buttonBoxChanged(); +} + +QQuickComboBox *QQuickFontDialogImplAttached::writingSystemComboBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->writingSystemComboBox; +} + +void QQuickFontDialogImplAttached::setWritingSystemComboBox(QQuickComboBox *writingSystemComboBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->writingSystemComboBox == writingSystemComboBox) + return; + + if (d->writingSystemComboBox) { + disconnect(d->writingSystemComboBox, &QQuickComboBox::activated, + this, &QQuickFontDialogImplAttached::_q_writingSystemChanged); + } + + d->writingSystemComboBox = writingSystemComboBox; + + if (d->writingSystemComboBox) { + QStringList writingSystemModel; + for (int i = 0; i < QFontDatabase::WritingSystemsCount; ++i) { + QFontDatabase::WritingSystem ws = QFontDatabase::WritingSystem(i); + QString wsName = QFontDatabase::writingSystemName(ws); + if (wsName.isEmpty()) + break; + writingSystemModel.append(wsName); + } + + d->writingSystemComboBox->setModel(writingSystemModel); + + connect(d->writingSystemComboBox, &QQuickComboBox::activated, + this, &QQuickFontDialogImplAttached::_q_writingSystemChanged); + } + + emit writingSystemComboBoxChanged(); +} + +QQuickCheckBox *QQuickFontDialogImplAttached::underlineCheckBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->underlineCheckBox; +} + +void QQuickFontDialogImplAttached::setUnderlineCheckBox(QQuickCheckBox *underlineCheckBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->underlineCheckBox == underlineCheckBox) + return; + + if (d->underlineCheckBox) { + disconnect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + d->underlineCheckBox = underlineCheckBox; + + if (d->underlineCheckBox) { + connect(d->underlineCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + emit underlineCheckBoxChanged(); +} + +QQuickCheckBox *QQuickFontDialogImplAttached::strikeoutCheckBox() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->strikeoutCheckBox; +} + +void QQuickFontDialogImplAttached::setStrikeoutCheckBox(QQuickCheckBox *strikeoutCheckBox) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->strikeoutCheckBox == strikeoutCheckBox) + return; + + if (d->strikeoutCheckBox) { + disconnect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + d->strikeoutCheckBox = strikeoutCheckBox; + + if (d->strikeoutCheckBox) { + connect(d->strikeoutCheckBox, &QQuickCheckBox::checkStateChanged, + this, &QQuickFontDialogImplAttached::_q_updateSample); + } + + emit strikeoutCheckBoxChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::familyEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->familyEdit; +} + +void QQuickFontDialogImplAttached::setFamilyEdit(QQuickTextField *familyEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->familyEdit == familyEdit) + return; + + d->familyEdit = familyEdit; + + emit familyEditChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::styleEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->styleEdit; +} + +void QQuickFontDialogImplAttached::setStyleEdit(QQuickTextField *styleEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->styleEdit == styleEdit) + return; + + d->styleEdit = styleEdit; + + emit styleEditChanged(); +} + +QQuickTextField *QQuickFontDialogImplAttached::sizeEdit() const +{ + Q_D(const QQuickFontDialogImplAttached); + return d->sizeEdit; +} + +void QQuickFontDialogImplAttached::setSizeEdit(QQuickTextField *sizeEdit) +{ + Q_D(QQuickFontDialogImplAttached); + + if (d->sizeEdit == sizeEdit) + return; + + if (d->sizeEdit) { + disconnect(d->sizeEdit, &QQuickTextField::textChanged, + this, &QQuickFontDialogImplAttached::_q_sizeEdited); + } + + d->sizeEdit = sizeEdit; + + if (d->sizeEdit) { + connect(d->sizeEdit, &QQuickTextField::textChanged, + this, &QQuickFontDialogImplAttached::_q_sizeEdited); + } + + emit sizeEditChanged(); +} + +/*! + \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); + + const QFontDialogOptions::FontDialogOptions spacingMask(QFontDialogOptions::ProportionalFonts + | QFontDialogOptions::MonospacedFonts); + + const auto p = qobject_cast<QQuickFontDialogImpl *>(parent()); + + const auto options = p->options()->options(); + + QStringList familyNames; + const auto families = QFontDatabase::families(m_writingSystem); + for (const auto &family : families) { + if (QFontDatabase::isPrivateFamily(family)) + continue; + + if ((options & scalableMask) && (options & scalableMask) != scalableMask) { + if (bool(options & QFontDialogOptions::ScalableFonts) + != QFontDatabase::isSmoothlyScalable(family)) + continue; + } + + if ((options & spacingMask) && (options & scalableMask) != spacingMask) { + if (bool(options & QFontDialogOptions::MonospacedFonts) + != QFontDatabase::isFixedPitch(family)) + continue; + } + + familyNames << family; + } + + auto listView = familyListView(); + + // Index will be set to -1 on empty model, and 0 for non empty models. + // Will overwrite selectedFamily and selectedStyle + listView->setModel(familyNames); + + 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); + } + + updateStyles(); +} + +/*! + \internal + + Updates the model for the style list view, and + attempt to reselect the style that was previously selected. + + Calls updateSizes() + */ +void QQuickFontDialogImplAttached::updateStyles() +{ + const QString family = familyListView()->currentIndex() >= 0 ? m_selectedFamily : QString(); + const QStringList styles = QFontDatabase::styles(family); + + auto listView = styleListView(); + + m_isUpdatingStyles = true; + + 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); + } + + listView->setCurrentIndex(newIndex); + + m_selectedStyle = styles.at(newIndex); + styleEdit()->setText(m_selectedStyle); + + m_smoothlyScalable = QFontDatabase::isSmoothlyScalable(m_selectedFamily, m_selectedStyle); + } + + m_isUpdatingStyles = false; + + updateSizes(); +} + +/*! + \internal + + Updates the model for the size list view, + and attempts to reselect the size that was previously selected + */ +void QQuickFontDialogImplAttached::updateSizes() +{ + if (!m_selectedFamily.isEmpty()) { + const QList<int> sizes = QFontDatabase::pointSizes(m_selectedFamily, m_selectedStyle); + + QStringList str_sizes; + + str_sizes.reserve(sizes.size()); + + int idx = 0, current = -1; + for (QList<int>::const_iterator it = sizes.constBegin(); it != sizes.constEnd(); it++) { + str_sizes.append(QString::number(*it)); + if (current == -1 && m_selectedSize == *it) { + current = idx; + } + ++idx; + } + + auto listView = sizeListView(); + + listView->setModel(str_sizes); + if (current != -1) + listView->setCurrentIndex(current); + + sizeEdit()->setText(!m_smoothlyScalable && listView->currentIndex() > 0 + ? str_sizes.at(listView->currentIndex()) + : QString::number(m_selectedSize)); + } else { + qCWarning(lcAttachedProperty) << "Warning! selectedFamily is empty"; + sizeEdit()->clear(); + } + + _q_updateSample(); +} + +void QQuickFontDialogImplAttached::_q_updateSample() +{ + const int pSize = sizeEdit()->text().toInt(); + + QFont newFont = QFontDatabase::font(m_selectedFamily, m_selectedStyle, pSize); + + newFont.setUnderline(underlineCheckBox()->isChecked()); + newFont.setStrikeOut(strikeoutCheckBox()->isChecked()); + + if (!m_selectedFamily.isEmpty()) { + sampleEdit()->setFont(newFont); + } +} + +void QQuickFontDialogImplAttached::_q_writingSystemChanged(int index) +{ + m_writingSystem = QFontDatabase::WritingSystem(index); + sampleEdit()->setText(QFontDatabase::writingSystemSample(m_writingSystem)); + + updateFamilies(); +} + +void QQuickFontDialogImplAttached::searchListView(const QString &s, QQuickListView *listView) +{ + const QStringList model = listView->model().toStringList(); + + bool redo = false; + + do { + m_search.append(s); + + for (int i = 0; i < model.count(); ++i) { + if (model.at(i).startsWith(m_search, Qt::CaseInsensitive)) { + listView->setCurrentIndex(i); + return; + } + } + + clearSearch(); + + redo = !redo; + } while (redo); +} + +void QQuickFontDialogImplAttached::clearSearch() +{ + m_search.clear(); +} + +void QQuickFontDialogImplAttached::_q_familyChanged() +{ + const int index = familyListView()->currentIndex(); + + if (index < 0) { + familyEdit()->clear(); + return; + } + + m_selectedFamily = familyListView()->model().toStringList().at(index); + familyEdit()->setText(m_selectedFamily); + + updateStyles(); +} + +void QQuickFontDialogImplAttached::_q_styleChanged() +{ + if (m_isUpdatingStyles) + return; + + const int index = styleListView()->currentIndex(); + + if (index < 0) { + qCWarning(lcAttachedProperty) << "currentIndex changed to -1"; + return; + } + + m_selectedStyle = styleListView()->model().toStringList().at(index); + styleEdit()->setText(m_selectedStyle); + + updateSizes(); +} + +void QQuickFontDialogImplAttached::_q_sizeEdited() +{ + const int size = sizeEdit()->text().toInt(); + + if (size == m_selectedSize) + return; + + m_selectedSize = size; + + if (sizeListView()->count()) { + auto model = sizeListView()->model().toStringList(); + + int i; + for (i = 0; i < model.count() - 1; ++i) { + if (model.at(i).toInt() >= size) + break; + } + + QSignalBlocker blocker(sizeListView()); + if (model.at(i).toInt() == size) + sizeListView()->setCurrentIndex(i); + else + sizeListView()->setCurrentIndex(-1); + } + + _q_updateSample(); +} + +void QQuickFontDialogImplAttached::_q_sizeChanged() +{ + const int index = sizeListView()->currentIndex(); + + if (index < 0) { + qCWarning(lcAttachedProperty) << "currentIndex changed to -1"; + return; + } + + const QString s = sizeListView()->model().toStringList().at(index); + m_selectedSize = s.toInt(); + + sizeEdit()->setText(s); + + _q_updateSample(); +} + +void QQuickFontDialogImplAttachedPrivate::currentFontChanged(const QFont &font) +{ + + auto fontDialogImpl = qobject_cast<QQuickFontDialogImpl *>(parent); + + if (!fontDialogImpl) { + return; + } + + fontDialogImpl->setCurrentFont(font); + + if (fontDialogImpl->options()->testOption(QFontDialogOptions::NoButtons)) + emit fontDialogImpl->fontSelected(font); +} + +QT_END_NAMESPACE diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h new file mode 100644 index 00000000..20629dc1 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p.h @@ -0,0 +1,215 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOGIMPL_P_H +#define QQUICKFONTDIALOGIMPL_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qfontdatabase.h> +#include <QtQuick/private/qquicklistview_p.h> +#include <QtQuick/private/qquicktextedit_p.h> +#include <QtQuickTemplates2/private/qquicktextfield_p.h> +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickcheckbox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickDialogButtonBox; + +class QQuickFontDialogImplAttached; +class QQuickFontDialogImplAttachedPrivate; +class QQuickFontDialogImplPrivate; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFontDialogImpl : public QQuickDialog +{ + Q_OBJECT + Q_PROPERTY(QFont currentFont READ currentFont WRITE setCurrentFont NOTIFY currentFontChanged FINAL) + QML_NAMED_ELEMENT(FontDialogImpl) + QML_ATTACHED(QQuickFontDialogImplAttached) + QML_ADDED_IN_VERSION(6, 2) + +public: + explicit QQuickFontDialogImpl(QObject *parent = nullptr); + + static QQuickFontDialogImplAttached *qmlAttachedProperties(QObject *object); + + QSharedPointer<QFontDialogOptions> options() const; + void setOptions(const QSharedPointer<QFontDialogOptions> &options); + + QFont currentFont() const; + void setCurrentFont(const QFont &font); + + void updateListViews(); + +Q_SIGNALS: + void optionsChanged(); + void currentFontChanged(const QFont &font); + void fontSelected(const QFont &font); + +private: + void keyReleaseEvent(QKeyEvent *event) override; + void focusOutEvent(QFocusEvent *event) override; + + Q_DISABLE_COPY(QQuickFontDialogImpl) + Q_DECLARE_PRIVATE(QQuickFontDialogImpl) +}; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickFontDialogImplAttached : public QObject +{ + Q_OBJECT + Q_PROPERTY(QQuickListView *familyListView READ familyListView WRITE setFamilyListView + NOTIFY familyListViewChanged) + Q_PROPERTY(QQuickListView *styleListView READ styleListView WRITE setStyleListView + NOTIFY styleListViewChanged) + Q_PROPERTY(QQuickListView *sizeListView READ sizeListView WRITE setSizeListView + NOTIFY sizeListViewChanged) + Q_PROPERTY(QQuickTextEdit *sampleEdit READ sampleEdit WRITE setSampleEdit + NOTIFY sampleEditChanged) + Q_PROPERTY(QQuickDialogButtonBox *buttonBox READ buttonBox WRITE setButtonBox + NOTIFY buttonBoxChanged) + Q_PROPERTY(QQuickComboBox *writingSystemComboBox READ writingSystemComboBox + WRITE setWritingSystemComboBox NOTIFY writingSystemComboBoxChanged) + Q_PROPERTY(QQuickCheckBox *underlineCheckBox READ underlineCheckBox WRITE setUnderlineCheckBox + NOTIFY underlineCheckBoxChanged) + Q_PROPERTY(QQuickCheckBox *strikeoutCheckBox READ strikeoutCheckBox WRITE setStrikeoutCheckBox + NOTIFY strikeoutCheckBoxChanged) + + Q_PROPERTY(QQuickTextField *familyEdit READ familyEdit WRITE setFamilyEdit + NOTIFY familyEditChanged) + Q_PROPERTY(QQuickTextField *styleEdit READ styleEdit WRITE setStyleEdit NOTIFY styleEditChanged) + Q_PROPERTY(QQuickTextField *sizeEdit READ sizeEdit WRITE setSizeEdit NOTIFY sizeEditChanged) + + Q_MOC_INCLUDE(<QtQuickTemplates2 / private / qquickdialogbuttonbox_p.h>) + +public: + explicit QQuickFontDialogImplAttached(QObject *parent = nullptr); + + QQuickListView *familyListView() const; + void setFamilyListView(QQuickListView *familyListView); + + QQuickListView *styleListView() const; + void setStyleListView(QQuickListView *styleListView); + + QQuickListView *sizeListView() const; + void setSizeListView(QQuickListView *sizeListView); + + QQuickTextEdit *sampleEdit() const; + void setSampleEdit(QQuickTextEdit *sampleEdit); + + QQuickDialogButtonBox *buttonBox() const; + void setButtonBox(QQuickDialogButtonBox *buttonBox); + + QQuickComboBox *writingSystemComboBox() const; + void setWritingSystemComboBox(QQuickComboBox *writingSystemComboBox); + + QQuickCheckBox *underlineCheckBox() const; + void setUnderlineCheckBox(QQuickCheckBox *underlineCheckBox); + + QQuickCheckBox *strikeoutCheckBox() const; + void setStrikeoutCheckBox(QQuickCheckBox *strikethroughCheckBox); + + QQuickTextField *familyEdit() const; + void setFamilyEdit(QQuickTextField *familyEdit); + + QQuickTextField *styleEdit() const; + void setStyleEdit(QQuickTextField *styleEdit); + + QQuickTextField *sizeEdit() const; + void setSizeEdit(QQuickTextField *sizeEdit); + +Q_SIGNALS: + void buttonBoxChanged(); + void familyListViewChanged(); + void styleListViewChanged(); + void sizeListViewChanged(); + void sampleEditChanged(); + void writingSystemComboBoxChanged(); + void underlineCheckBoxChanged(); + void strikeoutCheckBoxChanged(); + void familyEditChanged(); + void styleEditChanged(); + void sizeEditChanged(); + +public: + void searchFamily(const QString &s) { searchListView(s, familyListView()); } + void searchStyle(const QString &s) { searchListView(s, styleListView()); } + void clearSearch(); + + void updateFamilies(); + +private: + void updateStyles(); + void updateSizes(); + + void _q_familyChanged(); + void _q_styleChanged(); + void _q_sizeEdited(); + void _q_sizeChanged(); + void _q_updateSample(); + + void _q_writingSystemChanged(int index); + + void searchListView(const QString &s, QQuickListView *listView); + + QFontDatabase::WritingSystem m_writingSystem; + QString m_selectedFamily; + QString m_selectedStyle; + QString m_search; + int m_selectedSize; + bool m_smoothlyScalable; + bool m_isUpdatingStyles; + + Q_DISABLE_COPY(QQuickFontDialogImplAttached) + Q_DECLARE_PRIVATE(QQuickFontDialogImplAttached) +}; + +QT_END_NAMESPACE + +QML_DECLARE_TYPE(QQuickFontDialogImpl) + +#endif // QQUICKFONTDIALOGIMPL_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h new file mode 100644 index 00000000..2dc334a7 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickfontdialogimpl_p_p.h @@ -0,0 +1,104 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKFONTDIALOGIMPL_P_P_H +#define QQUICKFONTDIALOGIMPL_P_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtQuickTemplates2/private/qquickcombobox_p.h> +#include <QtQuickTemplates2/private/qquickdialog_p_p.h> +#include <QtQuickTemplates2/private/qquickdialogbuttonbox_p.h> + +#include "qquickfontdialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFontDialogImplPrivate : public QQuickDialogPrivate +{ + Q_DECLARE_PUBLIC(QQuickFontDialogImpl) +public: + QQuickFontDialogImplPrivate(); + + static QQuickFontDialogImplPrivate *get(QQuickFontDialogImpl *dialog) + { + return dialog->d_func(); + } + + QQuickFontDialogImplAttached *attachedOrWarn(); + + void updateEnabled(); + + void handleAccept() override; + void handleClick(QQuickAbstractButton *button) override; + + QSharedPointer<QFontDialogOptions> options; + + QFont currentFont; +}; + +class QQuickFontDialogImplAttachedPrivate : public QObjectPrivate +{ + Q_DECLARE_PUBLIC(QQuickFontDialogImplAttached) + + void currentFontChanged(const QFont &font); + +public: + QPointer<QQuickDialogButtonBox> buttonBox; + QPointer<QQuickListView> familyListView; + QPointer<QQuickListView> styleListView; + QPointer<QQuickListView> sizeListView; + QPointer<QQuickTextEdit> sampleEdit; + QPointer<QQuickComboBox> writingSystemComboBox; + QPointer<QQuickCheckBox> underlineCheckBox; + QPointer<QQuickCheckBox> strikeoutCheckBox; + QPointer<QQuickTextField> familyEdit; + QPointer<QQuickTextField> styleEdit; + QPointer<QQuickTextField> sizeEdit; +}; + +QT_END_NAMESPACE + +#endif // QQUICKFONTDIALOGIMPL_P_P_H diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp new file mode 100644 index 00000000..e0a91aeb --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog.cpp @@ -0,0 +1,173 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include "qquickplatformfontdialog_p.h" + +#include <QtCore/qloggingcategory.h> +#include <QtGui/qwindow.h> +#include <QtQml/qqmlcontext.h> +#include <QtQml/qqmlinfo.h> +#include <QtQuick/qquickwindow.h> +#include <QtQuickTemplates2/private/qquickdialog_p.h> +#include <QtQuickTemplates2/private/qquickpopup_p_p.h> +#include <QtQuickTemplates2/private/qquickpopupanchors_p.h> + +#include "qquickfontdialogimpl_p.h" + +QT_BEGIN_NAMESPACE + +Q_LOGGING_CATEGORY(lcQuickPlatformFontDialog, "qt.quick.dialogs.quickplatformfontdialog") + +/*! + \class QQuickPlatformFontDialog + \internal + + An interface that QQuickFontDialog can use to access the non-native Qt Quick FontDialog. + + Both this and the native implementations are created in QQuickAbstractDialog::create(). + +*/ +QQuickPlatformFontDialog::QQuickPlatformFontDialog(QObject *parent) +{ + qCDebug(lcQuickPlatformFontDialog) + << "creating non-native Qt Quick FontDialog with parent" << parent; + + // Set a parent so that we get deleted if we can't be shown for whatever reason. + // Our eventual parent should be the window, though. + setParent(parent); + + auto qmlContext = ::qmlContext(parent); + if (!qmlContext) { + qmlWarning(parent) << "No QQmlContext for QQuickPlatformFontDialog; can't create " + "non-native FontDialog implementation"; + return; + } + + const auto dialogQmlUrl = QUrl(QStringLiteral( + "qrc:/qt-project.org/imports/QtQuick/Dialogs/quickimpl/qml/FontDialog.qml")); + + QQmlComponent fontDialogComponent(qmlContext->engine(), dialogQmlUrl, parent); + if (!fontDialogComponent.isReady()) { + qmlWarning(parent) << "Failed to load non-native FontDialog implementation:\n" + << fontDialogComponent.errorString(); + return; + } + + m_dialog = qobject_cast<QQuickFontDialogImpl *>(fontDialogComponent.create()); + + if (!m_dialog) { + qmlWarning(parent) << "Failed to create an instance of the non-native FontDialog:\n" + << fontDialogComponent.errorString(); + return; + } + + m_dialog->setParent(this); + + connect(m_dialog, &QQuickDialog::accepted, this, &QPlatformDialogHelper::accept); + connect(m_dialog, &QQuickDialog::rejected, this, &QPlatformDialogHelper::reject); + + connect(m_dialog, &QQuickFontDialogImpl::currentFontChanged, + this, &QQuickPlatformFontDialog::currentFontChanged); + connect(m_dialog, &QQuickFontDialogImpl::fontSelected, this, &QQuickPlatformFontDialog::fontSelected); +} + +bool QQuickPlatformFontDialog::isValid() const +{ + return m_dialog; +} + +void QQuickPlatformFontDialog::setCurrentFont(const QFont &font) +{ + if (m_dialog) + m_dialog->setCurrentFont(font); +} + +QFont QQuickPlatformFontDialog::currentFont() const +{ + return m_dialog ? m_dialog->currentFont() : QFont(); +} + +void QQuickPlatformFontDialog::exec() +{ + qCWarning(lcQuickPlatformFontDialog) + << "exec() is not supported for the Qt Quick FontDialog fallback"; +} + +bool QQuickPlatformFontDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, + QWindow *parent) +{ + qCDebug(lcQuickPlatformFontDialog) + << "show called with flags" << flags << "modality" << modality << "parent" << parent; + + if (!isValid()) + return false; + + if (!parent) + return false; + + auto quickWindow = qobject_cast<QQuickWindow *>(parent); + if (!quickWindow) { + qmlInfo(this->parent()) << "Parent window (" << parent + << ") of non-native dialog is not a QQuickWindow"; + return false; + } + m_dialog->setParent(parent); + m_dialog->resetParentItem(); + + auto popupPrivate = QQuickPopupPrivate::get(m_dialog); + popupPrivate->getAnchors()->setCenterIn(m_dialog->parentItem()); + + QSharedPointer<QFontDialogOptions> options = QPlatformFontDialogHelper::options(); + m_dialog->setTitle(options->windowTitle()); + m_dialog->setOptions(options); + m_dialog->updateListViews(); + + m_dialog->open(); + return true; +} + +void QQuickPlatformFontDialog::hide() +{ + if (isValid()) + m_dialog->close(); +} + +QQuickFontDialogImpl *QQuickPlatformFontDialog::dialog() const +{ + return m_dialog; +} + +QT_END_NAMESPACE diff --git a/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h new file mode 100644 index 00000000..71192f50 --- /dev/null +++ b/src/quickdialogs2/quickdialogs2quickimpl/qquickplatformfontdialog_p.h @@ -0,0 +1,86 @@ +/**************************************************************************** +** +** Copyright (C) 2021 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the QtQuick Dialogs module of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL3$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 3 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPLv3 included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 3 requirements +** will be met: https://www.gnu.org/licenses/lgpl.html. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 2.0 or later as published by the Free +** Software Foundation and appearing in the file LICENSE.GPL included in +** the packaging of this file. Please review the following information to +** ensure the GNU General Public License version 2.0 requirements will be +** met: http://www.gnu.org/licenses/gpl-2.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#ifndef QQUICKPLATFORMFONTDIALOG_P_H +#define QQUICKPLATFORMFONTDIALOG_P_H + +// +// W A R N I N G +// ------------- +// +// This file is not part of the Qt API. It exists purely as an +// implementation detail. This header file may change from version to +// version without notice, or even be removed. +// +// We mean it. +// + +#include <QtGui/qpa/qplatformdialoghelper.h> + +#include "qtquickdialogs2quickimplglobal_p.h" + +QT_BEGIN_NAMESPACE + +class QQuickFontDialogImpl; +class QWindow; + +class Q_QUICKDIALOGS2QUICKIMPL_PRIVATE_EXPORT QQuickPlatformFontDialog + : public QPlatformFontDialogHelper +{ + Q_OBJECT + +public: + explicit QQuickPlatformFontDialog(QObject *parent); + ~QQuickPlatformFontDialog() = default; + + bool isValid() const; + + virtual void setCurrentFont(const QFont &font) override; + virtual QFont currentFont() const override; + + void exec() override; + bool show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) override; + void hide() override; + + QQuickFontDialogImpl *dialog() const; + +private: + QQuickFontDialogImpl *m_dialog = nullptr; +}; + +QT_END_NAMESPACE + +#endif // QQUICKPLATFORMFONTDIALOG_P_H |