Move QML files to src/qml and don't use internal qml modules
This commit is contained in:
12
src/qml/Settings/About.qml
Normal file
12
src/qml/Settings/About.qml
Normal file
@@ -0,0 +1,12 @@
|
||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.AboutPage {
|
||||
title: i18nc("@title:window", "About NeoChat")
|
||||
aboutData: Controller.aboutData
|
||||
}
|
||||
136
src/qml/Settings/AccountEditorPage.qml
Normal file
136
src/qml/Settings/AccountEditorPage.qml
Normal file
@@ -0,0 +1,136 @@
|
||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
// SPDX-FileCopyrightText: 2022 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as Controls
|
||||
import QtQuick.Layouts 1.15
|
||||
import Qt.labs.platform 1.1
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
id: root
|
||||
title: i18n("Edit Account")
|
||||
property var connection
|
||||
|
||||
ColumnLayout {
|
||||
Kirigami.FormLayout {
|
||||
RowLayout {
|
||||
Kirigami.Avatar {
|
||||
id: avatar
|
||||
source: root.connection && root.connection.localUser.avatarMediaId ? ("image://mxc/" + root.connection.localUser.avatarMediaId) : ""
|
||||
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
anchors.fill: parent
|
||||
property var fileDialog: null;
|
||||
onClicked: {
|
||||
if (fileDialog != null) {
|
||||
return;
|
||||
}
|
||||
|
||||
fileDialog = openFileDialog.createObject(Controls.ApplicationWindow.Overlay)
|
||||
|
||||
fileDialog.chosen.connect(function(receivedSource) {
|
||||
mouseArea.fileDialog = null;
|
||||
if (!receivedSource) {
|
||||
return;
|
||||
}
|
||||
parent.source = receivedSource;
|
||||
});
|
||||
fileDialog.onRejected.connect(function() {
|
||||
mouseArea.fileDialog = null;
|
||||
});
|
||||
fileDialog.open();
|
||||
}
|
||||
}
|
||||
}
|
||||
Controls.Button {
|
||||
visible: avatar.source.toString().length !== 0
|
||||
icon.name: "edit-clear"
|
||||
|
||||
onClicked: avatar.source = ""
|
||||
}
|
||||
Kirigami.FormData.label: i18n("Avatar:")
|
||||
}
|
||||
Controls.TextField {
|
||||
id: name
|
||||
text: root.connection ? root.connection.localUser.displayName : ""
|
||||
Kirigami.FormData.label: i18n("Name:")
|
||||
}
|
||||
Controls.TextField {
|
||||
id: accountLabel
|
||||
text: root.connection ? root.connection.localUser.accountLabel : ""
|
||||
Kirigami.FormData.label: i18n("Label:")
|
||||
}
|
||||
Controls.TextField {
|
||||
id: currentPassword
|
||||
Kirigami.FormData.label: i18n("Current Password:")
|
||||
enabled: roto.connection !== undefined && root.connection.canChangePassword !== false
|
||||
echoMode: TextInput.Password
|
||||
}
|
||||
Controls.TextField {
|
||||
id: newPassword
|
||||
Kirigami.FormData.label: i18n("New Password:")
|
||||
enabled: root.connection !== undefined && root.connection.canChangePassword !== false
|
||||
echoMode: TextInput.Password
|
||||
|
||||
}
|
||||
Controls.TextField {
|
||||
id: confirmPassword
|
||||
Kirigami.FormData.label: i18n("Confirm new Password:")
|
||||
enabled: root.connection !== undefined && root.connection.canChangePassword !== false
|
||||
echoMode: TextInput.Password
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: RowLayout {
|
||||
Item {
|
||||
Layout.fillWidth: true
|
||||
}
|
||||
|
||||
Controls.Button {
|
||||
text: i18n("Save")
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
onClicked: {
|
||||
if (!Controller.setAvatar(root.connection, avatar.source)) {
|
||||
showPassiveNotification("The Avatar could not be set");
|
||||
}
|
||||
if (root.connection.localUser.displayName !== name.text) {
|
||||
root.connection.localUser.rename(name.text);
|
||||
}
|
||||
if (root.connection.localUser.accountLabel !== accountLabel.text) {
|
||||
root.connection.localUser.setAccountLabel(accountLabel.text);
|
||||
}
|
||||
if(currentPassword.text !== "" && newPassword.text !== "" && confirmPassword.text !== "") {
|
||||
if(newPassword.text === confirmPassword.text) {
|
||||
Controller.changePassword(root.connection, currentPassword.text, newPassword.text);
|
||||
} else {
|
||||
showPassiveNotification(i18n("Passwords do not match"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
root.closeDialog();
|
||||
}
|
||||
}
|
||||
Controls.Button {
|
||||
text: i18n("Cancel")
|
||||
Layout.rightMargin: Kirigami.Units.smallSpacing
|
||||
Layout.bottomMargin: Kirigami.Units.smallSpacing
|
||||
Layout.topMargin: Kirigami.Units.smallSpacing
|
||||
onClicked: root.closeDialog();
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: openFileDialog
|
||||
|
||||
OpenFileDialog {
|
||||
folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
|
||||
}
|
||||
}
|
||||
}
|
||||
104
src/qml/Settings/AccountsPage.qml
Normal file
104
src/qml/Settings/AccountsPage.qml
Normal file
@@ -0,0 +1,104 @@
|
||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as Controls
|
||||
import QtQuick.Layouts 1.15
|
||||
import Qt.labs.platform 1.1
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18n("Accounts")
|
||||
|
||||
actions.main: Kirigami.Action {
|
||||
text: i18n("Add an account")
|
||||
icon.name: "list-add-user"
|
||||
onTriggered: pageStack.layers.push("qrc:/WelcomePage.qml")
|
||||
visible: !pageSettingStack.wideMode
|
||||
}
|
||||
|
||||
ListView {
|
||||
model: AccountRegistry
|
||||
anchors.fill: parent
|
||||
delegate: Kirigami.BasicListItem {
|
||||
text: model.connection.localUser.displayName
|
||||
labelItem.textFormat: Text.PlainText
|
||||
subtitle: model.connection.localUserId
|
||||
icon: model.connection.localUser.avatarMediaId ? ("image://mxc/" + model.connection.localUser.avatarMediaId) : "im-user"
|
||||
|
||||
onClicked: {
|
||||
Controller.activeConnection = model.connection;
|
||||
pageStack.layers.pop();
|
||||
}
|
||||
|
||||
trailing: RowLayout {
|
||||
Controls.ToolButton {
|
||||
display: Controls.AbstractButton.IconOnly
|
||||
Controls.ToolTip {
|
||||
text: parent.action.text
|
||||
}
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Edit this account")
|
||||
iconName: "document-edit"
|
||||
onTriggered: pageSettingStack.pushDialogLayer(Qt.resolvedUrl('./AccountEditorPage.qml'), {
|
||||
connection: model.connection
|
||||
}, {
|
||||
title: i18n("Account editor")
|
||||
});
|
||||
}
|
||||
}
|
||||
Controls.ToolButton {
|
||||
display: Controls.AbstractButton.IconOnly
|
||||
Controls.ToolTip {
|
||||
text: parent.action.text
|
||||
}
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Logout")
|
||||
iconName: "im-kick-user"
|
||||
onTriggered: {
|
||||
Controller.logout(model.connection, true);
|
||||
if (Controller.accountCount === 1) {
|
||||
pageStack.layers.pop();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: Controls.ToolBar {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
Kirigami.ActionToolBar {
|
||||
alignment: Qt.AlignRight
|
||||
rightPadding: Kirigami.Units.smallSpacing
|
||||
width: parent.width
|
||||
flat: false
|
||||
actions: Kirigami.Action {
|
||||
text: i18n("Add an account")
|
||||
icon.name: "list-add-user"
|
||||
onTriggered: pageStack.layers.push("qrc:/WelcomePage.qml")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: Controller
|
||||
function onConnectionAdded() {
|
||||
if (pageStack.layers.depth > 2)
|
||||
pageStack.layers.pop()
|
||||
}
|
||||
function onPasswordStatus(status) {
|
||||
if (status === Controller.Success) {
|
||||
showPassiveNotification(i18n("Password changed successfully"));
|
||||
} else if (status === Controller.Wrong) {
|
||||
showPassiveNotification(i18n("Wrong password entered"));
|
||||
} else {
|
||||
showPassiveNotification(i18n("Unknown problem while trying to change password"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
264
src/qml/Settings/AppearanceSettingsPage.qml
Normal file
264
src/qml/Settings/AppearanceSettingsPage.qml
Normal file
@@ -0,0 +1,264 @@
|
||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18nc("@title:window", "Appearance")
|
||||
ColumnLayout {
|
||||
RowLayout {
|
||||
Layout.alignment: Qt.AlignCenter
|
||||
spacing: Kirigami.Units.gridUnit * 2
|
||||
QQC2.ButtonGroup { id: themeGroup }
|
||||
ThemeRadioButton {
|
||||
innerObject: [
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Kirigami.Avatar {
|
||||
color: "#4a5bcc"
|
||||
Layout.alignment: Qt.AlignTop
|
||||
visible: Config.showAvatarInTimeline
|
||||
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
|
||||
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
|
||||
}
|
||||
QQC2.Control {
|
||||
Layout.fillWidth: true
|
||||
contentItem: ColumnLayout {
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 7
|
||||
text: "Paul Müller"
|
||||
color: "#4a5bcc"
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt."
|
||||
wrapMode: Text.Wrap
|
||||
font.pixelSize: 7
|
||||
}
|
||||
}
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
shadow.size: Kirigami.Units.smallSpacing
|
||||
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
|
||||
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
|
||||
border.width: 1
|
||||
}
|
||||
}
|
||||
},
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Kirigami.Avatar {
|
||||
color: "#9f244b"
|
||||
Layout.alignment: Qt.AlignTop
|
||||
visible: Config.showAvatarInTimeline
|
||||
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
|
||||
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
|
||||
}
|
||||
QQC2.Control {
|
||||
Layout.fillWidth: true
|
||||
contentItem: ColumnLayout {
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 7
|
||||
text: "Jean Paul"
|
||||
color: "#9f244b"
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta , quis sem suscipit tincidunt."
|
||||
wrapMode: Text.Wrap
|
||||
font.pixelSize: 7
|
||||
}
|
||||
}
|
||||
background: Kirigami.ShadowedRectangle {
|
||||
color: Kirigami.Theme.backgroundColor
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
shadow.size: Kirigami.Units.smallSpacing
|
||||
shadow.color: Qt.rgba(0.0, 0.0, 0.0, 0.10)
|
||||
border.color: Kirigami.ColorUtils.tintWithAlpha(color, Kirigami.Theme.textColor, 0.15)
|
||||
border.width: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
text: i18n("Bubbles")
|
||||
checked: !Config.compactLayout
|
||||
QQC2.ButtonGroup.group: themeGroup
|
||||
enabled: !Config.isCompactLayoutImmutable
|
||||
|
||||
onToggled: {
|
||||
Config.compactLayout = !checked;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
ThemeRadioButton {
|
||||
innerObject: [
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Kirigami.Avatar {
|
||||
color: "#4a5bcc"
|
||||
Layout.alignment: Qt.AlignTop
|
||||
visible: Config.showAvatarInTimeline
|
||||
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
|
||||
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 7
|
||||
text: "Paul Müller"
|
||||
color: "#4a5bcc"
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
text: "Lorem ipsum dolor sit amet, consectetur elit. Vivamus facilisis porta mauris, finibus sem suscipit tincidunt."
|
||||
wrapMode: Text.Wrap
|
||||
font.pixelSize: 7
|
||||
}
|
||||
}
|
||||
},
|
||||
RowLayout {
|
||||
Layout.fillWidth: true
|
||||
Kirigami.Avatar {
|
||||
color: "#9f244b"
|
||||
Layout.alignment: Qt.AlignTop
|
||||
visible: Config.showAvatarInTimeline
|
||||
Layout.preferredWidth: Config.showAvatarInTimeline ? Kirigami.Units.largeSpacing * 2 : 0
|
||||
Layout.preferredHeight: Kirigami.Units.largeSpacing * 2
|
||||
}
|
||||
ColumnLayout {
|
||||
Layout.fillWidth: true
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
font.weight: Font.Bold
|
||||
font.pixelSize: 7
|
||||
text: "Jean Paul"
|
||||
color: "#9f244b"
|
||||
wrapMode: Text.Wrap
|
||||
}
|
||||
QQC2.Label {
|
||||
Layout.fillWidth: true
|
||||
text: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Vivamus facilisis porta mauris, quis finibus sem suscipit tincidunt."
|
||||
wrapMode: Text.Wrap
|
||||
font.pixelSize: 7
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
text: i18n("Compact")
|
||||
checked: Config.compactLayout
|
||||
QQC2.ButtonGroup.group: themeGroup
|
||||
enabled: !Config.isCompactLayoutImmutable
|
||||
|
||||
onToggled: {
|
||||
Config.compactLayout = checked;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
Kirigami.FormLayout {
|
||||
Layout.maximumWidth: parent.width
|
||||
QQC2.CheckBox {
|
||||
Kirigami.FormData.label: i18n("Show Avatar:")
|
||||
text: i18n("In Chat")
|
||||
checked: Config.showAvatarInTimeline
|
||||
onToggled: {
|
||||
Config.showAvatarInTimeline = checked
|
||||
Config.save()
|
||||
}
|
||||
enabled: !Config.isShowAvatarInTimelineImmutable
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("In Sidebar")
|
||||
checked: Config.showAvatarInRoomDrawer
|
||||
enabled: !Config.isShowAvatarInRoomDrawerImmutable
|
||||
onToggled: {
|
||||
Config.showAvatarInRoomDrawer = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Show Fancy Effects")
|
||||
checked: Config.showFancyEffects
|
||||
enabled: !Config.isShowFancyEffectsImmutable
|
||||
onToggled: {
|
||||
Config.showFancyEffects = checked;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
visible: item !== null
|
||||
Kirigami.FormData.label: item ? i18n("Theme:") : ""
|
||||
source: "qrc:/ColorScheme.qml"
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
visible: Controller.hasWindowSystem
|
||||
text: i18n("Use transparent chat page")
|
||||
enabled: !Config.compactLayout && !Config.isBlurImmutable
|
||||
checked: Config.blur
|
||||
onToggled: {
|
||||
Config.blur = checked;
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
RowLayout {
|
||||
visible: Controller.hasWindowSystem && Config.blur
|
||||
enabled: !Config.isTransparancyImmutable
|
||||
Kirigami.FormData.label: i18n("Transparency:")
|
||||
QQC2.Slider {
|
||||
enabled: !Config.compactLayout && Config.blur
|
||||
from: 0
|
||||
to: 1
|
||||
stepSize: 0.05
|
||||
value: Config.transparency
|
||||
onMoved: {
|
||||
Config.transparency = value;
|
||||
Config.save();
|
||||
}
|
||||
|
||||
HoverHandler { id: sliderHover }
|
||||
QQC2.ToolTip.visible: sliderHover.hovered && !enabled
|
||||
QQC2.ToolTip.text: i18n("Only enabled if the transparent chat page is enabled.")
|
||||
QQC2.ToolTip.delay: Kirigami.Units.toolTipDelay
|
||||
}
|
||||
QQC2.Label {
|
||||
text: Math.round(Config.transparency * 100) + "%"
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Show your messages on the right")
|
||||
checked: Config.showLocalMessagesOnRight
|
||||
enabled: !Config.isShowLocalMessagesOnRightImmutable && !Config.compactLayout
|
||||
onToggled: {
|
||||
Config.showLocalMessagesOnRight = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Show links preview in the chat messages")
|
||||
checked: Config.showLinkPreview
|
||||
onToggled: {
|
||||
Config.showLinkPreview = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
21
src/qml/Settings/ColorScheme.qml
Normal file
21
src/qml/Settings/ColorScheme.qml
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-FileCopyrightText: 2020 Carl Schwan <carlschwan@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
QQC2.ComboBox {
|
||||
textRole: "display"
|
||||
model: ColorSchemer.model
|
||||
Component.onCompleted: currentIndex = ColorSchemer.indexForScheme(Config.colorScheme);
|
||||
onActivated: {
|
||||
ColorSchemer.apply(currentIndex);
|
||||
Config.colorScheme = ColorSchemer.nameForIndex(currentIndex);
|
||||
Config.save();
|
||||
}
|
||||
}
|
||||
114
src/qml/Settings/DevicesPage.qml
Normal file
114
src/qml/Settings/DevicesPage.qml
Normal file
@@ -0,0 +1,114 @@
|
||||
// SPDX-FileCopyrightText: Tobias Fella <fella@posteo.de>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as Controls
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.19 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18n("Devices")
|
||||
|
||||
ListView {
|
||||
model: DevicesModel {
|
||||
id: devices
|
||||
}
|
||||
|
||||
anchors.fill: parent
|
||||
|
||||
Kirigami.LoadingPlaceholder {
|
||||
visible: parent.count === 0 // We can assume 0 means loading since there is at least one device
|
||||
anchors.centerIn: parent
|
||||
}
|
||||
|
||||
delegate: Kirigami.BasicListItem {
|
||||
text: model.displayName
|
||||
subtitle: model.id
|
||||
icon: "network-connect"
|
||||
trailing: RowLayout {
|
||||
Controls.ToolButton {
|
||||
display: Controls.AbstractButton.IconOnly
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Edit device name")
|
||||
iconName: "document-edit"
|
||||
onTriggered: {
|
||||
renameSheet.index = model.index
|
||||
renameSheet.name = model.displayName
|
||||
renameSheet.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
Controls.ToolButton {
|
||||
display: Controls.AbstractButton.IconOnly
|
||||
visible: Controller.encryptionSupported
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Verify device")
|
||||
iconName: "security-low-symbolic"
|
||||
onTriggered: {
|
||||
devices.connection.startKeyVerificationSession(model.id)
|
||||
}
|
||||
}
|
||||
}
|
||||
Controls.ToolButton {
|
||||
display: Controls.AbstractButton.IconOnly
|
||||
action: Kirigami.Action {
|
||||
text: i18n("Logout device")
|
||||
iconName: "edit-delete-remove"
|
||||
onTriggered: {
|
||||
passwordSheet.index = index
|
||||
passwordSheet.open()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: passwordSheet
|
||||
|
||||
property var index
|
||||
|
||||
title: i18n("Remove device")
|
||||
Kirigami.FormLayout {
|
||||
Controls.TextField {
|
||||
id: passwordField
|
||||
Kirigami.FormData.label: i18n("Password:")
|
||||
echoMode: TextInput.Password
|
||||
}
|
||||
Controls.Button {
|
||||
text: i18n("Confirm")
|
||||
onClicked: {
|
||||
devices.logout(passwordSheet.index, passwordField.text)
|
||||
passwordField.text = ""
|
||||
passwordSheet.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.OverlaySheet {
|
||||
id: renameSheet
|
||||
property int index
|
||||
property string name
|
||||
|
||||
title: i18n("Edit device")
|
||||
Kirigami.FormLayout {
|
||||
Controls.TextField {
|
||||
id: nameField
|
||||
Kirigami.FormData.label: i18n("Name:")
|
||||
text: renameSheet.name
|
||||
}
|
||||
Controls.Button {
|
||||
text: i18n("Save")
|
||||
onClicked: {
|
||||
devices.setName(renameSheet.index, nameField.text)
|
||||
renameSheet.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
115
src/qml/Settings/Emoticons.qml
Normal file
115
src/qml/Settings/Emoticons.qml
Normal file
@@ -0,0 +1,115 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carson Black <uhhadd@gmail.com>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import Qt.labs.platform 1.1
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18nc("@title:window", "Custom Emojis")
|
||||
|
||||
ListView {
|
||||
anchors.fill: parent
|
||||
|
||||
model: CustomEmojiModel
|
||||
|
||||
Kirigami.PlaceholderMessage {
|
||||
anchors.centerIn: parent
|
||||
text: i18n("No custom inline stickers found")
|
||||
visible: parent.model.count === 0
|
||||
}
|
||||
|
||||
delegate: Kirigami.BasicListItem {
|
||||
id: del
|
||||
|
||||
required property string name
|
||||
required property url imageURL
|
||||
|
||||
text: name
|
||||
reserveSpaceForSubtitle: true
|
||||
|
||||
leading: Image {
|
||||
width: height
|
||||
sourceSize.width: width
|
||||
sourceSize.height: height
|
||||
source: imageURL
|
||||
|
||||
Rectangle {
|
||||
anchors.fill: parent
|
||||
visible: parent.status === Image.Loading
|
||||
radius: height/2
|
||||
gradient: ShimmerGradient { }
|
||||
}
|
||||
}
|
||||
|
||||
trailing: QQC2.ToolButton {
|
||||
width: height
|
||||
icon.name: "delete"
|
||||
onClicked: emojiModel.removeEmoji(del.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
footer: QQC2.ToolBar {
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.Window
|
||||
Kirigami.ActionToolBar {
|
||||
id: emojiCreator
|
||||
alignment: Qt.AlignRight
|
||||
rightPadding: Kirigami.Units.smallSpacing
|
||||
width: parent.width
|
||||
flat: false
|
||||
property string name
|
||||
actions: [
|
||||
Kirigami.Action {
|
||||
displayComponent: QQC2.TextField {
|
||||
id: emojiField
|
||||
placeholderText: i18n("new_emoji_name_here")
|
||||
|
||||
validator: RegularExpressionValidator {
|
||||
regularExpression: /[a-zA-Z_0-9]*/
|
||||
}
|
||||
onTextChanged: emojiCreator.name = text
|
||||
}
|
||||
},
|
||||
Kirigami.Action {
|
||||
text: i18n("Add Emoji...")
|
||||
|
||||
enabled: emojiCreator.name.length > 0
|
||||
property var fileDialog: null
|
||||
icon.name: 'list-add'
|
||||
|
||||
onTriggered: {
|
||||
if (this.fileDialog !== null) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.fileDialog = openFileDialog.createObject(QQC2.Overlay.overlay)
|
||||
|
||||
this.fileDialog.chosen.connect((url) => {
|
||||
CustomEmojiModel.addEmoji(emojiCreator.name, url)
|
||||
this.fileDialog = null
|
||||
})
|
||||
this.fileDialog.onRejected.connect(() => {
|
||||
this.fileDialog = null
|
||||
})
|
||||
this.fileDialog.open()
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
id: openFileDialog
|
||||
|
||||
OpenFileDialog {
|
||||
folder: StandardPaths.writableLocation(StandardPaths.PicturesLocation)
|
||||
}
|
||||
}
|
||||
}
|
||||
136
src/qml/Settings/GeneralSettingsPage.qml
Normal file
136
src/qml/Settings/GeneralSettingsPage.qml
Normal file
@@ -0,0 +1,136 @@
|
||||
// SPDX-FileCopyrightText: 2020 Tobias Fella <fella@posteo.de>
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carl@carlschwan.eu>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
import org.kde.neochat 1.0
|
||||
|
||||
Kirigami.ScrollablePage {
|
||||
title: i18nc("@title:window", "General")
|
||||
ColumnLayout {
|
||||
Kirigami.FormLayout {
|
||||
Layout.fillWidth: true
|
||||
QQC2.CheckBox {
|
||||
Kirigami.FormData.label: i18n("General settings:")
|
||||
text: i18n("Close to system tray")
|
||||
checked: Config.systemTray
|
||||
visible: Controller.supportSystemTray
|
||||
enabled: !Config.isSystemTrayImmutable
|
||||
onToggled: {
|
||||
Config.systemTray = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Minimize to system tray on startup")
|
||||
checked: Config.minimizeToSystemTrayOnStartup
|
||||
visible: Controller.supportSystemTray && !Kirigami.Settings.isMobile
|
||||
enabled: Config.systemTray && !Config.isMinimizeToSystemTrayOnStartupImmutable
|
||||
onToggled: {
|
||||
Config.minimizeToSystemTrayOnStartup = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
// TODO: When there are enough notification and timeline event
|
||||
// settings, make 2 separate groups with FormData labels.
|
||||
Kirigami.FormData.label: i18n("Notifications and events:")
|
||||
text: i18n("Show notifications")
|
||||
checked: Config.showNotifications
|
||||
enabled: !Config.isShowNotificationsImmutable
|
||||
onToggled: {
|
||||
Config.showNotifications = checked
|
||||
Config.save()
|
||||
NotificationsManager.globalNotificationsEnabled = checked
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Show leave and join events")
|
||||
checked: Config.showLeaveJoinEvent
|
||||
enabled: !Config.isShowLeaveJoinEventImmutable
|
||||
onToggled: {
|
||||
Config.showLeaveJoinEvent = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Show name change events")
|
||||
checked: Config.showRename
|
||||
enabled: !Config.isShowRenameImmutable
|
||||
onToggled: {
|
||||
Config.showRename = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Show avatar update events")
|
||||
checked: Config.showAvatarUpdate
|
||||
enabled: !Config.isShowAvatarUpdateImmutable
|
||||
onToggled: {
|
||||
Config.showAvatarUpdate = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.RadioButton {
|
||||
Kirigami.FormData.label: i18n("Rooms and private chats:")
|
||||
text: i18n("Separated")
|
||||
checked: !Config.mergeRoomList
|
||||
enabled: !Config.isMergeRoomListImmutable
|
||||
onToggled: {
|
||||
Config.mergeRoomList = false
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.RadioButton {
|
||||
text: i18n("Intermixed")
|
||||
checked: Config.mergeRoomList
|
||||
enabled: !Config.isMergeRoomListImmutable
|
||||
onToggled: {
|
||||
Config.mergeRoomList = true
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
id: quickEditCheckbox
|
||||
Layout.maximumWidth: parent.width
|
||||
text: i18n("Use s/text/replacement syntax to edit your last message")
|
||||
checked: Config.allowQuickEdit
|
||||
enabled: !Config.isAllowQuickEditImmutable
|
||||
onToggled: {
|
||||
Config.allowQuickEdit = checked
|
||||
Config.save()
|
||||
}
|
||||
|
||||
// TODO KF5.97 remove this line
|
||||
Component.onCompleted: this.contentItem.wrap = QQC2.Label.Wrap
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Send Typing Notifications")
|
||||
checked: Config.typingNotifications
|
||||
enabled: !Config.isTypingNotificationsImmutable
|
||||
onToggled: {
|
||||
Config.typingNotifications = checked
|
||||
Config.save()
|
||||
}
|
||||
}
|
||||
QQC2.CheckBox {
|
||||
text: i18n("Automatically hide/unhide the room information when resizing the window")
|
||||
Layout.maximumWidth: parent.width
|
||||
checked: Config.autoRoomInfoDrawer
|
||||
enabled: !Config.isAutoRoomInfoDrawerImmutable
|
||||
onToggled: {
|
||||
Config.autoRoomInfoDrawer = checked
|
||||
Config.save()
|
||||
}
|
||||
|
||||
// TODO KF5.97 remove this line
|
||||
Component.onCompleted: this.contentItem.wrap = QQC2.Label.Wrap
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
47
src/qml/Settings/SettingsPage.qml
Normal file
47
src/qml/Settings/SettingsPage.qml
Normal file
@@ -0,0 +1,47 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import org.kde.kirigami 2.18 as Kirigami
|
||||
import QtQuick.Layouts 1.15
|
||||
|
||||
Kirigami.CategorizedSettings {
|
||||
objectName: "settingsPage"
|
||||
actions: [
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("General")
|
||||
icon.name: "org.kde.neochat"
|
||||
page: Qt.resolvedUrl("GeneralSettingsPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Appearance")
|
||||
icon.name: "preferences-desktop-theme-global"
|
||||
page: Qt.resolvedUrl("AppearanceSettingsPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Accounts")
|
||||
icon.name: "preferences-system-users"
|
||||
page: Qt.resolvedUrl("AccountsPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Custom Emojis")
|
||||
icon.name: "preferences-desktop-emoticons"
|
||||
page: Qt.resolvedUrl("Emoticons.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Spell Checking")
|
||||
iconName: "tools-check-spelling"
|
||||
page: Qt.resolvedUrl("SonnetConfigPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("Devices")
|
||||
iconName: "network-connect"
|
||||
page: Qt.resolvedUrl("DevicesPage.qml")
|
||||
},
|
||||
Kirigami.SettingAction {
|
||||
text: i18n("About NeoChat")
|
||||
icon.name: "help-about"
|
||||
page: Qt.resolvedUrl("About.qml")
|
||||
}
|
||||
]
|
||||
}
|
||||
344
src/qml/Settings/SonnetConfigPage.qml
Normal file
344
src/qml/Settings/SonnetConfigPage.qml
Normal file
@@ -0,0 +1,344 @@
|
||||
// SPDX-FileCopyrightText: 2021 Carl Schwan <carlschwan@kde.org>
|
||||
// SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
|
||||
import QtQml 2.15
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
import org.kde.sonnet 1.0 as Sonnet
|
||||
|
||||
Kirigami.Page {
|
||||
id: page
|
||||
|
||||
/**
|
||||
* This property holds whether the setting on that page are automatically
|
||||
* applied or whether the user can apply then manually. By default, false.
|
||||
*/
|
||||
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 {
|
||||
id: settings
|
||||
}
|
||||
|
||||
ColumnLayout {
|
||||
anchors.fill: parent
|
||||
|
||||
Kirigami.FormLayout {
|
||||
Layout.fillWidth: true
|
||||
Layout.leftMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
|
||||
Layout.rightMargin: wideMode ? 0 : Kirigami.Units.largeSpacing
|
||||
|
||||
QQC2.ComboBox {
|
||||
Kirigami.FormData.label: i18n("Selected default language:")
|
||||
model: settings.dictionaryModel
|
||||
textRole: "display"
|
||||
valueRole: "languageCode"
|
||||
Component.onCompleted: currentIndex = indexOfValue(settings.defaultLanguage);
|
||||
onActivated: {
|
||||
settings.defaultLanguage = currentValue;
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.Button {
|
||||
text: i18n("Open Personal Dictionary")
|
||||
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
|
||||
text: i18n("Enable automatic spell checking")
|
||||
onCheckedChanged: {
|
||||
settings.checkerEnabledByDefault = checked;
|
||||
if (instantApply) {
|
||||
settings.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.CheckBox {
|
||||
checked: settings.skipUppercase
|
||||
text: i18n("Ignore uppercase words")
|
||||
onCheckedChanged: {
|
||||
settings.skipUppercase = checked;
|
||||
if (instantApply) {
|
||||
settings.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.CheckBox {
|
||||
checked: settings.skipRunTogether
|
||||
text: i18n("Ignore hyphenated words")
|
||||
onCheckedChanged: {
|
||||
settings.skipRunTogether = checked;
|
||||
if (instantApply) {
|
||||
settings.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.CheckBox {
|
||||
id: autodetectLanguageCheckbox
|
||||
checked: settings.autodetectLanguage
|
||||
text: i18n("Detect language automatically")
|
||||
onCheckedChanged: {
|
||||
settings.autodetectLanguage = checked;
|
||||
if (instantApply) {
|
||||
settings.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Kirigami.Heading {
|
||||
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 {
|
||||
id: scroll
|
||||
Layout.fillWidth: true
|
||||
Layout.fillHeight: true
|
||||
enabled: autodetectLanguageCheckbox.checked
|
||||
Component.onCompleted: background.visible = wideMode
|
||||
|
||||
// HACK: Hide unnecessary horizontal scrollbar (https://bugreports.qt.io/browse/QTBUG-83890)
|
||||
QQC2.ScrollBar.horizontal.policy: QQC2.ScrollBar.AlwaysOff
|
||||
|
||||
ListView {
|
||||
clip: true
|
||||
model: settings.dictionaryModel
|
||||
delegate: Kirigami.CheckableListItem {
|
||||
label: model.display
|
||||
action: Kirigami.Action {
|
||||
onTriggered: model.checked = checked
|
||||
}
|
||||
checked: model.checked
|
||||
trailing: Kirigami.Icon {
|
||||
source: "favorite"
|
||||
visible: model.isDefault
|
||||
HoverHandler {
|
||||
id: hover
|
||||
}
|
||||
QQC2.ToolTip {
|
||||
visible: hover.hovered
|
||||
text: qsTr("Default Language")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
component SheetHeader : RowLayout {
|
||||
QQC2.TextField {
|
||||
id: dictionaryField
|
||||
Layout.fillWidth: true
|
||||
placeholderText: i18n("Add a new word to your personal dictionary…")
|
||||
}
|
||||
QQC2.Button {
|
||||
text: i18nc("@action:button", "Add word")
|
||||
icon.name: "list-add"
|
||||
enabled: dictionaryField.text.length > 0
|
||||
onClicked: {
|
||||
add(dictionaryField.text);
|
||||
dictionaryField.clear();
|
||||
if (instantApply) {
|
||||
settings.save();
|
||||
}
|
||||
}
|
||||
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 {
|
||||
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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Component {
|
||||
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;
|
||||
dictionary.push(word);
|
||||
settings.currentIgnoreList = dictionary;
|
||||
}
|
||||
|
||||
function remove(word) {
|
||||
settings.currentIgnoreList = settings.currentIgnoreList.filter(function (value, _, _) {
|
||||
return value !== word;
|
||||
});
|
||||
}
|
||||
}
|
||||
65
src/qml/Settings/ThemeRadioButton.qml
Normal file
65
src/qml/Settings/ThemeRadioButton.qml
Normal file
@@ -0,0 +1,65 @@
|
||||
// Copyright 2021 Marco Martin <mart@kde.org>
|
||||
// Copyright 2018 Furkan Tokac <furkantokac34@gmail.com>
|
||||
// Copyright 2019 Nate Graham <nate@kde.org>
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
|
||||
import QtQuick 2.15
|
||||
import QtQuick.Controls 2.15 as QQC2
|
||||
import QtQuick.Layouts 1.15
|
||||
import org.kde.kirigami 2.15 as Kirigami
|
||||
|
||||
QQC2.RadioButton {
|
||||
id: delegate
|
||||
|
||||
implicitWidth: contentItem.implicitWidth
|
||||
implicitHeight: contentItem.implicitHeight
|
||||
|
||||
property alias innerObject: contentLayout.children
|
||||
|
||||
contentItem: ColumnLayout {
|
||||
Kirigami.ShadowedRectangle {
|
||||
implicitWidth: implicitHeight * 1.6
|
||||
implicitHeight: Kirigami.Units.gridUnit * 6
|
||||
radius: Kirigami.Units.smallSpacing
|
||||
Kirigami.Theme.inherit: false
|
||||
Kirigami.Theme.colorSet: Kirigami.Theme.View
|
||||
|
||||
shadow.xOffset: 0
|
||||
shadow.yOffset: 2
|
||||
shadow.size: 10
|
||||
shadow.color: Qt.rgba(0, 0, 0, 0.3)
|
||||
|
||||
color: {
|
||||
if (delegate.checked) {
|
||||
return Kirigami.Theme.highlightColor;
|
||||
} else if (delegate.hovered) {
|
||||
// Match appearance of hovered list items
|
||||
return Qt.rgba(Kirigami.Theme.highlightColor.r,
|
||||
Kirigami.Theme.highlightColor.g,
|
||||
Kirigami.Theme.highlightColor.b,
|
||||
0.5);
|
||||
} else {
|
||||
return Kirigami.Theme.backgroundColor;
|
||||
}
|
||||
}
|
||||
ColumnLayout {
|
||||
id: contentLayout
|
||||
anchors.fill: parent
|
||||
anchors.margins: Kirigami.Units.smallSpacing
|
||||
clip: true
|
||||
}
|
||||
}
|
||||
|
||||
QQC2.Label {
|
||||
id: label
|
||||
Layout.fillWidth: true
|
||||
text: delegate.text
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
}
|
||||
}
|
||||
|
||||
indicator: Item {}
|
||||
background: Item {}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user