/**************************************************************************** ** ** Copyright (C) 2016 The Qt Company Ltd. ** Contact: https://www.qt.io/licensing/ ** ** This file is part of the Qt Quick Dialogs module of the Qt Toolkit. ** ** $QT_BEGIN_LICENSE:LGPL$ ** 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 https://www.qt.io/terms-conditions. For further ** information use the contact form at https://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.LGPL3 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-3.0.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 (at your option) the GNU General ** Public license version 3 or any later version approved by the KDE Free ** Qt Foundation. The licenses are as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3 ** included in the packaging of this file. Please review the following ** information to ensure the GNU General Public License requirements will ** be met: https://www.gnu.org/licenses/gpl-2.0.html and ** https://www.gnu.org/licenses/gpl-3.0.html. ** ** $QT_END_LICENSE$ ** ****************************************************************************/ import QtQuick 2.2 import QtQuick.Controls 1.2 import QtQuick.Controls.Private 1.0 import QtQuick.Controls.Styles 1.0 import QtQuick.Dialogs 1.1 import QtQuick.Dialogs.Private 1.1 import QtQuick.Layouts 1.1 import QtQuick.Window 2.1 import "qml" AbstractFontDialog { id: root property alias font: content.externalFont property alias currentFont: content.font Rectangle { id: content SystemPalette { id: palette } implicitWidth: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 100, mainLayout.implicitWidth + outerSpacing * 2)) implicitHeight: Math.min(root.__maximumDimension, Math.max(Screen.pixelDensity * 60, mainLayout.implicitHeight + outerSpacing * 2)) property real spacing: 6 property real outerSpacing: 12 color: palette.window property font font: Qt.font({ family: "Helvetica", pointSize: 24, weight: Font.Normal }) property font externalFont property string writingSystem property string writingSystemSample property var pointSizes onExternalFontChanged: { if (Component.status != Component.Ready) return if (content.font != content.externalFont) { font = externalFont wsComboBox.reset() fontListView.reset() weightListView.reset() } } Component.onCompleted: externalFontChanged() onWritingSystemSampleChanged: { sample.text = writingSystemSample; } Keys.onPressed: { event.accepted = true switch (event.key) { case Qt.Key_Return: case Qt.Key_Select: updateUponAccepted() break case Qt.Key_Escape: case Qt.Key_Back: reject() break default: // do nothing event.accepted = false break } } function updateUponAccepted() { root.font = content.font root.accept() } ColumnLayout { id: mainLayout anchors { fill: parent; margins: content.outerSpacing } spacing: content.spacing GridLayout { columnSpacing: content.spacing; rowSpacing: content.spacing columns: 3 Label { id: fontNameLabel; Layout.fillWidth: true; text: qsTr("Font"); font.bold: true } Label { id: weightLabel; text: qsTr("Weight"); font.bold: true } Label { id: sizeLabel; text: qsTr("Size"); font.bold: true } TableView { id: fontListView focus: true Layout.fillWidth: true Layout.fillHeight: true Layout.preferredWidth: fontColumn.width headerVisible: false function reset() { fontModel.findIndex() content.pointSizes = fontModel.pointSizes() fontModel.findPointSizesIndex() } TableViewColumn{ id: fontColumn; role: "family"; title: qsTr("Font Family") } model: FontListModel { id: fontModel scalableFonts: root.scalableFonts nonScalableFonts: root.nonScalableFonts monospacedFonts: root.monospacedFonts proportionalFonts: root.proportionalFonts Component.onCompleted: fontListView.reset() onModelReset: { findIndex(); } function findIndex() { fontListView.selection.clear() if (fontModel.count <= 0 || fontListView.rowCount <= 0) return var currentRow = 0 if (content.font.family != "") { for (var i = 0; i < fontModel.count; ++i) { if (content.font.family == fontModel.get(i).family) { currentRow = i break } } } content.font.family = fontModel.get(currentRow).family fontListView.selection.select(currentRow) fontListView.positionViewAtRow(currentRow, ListView.Contain) fontListView.clicked(currentRow) } function findPointSizesIndex() { pointSizesListView.selection.clear() if (content.pointSizes.length <= 0 || pointSizesListView.rowCount <= 0) return var currentRow = -1 for (var i = 0; i < content.pointSizes.length; ++i) { if (content.font.pointSize == content.pointSizes[i]) { currentRow = i break } } if (currentRow != -1) { content.font.pointSize = content.pointSizes[currentRow] pointSizesListView.selection.select(currentRow) pointSizesListView.positionViewAtRow(currentRow, ListView.Contain) pointSizesListView.clicked(currentRow) } } } function select(row) { if (row == -1) return currentRow = row content.font.family = fontModel.get(row).family positionViewAtRow(row, ListView.Contain) } onClicked: select(row) onCurrentRowChanged: select(currentRow) } TableView { id: weightListView implicitWidth: (Component.status == Component.Ready) ? (weightColumn.width + content.outerSpacing) : (100) Layout.fillHeight: true Component.onCompleted: resizeColumnsToContents(); headerVisible: false function reset() { weightModel.findIndex() } TableViewColumn { id: weightColumn; role: "name"; title: qsTr("Weight") } model: ListModel { id: weightModel ListElement { name: qsTr("Thin"); weight: Font.Thin } ListElement { name: qsTr("ExtraLight"); weight: Font.ExtraLight } ListElement { name: qsTr("Light"); weight: Font.Light } ListElement { name: qsTr("Normal"); weight: Font.Normal } ListElement { name: qsTr("Medium"); weight: Font.Medium } ListElement { name: qsTr("DemiBold"); weight: Font.DemiBold } ListElement { name: qsTr("Bold"); weight: Font.Bold } ListElement { name: qsTr("ExtraBold"); weight: Font.ExtraBold } ListElement { name: qsTr("Black"); weight: Font.Black } Component.onCompleted: weightListView.reset() function findIndex() { var currentRow = 1 for (var i = 0; i < weightModel.count; ++i) { if (content.font.weight == weightModel.get(i).weight) { currentRow = i break } } content.font.weight = weightModel.get(currentRow).family weightListView.selection.select(currentRow) weightListView.positionViewAtRow(currentRow, ListView.Contain) weightListView.clicked(currentRow) } } function select(row) { if (row == -1) return currentRow = row content.font.weight = weightModel.get(row).weight positionViewAtRow(row, ListView.Contain) } onClicked: select(row) onCurrentRowChanged: select(currentRow) } ColumnLayout { SpinBox { id: pointSizeSpinBox; implicitWidth: (Component.status == Component.Ready) ? (psColumn.width + content.outerSpacing) : (80) value: content.font.pointSize decimals: 0 minimumValue: 1 maximumValue: 512 onValueChanged: { content.font.pointSize = Number(value); updatePointSizesIndex(); } function updatePointSizesIndex() { pointSizesListView.selection.clear() if (content.pointSizes.length <= 0 || pointSizesListView.rowCount <= 0) return var currentRow = -1 for (var i = 0; i < content.pointSizes.length; ++i) { if (content.font.pointSize == content.pointSizes[i]) { currentRow = i break } } if (currentRow < 0) return content.font.pointSize = content.pointSizes[currentRow] pointSizesListView.selection.select(currentRow) pointSizesListView.positionViewAtRow(currentRow, ListView.Contain) pointSizesListView.clicked(currentRow) } } TableView { id: pointSizesListView Layout.fillHeight: true headerVisible: false implicitWidth: (Component.status == Component.Ready) ? (psColumn.width + content.outerSpacing) : (80) Component.onCompleted: resizeColumnsToContents(); TableViewColumn{ id: psColumn; role: ""; title: qsTr("Size") } model: content.pointSizes property bool guard: false function select(row) { if (row == -1 || !guard) return currentRow = row content.font.pointSize = content.pointSizes[row] pointSizeSpinBox.value = content.pointSizes[row] positionViewAtRow(row, ListView.Contain) } onClicked: select(row) onCurrentRowChanged: { select(currentRow) if (!guard) guard = true } } } } RowLayout { spacing: content.spacing Layout.fillHeight: false ColumnLayout { spacing: content.spacing Layout.rowSpan: 3 Label { id: optionsLabel; text: qsTr("Style"); font.bold: true } CheckBox { id: italicCheckBox text: qsTr("Italic") checked: content.font.italic onClicked: { content.font.italic = italicCheckBox.checked } } CheckBox { id: underlineCheckBox text: qsTr("Underline") checked: content.font.underline onClicked: { content.font.underline = underlineCheckBox.checked } } CheckBox { id: overlineCheckBox text: qsTr("Overline") checked: content.font.overline onClicked: { content.font.overline = overlineCheckBox.checked } } CheckBox { id: strikeoutCheckBox text: qsTr("Strikeout") checked: content.font.strikeout onClicked: { content.font.strikeout = strikeoutCheckBox.checked } } Item { Layout.fillHeight: true; } //spacer Label { id: writingSystemLabel; text: qsTr("Writing System"); font.bold: true } } ColumnLayout { Layout.rowSpan: 3 spacing: content.spacing Layout.columnSpan: 2 Layout.fillWidth: true Layout.fillHeight: true Label { id: sampleLabel; text: qsTr("Sample"); font.bold: true } Rectangle { clip: true Layout.fillWidth: true Layout.fillHeight: true implicitWidth: Math.min(360, sample.implicitWidth + parent.spacing) implicitHeight: Math.min(240, sample.implicitHeight + parent.spacing) color: "white" border.color: "#999" TextInput { id: sample activeFocusOnTab: true Accessible.name: text Accessible.role: Accessible.EditableText anchors.centerIn: parent font: content.font onFocusChanged: if (!focus && sample.text == "") sample.text = content.writingSystemSample renderType: Settings.isMobile ? Text.QtRendering : Text.NativeRendering } } } } RowLayout { id: buttonRow Layout.columnSpan: 3 spacing: content.spacing ComboBox { id: wsComboBox function reset() { if (wsModel.count > 0) { currentIndex = 0 } } textRole: "name" model: WritingSystemListModel { id: wsModel Component.onCompleted: wsComboBox.reset() } onCurrentIndexChanged: { if (currentIndex == -1) return content.writingSystem = wsModel.get(currentIndex).name fontModel.writingSystem = content.writingSystem content.writingSystemSample = wsModel.get(currentIndex).sample fontListView.reset() } } Item { Layout.fillWidth: true; } //spacer Button { text: qsTr("Cancel") onClicked: root.reject() } Button { text: qsTr("OK") onClicked: { content.updateUponAccepted() } } } } } }