Port SpellChecking setting page to mobileform

This commit is contained in:
Carl Schwan
2023-04-22 10:30:39 +02:00
parent fc1dc5c1d6
commit 2fb4fdd18f

View File

@@ -7,193 +7,122 @@ import QtQuick.Controls 2.15 as QQC2
import QtQuick.Layouts 1.15 import QtQuick.Layouts 1.15
import org.kde.kirigami 2.15 as Kirigami import org.kde.kirigami 2.15 as Kirigami
import org.kde.sonnet 1.0 as Sonnet import org.kde.sonnet 1.0 as Sonnet
import org.kde.kirigamiaddons.labs.mobileform 0.1 as MobileForm
Kirigami.Page { Kirigami.ScrollablePage {
id: page id: page
/** ColumnLayout {
* This property holds whether the setting on that page are automatically MobileForm.FormCard {
* applied or whether the user can apply then manually. By default, false. id: card
*/
property bool instantApply: false
/**
* This property holds whether the ListViews inside the page should get
* extra padding and a background. By default, use the Kirigami.ApplicationWindow
* wideMode value.
*/
property bool wideMode: QQC2.ApplicationWindow.window.wideMode ?? QQC2.ApplicationWindow.window.width > Kirigami.Units.gridUnit * 40
/**
* Signal emmited when the user decide to discard it's change and close the
* setting page.
*
* For example when using the ConfigPage inside Kirigami PageRow:
*
* \code
* Sonnet.ConfigPage {
* onClose: applicationWindow().pageStack.pop();
* }
* \endcode
*/
signal close()
function onBackRequested(event) {
if (settings.modified) {
applyDialog.open();
event.accepted = true;
}
if (dialog) {
dialog.close();
}
}
title: i18nc("@window:title", "Spellchecking")
QQC2.Dialog {
id: applyDialog
title: qsTr("Apply Settings")
contentItem: QQC2.Label {
text: qsTr("The settings of the current module have changed.<br /> Do you want to apply the changes or discard them?")
}
standardButtons: QQC2.Dialog.Ok | QQC2.Dialog.Cancel | QQC2.Dialog.Discard
onAccepted: {
settings.save();
applyDialog.close();
page.close();
}
onDiscarded: {
applyDialog.close();
page.close();
}
onRejected: applyDialog.close();
}
onWideModeChanged: scroll.background.visible = wideMode;
leftPadding: wideMode ? Kirigami.Units.gridUnit : 0
topPadding: wideMode ? Kirigami.Units.gridUnit : 0
bottomPadding: wideMode ? Kirigami.Units.gridUnit : 0
rightPadding: wideMode ? Kirigami.Units.gridUnit : 0
property var dialog: null
Sonnet.Settings { Sonnet.Settings {
id: settings id: settings
} }
ColumnLayout { Layout.topMargin: Kirigami.Units.largeSpacing
anchors.fill: parent
Kirigami.FormLayout {
Layout.fillWidth: true Layout.fillWidth: true
Layout.leftMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
Layout.rightMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
QQC2.ComboBox { contentItem: ColumnLayout {
Kirigami.FormData.label: i18n("Selected default language:") spacing: 0
model: settings.dictionaryModel MobileForm.FormCardHeader {
textRole: "display" title: i18n("Spellchecking")
valueRole: "languageCode"
Component.onCompleted: currentIndex = indexOfValue(settings.defaultLanguage);
onActivated: {
settings.defaultLanguage = currentValue;
}
} }
QQC2.Button { MobileForm.FormCheckDelegate {
text: i18n("Open Personal Dictionary") id: enable
onClicked: if (!dialog) {
if (Kirigami.Settings.isMobile) {
dialog = mobileSheet.createObject(page, {settings: settings});
dialog.open();
} else {
dialog = desktopSheet.createObject(page, {settings: settings})
dialog.show();
}
} else {
if (Kirigami.Settings.isMobile) {
dialog.open();
} else {
dialog.show();
}
}
}
QQC2.CheckBox {
Kirigami.FormData.label: i18n("Options:")
checked: settings.checkerEnabledByDefault checked: settings.checkerEnabledByDefault
text: i18n("Enable automatic spell checking") text: i18n("Enable automatic spell checking")
onCheckedChanged: { onCheckedChanged: {
settings.checkerEnabledByDefault = checked; settings.checkerEnabledByDefault = checked;
if (instantApply) {
settings.save(); settings.save();
} }
} }
}
QQC2.CheckBox { MobileForm.FormDelegateSeparator { below: enable; above: skipUppercase }
MobileForm.FormCheckDelegate {
id: skipUppercase
checked: settings.skipUppercase checked: settings.skipUppercase
text: i18n("Ignore uppercase words") text: i18n("Ignore uppercase words")
onCheckedChanged: { onCheckedChanged: {
settings.skipUppercase = checked; settings.skipUppercase = checked;
if (instantApply) {
settings.save(); settings.save();
} }
} }
}
QQC2.CheckBox { MobileForm.FormDelegateSeparator { below: skipUppercase; above: skipRunTogether }
MobileForm.FormCheckDelegate {
id: skipRunTogether
checked: settings.skipRunTogether checked: settings.skipRunTogether
text: i18n("Ignore hyphenated words") text: i18n("Ignore hyphenated words")
onCheckedChanged: { onCheckedChanged: {
settings.skipRunTogether = checked; settings.skipRunTogether = checked;
if (instantApply) {
settings.save(); settings.save();
} }
} }
}
QQC2.CheckBox { MobileForm.FormDelegateSeparator { below: skipRunTogether; above: autodetectLanguageCheckbox }
MobileForm.FormCheckDelegate {
id: autodetectLanguageCheckbox id: autodetectLanguageCheckbox
checked: settings.autodetectLanguage checked: settings.autodetectLanguage
text: i18n("Detect language automatically") text: i18n("Detect language automatically")
onCheckedChanged: { onCheckedChanged: {
settings.autodetectLanguage = checked; settings.autodetectLanguage = checked;
if (instantApply) {
settings.save(); settings.save();
} }
} }
MobileForm.FormDelegateSeparator { below: autodetectLanguageCheckbox; above: selectedDefaultLanguage }
MobileForm.FormComboBoxDelegate {
id: selectedDefaultLanguage
text: i18n("Selected default language:")
model: isEmpty ? [{"display": i18n("None")}] : settings.dictionaryModel
textRole: "display"
displayMode: Kirigami.Settings.isMobile ? MobileForm.FormComboBoxDelegate.Dialog : MobileForm.FormComboBoxDelegate.Page
valueRole: "languageCode"
property bool isEmpty: false
Component.onCompleted: {
if (settings.dictionaryModel.rowCount() === 0) {
isEmpty = true;
} else {
currentIndex = indexOfValue(settings.defaultLanguage);
} }
} }
onActivated: settings.defaultLanguage = currentValue;
}
Kirigami.Heading { MobileForm.FormDelegateSeparator { below: selectedDefaultLanguage; above: spellCheckingLanguage }
level: 2
text: i18n("Spell checking languages")
wrapMode: Text.WordWrap
Layout.fillWidth: true
Layout.topMargin: Kirigami.Units.largeSpacing
Layout.leftMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
Layout.rightMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
}
QQC2.Label {
text: i18n("%1 will provide spell checking and suggestions for the languages listed here when autodetection is enabled.", Qt.application.displayName)
wrapMode: Text.WordWrap
Layout.fillWidth: true
Layout.leftMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
Layout.rightMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
}
QQC2.ScrollView { MobileForm.FormButtonDelegate {
id: scroll id: spellCheckingLanguage
Layout.fillWidth: true text: i18n("Additional spell checking languages")
Layout.fillHeight: true description: i18n("%1 will provide spell checking and suggestions for the languages listed here when autodetection is enabled.", Qt.application.displayName)
enabled: autodetectLanguageCheckbox.checked enabled: autodetectLanguageCheckbox.checked
Component.onCompleted: background.visible = wideMode onClicked: pageStack.pushDialogLayer(spellCheckingLanguageList, {}, {
width: pageStack.width - Kirigami.Units.gridUnit * 5,
height: pageStack.height - Kirigami.Units.gridUnit * 5,
})
}
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890) MobileForm.FormDelegateSeparator { below: spellCheckingLanguageList; above: personalDictionary }
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
MobileForm.FormButtonDelegate {
id: personalDictionary
text: i18n("Open Personal Dictionary")
onClicked: pageStack.pushDialogLayer(dictionaryPage, {}, {
width: pageStack.width - Kirigami.Units.gridUnit * 5,
height: pageStack.height - Kirigami.Units.gridUnit * 5,
})
}
Component {
id: spellCheckingLanguageList
Kirigami.ScrollablePage {
id: scroll
title: i18nc("@title:window", "Spell checking languages")
ListView { ListView {
clip: true clip: true
model: settings.dictionaryModel model: settings.dictionaryModel
@@ -202,6 +131,7 @@ Kirigami.Page {
action: Kirigami.Action { action: Kirigami.Action {
onTriggered: model.checked = checked onTriggered: model.checked = checked
} }
Accessible.description: model.isDefault ? i18n("Default Language") : ''
checked: model.checked checked: model.checked
trailing: Kirigami.Icon { trailing: Kirigami.Icon {
source: "favorite" source: "favorite"
@@ -211,7 +141,8 @@ Kirigami.Page {
} }
QQC2.ToolTip { QQC2.ToolTip {
visible: hover.hovered visible: hover.hovered
text: qsTr("Default Language") text: i18n("Default Language")
}
} }
} }
} }
@@ -219,10 +150,16 @@ Kirigami.Page {
} }
} }
component SheetHeader : RowLayout { Component {
id: dictionaryPage
Kirigami.ScrollablePage {
title: i18n("Spell checking dictionary")
footer: QQC2.ToolBar {
contentItem: RowLayout {
QQC2.TextField { QQC2.TextField {
id: dictionaryField id: dictionaryField
Layout.fillWidth: true Layout.fillWidth: true
Accessible.name: placeholderText
placeholderText: i18n("Add a new word to your personal dictionary…") placeholderText: i18n("Add a new word to your personal dictionary…")
} }
QQC2.Button { QQC2.Button {
@@ -239,29 +176,7 @@ Kirigami.Page {
Layout.rightMargin: Kirigami.Units.largeSpacing Layout.rightMargin: Kirigami.Units.largeSpacing
} }
} }
Component {
id: desktopSheet
QQC2.ApplicationWindow {
id: window
required property Sonnet.Settings settings
title: i18n("Spell checking dictionary")
width: Kirigami.Units.gridUnit * 20
height: Kirigami.Units.gridUnit * 20
flags: Qt.Dialog | Qt.WindowCloseButtonHint
header: Kirigami.AbstractApplicationHeader {
leftPadding: Kirigami.Units.smallSpacing
rightPadding: Kirigami.Units.smallSpacing
contentItem: SheetHeader {
anchors.fill: parent
} }
}
QQC2.ScrollView {
anchors.fill: parent
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
ListView { ListView {
model: settings.currentIgnoreList model: settings.currentIgnoreList
delegate: Kirigami.BasicListItem { delegate: Kirigami.BasicListItem {
@@ -282,63 +197,18 @@ Kirigami.Page {
} }
} }
} }
}
Component { function add(word: string) {
id: mobileSheet
Kirigami.OverlaySheet {
required property Sonnet.Settings settings
id: dictionarySheet
header: SheetHeader {}
ListView {
implicitWidth: Kirigami.Units.gridUnit * 15
model: settings.currentIgnoreList
delegate: Kirigami.BasicListItem {
label: model.modelData
trailing: QQC2.ToolButton {
icon.name: "delete"
onClicked: {
remove(modelData)
if (instantApply) {
settings.save();
}
}
QQC2.ToolTip {
text: i18n("Delete word")
}
}
}
}
}
}
footer: QQC2.ToolBar {
visible: !instantApply
height: visible ? implicitHeight : 0
contentItem: RowLayout {
Item {
Layout.fillWidth: true
}
QQC2.Button {
text: i18n("Apply")
enabled: settings.modified
onClicked: settings.save();
}
}
}
function add(word) {
const dictionary = settings.currentIgnoreList; const dictionary = settings.currentIgnoreList;
dictionary.push(word); dictionary.push(word);
settings.currentIgnoreList = dictionary; settings.currentIgnoreList = dictionary;
} }
function remove(word) { function remove(word: string) {
settings.currentIgnoreList = settings.currentIgnoreList.filter(function (value, _, _) { settings.currentIgnoreList = settings.currentIgnoreList.filter((value, _, _) => {
return value !== word; return value !== word;
}); });
} }
} }
}
}