2022-05-13 13:12:05 +00:00
|
|
|
// Copyright (C) 2017 The Qt Company Ltd.
|
|
|
|
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause
|
2016-07-26 12:15:31 +00:00
|
|
|
|
2020-03-26 16:01:51 +00:00
|
|
|
import QtQuick
|
|
|
|
import QtQuick.Controls
|
|
|
|
import QtQuick.Layouts
|
2016-07-26 12:15:31 +00:00
|
|
|
|
|
|
|
// TODO:
|
|
|
|
// - make designer-friendly
|
|
|
|
|
|
|
|
ApplicationWindow {
|
|
|
|
id: window
|
2024-02-13 01:39:37 +00:00
|
|
|
width: 480
|
|
|
|
height: 640
|
2016-07-26 12:15:31 +00:00
|
|
|
visible: true
|
2024-02-13 01:39:37 +00:00
|
|
|
title: textArea.textDocument.source +
|
|
|
|
" - Text Editor Example" + (textArea.textDocument.modified ? " *" : "")
|
|
|
|
|
|
|
|
Action {
|
|
|
|
id: boldAction
|
|
|
|
shortcut: StandardKey.Bold
|
|
|
|
checkable: true
|
|
|
|
checked: textArea.cursorSelection.font.bold
|
|
|
|
onTriggered: textArea.cursorSelection.font = Qt.font({ bold: checked })
|
|
|
|
}
|
|
|
|
|
|
|
|
Action {
|
|
|
|
id: italicAction
|
|
|
|
shortcut: StandardKey.Italic
|
|
|
|
checkable: true
|
|
|
|
checked: textArea.cursorSelection.font.italic
|
|
|
|
onTriggered: textArea.cursorSelection.font = Qt.font({ italic: checked })
|
|
|
|
}
|
|
|
|
|
|
|
|
Action {
|
|
|
|
id: underlineAction
|
|
|
|
shortcut: StandardKey.Underline
|
|
|
|
checkable: true
|
|
|
|
checked: textArea.cursorSelection.font.underline
|
|
|
|
onTriggered: textArea.cursorSelection.font = Qt.font({ underline: checked })
|
|
|
|
}
|
|
|
|
|
|
|
|
Action {
|
|
|
|
id: alignLeftAction
|
|
|
|
shortcut: "Ctrl+{"
|
|
|
|
checkable: true
|
|
|
|
checked: textArea.cursorSelection.alignment === Qt.AlignLeft
|
|
|
|
onTriggered: textArea.cursorSelection.alignment = Qt.AlignLeft
|
|
|
|
}
|
|
|
|
|
|
|
|
Action {
|
|
|
|
id: alignCenterAction
|
|
|
|
shortcut: "Ctrl+|"
|
|
|
|
checkable: true
|
|
|
|
checked: textArea.cursorSelection.alignment === Qt.AlignCenter
|
|
|
|
onTriggered: textArea.cursorSelection.alignment = Qt.AlignCenter
|
|
|
|
}
|
|
|
|
|
|
|
|
Action {
|
|
|
|
id: alignRightAction
|
|
|
|
shortcut: "Ctrl+}"
|
|
|
|
checkable: true
|
|
|
|
checked: textArea.cursorSelection.alignment === Qt.AlignRight
|
|
|
|
onTriggered: textArea.cursorSelection.alignment = Qt.AlignRight
|
|
|
|
}
|
|
|
|
|
|
|
|
Action {
|
|
|
|
id: alignJustifyAction
|
|
|
|
shortcut: "Ctrl+Alt+}"
|
|
|
|
checkable: true
|
|
|
|
checked: textArea.cursorSelection.alignment === Qt.AlignJustify
|
|
|
|
onTriggered: textArea.cursorSelection.alignment = Qt.AlignJustify
|
|
|
|
}
|
2016-07-26 12:15:31 +00:00
|
|
|
|
|
|
|
header: ToolBar {
|
|
|
|
leftPadding: 5
|
|
|
|
|
|
|
|
RowLayout {
|
|
|
|
anchors.fill: parent
|
|
|
|
spacing: 0
|
|
|
|
|
|
|
|
ToolButton {
|
|
|
|
id: doneEditingButton
|
|
|
|
font.family: "fontello"
|
2024-02-13 01:39:37 +00:00
|
|
|
text: "\uE809" // icon-ok
|
2016-07-26 12:15:31 +00:00
|
|
|
opacity: !textArea.readOnly ? 1 : 0
|
|
|
|
onClicked: textArea.readOnly = true
|
2024-01-19 17:06:58 +00:00
|
|
|
Layout.fillWidth: false
|
2016-07-26 12:15:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
Label {
|
|
|
|
text: qsTr("Text Editor Example")
|
|
|
|
font.bold: true
|
|
|
|
font.pixelSize: 20
|
2016-08-26 11:15:58 +00:00
|
|
|
elide: Label.ElideRight
|
2016-07-26 12:15:31 +00:00
|
|
|
Layout.fillWidth: true
|
|
|
|
}
|
|
|
|
|
|
|
|
ToolButton {
|
|
|
|
font.family: "fontello"
|
|
|
|
text: "\uF142" // icon-ellipsis-vert
|
|
|
|
onClicked: menu.open()
|
2024-01-19 17:06:58 +00:00
|
|
|
Layout.fillWidth: false
|
2016-07-26 12:15:31 +00:00
|
|
|
|
|
|
|
Menu {
|
|
|
|
id: menu
|
|
|
|
|
|
|
|
MenuItem {
|
|
|
|
text: qsTr("About")
|
|
|
|
onTriggered: aboutDialog.open()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Flickable {
|
|
|
|
id: flickable
|
|
|
|
flickableDirection: Flickable.VerticalFlick
|
|
|
|
anchors.fill: parent
|
|
|
|
|
|
|
|
TextArea.flickable: TextArea {
|
|
|
|
id: textArea
|
|
|
|
textFormat: Qt.RichText
|
|
|
|
wrapMode: TextArea.Wrap
|
|
|
|
readOnly: true
|
|
|
|
persistentSelection: true
|
|
|
|
// Different styles have different padding and background
|
|
|
|
// decorations, but since this editor is almost taking up the
|
|
|
|
// entire window, we don't need them.
|
|
|
|
leftPadding: 6
|
|
|
|
rightPadding: 6
|
|
|
|
topPadding: 0
|
|
|
|
bottomPadding: 0
|
|
|
|
background: null
|
|
|
|
|
|
|
|
onLinkActivated: Qt.openUrlExternally(link)
|
2023-11-22 20:45:46 +00:00
|
|
|
|
|
|
|
Component.onCompleted: textDocument.source = "qrc:/texteditor.html"
|
|
|
|
|
2024-02-13 01:39:37 +00:00
|
|
|
textDocument.onStatusChanged: {
|
|
|
|
// a message lookup table using computed properties:
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer
|
|
|
|
const statusMessages = {
|
|
|
|
[ TextDocument.ReadError ]: qsTr("Failed to load “%1”"),
|
|
|
|
[ TextDocument.WriteError ]: qsTr("Failed to save “%1”"),
|
|
|
|
[ TextDocument.NonLocalFileError ]: qsTr("Not a local file: “%1”"),
|
|
|
|
}
|
|
|
|
const err = statusMessages[textDocument.status]
|
|
|
|
if (err) {
|
|
|
|
errorDialog.text = err.arg(textDocument.source)
|
|
|
|
errorDialog.open()
|
|
|
|
}
|
2023-11-22 20:45:46 +00:00
|
|
|
}
|
2016-07-26 12:15:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ScrollBar.vertical: ScrollBar {}
|
|
|
|
}
|
|
|
|
|
|
|
|
footer: ToolBar {
|
|
|
|
visible: !textArea.readOnly && textArea.activeFocus
|
|
|
|
|
|
|
|
Flickable {
|
|
|
|
anchors.fill: parent
|
2016-08-26 11:09:44 +00:00
|
|
|
contentWidth: toolRow.implicitWidth
|
2016-07-26 12:15:31 +00:00
|
|
|
flickableDirection: Qt.Horizontal
|
|
|
|
boundsBehavior: Flickable.StopAtBounds
|
|
|
|
|
2016-08-26 11:09:44 +00:00
|
|
|
Row {
|
|
|
|
id: toolRow
|
|
|
|
|
|
|
|
ToolButton {
|
|
|
|
id: boldButton
|
|
|
|
text: "\uE800" // icon-bold
|
|
|
|
font.family: "fontello"
|
|
|
|
// Don't want to close the virtual keyboard when this is clicked.
|
|
|
|
focusPolicy: Qt.NoFocus
|
2024-02-13 01:39:37 +00:00
|
|
|
action: boldAction
|
2016-08-26 11:09:44 +00:00
|
|
|
}
|
|
|
|
ToolButton {
|
|
|
|
id: italicButton
|
|
|
|
text: "\uE801" // icon-italic
|
|
|
|
font.family: "fontello"
|
|
|
|
focusPolicy: Qt.NoFocus
|
2024-02-13 01:39:37 +00:00
|
|
|
action: italicAction
|
2016-08-26 11:09:44 +00:00
|
|
|
}
|
|
|
|
ToolButton {
|
|
|
|
id: underlineButton
|
|
|
|
text: "\uF0CD" // icon-underline
|
|
|
|
font.family: "fontello"
|
|
|
|
focusPolicy: Qt.NoFocus
|
2024-02-13 01:39:37 +00:00
|
|
|
action: underlineAction
|
2016-07-26 12:15:31 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
ToolSeparator {}
|
|
|
|
|
2016-08-26 11:09:44 +00:00
|
|
|
ToolButton {
|
|
|
|
id: alignLeftButton
|
|
|
|
text: "\uE803" // icon-align-left
|
|
|
|
font.family: "fontello"
|
|
|
|
focusPolicy: Qt.NoFocus
|
2024-02-13 01:39:37 +00:00
|
|
|
action: alignLeftAction
|
2016-08-26 11:09:44 +00:00
|
|
|
}
|
|
|
|
ToolButton {
|
|
|
|
id: alignCenterButton
|
|
|
|
text: "\uE804" // icon-align-center
|
|
|
|
font.family: "fontello"
|
|
|
|
focusPolicy: Qt.NoFocus
|
2024-02-13 01:39:37 +00:00
|
|
|
action: alignCenterAction
|
2016-08-26 11:09:44 +00:00
|
|
|
}
|
|
|
|
ToolButton {
|
|
|
|
id: alignRightButton
|
|
|
|
text: "\uE805" // icon-align-right
|
|
|
|
font.family: "fontello"
|
|
|
|
focusPolicy: Qt.NoFocus
|
2024-02-13 01:39:37 +00:00
|
|
|
action: alignRightAction
|
2016-08-26 11:09:44 +00:00
|
|
|
}
|
|
|
|
ToolButton {
|
|
|
|
id: alignJustifyButton
|
|
|
|
text: "\uE806" // icon-align-justify
|
|
|
|
font.family: "fontello"
|
|
|
|
focusPolicy: Qt.NoFocus
|
2024-02-13 01:39:37 +00:00
|
|
|
action: alignJustifyAction
|
2016-07-26 12:15:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-09-03 10:46:10 +00:00
|
|
|
RoundButton {
|
2016-07-26 12:15:31 +00:00
|
|
|
id: editButton
|
|
|
|
font.family: "fontello"
|
|
|
|
text: "\uE809" // icon-pencil
|
|
|
|
width: 48
|
|
|
|
height: width
|
|
|
|
// Don't want to use anchors for the y position, because it will anchor
|
|
|
|
// to the footer, leaving a large vertical gap.
|
|
|
|
y: parent.height - height - 12
|
|
|
|
anchors.right: parent.right
|
|
|
|
anchors.margins: 12
|
|
|
|
visible: textArea.readOnly
|
2016-08-26 15:30:27 +00:00
|
|
|
highlighted: true
|
2016-07-26 12:15:31 +00:00
|
|
|
|
|
|
|
onClicked: {
|
|
|
|
textArea.readOnly = false
|
|
|
|
// Force focus on the text area so the cursor and footer show up.
|
|
|
|
textArea.forceActiveFocus()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Dialog {
|
|
|
|
id: aboutDialog
|
|
|
|
standardButtons: Dialog.Ok
|
|
|
|
modal: true
|
|
|
|
x: parent.width / 2 - width / 2
|
|
|
|
y: parent.height / 2 - height / 2
|
|
|
|
|
|
|
|
contentItem: Label {
|
2020-11-13 12:30:10 +00:00
|
|
|
text: qsTr("Qt Quick Controls - Text Editor Example")
|
2016-07-26 12:15:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|