summaryrefslogtreecommitdiffstats
path: root/src/declarative/fx/qfxtextedit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative/fx/qfxtextedit.cpp')
-rw-r--r--src/declarative/fx/qfxtextedit.cpp248
1 files changed, 243 insertions, 5 deletions
diff --git a/src/declarative/fx/qfxtextedit.cpp b/src/declarative/fx/qfxtextedit.cpp
index 7a42bdf..cdd94b5 100644
--- a/src/declarative/fx/qfxtextedit.cpp
+++ b/src/declarative/fx/qfxtextedit.cpp
@@ -41,10 +41,8 @@
#include <qfxtextedit.h>
#include "qfxtextedit_p.h"
-
#include <private/qtextcontrol_p.h>
-
-#include <qfxperf.h>
+#include <private/qfxperf_p.h>
#include "qfxevents_p.h"
#include <QTextLayout>
#include <QTextLine>
@@ -175,7 +173,7 @@ void QFxTextEdit::setText(const QString &text)
Supported text formats are \c AutoText, \c PlainText and \c RichText.
The default is AutoText. If the text format is AutoText the text edit
- edit will automatically determine whether the text should be treated as
+ will automatically determine whether the text should be treated as
rich text. This determination is made using Qt::mightBeRichText().
\table
@@ -320,6 +318,36 @@ void QFxTextEdit::setHighlightColor(const QColor &color)
}
/*!
+ \qmlproperty color TextEdit::highlightedTextColor
+
+ The highlighted text color, used in selections.
+*/
+
+/*!
+ \property QFxTextEdit::highlightedTextColor
+ \brief the text edit's default highlighted text color
+*/
+QColor QFxTextEdit::highlightedTextColor() const
+{
+ Q_D(const QFxTextEdit);
+ return d->highlightColor;
+}
+
+void QFxTextEdit::setHighlightedTextColor(const QColor &color)
+{
+ Q_D(QFxTextEdit);
+ if (d->highlightedTextColor == color)
+ return;
+
+ clearCache();
+ d->highlightedTextColor = color;
+ QPalette pal = d->control->palette();
+ pal.setColor(QPalette::HighlightedText, color);
+ d->control->setPalette(pal);
+ update();
+}
+
+/*!
\qmlproperty enumeration TextEdit::hAlign
\qmlproperty enumeration TextEdit::vAlign
@@ -406,7 +434,7 @@ void QFxTextEdit::setWrap(bool w)
}
/*!
- \property QFxTextEdit::cursorVisible
+ \qmlproperty TextEdit::cursorVisible
\brief If true the text edit shows a cursor.
This property is set and unset when the text edit gets focus, but it can also
@@ -431,6 +459,164 @@ void QFxTextEdit::setCursorVisible(bool on)
}
/*!
+ \qmlproperty TextEdit::cursorPosition
+ \brief The position of the cursor in the TextEdit.
+*/
+int QFxTextEdit::cursorPosition() const
+{
+ Q_D(const QFxTextEdit);
+ return d->control->textCursor().position();
+}
+
+void QFxTextEdit::setCursorPosition(int pos)
+{
+ Q_D(QFxTextEdit);
+ QTextCursor cursor = d->control->textCursor();
+ if (cursor.position() == pos)
+ return;
+ cursor.setPosition(pos);
+ d->control->setTextCursor(cursor);
+}
+
+/*!
+ \qmlproperty TextEdit::cursorDelegate
+ \brief The delegate for the cursor in the TextEdit.
+
+ If you set a cursorDelegate for a TextEdit, this delegate will be used for
+ drawing the cursor instead of the standard cursor. An instance of the
+ delegate will be created and managed by the text edit when a cursor is
+ needed, and the x and y properties of delegate instance will be set so as
+ to be one pixel before the top left of the current character.
+
+ Note that the root item of the delegate component must be a QFxItem or
+ QFxItem derived item.
+*/
+QmlComponent* QFxTextEdit::cursorDelegate() const
+{
+ Q_D(const QFxTextEdit);
+ return d->cursorComponent;
+}
+
+void QFxTextEdit::setCursorDelegate(QmlComponent* c)
+{
+ Q_D(QFxTextEdit);
+ if(d->cursorComponent){
+ delete d->cursorComponent;
+ if(d->cursor){
+ disconnect(d->control, SIGNAL(cursorPositionChanged()),
+ this, SLOT(moveCursorDelegate()));
+ d->control->setCursorWidth(-1);
+ dirtyCache(cursorRect());
+ delete d->cursor;
+ d->cursor = 0;
+ }
+ }
+ d->cursorComponent = c;
+ if(c && c->isReady()){
+ loadCursorDelegate();
+ }else{
+ if(c)
+ connect(c, SIGNAL(statusChanged()),
+ this, SLOT(loadCursorDelegate()));
+ }
+}
+
+void QFxTextEdit::loadCursorDelegate()
+{
+ Q_D(QFxTextEdit);
+ if(d->cursorComponent->isLoading())
+ return;
+ d->cursor = qobject_cast<QFxItem*>(d->cursorComponent->create(qmlContext(this)));
+ if(d->cursor){
+ connect(d->control, SIGNAL(cursorPositionChanged()),
+ this, SLOT(moveCursorDelegate()));
+ d->control->setCursorWidth(0);
+ dirtyCache(cursorRect());
+ d->cursor->setItemParent(this);
+ d->cursor->setHeight(QFontMetrics(d->font.font()).height());
+ moveCursorDelegate();
+ }else{
+ qWarning() << "Error loading cursor delegate for TextEdit:" + objectName();
+ }
+}
+
+/*!
+ \qmlproperty int TextEdit::selectionStart
+
+ The cursor position before the first character in the current selection.
+ Setting this and selectionEnd allows you to specify a selection in the
+ text edit.
+
+ Note that if selectionStart == selectionEnd then there is no current
+ selection. If you attempt to set selectionStart to a value outside of
+ the current text, selectionStart will not be changed.
+
+ \sa selectionEnd, cursorPosition, selectedText
+*/
+int QFxTextEdit::selectionStart() const
+{
+ Q_D(const QFxTextEdit);
+ return d->control->textCursor().selectionStart();
+}
+
+void QFxTextEdit::setSelectionStart(int s)
+{
+ Q_D(QFxTextEdit);
+ if(d->lastSelectionStart == s || s < 0 || s > text().length())
+ return;
+ d->lastSelectionStart = s;
+ d->updateSelection();// Will emit the relevant signals
+}
+
+/*!
+ \qmlproperty int TextEdit::selectionEnd
+
+ The cursor position after the last character in the current selection.
+ Setting this and selectionStart allows you to specify a selection in the
+ text edit.
+
+ Note that if selectionStart == selectionEnd then there is no current
+ selection. If you attempt to set selectionEnd to a value outside of
+ the current text, selectionEnd will not be changed.
+
+ \sa selectionStart, cursorPosition, selectedText
+*/
+int QFxTextEdit::selectionEnd() const
+{
+ Q_D(const QFxTextEdit);
+ return d->control->textCursor().selectionEnd();
+}
+
+void QFxTextEdit::setSelectionEnd(int s)
+{
+ Q_D(QFxTextEdit);
+ if(d->lastSelectionEnd == s || s < 0 || s > text().length())
+ return;
+ d->lastSelectionEnd = s;
+ d->updateSelection();// Will emit the relevant signals
+}
+
+/*!
+ \qmlproperty string TextEdit::selectedText
+
+ This read-only property provides the text currently selected in the
+ text edit.
+
+ It is equivalent to the following snippet, but is faster and easier
+ to use.
+ \code
+ //myTextEdit is the id of the TextEdit
+ myTextEdit.text.toString().substring(myTextEdit.selectionStart,
+ myTextEdit.selectionEnd);
+ \endcode
+*/
+QString QFxTextEdit::selectedText() const
+{
+ Q_D(const QFxTextEdit);
+ return d->control->textCursor().selectedText();
+}
+
+/*!
\qmlproperty bool TextEdit::focusOnPress
Whether the TextEdit should gain focus on a mouse press. By default this is
@@ -820,6 +1006,10 @@ void QFxTextEdit::fontChanged()
Q_D(QFxTextEdit);
clearCache();
d->document->setDefaultFont(d->font.font());
+ if(d->cursor){
+ d->cursor->setHeight(QFontMetrics(d->font.font()).height());
+ moveCursorDelegate();
+ }
updateSize();
emit update();
}
@@ -846,6 +1036,9 @@ void QFxTextEditPrivate::init()
QObject::connect(control, SIGNAL(updateRequest(QRectF)), q, SLOT(updateImgCache(QRectF)));
QObject::connect(control, SIGNAL(textChanged()), q, SLOT(q_textChanged()));
+ QObject::connect(control, SIGNAL(selectionChanged()), q, SIGNAL(selectionChanged()));
+ QObject::connect(control, SIGNAL(selectionChanged()), q, SLOT(updateSelectionMarkers()));
+ QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SLOT(updateSelectionMarkers()));
QObject::connect(control, SIGNAL(cursorPositionChanged()), q, SIGNAL(cursorPositionChanged()));
document = control->document();
@@ -863,6 +1056,51 @@ void QFxTextEdit::q_textChanged()
emit textChanged(text());
}
+void QFxTextEdit::moveCursorDelegate()
+{
+ Q_D(QFxTextEdit);
+ if(!d->cursor)
+ return;
+ QRectF cursorRect = d->control->cursorRect();
+ d->cursor->setX(cursorRect.x());
+ d->cursor->setY(cursorRect.y());
+}
+
+void QFxTextEditPrivate::updateSelection()
+{
+ Q_Q(QFxTextEdit);
+ QTextCursor cursor = control->textCursor();
+ bool startChange = (lastSelectionStart != cursor.selectionStart());
+ bool endChange = (lastSelectionEnd != cursor.selectionEnd());
+ //### Is it worth calculating a more minimal set of movements?
+ cursor.beginEditBlock();
+ cursor.setPosition(lastSelectionStart, QTextCursor::MoveAnchor);
+ cursor.setPosition(lastSelectionEnd, QTextCursor::KeepAnchor);
+ cursor.endEditBlock();
+ control->setTextCursor(cursor);
+ if(startChange)
+ q->selectionStartChanged();
+ if(endChange)
+ q->selectionEndChanged();
+ startChange = (lastSelectionStart != control->textCursor().selectionStart());
+ endChange = (lastSelectionEnd != control->textCursor().selectionEnd());
+ if(startChange || endChange)
+ qWarning() << "QFxTextEditPrivate::updateSelection() has failed you.";
+}
+
+void QFxTextEdit::updateSelectionMarkers()
+{
+ Q_D(QFxTextEdit);
+ if(d->lastSelectionStart != d->control->textCursor().selectionStart()){
+ d->lastSelectionStart = d->control->textCursor().selectionStart();
+ emit selectionStartChanged();
+ }
+ if(d->lastSelectionEnd != d->control->textCursor().selectionEnd()){
+ d->lastSelectionEnd = d->control->textCursor().selectionEnd();
+ emit selectionEndChanged();
+ }
+}
+
//### we should perhaps be a bit smarter here -- depending on what has changed, we shouldn't
// need to do all the calculations each time
void QFxTextEdit::updateSize()