978 lines
35 KiB
QML
978 lines
35 KiB
QML
/****************************************************************************
|
|
**
|
|
** Copyright (C) 2016 The Qt Company Ltd.
|
|
** Contact: https://www.qt.io/licensing/
|
|
**
|
|
** This file is part of the Qt Quick Controls 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.6
|
|
import QtQuick.Window 2.2
|
|
import QtQuick.Controls 1.2
|
|
import QtQuick.Controls.Private 1.0
|
|
/*!
|
|
\qmltype TextArea
|
|
\inqmlmodule QtQuick.Controls
|
|
\since 5.1
|
|
\ingroup controls
|
|
\brief Displays multiple lines of editable formatted text.
|
|
|
|
\image textarea.png
|
|
|
|
It can display both plain and rich text. For example:
|
|
|
|
\qml
|
|
TextArea {
|
|
width: 240
|
|
text:
|
|
"Lorem ipsum dolor sit amet, consectetur adipisicing elit, " +
|
|
"sed do eiusmod tempor incididunt ut labore et dolore magna " +
|
|
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation " +
|
|
"ullamco laboris nisi ut aliquip ex ea commodo cosnsequat. ";
|
|
}
|
|
\endqml
|
|
|
|
Clipboard support is provided by the cut(), copy(), and paste() functions, and the selection can
|
|
be handled in a traditional "mouse" mechanism by setting selectByMouse, or handled completely
|
|
from QML by manipulating selectionStart and selectionEnd, or using selectAll() or selectWord().
|
|
|
|
You can translate between cursor positions (characters from the start of the document) and pixel
|
|
points using positionAt() and positionToRectangle().
|
|
|
|
You can create a custom appearance for a TextArea by
|
|
assigning a \l {TextAreaStyle}.
|
|
|
|
\sa TextField, TextEdit
|
|
*/
|
|
|
|
ScrollView {
|
|
id: area
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::activeFocusOnPress
|
|
|
|
Whether the TextEdit should gain active focus on a mouse press. By default this is
|
|
set to true.
|
|
*/
|
|
property alias activeFocusOnPress: edit.activeFocusOnPress
|
|
|
|
/*!
|
|
\qmlproperty url TextArea::baseUrl
|
|
|
|
This property specifies a base URL which is used to resolve relative URLs
|
|
within the text.
|
|
|
|
The default value is the url of the QML file instantiating the TextArea item.
|
|
*/
|
|
property alias baseUrl: edit.baseUrl
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::canPaste
|
|
|
|
Returns true if the TextArea is writable and the content of the clipboard is
|
|
suitable for pasting into the TextArea.
|
|
*/
|
|
readonly property alias canPaste: edit.canPaste
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::canRedo
|
|
|
|
Returns true if the TextArea is writable and there are \l {undo}{undone}
|
|
operations that can be redone.
|
|
*/
|
|
readonly property alias canRedo: edit.canRedo
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::canUndo
|
|
|
|
Returns true if the TextArea is writable and there are previous operations
|
|
that can be undone.
|
|
*/
|
|
readonly property alias canUndo: edit.canUndo
|
|
|
|
/*!
|
|
\qmlproperty color TextArea::textColor
|
|
|
|
The text color.
|
|
|
|
\qml
|
|
TextArea { textColor: "orange" }
|
|
\endqml
|
|
*/
|
|
property alias textColor: edit.color
|
|
|
|
/*!
|
|
\qmlproperty int TextArea::cursorPosition
|
|
The position of the cursor in the TextArea.
|
|
*/
|
|
property alias cursorPosition: edit.cursorPosition
|
|
|
|
/*!
|
|
\qmlproperty rect TextArea::cursorRectangle
|
|
\since QtQuick.Controls 1.3
|
|
|
|
The rectangle where the text cursor is rendered within the text area.
|
|
*/
|
|
readonly property alias cursorRectangle: edit.cursorRectangle
|
|
|
|
/*! \qmlproperty font TextArea::font
|
|
|
|
The font of the TextArea.
|
|
*/
|
|
property alias font: edit.font
|
|
|
|
/*!
|
|
\qmlproperty enumeration TextArea::horizontalAlignment
|
|
|
|
Sets the alignment of the text within the TextArea item's width.
|
|
|
|
By default, the horizontal text alignment follows the natural alignment of the text,
|
|
for example, text that is read from left to right will be aligned to the left.
|
|
|
|
The valid values for \c horizontalAlignment are:
|
|
\list
|
|
\li TextEdit.AlignLeft (Default)
|
|
\li TextEdit.AlignRight
|
|
\li TextEdit.AlignHCenter
|
|
\endlist
|
|
|
|
When using the attached property LayoutMirroring::enabled to mirror application
|
|
layouts, the horizontal alignment of text will also be mirrored. However, the property
|
|
\c horizontalAlignment will remain unchanged. To query the effective horizontal alignment
|
|
of TextArea, use the read-only property \c effectiveHorizontalAlignment.
|
|
*/
|
|
property alias horizontalAlignment: edit.horizontalAlignment
|
|
|
|
/*!
|
|
\qmlproperty enumeration TextArea::effectiveHorizontalAlignment
|
|
|
|
Gets the effective horizontal alignment of the text within the TextArea item's width.
|
|
|
|
To set/get the default horizontal alignment of TextArea, use the property \c horizontalAlignment.
|
|
|
|
*/
|
|
readonly property alias effectiveHorizontalAlignment: edit.effectiveHorizontalAlignment
|
|
|
|
/*!
|
|
\qmlproperty enumeration TextArea::verticalAlignment
|
|
|
|
Sets the alignment of the text within the TextArea item's height.
|
|
|
|
The valid values for \c verticalAlignment are:
|
|
\list
|
|
\li TextEdit.AlignTop
|
|
\li TextEdit.AlignBottom
|
|
\li TextEdit.AlignVCenter (Default)
|
|
\endlist
|
|
*/
|
|
property alias verticalAlignment: edit.verticalAlignment
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::inputMethodComposing
|
|
\since QtQuick.Controls 1.3
|
|
|
|
This property holds whether the TextArea has partial text input from an input method.
|
|
|
|
While it is composing an input method may rely on mouse or key events from the TextArea
|
|
to edit or commit the partial text. This property can be used to determine when to disable
|
|
events handlers that may interfere with the correct operation of an input method.
|
|
*/
|
|
readonly property bool inputMethodComposing: !!edit.inputMethodComposing
|
|
|
|
/*!
|
|
\qmlproperty enumeration TextArea::inputMethodHints
|
|
|
|
Provides hints to the input method about the expected content of the text edit, and how it
|
|
should operate.
|
|
|
|
The value is a bit-wise combination of flags or Qt.ImhNone if no hints are set.
|
|
|
|
The default value is \c Qt.ImhNone.
|
|
|
|
Flags that alter behavior are:
|
|
|
|
\list
|
|
\li Qt.ImhHiddenText - Characters should be hidden, as is typically used when entering passwords.
|
|
\li Qt.ImhSensitiveData - Typed text should not be stored by the active input method
|
|
in any persistent storage like predictive user dictionary.
|
|
\li Qt.ImhNoAutoUppercase - The input method should not try to automatically switch to upper case
|
|
when a sentence ends.
|
|
\li Qt.ImhPreferNumbers - Numbers are preferred (but not required).
|
|
\li Qt.ImhPreferUppercase - Upper case letters are preferred (but not required).
|
|
\li Qt.ImhPreferLowercase - Lower case letters are preferred (but not required).
|
|
\li Qt.ImhNoPredictiveText - Do not use predictive text (i.e. dictionary lookup) while typing.
|
|
|
|
\li Qt.ImhDate - The text editor functions as a date field.
|
|
\li Qt.ImhTime - The text editor functions as a time field.
|
|
\endlist
|
|
|
|
Flags that restrict input (exclusive flags) are:
|
|
|
|
\list
|
|
\li Qt.ImhDigitsOnly - Only digits are allowed.
|
|
\li Qt.ImhFormattedNumbersOnly - Only number input is allowed. This includes decimal point and minus sign.
|
|
\li Qt.ImhUppercaseOnly - Only upper case letter input is allowed.
|
|
\li Qt.ImhLowercaseOnly - Only lower case letter input is allowed.
|
|
\li Qt.ImhDialableCharactersOnly - Only characters suitable for phone dialing are allowed.
|
|
\li Qt.ImhEmailCharactersOnly - Only characters suitable for email addresses are allowed.
|
|
\li Qt.ImhUrlCharactersOnly - Only characters suitable for URLs are allowed.
|
|
\endlist
|
|
|
|
Masks:
|
|
|
|
\list
|
|
\li Qt.ImhExclusiveInputMask - This mask yields nonzero if any of the exclusive flags are used.
|
|
\endlist
|
|
*/
|
|
property alias inputMethodHints: edit.inputMethodHints
|
|
|
|
/*!
|
|
\qmlproperty int TextArea::length
|
|
|
|
Returns the total number of plain text characters in the TextArea item.
|
|
|
|
As this number doesn't include any formatting markup, it may not be the same as the
|
|
length of the string returned by the \l text property.
|
|
|
|
This property can be faster than querying the length the \l text property as it doesn't
|
|
require any copying or conversion of the TextArea's internal string data.
|
|
*/
|
|
readonly property alias length: edit.length
|
|
|
|
/*!
|
|
\qmlproperty int TextArea::lineCount
|
|
|
|
Returns the total number of lines in the TextArea item.
|
|
*/
|
|
readonly property alias lineCount: edit.lineCount
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::readOnly
|
|
|
|
Whether the user can interact with the TextArea item.
|
|
|
|
The difference from a disabled text field is that it will appear
|
|
to be active, and text can be selected and copied.
|
|
|
|
If this property is set to \c true, the text cannot be edited by user interaction.
|
|
|
|
By default this property is \c false.
|
|
*/
|
|
property alias readOnly: edit.readOnly
|
|
Accessible.readOnly: readOnly
|
|
|
|
/*!
|
|
\qmlproperty string TextArea::selectedText
|
|
|
|
This read-only property provides the text currently selected in the
|
|
text edit.
|
|
*/
|
|
readonly property alias selectedText: edit.selectedText
|
|
|
|
/*!
|
|
\qmlproperty int TextArea::selectionEnd
|
|
|
|
The cursor position after the last character in the current selection.
|
|
|
|
This property is read-only. To change the selection, use select(start,end),
|
|
selectAll(), or selectWord().
|
|
|
|
\sa selectionStart, cursorPosition, selectedText
|
|
*/
|
|
readonly property alias selectionEnd: edit.selectionEnd
|
|
|
|
/*!
|
|
\qmlproperty int TextArea::selectionStart
|
|
|
|
The cursor position before the first character in the current selection.
|
|
|
|
This property is read-only. To change the selection, use select(start,end),
|
|
selectAll(), or selectWord().
|
|
|
|
\sa selectionEnd, cursorPosition, selectedText
|
|
*/
|
|
readonly property alias selectionStart: edit.selectionStart
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::tabChangesFocus
|
|
|
|
This property holds whether Tab changes focus, or is accepted as input.
|
|
|
|
Defaults to \c false.
|
|
*/
|
|
property bool tabChangesFocus: false
|
|
|
|
/*!
|
|
\qmlproperty string TextArea::text
|
|
|
|
The text to display. If the text format is AutoText the text edit will
|
|
automatically determine whether the text should be treated as
|
|
rich text. This determination is made using Qt::mightBeRichText().
|
|
*/
|
|
property alias text: edit.text
|
|
|
|
/*!
|
|
\qmlproperty enumeration TextArea::textFormat
|
|
|
|
The way the text property should be displayed.
|
|
|
|
\list
|
|
\li TextEdit.AutoText
|
|
\li TextEdit.PlainText
|
|
\li TextEdit.RichText
|
|
\endlist
|
|
|
|
The default is TextEdit.PlainText. If the text format is TextEdit.AutoText the text edit
|
|
will automatically determine whether the text should be treated as
|
|
rich text. This determination is made using Qt::mightBeRichText().
|
|
*/
|
|
property alias textFormat: edit.textFormat
|
|
|
|
/*!
|
|
\qmlproperty enumeration TextArea::wrapMode
|
|
|
|
Set this property to wrap the text to the TextArea item's width.
|
|
|
|
\list
|
|
\li TextEdit.NoWrap - no wrapping will be performed.
|
|
\li TextEdit.WordWrap (default) - wrapping is done on word boundaries only.
|
|
\li TextEdit.WrapAnywhere - wrapping is done at any point on a line, even if it occurs in the middle of a word.
|
|
\li TextEdit.Wrap - if possible, wrapping occurs at a word boundary; otherwise it will occur at the appropriate point on the line, even in the middle of a word.
|
|
\endlist
|
|
*/
|
|
property alias wrapMode: edit.wrapMode
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::selectByMouse
|
|
|
|
This property determines if the user can select the text with the
|
|
mouse.
|
|
|
|
The default value is \c true.
|
|
*/
|
|
property bool selectByMouse: true
|
|
|
|
/*!
|
|
\qmlproperty bool TextArea::selectByKeyboard
|
|
|
|
This property determines if the user can select the text with the
|
|
keyboard.
|
|
|
|
If set to \c true, the user can use the keyboard to select the text
|
|
even if the editor is read-only. If set to \c false, the user cannot
|
|
use the keyboard to select the text even if the editor is editable.
|
|
|
|
The default value is \c true when the editor is editable,
|
|
and \c false when read-only.
|
|
|
|
\sa readOnly
|
|
*/
|
|
property alias selectByKeyboard: edit.selectByKeyboard
|
|
|
|
/*!
|
|
\qmlsignal TextArea::linkActivated(string link)
|
|
|
|
This signal is emitted when the user clicks on a link embedded in the text.
|
|
The link must be in rich text or HTML format and the
|
|
\a link string provides access to the particular link.
|
|
|
|
The corresponding handler is \c onLinkActivated.
|
|
*/
|
|
signal linkActivated(string link)
|
|
|
|
/*!
|
|
\qmlsignal TextArea::linkHovered(string link)
|
|
\since QtQuick.Controls 1.1
|
|
|
|
This signal is emitted when the user hovers a link embedded in the text.
|
|
The link must be in rich text or HTML format and the
|
|
\a link string provides access to the particular link.
|
|
|
|
\sa hoveredLink
|
|
|
|
The corresponding handler is \c onLinkHovered.
|
|
*/
|
|
signal linkHovered(string link)
|
|
|
|
/*!
|
|
\qmlsignal TextArea::editingFinished()
|
|
\since QtQuick.Controls 1.5
|
|
|
|
This signal is emitted when the text area loses focus.
|
|
|
|
The corresponding handler is \c onEditingFinished.
|
|
*/
|
|
signal editingFinished()
|
|
|
|
/*!
|
|
\qmlproperty string TextArea::hoveredLink
|
|
\since QtQuick.Controls 1.1
|
|
|
|
This property contains the link string when user hovers a link
|
|
embedded in the text. The link must be in rich text or HTML format
|
|
and the link string provides access to the particular link.
|
|
*/
|
|
readonly property alias hoveredLink: edit.hoveredLink
|
|
|
|
/*!
|
|
\since QtQuick.Controls 1.3
|
|
|
|
This property contains the edit \l Menu for working
|
|
with text selection. Set it to \c null if no menu
|
|
is wanted.
|
|
|
|
\sa Menu
|
|
*/
|
|
property Component menu: editMenu.defaultMenu
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::append(string text)
|
|
|
|
Appends \a string as a new line to the end of the text area.
|
|
*/
|
|
function append (string) {
|
|
edit.append(string)
|
|
__verticalScrollBar.value = __verticalScrollBar.maximumValue
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::copy()
|
|
|
|
Copies the currently selected text to the system clipboard.
|
|
*/
|
|
function copy() {
|
|
edit.copy();
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::cut()
|
|
|
|
Moves the currently selected text to the system clipboard.
|
|
*/
|
|
function cut() {
|
|
edit.cut();
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::deselect()
|
|
|
|
Removes active text selection.
|
|
*/
|
|
function deselect() {
|
|
edit.deselect();
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod string TextArea::getFormattedText(int start, int end)
|
|
|
|
Returns the section of text that is between the \a start and \a end positions.
|
|
|
|
The returned text will be formatted according to the \l textFormat property.
|
|
*/
|
|
function getFormattedText(start, end) {
|
|
return edit.getFormattedText(start, end);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod string TextArea::getText(int start, int end)
|
|
|
|
Returns the section of text that is between the \a start and \a end positions.
|
|
|
|
The returned text does not include any rich text formatting.
|
|
*/
|
|
function getText(start, end) {
|
|
return edit.getText(start, end);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::insert(int position, string text)
|
|
|
|
Inserts \a text into the TextArea at position.
|
|
*/
|
|
function insert(position, text) {
|
|
edit.insert(position, text);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod bool TextArea::isRightToLeft(int start, int end)
|
|
|
|
Returns true if the natural reading direction of the editor text
|
|
found between positions \a start and \a end is right to left.
|
|
*/
|
|
function isRightToLeft(start, end) {
|
|
return edit.isRightToLeft(start, end);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::moveCursorSelection(int position, SelectionMode mode = TextEdit.SelectCharacters)
|
|
|
|
Moves the cursor to \a position and updates the selection according to the optional \a mode
|
|
parameter. (To only move the cursor, set the \l cursorPosition property.)
|
|
|
|
When this method is called it additionally sets either the
|
|
selectionStart or the selectionEnd (whichever was at the previous cursor position)
|
|
to the specified position. This allows you to easily extend and contract the selected
|
|
text range.
|
|
|
|
The selection mode specifies whether the selection is updated on a per character or a per word
|
|
basis. If not specified the selection mode will default to TextEdit.SelectCharacters.
|
|
|
|
\list
|
|
\li TextEdit.SelectCharacters - Sets either the selectionStart or selectionEnd (whichever was at
|
|
the previous cursor position) to the specified position.
|
|
\li TextEdit.SelectWords - Sets the selectionStart and selectionEnd to include all
|
|
words between the specified position and the previous cursor position. Words partially in the
|
|
range are included.
|
|
\endlist
|
|
|
|
For example, take this sequence of calls:
|
|
|
|
\code
|
|
cursorPosition = 5
|
|
moveCursorSelection(9, TextEdit.SelectCharacters)
|
|
moveCursorSelection(7, TextEdit.SelectCharacters)
|
|
\endcode
|
|
|
|
This moves the cursor to the 5th position, extends the selection end from 5 to 9,
|
|
and then retracts the selection end from 9 to 7, leaving the text from the 5th
|
|
position to the 7th position selected (the 6th and 7th characters).
|
|
|
|
The same sequence with TextEdit.SelectWords will extend the selection start to a word boundary
|
|
before or on the 5th position, and extend the selection end to a word boundary on or past the 9th position.
|
|
*/
|
|
function moveCursorSelection(position, mode) {
|
|
edit.moveCursorSelection(position, mode);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::paste()
|
|
|
|
Replaces the currently selected text by the contents of the system clipboard.
|
|
*/
|
|
function paste() {
|
|
edit.paste();
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod int TextArea::positionAt(int x, int y)
|
|
|
|
Returns the text position closest to pixel position (\a x, \a y).
|
|
|
|
Position 0 is before the first character, position 1 is after the first character
|
|
but before the second, and so on until position \l {text}.length, which is after all characters.
|
|
*/
|
|
function positionAt(x, y) {
|
|
return edit.positionAt(x, y);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod rectangle TextArea::positionToRectangle(position)
|
|
|
|
Returns the rectangle at the given \a position in the text. The x, y,
|
|
and height properties correspond to the cursor that would describe
|
|
that position.
|
|
*/
|
|
function positionToRectangle(position) {
|
|
return edit.positionToRectangle(position);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::redo()
|
|
|
|
Redoes the last operation if redo is \l {canRedo}{available}.
|
|
*/
|
|
function redo() {
|
|
edit.redo();
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod string TextArea::remove(int start, int end)
|
|
|
|
Removes the section of text that is between the \a start and \a end positions from the TextArea.
|
|
*/
|
|
function remove(start, end) {
|
|
return edit.remove(start, end);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::select(int start, int end)
|
|
|
|
Causes the text from \a start to \a end to be selected.
|
|
|
|
If either start or end is out of range, the selection is not changed.
|
|
|
|
After calling this, selectionStart will become the lesser
|
|
and selectionEnd will become the greater (regardless of the order passed
|
|
to this method).
|
|
|
|
\sa selectionStart, selectionEnd
|
|
*/
|
|
function select(start, end) {
|
|
edit.select(start, end);
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::selectAll()
|
|
|
|
Causes all text to be selected.
|
|
*/
|
|
function selectAll() {
|
|
edit.selectAll();
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::selectWord()
|
|
|
|
Causes the word closest to the current cursor position to be selected.
|
|
*/
|
|
function selectWord() {
|
|
edit.selectWord();
|
|
}
|
|
|
|
/*!
|
|
\qmlmethod void TextArea::undo()
|
|
|
|
Undoes the last operation if undo is \l {canUndo}{available}. Deselects any
|
|
current selection, and updates the selection start to the current cursor
|
|
position.
|
|
*/
|
|
function undo() {
|
|
edit.undo();
|
|
}
|
|
|
|
/*! \qmlproperty bool TextArea::backgroundVisible
|
|
|
|
This property determines if the background should be filled or not.
|
|
|
|
The default value is \c true.
|
|
*/
|
|
property alias backgroundVisible: colorRect.visible
|
|
|
|
/*! \internal */
|
|
default property alias data: area.data
|
|
|
|
/*! \qmlproperty real TextArea::textMargin
|
|
\since QtQuick.Controls 1.1
|
|
|
|
The margin, in pixels, around the text in the TextArea.
|
|
*/
|
|
property alias textMargin: edit.textMargin
|
|
|
|
/*! \qmlproperty real TextArea::contentWidth
|
|
\since QtQuick.Controls 1.3
|
|
|
|
The width of the text content.
|
|
*/
|
|
readonly property alias contentWidth: edit.contentWidth
|
|
|
|
/*! \qmlproperty real TextArea::contentHeight
|
|
\since QtQuick.Controls 1.3
|
|
|
|
The height of the text content.
|
|
*/
|
|
readonly property alias contentHeight: edit.contentHeight
|
|
|
|
frameVisible: true
|
|
|
|
activeFocusOnTab: true
|
|
|
|
Accessible.role: Accessible.EditableText
|
|
|
|
style: Settings.styleComponent(Settings.style, "TextAreaStyle.qml", area)
|
|
|
|
/*!
|
|
\qmlproperty TextDocument TextArea::textDocument
|
|
|
|
This property exposes the \l QQuickTextDocument of this TextArea.
|
|
\sa TextEdit::textDocument
|
|
*/
|
|
property alias textDocument: edit.textDocument
|
|
|
|
Flickable {
|
|
id: flickable
|
|
|
|
interactive: !edit.selectByMouse
|
|
anchors.fill: parent
|
|
|
|
TextEdit {
|
|
id: edit
|
|
focus: true
|
|
cursorDelegate: __style && __style.__cursorDelegate ? __style.__cursorDelegate : null
|
|
persistentSelection: true
|
|
|
|
Rectangle {
|
|
id: colorRect
|
|
parent: viewport
|
|
anchors.fill: parent
|
|
color: __style ? __style.backgroundColor : "white"
|
|
z: -1
|
|
}
|
|
|
|
property int layoutRecursionDepth: 0
|
|
|
|
function doLayout() {
|
|
// scrollbars affect the document/viewport size and vice versa, so we
|
|
// must allow the layout loop to recurse twice until the sizes stabilize
|
|
if (layoutRecursionDepth <= 2) {
|
|
layoutRecursionDepth++
|
|
|
|
if (wrapMode == TextEdit.NoWrap) {
|
|
__horizontalScrollBar.visible = edit.contentWidth > viewport.width
|
|
edit.width = Math.max(viewport.width, edit.contentWidth)
|
|
} else {
|
|
__horizontalScrollBar.visible = false
|
|
edit.width = viewport.width
|
|
}
|
|
edit.height = Math.max(viewport.height, edit.contentHeight)
|
|
|
|
flickable.contentWidth = edit.contentWidth
|
|
flickable.contentHeight = edit.contentHeight
|
|
|
|
layoutRecursionDepth--
|
|
}
|
|
}
|
|
|
|
Connections {
|
|
target: area.viewport
|
|
onWidthChanged: edit.doLayout()
|
|
onHeightChanged: edit.doLayout()
|
|
}
|
|
onContentWidthChanged: edit.doLayout()
|
|
onContentHeightChanged: edit.doLayout()
|
|
onWrapModeChanged: edit.doLayout()
|
|
|
|
renderType: __style ? __style.renderType : Text.NativeRendering
|
|
font: __style ? __style.font : TextSingleton.font
|
|
color: __style ? __style.textColor : "darkgray"
|
|
selectionColor: __style ? __style.selectionColor : "darkred"
|
|
selectedTextColor: __style ? __style.selectedTextColor : "white"
|
|
wrapMode: TextEdit.WordWrap
|
|
textMargin: __style && __style.textMargin !== undefined ? __style.textMargin : 4
|
|
|
|
selectByMouse: area.selectByMouse && Qt.platform.os != "ios" && (!Settings.isMobile || !cursorHandle.delegate || !selectionHandle.delegate)
|
|
readOnly: false
|
|
|
|
Keys.forwardTo: area
|
|
|
|
KeyNavigation.priority: KeyNavigation.BeforeItem
|
|
KeyNavigation.tab: area.tabChangesFocus ? area.KeyNavigation.tab : null
|
|
KeyNavigation.backtab: area.tabChangesFocus ? area.KeyNavigation.backtab : null
|
|
|
|
property bool blockRecursion: false
|
|
property bool hasSelection: selectionStart !== selectionEnd
|
|
readonly property int selectionPosition: selectionStart !== cursorPosition ? selectionStart : selectionEnd
|
|
|
|
// force re-evaluation when contentWidth changes => text layout changes => selection moves
|
|
property rect selectionRectangle: contentWidth ? positionToRectangle(selectionPosition)
|
|
: positionToRectangle(selectionPosition)
|
|
|
|
onSelectionStartChanged: syncHandlesWithSelection()
|
|
onCursorPositionChanged: syncHandlesWithSelection()
|
|
|
|
function syncHandlesWithSelection()
|
|
{
|
|
if (!blockRecursion && selectionHandle.delegate) {
|
|
blockRecursion = true
|
|
// We cannot use property selectionPosition since it gets updated after onSelectionStartChanged
|
|
cursorHandle.position = cursorPosition
|
|
selectionHandle.position = (selectionStart !== cursorPosition) ? selectionStart : selectionEnd
|
|
blockRecursion = false
|
|
}
|
|
ensureVisible(cursorRectangle)
|
|
}
|
|
|
|
function ensureVisible(rect) {
|
|
if (rect.y >= flickableItem.contentY + viewport.height - rect.height - textMargin) {
|
|
// moving down
|
|
flickableItem.contentY = rect.y - viewport.height + rect.height + textMargin
|
|
} else if (rect.y < flickableItem.contentY) {
|
|
// moving up
|
|
flickableItem.contentY = rect.y - textMargin
|
|
}
|
|
|
|
if (rect.x >= flickableItem.contentX + viewport.width - textMargin) {
|
|
// moving right
|
|
flickableItem.contentX = rect.x - viewport.width + textMargin
|
|
} else if (rect.x < flickableItem.contentX) {
|
|
// moving left
|
|
flickableItem.contentX = rect.x - textMargin
|
|
}
|
|
}
|
|
|
|
onLinkActivated: area.linkActivated(link)
|
|
onLinkHovered: area.linkHovered(link)
|
|
onEditingFinished: area.editingFinished()
|
|
|
|
function activate() {
|
|
if (activeFocusOnPress) {
|
|
forceActiveFocus()
|
|
if (!readOnly)
|
|
Qt.inputMethod.show()
|
|
}
|
|
cursorHandle.activate()
|
|
selectionHandle.activate()
|
|
}
|
|
|
|
function moveHandles(cursor, selection) {
|
|
blockRecursion = true
|
|
cursorPosition = cursor
|
|
if (selection === -1) {
|
|
selectWord()
|
|
selection = selectionStart
|
|
}
|
|
selectionHandle.position = selection
|
|
cursorHandle.position = cursorPosition
|
|
blockRecursion = false
|
|
}
|
|
|
|
MouseArea {
|
|
id: mouseArea
|
|
anchors.fill: parent
|
|
cursorShape: edit.hoveredLink ? Qt.PointingHandCursor : Qt.IBeamCursor
|
|
acceptedButtons: (edit.selectByMouse ? Qt.NoButton : Qt.LeftButton) | (area.menu ? Qt.RightButton : Qt.NoButton)
|
|
onClicked: {
|
|
if (editMenu.item)
|
|
return;
|
|
var pos = edit.positionAt(mouse.x, mouse.y)
|
|
edit.moveHandles(pos, pos)
|
|
edit.activate()
|
|
}
|
|
onPressAndHold: {
|
|
if (editMenu.item)
|
|
return;
|
|
var pos = edit.positionAt(mouse.x, mouse.y)
|
|
edit.moveHandles(pos, area.selectByMouse ? -1 : pos)
|
|
edit.activate()
|
|
}
|
|
}
|
|
|
|
EditMenu {
|
|
id: editMenu
|
|
control: area
|
|
input: edit
|
|
mouseArea: mouseArea
|
|
cursorHandle: cursorHandle
|
|
selectionHandle: selectionHandle
|
|
flickable: flickable
|
|
anchors.fill: parent
|
|
}
|
|
|
|
ScenePosListener {
|
|
id: listener
|
|
item: edit
|
|
enabled: edit.activeFocus && Qt.platform.os !== "ios" && Settings.isMobile
|
|
}
|
|
|
|
TextHandle {
|
|
id: selectionHandle
|
|
|
|
editor: edit
|
|
control: area
|
|
z: 1000001 // DefaultWindowDecoration+1
|
|
parent: !edit.activeFocus || Qt.platform.os === "ios" ? editor : Window.contentItem // float (QTBUG-42538)
|
|
active: area.selectByMouse && Settings.isMobile
|
|
delegate: __style.__selectionHandle
|
|
maximum: cursorHandle.position - 1
|
|
|
|
// Mention scenePos, contentX and contentY in the mappedPos binding to force re-evaluation if they change
|
|
property var mappedPos: listener.scenePos.x !== listener.scenePos.y !== flickableItem.contentX !== flickableItem.contentY !== Number.MAX_VALUE ?
|
|
editor.mapToItem(parent, editor.selectionRectangle.x, editor.selectionRectangle.y) : -1
|
|
x: mappedPos.x
|
|
y: mappedPos.y
|
|
|
|
property var posInViewport: flickableItem.contentX !== flickableItem.contentY !== Number.MAX_VALUE ?
|
|
viewport.mapFromItem(parent, handleX, handleY) : -1
|
|
visible: pressed || (edit.hasSelection
|
|
&& posInViewport.y + handleHeight >= -1
|
|
&& posInViewport.y <= viewport.height + 1
|
|
&& posInViewport.x + handleWidth >= -1
|
|
&& posInViewport.x <= viewport.width + 1)
|
|
|
|
onPositionChanged: {
|
|
if (!edit.blockRecursion) {
|
|
edit.blockRecursion = true
|
|
edit.select(selectionHandle.position, cursorHandle.position)
|
|
if (pressed)
|
|
edit.ensureVisible(edit.selectionRectangle)
|
|
edit.blockRecursion = false
|
|
}
|
|
}
|
|
}
|
|
|
|
TextHandle {
|
|
id: cursorHandle
|
|
|
|
editor: edit
|
|
control: area
|
|
z: 1000001 // DefaultWindowDecoration+1
|
|
parent: !edit.activeFocus || Qt.platform.os === "ios" ? editor : Window.contentItem // float (QTBUG-42538)
|
|
active: area.selectByMouse && Settings.isMobile
|
|
delegate: __style.__cursorHandle
|
|
minimum: edit.hasSelection ? selectionHandle.position + 1 : -1
|
|
|
|
// Mention scenePos, contentX and contentY in the mappedPos binding to force re-evaluation if they change
|
|
property var mappedPos: listener.scenePos.x !== listener.scenePos.y !== flickableItem.contentX !== flickableItem.contentY !== Number.MAX_VALUE ?
|
|
editor.mapToItem(parent, editor.cursorRectangle.x, editor.cursorRectangle.y) : -1
|
|
x: mappedPos.x
|
|
y: mappedPos.y
|
|
|
|
property var posInViewport: flickableItem.contentX !== flickableItem.contentY !== Number.MAX_VALUE ?
|
|
viewport.mapFromItem(parent, handleX, handleY) : -1
|
|
visible: pressed || ((edit.cursorVisible || edit.hasSelection)
|
|
&& posInViewport.y + handleHeight >= -1
|
|
&& posInViewport.y <= viewport.height + 1
|
|
&& posInViewport.x + handleWidth >= -1
|
|
&& posInViewport.x <= viewport.width + 1)
|
|
|
|
onPositionChanged: {
|
|
if (!edit.blockRecursion) {
|
|
edit.blockRecursion = true
|
|
if (!edit.hasSelection)
|
|
selectionHandle.position = cursorHandle.position
|
|
edit.select(selectionHandle.position, cursorHandle.position)
|
|
edit.blockRecursion = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
Keys.onPressed: {
|
|
if (event.key == Qt.Key_PageUp) {
|
|
__verticalScrollBar.value -= area.height
|
|
} else if (event.key == Qt.Key_PageDown)
|
|
__verticalScrollBar.value += area.height
|
|
}
|
|
|
|
}
|