Warning, /maui/mauikit-texteditor/src/controls.5/TextEditor.qml is written in an unsupported language. File is not indexed.
0001 import QtQuick 2.15
0002 import QtQml 2.14
0003 import QtQuick.Controls 2.15
0004 import QtQuick.Layouts 1.3
0005 import QtQuick.Templates 2.15 as T
0006
0007 import org.mauikit.controls 1.3 as Maui
0008 import org.mauikit.texteditor 1.0 as TE
0009
0010 import org.kde.sonnet 1.0 as Sonnet
0011
0012 /*!
0013 * \ since org.mauikit.texteditor 1.0
0014 * \inqmlmodule org.mauikit.texteditor
0015 * \brief Integrated text editor component
0016 *
0017 * A text area for editing text with convinient functions.
0018 * The Editor is controlled by the DocumentHandler which controls the files I/O,
0019 * the syntax highlighting styles, and many more text editing properties.
0020 */
0021 Page
0022 {
0023 id: control
0024
0025 padding: 0
0026 focus: false
0027 clip: false
0028 title: document.fileName + (document.modified ? "*" : "")
0029 // showTitle: false
0030
0031 property bool showFindBar: false
0032
0033 onShowFindBarChanged:
0034 {
0035 if(showFindBar)
0036 {
0037 _findField.forceActiveFocus()
0038 }else
0039 {
0040 body.forceActiveFocus()
0041 }
0042 }
0043
0044 /*!
0045 * \qmlproperty TextArea Editor::body
0046 * Access to the editor text area.
0047 */
0048 readonly property alias body : body
0049
0050 /*!
0051 * \qmlproperty DocumentHandler Editor::document
0052 */
0053 readonly property alias document : document
0054
0055 /*!
0056 * \qmlproperty ScrollablePage Editor::scrollView
0057 */
0058 readonly property alias scrollView: _scrollView
0059
0060 readonly property alias documentMenu : _documentMenuLoader.item
0061
0062 /*!
0063 * \qmlproperty string Editor::text
0064 */
0065 property alias text: body.text
0066
0067 /*!
0068 * \qmlproperty bool Editor::uppercase
0069 */
0070 property alias uppercase: document.uppercase
0071
0072 /*!
0073 * \qmlproperty bool Editor::underline
0074 */
0075 property alias underline: document.underline
0076
0077 /*!
0078 * \qmlproperty bool Editor::italic
0079 */
0080 property alias italic: document.italic
0081
0082 /*!
0083 * \qmlproperty bool Editor::bold
0084 */
0085 property alias bold: document.bold
0086
0087 /*!
0088 * \qmlproperty bool Editor::canRedo
0089 */
0090 property alias canRedo: body.canRedo
0091
0092 /*!
0093 * \qmlproperty url Editor::fileUrl
0094 *
0095 * If a file url is provided the DocumentHandler will try to open its contents and display it.
0096 */
0097 property alias fileUrl : document.fileUrl
0098
0099 /*!
0100 * \qmlproperty bool Editor::showLineNumbers
0101 *
0102 * If a sidebar listing each line number should be visible.
0103 */
0104 property bool showLineNumbers : false
0105
0106 property bool spellcheckEnabled: false
0107
0108 TE.DocumentHandler
0109 {
0110 id: document
0111 document: body.textDocument
0112 cursorPosition: body.cursorPosition
0113 selectionStart: body.selectionStart
0114 selectionEnd: body.selectionEnd
0115 backgroundColor: control.Maui.Theme.backgroundColor
0116 enableSyntaxHighlighting: false
0117 findCaseSensitively: _findCaseSensitively.checked
0118 findWholeWords: _findWholeWords.checked
0119
0120 onSearchFound:
0121 {
0122 body.select(start, end)
0123 }
0124 }
0125
0126 Loader
0127 {
0128 id: spellcheckhighlighterLoader
0129 property bool activable: control.spellcheckEnabled
0130 property Sonnet.Settings settings: Sonnet.Settings {}
0131 active: activable && settings.checkerEnabledByDefault
0132 onActiveChanged: if (active) {
0133 item.active = true;
0134 }
0135 sourceComponent: Sonnet.SpellcheckHighlighter {
0136 id: spellcheckhighlighter
0137 document: body.textDocument
0138 cursorPosition: body.cursorPosition
0139 selectionStart: body.selectionStart
0140 selectionEnd: body.selectionEnd
0141 misspelledColor: Maui.Theme.negativeTextColor
0142 active: spellcheckhighlighterLoader.activable && settings.checkerEnabledByDefault
0143
0144 onChangeCursorPosition: {
0145 body.cursorPosition = start;
0146 body.moveCursorSelection(end, TextEdit.SelectCharacters);
0147 }
0148 }
0149 }
0150
0151 Loader
0152 {
0153 id: _documentMenuLoader
0154
0155 asynchronous: true
0156 sourceComponent: Maui.ContextualMenu
0157 {
0158 property var spellcheckhighlighter: null
0159 property var spellcheckhighlighterLoader: null
0160 property int restoredCursorPosition: 0
0161 property int restoredSelectionStart
0162 property int restoredSelectionEnd
0163 property var suggestions: []
0164 property bool deselectWhenMenuClosed: true
0165 property var runOnMenuClose: () => {}
0166 property bool persistentSelectionSetting
0167 Component.onCompleted: persistentSelectionSetting = body.persistentSelection
0168
0169 Maui.MenuItemActionRow
0170 {
0171 Action
0172 {
0173 icon.name: "edit-undo-symbolic"
0174 text: qsTr("Undo")
0175 shortcut: StandardKey.Undo
0176
0177 onTriggered:
0178 {
0179 documentMenu.deselectWhenMenuClosed = false;
0180 documentMenu.runOnMenuClose = () => body.undo();
0181 }
0182 }
0183
0184 Action
0185 {
0186 icon.name: "edit-redo-symbolic"
0187 text: qsTr("Redo")
0188 shortcut: StandardKey.Redo
0189
0190 onTriggered:
0191 {
0192 documentMenu.deselectWhenMenuClosed = false;
0193 documentMenu.runOnMenuClose = () => body.redo();
0194 }
0195 }
0196 }
0197
0198 MenuItem
0199 {
0200 action: Action {
0201 icon.name: "edit-copy-symbolic"
0202 text: qsTr("Copy")
0203 shortcut: StandardKey.Copy
0204 }
0205 onTriggered:
0206 {
0207 documentMenu.deselectWhenMenuClosed = false;
0208 documentMenu.runOnMenuClose = () => control.body.copy();
0209 }
0210 enabled: body.selectedText.length
0211 }
0212
0213 MenuItem
0214 {
0215 action: Action {
0216 icon.name: "edit-cut-symbolic"
0217 text: qsTr("Cut")
0218 shortcut: StandardKey.Cut
0219 }
0220 onTriggered:
0221 {
0222 documentMenu.deselectWhenMenuClosed = false;
0223 documentMenu.runOnMenuClose = () => control.body.cut();
0224 }
0225 enabled: !body.readOnly && body.selectedText.length
0226 }
0227
0228 MenuItem
0229 {
0230 action: Action {
0231 icon.name: "edit-paste-symbolic"
0232 text: qsTr("Paste")
0233 shortcut: StandardKey.Paste
0234 }
0235 onTriggered:
0236 {
0237 documentMenu.deselectWhenMenuClosed = false;
0238 documentMenu.runOnMenuClose = () => control.body.paste();
0239 }
0240 enabled: !body.readOnly
0241 }
0242
0243
0244 MenuItem
0245 {
0246 action: Action {
0247 icon.name: "edit-select-all-symbolic"
0248 text: qsTr("Select All")
0249 shortcut: StandardKey.SelectAll
0250 }
0251 onTriggered:
0252 {
0253 documentMenu.deselectWhenMenuClosed = false
0254 documentMenu.runOnMenuClose = () => control.body.selectAll();
0255 }
0256 }
0257
0258 MenuItem
0259 {
0260 text: i18nd("mauikittexteditor","Search Selected Text on Google...")
0261 onTriggered: Qt.openUrlExternally("https://www.google.com/search?q="+body.selectedText)
0262 enabled: body.selectedText.length
0263 }
0264
0265 MenuItem
0266 {
0267 enabled: !control.body.readOnly && control.body.selectedText
0268 action: Action {
0269 icon.name: "edit-delete-symbolic"
0270 text: qsTr("Delete")
0271 shortcut: StandardKey.Delete
0272 }
0273 onTriggered: {
0274 documentMenu.deselectWhenMenuClosed = false;
0275 documentMenu.runOnMenuClose = () => control.body.remove(control.body.selectionStart, control.body.selectionEnd);
0276 }
0277 }
0278
0279
0280 MenuSeparator
0281 {
0282 }
0283
0284 Menu
0285 {
0286 id: _spellingMenu
0287 title: i18nd("mauikittexteditor","Spelling")
0288 enabled: control.spellcheckEnabled
0289
0290 Instantiator
0291 {
0292 id: _suggestions
0293 active: !control.body.readOnly && documentMenu.spellcheckhighlighter !== null && documentMenu.spellcheckhighlighter.active && documentMenu.spellcheckhighlighter.wordIsMisspelled
0294 model: documentMenu.suggestions
0295 delegate: MenuItem
0296 {
0297 text: modelData
0298 onClicked:
0299 {
0300 documentMenu.deselectWhenMenuClosed = false;
0301 documentMenu.runOnMenuClose = () => documentMenu.spellcheckhighlighter.replaceWord(modelData);
0302 }
0303 }
0304 onObjectAdded:
0305 {
0306 _spellingMenu.insertItem(0, object)
0307 }
0308 onObjectRemoved: _spellingMenu.removeItem(0)
0309 }
0310
0311 MenuSeparator
0312 {
0313 enabled: !control.body.readOnly && ((documentMenu.spellcheckhighlighter !== null && documentMenu.spellcheckhighlighter.active && documentMenu.spellcheckhighlighter.wordIsMisspelled) || (documentMenu.spellcheckhighlighterLoader && documentMenu.spellcheckhighlighterLoader.activable))
0314 }
0315
0316 MenuItem {
0317 enabled: !control.body.readOnly && documentMenu.spellcheckhighlighter !== null && documentMenu.spellcheckhighlighter.active && documentMenu.spellcheckhighlighter.wordIsMisspelled && documentMenu.suggestions.length === 0
0318 action: Action {
0319 text: documentMenu.spellcheckhighlighter ? qsTr("No suggestions for \"%1\"").arg(documentMenu.spellcheckhighlighter.wordUnderMouse) : ''
0320 enabled: false
0321 }
0322 }
0323 MenuItem {
0324 enabled: !control.body.readOnly && documentMenu.spellcheckhighlighter !== null && documentMenu.spellcheckhighlighter.active && documentMenu.spellcheckhighlighter.wordIsMisspelled
0325 action: Action {
0326 text: documentMenu.spellcheckhighlighter ? qsTr("Add \"%1\" to dictionary").arg(documentMenu.spellcheckhighlighter.wordUnderMouse) : ''
0327 onTriggered: {
0328 documentMenu.deselectWhenMenuClosed = false;
0329 documentMenu.runOnMenuClose = () => spellcheckhighlighter.addWordToDictionary(documentMenu.spellcheckhighlighter.wordUnderMouse);
0330 }
0331 }
0332 }
0333
0334 MenuItem {
0335 enabled: !control.body.readOnly && documentMenu.spellcheckhighlighter !== null && documentMenu.spellcheckhighlighter.active && documentMenu.spellcheckhighlighter.wordIsMisspelled
0336 action: Action {
0337 text: qsTr("Ignore")
0338 onTriggered: {
0339 documentMenu.deselectWhenMenuClosed = false;
0340 documentMenu.runOnMenuClose = () => documentMenu.spellcheckhighlighter.ignoreWord(documentMenu.spellcheckhighlighter.wordUnderMouse);
0341 }
0342 }
0343 }
0344
0345 MenuItem
0346 {
0347 enabled: !control.body.readOnly && documentMenu.spellcheckhighlighterLoader && documentMenu.spellcheckhighlighterLoader.activable
0348 checkable: true
0349 checked: documentMenu.spellcheckhighlighter ? documentMenu.spellcheckhighlighter.active : false
0350 text: qsTr("Enable Spellchecker")
0351 onCheckedChanged: {
0352 spellcheckhighlighterLoader.active = checked;
0353 documentMenu.spellcheckhighlighter = documentMenu.spellcheckhighlighterLoader.item;
0354 }
0355 }
0356 }
0357
0358 function targetClick(spellcheckhighlighter, mousePosition)
0359 {
0360 control.body.persistentSelection = true; // persist selection when menu is opened
0361 documentMenu.spellcheckhighlighterLoader = spellcheckhighlighter;
0362 if (spellcheckhighlighter && spellcheckhighlighter.active) {
0363 documentMenu.spellcheckhighlighter = spellcheckhighlighter.item;
0364 documentMenu.suggestions = mousePosition ? spellcheckhighlighter.item.suggestions(mousePosition) : [];
0365 } else {
0366 documentMenu.spellcheckhighlighter = null;
0367 documentMenu.suggestions = [];
0368 }
0369
0370 storeCursorAndSelection();
0371 documentMenu.show()
0372 }
0373
0374 function storeCursorAndSelection()
0375 {
0376 documentMenu.restoredCursorPosition = control.body.cursorPosition;
0377 documentMenu.restoredSelectionStart = control.body.selectionStart;
0378 documentMenu.restoredSelectionEnd = control.body.selectionEnd;
0379 }
0380
0381 onOpened:
0382 {
0383 runOnMenuClose = () => {};
0384 }
0385
0386 onClosed:
0387 {
0388 // restore text field's original persistent selection setting
0389 body.persistentSelection = documentMenu.persistentSelectionSetting
0390 // deselect text field text if menu is closed not because of a right click on the text field
0391 if (documentMenu.deselectWhenMenuClosed)
0392 {
0393 body.deselect();
0394 }
0395 documentMenu.deselectWhenMenuClosed = true;
0396
0397 // restore cursor position
0398 body.forceActiveFocus();
0399 body.cursorPosition = documentMenu.restoredCursorPosition;
0400 body.select(documentMenu.restoredSelectionStart, documentMenu.restoredSelectionEnd);
0401
0402 // run action, and free memory
0403 runOnMenuClose();
0404 runOnMenuClose = () => {};
0405 }
0406 }
0407 }
0408
0409 footer: Column
0410 {
0411 width: parent.width
0412
0413 Maui.ToolBar
0414 {
0415 id: _findToolBar
0416 visible: showFindBar
0417 width: parent.width
0418 position: ToolBar.Footer
0419
0420 rightContent: ToolButton
0421 {
0422 id: _replaceButton
0423 icon.name: "edit-find-replace"
0424 checkable: true
0425 checked: false
0426 }
0427
0428 leftContent: Maui.ToolButtonMenu
0429 {
0430 icon.name: "overflow-menu"
0431
0432 MenuItem
0433 {
0434 id: _findCaseSensitively
0435 checkable: true
0436 text: i18nd("mauikittexteditor","Case Sensitive")
0437 }
0438
0439 MenuItem
0440 {
0441 id: _findWholeWords
0442 checkable: true
0443 text: i18nd("mauikittexteditor","Whole Words Only")
0444 }
0445 }
0446
0447 middleContent: Maui.SearchField
0448 {
0449 id: _findField
0450 Layout.fillWidth: true
0451 Layout.maximumWidth: 500
0452 Layout.alignment: Qt.AlignCenter
0453 placeholderText: i18nd("mauikittexteditor","Find")
0454
0455 onAccepted:
0456 {
0457 document.find(text)
0458 }
0459
0460 actions:[
0461
0462 Action
0463 {
0464 enabled: _findField.text.length
0465 icon.name: "arrow-up"
0466 onTriggered: document.find(_findField.text, false)
0467 }
0468 ]
0469 }
0470 }
0471
0472 Maui.ToolBar
0473 {
0474 id: _replaceToolBar
0475 position: ToolBar.Footer
0476 visible: _replaceButton.checked && _findToolBar.visible
0477 width: parent.width
0478 enabled: !body.readOnly
0479 forceCenterMiddleContent: false
0480
0481 middleContent: Maui.SearchField
0482 {
0483 id: _replaceField
0484 placeholderText: i18nd("mauikittexteditor","Replace")
0485 Layout.fillWidth: true
0486 Layout.maximumWidth: 500
0487 Layout.alignment: Qt.AlignCenter
0488 icon.source: "edit-find-replace"
0489 actions: Action
0490 {
0491 text: i18nd("mauikittexteditor","Replace")
0492 enabled: _replaceField.text.length
0493 icon.name: "checkmark"
0494 onTriggered: document.replace(_findField.text, _replaceField.text)
0495 }
0496 }
0497
0498 rightContent: Button
0499 {
0500 enabled: _replaceField.text.length
0501 text: i18nd("mauikittexteditor","Replace All")
0502 onClicked: document.replaceAll(_findField.text, _replaceField.text)
0503 }
0504 }
0505 }
0506
0507 header: Column
0508 {
0509 width: parent.width
0510
0511 Repeater
0512 {
0513 model: document.alerts
0514
0515 Maui.ToolBar
0516 {
0517 id: _alertBar
0518 property var alert : model.alert
0519 readonly property int index_ : index
0520 width: parent.width
0521
0522 Maui.Theme.backgroundColor:
0523 {
0524 switch(alert.level)
0525 {
0526 case 0: return Maui.Theme.positiveBackgroundColor
0527 case 1: return Maui.Theme.neutralBackgroundColor
0528 case 2: return Maui.Theme.negativeBackgroundColor
0529 }
0530 }
0531
0532 Maui.Theme.textColor:
0533 {
0534 switch(alert.level)
0535 {
0536 case 0: return Maui.Theme.positiveTextColor
0537 case 1: return Maui.Theme.neutralTextColor
0538 case 2: return Maui.Theme.negativeTextColor
0539 }
0540 }
0541
0542 forceCenterMiddleContent: false
0543 middleContent: Maui.ListItemTemplate
0544 {
0545 Maui.Theme.inherit: true
0546 Layout.fillWidth: true
0547 Layout.fillHeight: true
0548 label1.text: alert.title
0549 label2.text: alert.body
0550 }
0551
0552 rightContent: Repeater
0553 {
0554 model: alert.actionLabels
0555
0556 Button
0557 {
0558 id: _alertAction
0559 property int index_ : index
0560 text: modelData
0561 onClicked: alert.triggerAction(_alertAction.index_, _alertBar.index_)
0562
0563 Maui.Theme.backgroundColor: Qt.lighter(_alertBar.Maui.Theme.backgroundColor, 1.2)
0564 Maui.Theme.hoverColor: Qt.lighter(_alertBar.Maui.Theme.backgroundColor, 1)
0565 Maui.Theme.textColor: Qt.darker(Maui.Theme.backgroundColor)
0566 }
0567 }
0568 }
0569 }
0570 }
0571
0572 contentItem: Item
0573 {
0574 clip: false
0575
0576 ScrollView
0577 {
0578 id: _scrollView
0579 anchors.fill: parent
0580 clip: false
0581 contentWidth: availableWidth
0582
0583 Keys.enabled: true
0584 Keys.forwardTo: body
0585 Keys.onPressed:
0586 {
0587 if((event.key === Qt.Key_F) && (event.modifiers & Qt.ControlModifier))
0588 {
0589 control.showFindBar = true
0590
0591 if(control.body.selectedText.length)
0592 {
0593 _findField.text = control.body.selectedText
0594 }else
0595 {
0596 _findField.selectAll()
0597 }
0598
0599 _findField.forceActiveFocus()
0600 event.accepted = true
0601 }
0602
0603 if((event.key === Qt.Key_R) && (event.modifiers & Qt.ControlModifier))
0604 {
0605 control.showFindBar = true
0606 _replaceButton.checked = true
0607 _findField.text = control.body.selectedText
0608 _replaceField.forceActiveFocus()
0609 event.accepted = true
0610 }
0611 }
0612
0613 Flickable
0614 {
0615 id: _flickable
0616 clip: false
0617 interactive: true
0618 boundsBehavior : Flickable.StopAtBounds
0619 boundsMovement : Flickable.StopAtBounds
0620
0621 TextArea.flickable: TextArea
0622 {
0623 id: body
0624 Maui.Theme.inherit: true
0625 text: document.text
0626
0627 placeholderText: i18nd("mauikittexteditor","Body")
0628
0629 textFormat: TextEdit.PlainText
0630
0631 leftPadding: _linesCounter.width + padding
0632
0633 Keys.onPressed:
0634 {
0635 if(event.key === Qt.Key_PageUp)
0636 {
0637 _flickable.flick(0, 60*Math.sqrt(_flickable.height))
0638 event.accepted = true
0639 }
0640
0641 if(event.key === Qt.Key_PageDown)
0642 {
0643 _flickable.flick(0, -60*Math.sqrt(_flickable.height))
0644 event.accepted = true
0645 } // TODO: Move cursor
0646 }
0647
0648 onPressAndHold:
0649 {
0650 // if(Maui.Handy.isMobile)
0651 // {
0652 // return
0653 // }
0654 //
0655 documentMenu.targetClick(spellcheckhighlighterLoader, body.positionAt(point.position.x, point.position.y));
0656 }
0657
0658 onPressed:
0659 {
0660 if(Maui.Handy.isMobile)
0661 {
0662 return
0663 }
0664
0665 if(event.button === Qt.RightButton)
0666 {
0667 documentMenu.targetClick(spellcheckhighlighterLoader, body.positionAt(event.x, event.y))
0668 }
0669 }
0670
0671 Loader
0672 {
0673 id: _linesCounter
0674 asynchronous: true
0675 active: control.showLineNumbers && !document.isRich
0676
0677 anchors.left: parent.left
0678 anchors.top: parent.top
0679
0680 height: Math.max(_flickable.contentHeight, control.height)
0681 width: active ? 48 : 0
0682 sourceComponent: _linesCounterComponent
0683 }
0684
0685 Component
0686 {
0687 id: _linesCounterComponent
0688
0689 Rectangle
0690 {
0691 color: Qt.darker(Maui.Theme.backgroundColor, 1)
0692
0693 ListView
0694 {
0695 id: _linesCounterList
0696
0697 anchors.fill: parent
0698 anchors.topMargin: body.topPadding + body.textMargin
0699
0700 model: document.lineCount
0701
0702 Binding on currentIndex
0703 {
0704 value: document.currentLineIndex
0705 restoreMode: Binding.RestoreBindingOrValue
0706 }
0707
0708 Timer
0709 {
0710 id: _lineIndexTimer
0711 interval: 250
0712 onTriggered: _linesCounterList.currentIndex= document.currentLineIndex
0713 }
0714
0715 Connections
0716 {
0717 target: document
0718 function onLineCountChanged()
0719 {
0720 _lineIndexTimer.restart()
0721 }
0722 }
0723
0724 orientation: ListView.Vertical
0725 interactive: false
0726 snapMode: ListView.NoSnap
0727
0728 boundsBehavior: Flickable.StopAtBounds
0729 boundsMovement :Flickable.StopAtBounds
0730
0731 preferredHighlightBegin: 0
0732 preferredHighlightEnd: width
0733
0734 highlightRangeMode: ListView.StrictlyEnforceRange
0735 highlightMoveDuration: 0
0736 highlightFollowsCurrentItem: false
0737 highlightResizeDuration: 0
0738 highlightMoveVelocity: -1
0739 highlightResizeVelocity: -1
0740
0741 maximumFlickVelocity: 0
0742
0743 delegate: Row
0744 {
0745 id: _delegate
0746 readonly property int line : index
0747 property bool foldable : control.document.isFoldable(line)
0748 width: ListView.view.width
0749 height: Math.max(fontSize, document.lineHeight(line))
0750
0751 readonly property real fontSize : control.body.font.pointSize
0752
0753 readonly property bool isCurrentItem : ListView.isCurrentItem
0754
0755 Connections
0756 {
0757 target: control.body
0758
0759 function onContentHeightChanged()
0760 {
0761 if(_delegate.isCurrentItem)
0762 {
0763 console.log("Updating line height")
0764 _delegate.height = control.document.lineHeight(_delegate.line)
0765 _delegate.foldable = control.document.isFoldable(_delegate.line)
0766 }
0767 }
0768 }
0769
0770 Label
0771 {
0772 width: 32
0773 height: parent.height
0774 opacity: isCurrentItem ? 1 : 0.7
0775 color: isCurrentItem ? control.Maui.Theme.highlightColor : control.body.color
0776 font.pointSize: Math.min(Maui.Style.fontSizes.medium, body.font.pointSize)
0777 horizontalAlignment: Text.AlignHCenter
0778 verticalAlignment: Text.AlignVCenter
0779 // renderType: Text.NativeRendering
0780 font.family: "Monospace"
0781 text: index+1
0782 }
0783
0784 AbstractButton
0785 {
0786 visible: foldable
0787 anchors.verticalCenter: parent.verticalCenter
0788 height: 8
0789 width: 8
0790 //onClicked:
0791 //{
0792 //control.goToLine(_delegate.line)
0793 //control.document.toggleFold(_delegate.line)
0794 //}
0795 contentItem: Maui.Icon
0796 {
0797 source: "go-down"
0798 }
0799 }
0800 }
0801 }
0802
0803 // Maui.Separator
0804 // {
0805 // anchors.top: parent.top
0806 // anchors.bottom: parent.bottom
0807 // anchors.right: parent.right
0808 // width: 0.5
0809 // weight: Maui.Separator.Weight.Light
0810 // }
0811 }
0812 }
0813 }
0814 }
0815 }
0816
0817 Loader
0818 {
0819 active: Maui.Handy.isTouch
0820 asynchronous: true
0821
0822 anchors.bottom: parent.bottom
0823 anchors.right: parent.right
0824 anchors.margins: Maui.Style.space.big
0825
0826 sourceComponent: Maui.FloatingButton
0827 {
0828 icon.name: "edit-menu"
0829 onClicked: documentMenu.targetClick(spellcheckhighlighterLoader, body.cursorPosition)
0830 }
0831 }
0832 }
0833
0834 function forceActiveFocus()
0835 {
0836 body.forceActiveFocus()
0837 }
0838
0839 function goToLine(line)
0840 {
0841 if(line>0 && line <= body.lineCount)
0842 {
0843 body.cursorPosition = document.goToLine(line-1)
0844 body.forceActiveFocus()
0845 }
0846 }
0847 }