summaryrefslogtreecommitdiffstats
path: root/src/declarative
diff options
context:
space:
mode:
Diffstat (limited to 'src/declarative')
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit.cpp40
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextedit_p.h4
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput.cpp59
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextinput_p.h6
-rw-r--r--src/declarative/graphicsitems/qdeclarativetextlayout.cpp11
5 files changed, 101 insertions, 19 deletions
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit.cpp b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
index 59921d5..c28d7f4 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextedit.cpp
@@ -606,6 +606,22 @@ int QDeclarativeTextEdit::positionAt(int x, int y) const
{
Q_D(const QDeclarativeTextEdit);
int r = d->document->documentLayout()->hitTest(QPoint(x,y-d->yoff), Qt::FuzzyHit);
+ QTextCursor cursor = d->control->textCursor();
+ if (r > cursor.position()) {
+ // The cursor position includes positions within the preedit text, but only positions in the
+ // same text block are offset so it is possible to get a position that is either part of the
+ // preedit or the next text block.
+ QTextLayout *layout = cursor.block().layout();
+ const int preeditLength = layout
+ ? layout->preeditAreaText().length()
+ : 0;
+ if (preeditLength > 0
+ && d->document->documentLayout()->blockBoundingRect(cursor.block()).contains(x,y-d->yoff)) {
+ r = r > cursor.position() + preeditLength
+ ? r - preeditLength
+ : cursor.position();
+ }
+ }
return r;
}
@@ -1318,7 +1334,10 @@ Handles the given input method \a event.
void QDeclarativeTextEdit::inputMethodEvent(QInputMethodEvent *event)
{
Q_D(QDeclarativeTextEdit);
+ const bool wasComposing = isInputMethodComposing();
d->control->processEvent(event, QPointF(0, -d->yoff));
+ if (wasComposing != isInputMethodComposing())
+ emit inputMethodComposingChanged();
}
/*!
@@ -1394,6 +1413,27 @@ bool QDeclarativeTextEdit::canPaste() const
return d->canPaste;
}
+/*!
+ \qmlproperty bool TextEdit::isInputMethodComposing()
+
+ \since QtQuick 1.1
+
+ This property holds whether the TextEdit has partial text input from an
+ input method.
+
+ While it is composing an input method may rely on mouse or key events from
+ the TextEdit 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.
+*/
+bool QDeclarativeTextEdit::isInputMethodComposing() const
+{
+ Q_D(const QDeclarativeTextEdit);
+ if (QTextLayout *layout = d->control->textCursor().block().layout())
+ return layout->preeditAreaText().length() > 0;
+ return false;
+}
+
void QDeclarativeTextEditPrivate::init()
{
Q_Q(QDeclarativeTextEdit);
diff --git a/src/declarative/graphicsitems/qdeclarativetextedit_p.h b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
index 7785a7a..612f9a9 100644
--- a/src/declarative/graphicsitems/qdeclarativetextedit_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextedit_p.h
@@ -94,6 +94,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextEdit : public QDeclarativeImplicitSizePa
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged REVISION 1)
Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged REVISION 1)
+ Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged REVISION 1)
public:
QDeclarativeTextEdit(QDeclarativeItem *parent=0);
@@ -215,6 +216,8 @@ public:
QRectF boundingRect() const;
+ bool isInputMethodComposing() const;
+
Q_SIGNALS:
void textChanged(const QString &);
void paintedSizeChanged();
@@ -242,6 +245,7 @@ Q_SIGNALS:
Q_REVISION(1) void mouseSelectionModeChanged(SelectionMode mode);
Q_REVISION(1) void linkActivated(const QString &link);
Q_REVISION(1) void canPasteChanged();
+ Q_REVISION(1) void inputMethodComposingChanged();
public Q_SLOTS:
void selectAll();
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput.cpp b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
index 65ed5c6..dc44bfe 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextinput.cpp
@@ -482,6 +482,7 @@ QRect QDeclarativeTextInput::cursorRectangle() const
Q_D(const QDeclarativeTextInput);
QRect r = d->control->cursorRect();
r.setHeight(r.height()-1); // Make consistent with TextEdit (QLineControl inexplicably adds 1)
+ r.moveLeft(r.x() - d->hscroll);
return r;
}
@@ -921,6 +922,8 @@ void QDeclarativeTextInput::moveCursor()
QRectF QDeclarativeTextInput::positionToRectangle(int pos) const
{
Q_D(const QDeclarativeTextInput);
+ if (pos > d->control->cursorPosition())
+ pos += d->control->preeditAreaText().length();
return QRectF(d->control->cursorToX(pos)-d->hscroll,
0.0,
d->control->cursorWidth(),
@@ -929,8 +932,7 @@ QRectF QDeclarativeTextInput::positionToRectangle(int pos) const
int QDeclarativeTextInput::positionAt(int x) const
{
- Q_D(const QDeclarativeTextInput);
- return d->control->xToPos(x + d->hscroll);
+ return positionAt(x, CursorBetweenCharacters);
}
/*!
@@ -952,10 +954,18 @@ int QDeclarativeTextInput::positionAt(int x) const
\o TextInput.CursorOnCharacter - Returns the position before the character that is nearest x.
\endlist
*/
-int QDeclarativeTextInput::positionAt(int x, CursorPosition position)
+int QDeclarativeTextInput::positionAt(int x, CursorPosition position) const
{
Q_D(const QDeclarativeTextInput);
- return d->control->xToPos(x + d->hscroll, QTextLine::CursorPosition(position));
+ int pos = d->control->xToPos(x + d->hscroll, QTextLine::CursorPosition(position));
+ const int cursor = d->control->cursor();
+ if (pos > cursor) {
+ const int preeditLength = d->control->preeditAreaText().length();
+ pos = pos > cursor + preeditLength
+ ? pos - preeditLength
+ : cursor;
+ }
+ return pos;
}
void QDeclarativeTextInputPrivate::focusChanged(bool hasFocus)
@@ -996,18 +1006,22 @@ void QDeclarativeTextInput::inputMethodEvent(QInputMethodEvent *ev)
{
Q_D(QDeclarativeTextInput);
ev->ignore();
+ const bool wasComposing = d->control->preeditAreaText().length() > 0;
inputMethodPreHandler(ev);
- if (ev->isAccepted())
- return;
- if (d->control->isReadOnly()) {
- ev->ignore();
- } else {
- d->control->processInputMethodEvent(ev);
- updateSize();
- d->updateHorizontalScroll();
+ if (!ev->isAccepted()) {
+ if (d->control->isReadOnly()) {
+ ev->ignore();
+ } else {
+ d->control->processInputMethodEvent(ev);
+ updateSize();
+ d->updateHorizontalScroll();
+ }
}
if (!ev->isAccepted())
QDeclarativePaintedItem::inputMethodEvent(ev);
+
+ if (wasComposing != (d->control->preeditAreaText().length() > 0))
+ emit inputMethodComposingChanged();
}
/*!
@@ -1061,7 +1075,7 @@ void QDeclarativeTextInput::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
{
Q_D(QDeclarativeTextInput);
if (d->sendMouseEventToInputContext(event, QEvent::MouseMove))
- event->setAccepted(true);
+ return;
if (d->selectByMouse) {
if (qAbs(int(event->pos().x() - d->pressPos.x())) > QApplication::startDragDistance())
setKeepMouseGrab(true);
@@ -1706,6 +1720,25 @@ void QDeclarativeTextInput::focusInEvent(QFocusEvent *event)
QDeclarativePaintedItem::focusInEvent(event);
}
+/*!
+ \qmlproperty bool TextInput::isInputMethodComposing()
+
+ \since QtQuick 1.1
+
+ This property holds whether the TextInput has partial text input from an
+ input method.
+
+ While it is composing an input method may rely on mouse or key events from
+ the TextInput 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.
+*/
+bool QDeclarativeTextInput::isInputMethodComposing() const
+{
+ Q_D(const QDeclarativeTextInput);
+ return d->control->preeditAreaText().length() > 0;
+}
+
void QDeclarativeTextInputPrivate::init()
{
Q_Q(QDeclarativeTextInput);
diff --git a/src/declarative/graphicsitems/qdeclarativetextinput_p.h b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
index c29be26..822d5e2 100644
--- a/src/declarative/graphicsitems/qdeclarativetextinput_p.h
+++ b/src/declarative/graphicsitems/qdeclarativetextinput_p.h
@@ -97,6 +97,7 @@ class Q_AUTOTEST_EXPORT QDeclarativeTextInput : public QDeclarativeImplicitSizeP
Q_PROPERTY(bool selectByMouse READ selectByMouse WRITE setSelectByMouse NOTIFY selectByMouseChanged)
Q_PROPERTY(SelectionMode mouseSelectionMode READ mouseSelectionMode WRITE setMouseSelectionMode NOTIFY mouseSelectionModeChanged REVISION 1)
Q_PROPERTY(bool canPaste READ canPaste NOTIFY canPasteChanged REVISION 1)
+ Q_PROPERTY(bool inputMethodComposing READ isInputMethodComposing NOTIFY inputMethodComposingChanged REVISION 1)
public:
QDeclarativeTextInput(QDeclarativeItem* parent=0);
@@ -127,7 +128,7 @@ public:
//Auxilliary functions needed to control the TextInput from QML
Q_INVOKABLE int positionAt(int x) const;
- Q_INVOKABLE Q_REVISION(1) int positionAt(int x, CursorPosition position);
+ Q_INVOKABLE Q_REVISION(1) int positionAt(int x, CursorPosition position) const;
Q_INVOKABLE QRectF positionToRectangle(int pos) const;
Q_INVOKABLE void moveCursorSelection(int pos);
Q_INVOKABLE Q_REVISION(1) void moveCursorSelection(int pos, SelectionMode mode);
@@ -210,6 +211,8 @@ public:
QRectF boundingRect() const;
bool canPaste() const;
+ bool isInputMethodComposing() const;
+
Q_SIGNALS:
void textChanged();
void cursorPositionChanged();
@@ -237,6 +240,7 @@ Q_SIGNALS:
void selectByMouseChanged(bool selectByMouse);
Q_REVISION(1) void mouseSelectionModeChanged(SelectionMode mode);
Q_REVISION(1) void canPasteChanged();
+ Q_REVISION(1) void inputMethodComposingChanged();
protected:
virtual void geometryChanged(const QRectF &newGeometry,
diff --git a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
index b24dd2c..31819f5 100644
--- a/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
+++ b/src/declarative/graphicsitems/qdeclarativetextlayout.cpp
@@ -99,7 +99,6 @@ class DrawTextItemRecorder: public QPaintEngine
needFreshCurrentItem = false;
last.numChars += ti.num_chars;
- last.numGlyphs += ti.glyphs.numGlyphs;
}
}
@@ -111,7 +110,7 @@ class DrawTextItemRecorder: public QPaintEngine
currentItem.font = ti.font();
currentItem.charOffset = charOffset;
currentItem.numChars = ti.num_chars;
- currentItem.numGlyphs = ti.glyphs.numGlyphs;
+ currentItem.numGlyphs = 0;
currentItem.glyphOffset = glyphOffset;
currentItem.positionOffset = positionOffset;
currentItem.useBackendOptimizations = m_useBackendOptimizations;
@@ -121,6 +120,8 @@ class DrawTextItemRecorder: public QPaintEngine
m_inertText->items.append(currentItem);
}
+ QStaticTextItem &currentItem = m_inertText->items.last();
+
QTransform matrix = m_untransformedCoordinates ? QTransform() : state->transform();
matrix.translate(position.x(), position.y());
@@ -129,18 +130,18 @@ class DrawTextItemRecorder: public QPaintEngine
ti.fontEngine->getGlyphPositions(ti.glyphs, matrix, ti.flags, glyphs, positions);
int size = glyphs.size();
- Q_ASSERT(size == ti.glyphs.numGlyphs);
Q_ASSERT(size == positions.size());
+ currentItem.numGlyphs += size;
m_inertText->glyphs.resize(m_inertText->glyphs.size() + size);
m_inertText->positions.resize(m_inertText->glyphs.size());
m_inertText->chars.resize(m_inertText->chars.size() + ti.num_chars);
glyph_t *glyphsDestination = m_inertText->glyphs.data() + glyphOffset;
- qMemCopy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * ti.glyphs.numGlyphs);
+ qMemCopy(glyphsDestination, glyphs.constData(), sizeof(glyph_t) * size);
QFixedPoint *positionsDestination = m_inertText->positions.data() + positionOffset;
- qMemCopy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * ti.glyphs.numGlyphs);
+ qMemCopy(positionsDestination, positions.constData(), sizeof(QFixedPoint) * size);
QChar *charsDestination = m_inertText->chars.data() + charOffset;
qMemCopy(charsDestination, ti.chars, sizeof(QChar) * ti.num_chars);