diff options
author | Alan Alpert <alan.alpert@nokia.com> | 2009-07-08 02:49:52 (GMT) |
---|---|---|
committer | Alan Alpert <alan.alpert@nokia.com> | 2009-07-08 02:49:52 (GMT) |
commit | 69bf65348194ab339575aa0743832c1960e22962 (patch) | |
tree | 5c73baf07402e612331f5f24129f2149b7bb9794 | |
parent | 131541866b374b90e04af75ec1382154c78b69b9 (diff) | |
download | Qt-69bf65348194ab339575aa0743832c1960e22962.zip Qt-69bf65348194ab339575aa0743832c1960e22962.tar.gz Qt-69bf65348194ab339575aa0743832c1960e22962.tar.bz2 |
Add Cursor Delegate to QFxTextEdit
Adds the cursorDelegate property, including docs and autotest. No
example is included because we don't really have a text example yet.
-rw-r--r-- | src/declarative/fx/qfxtextedit.cpp | 70 | ||||
-rw-r--r-- | src/declarative/fx/qfxtextedit.h | 6 | ||||
-rw-r--r-- | src/declarative/fx/qfxtextedit_p.h | 4 | ||||
-rw-r--r-- | tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp | 80 |
4 files changed, 159 insertions, 1 deletions
diff --git a/src/declarative/fx/qfxtextedit.cpp b/src/declarative/fx/qfxtextedit.cpp index 7162bdf..bfcc17f 100644 --- a/src/declarative/fx/qfxtextedit.cpp +++ b/src/declarative/fx/qfxtextedit.cpp @@ -454,6 +454,66 @@ void QFxTextEdit::setCursorPosition(int pos) } /*! + \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{ + 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); + moveCursorDelegate(); + }else{ + qWarning() << "Error loading cursor delegate for TextEdit:" + objectName(); + } +} + +/*! \qmlproperty bool TextEdit::focusOnPress Whether the TextEdit should gain focus on a mouse press. By default this is @@ -896,6 +956,16 @@ 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()); +} + //### 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() diff --git a/src/declarative/fx/qfxtextedit.h b/src/declarative/fx/qfxtextedit.h index 6988822..4934743 100644 --- a/src/declarative/fx/qfxtextedit.h +++ b/src/declarative/fx/qfxtextedit.h @@ -78,6 +78,7 @@ class Q_DECLARATIVE_EXPORT QFxTextEdit : public QFxPaintedItem Q_PROPERTY(bool readOnly READ isReadOnly WRITE setReadOnly) Q_PROPERTY(bool cursorVisible READ isCursorVisible WRITE setCursorVisible) Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition) + Q_PROPERTY(QmlComponent* cursorDelegate READ cursorDelegate WRITE setCursorDelegate); Q_PROPERTY(bool focusOnPress READ focusOnPress WRITE setFocusOnPress) Q_PROPERTY(bool preserveSelection READ preserveSelection WRITE setPreserveSelection) Q_PROPERTY(qreal textMargin READ textMargin WRITE setTextMargin) @@ -133,6 +134,9 @@ public: int cursorPosition() const; void setCursorPosition(int pos); + QmlComponent* cursorDelegate() const; + void setCursorDelegate(QmlComponent*); + bool focusOnPress() const; void setFocusOnPress(bool on); @@ -176,6 +180,8 @@ private Q_SLOTS: void fontChanged(); void updateImgCache(const QRectF &rect); void q_textChanged(); + void moveCursorDelegate(); + void loadCursorDelegate(); private: void updateSize(); diff --git a/src/declarative/fx/qfxtextedit_p.h b/src/declarative/fx/qfxtextedit_p.h index f733a4c..d3b9c08 100644 --- a/src/declarative/fx/qfxtextedit_p.h +++ b/src/declarative/fx/qfxtextedit_p.h @@ -70,7 +70,7 @@ public: QFxTextEditPrivate() : font(0), color("black"), imgDirty(true), hAlign(QFxTextEdit::AlignLeft), vAlign(QFxTextEdit::AlignTop), dirty(false), wrap(false), richText(false), cursorVisible(false), focusOnPress(false), preserveSelection(true), - textMargin(0.0), format(QFxTextEdit::AutoText), document(0) + textMargin(0.0), cursor(0), cursorComponent(0), format(QFxTextEdit::AutoText), document(0) { } @@ -100,6 +100,8 @@ public: bool focusOnPress; bool preserveSelection; qreal textMargin; + QmlComponent* cursorComponent; + QFxItem* cursor; QFxTextEdit::TextFormat format; QTextDocument *document; QTextControl *control; diff --git a/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp index 7be5b50..b498b14 100644 --- a/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp +++ b/tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp @@ -1,6 +1,8 @@ #include <qtest.h> #include <QTextDocument> #include <QtDeclarative/qmlengine.h> +#include <QtDeclarative/qmlcontext.h> +#include <QtDeclarative/qmlexpression.h> #include <QtDeclarative/qmlcomponent.h> #include <QtDeclarative/qfxtextedit.h> #include <QFontMetrics> @@ -23,6 +25,8 @@ private slots: void font(); void color(); + void cursorDelegate(); + private: QStringList standard; QStringList richText; @@ -38,6 +42,38 @@ private: QmlEngine engine; }; +/* + Find an item with the specified id. If index is supplied then the + item must also evaluate the {index} expression equal to index + + Copied from ListView test +*/ +template<typename T> +T *findItem(QFxItem *parent, const QString &id, int index=0) +{ + const QMetaObject &mo = T::staticMetaObject; + qDebug() << parent->children()->count() << "children"; + for (int i = 0; i < parent->children()->count(); ++i) { + QFxItem *item = parent->children()->at(i); + qDebug() << "try" << item; + if (mo.cast(item) && (id.isEmpty() || item->id() == id)) { + if (index != -1) { + QmlExpression e(qmlContext(item), "index", item); + e.setTrackChange(false); + if (e.value().toInt() == index) + return static_cast<T*>(item); + } else { + return static_cast<T*>(item); + } + } + item = findItem<T>(item, id, index); + if (item) + return static_cast<T*>(item); + } + + return 0; +} + tst_qfxtextedit::tst_qfxtextedit() { standard << "the quick brown fox jumped over the lazy dog" @@ -124,6 +160,7 @@ void tst_qfxtextedit::width() QmlComponent texteditComponent(&engine, "TextEdit { text: \"\" }"); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->width(), 0.); } @@ -137,6 +174,7 @@ void tst_qfxtextedit::width() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->width(), qreal(metricWidth)); } @@ -152,6 +190,7 @@ void tst_qfxtextedit::width() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->width(), qreal(documentWidth)); } } @@ -163,6 +202,7 @@ void tst_qfxtextedit::wrap() QmlComponent texteditComponent(&engine, "TextEdit { text: \"\"; wrap: true; width: 300 }"); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->width(), 300.); } @@ -172,6 +212,7 @@ void tst_qfxtextedit::wrap() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->width(), 300.); } @@ -181,6 +222,7 @@ void tst_qfxtextedit::wrap() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->width(), 300.); } @@ -199,6 +241,7 @@ void tst_qfxtextedit::hAlign() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); } } @@ -211,6 +254,7 @@ void tst_qfxtextedit::hAlign() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE((int)textEditObject->hAlign(), (int)hAlignments.at(j)); } } @@ -229,6 +273,7 @@ void tst_qfxtextedit::vAlign() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); } } @@ -241,6 +286,7 @@ void tst_qfxtextedit::vAlign() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE((int)textEditObject->vAlign(), (int)vAlignments.at(j)); } } @@ -255,6 +301,7 @@ void tst_qfxtextedit::font() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->font()->size(), qreal(40)); QCOMPARE(textEditObject->font()->bold(), false); QCOMPARE(textEditObject->font()->italic(), false); @@ -265,6 +312,7 @@ void tst_qfxtextedit::font() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->font()->bold(), true); QCOMPARE(textEditObject->font()->italic(), false); } @@ -274,6 +322,7 @@ void tst_qfxtextedit::font() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->font()->italic(), true); QCOMPARE(textEditObject->font()->bold(), false); } @@ -283,6 +332,7 @@ void tst_qfxtextedit::font() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->font()->family(), QString("Helvetica")); QCOMPARE(textEditObject->font()->bold(), false); QCOMPARE(textEditObject->font()->italic(), false); @@ -293,6 +343,7 @@ void tst_qfxtextedit::font() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->font()->family(), QString("")); } } @@ -306,6 +357,7 @@ void tst_qfxtextedit::color() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); //qDebug() << "textEditObject: " << textEditObject->color() << "vs. " << QColor(colorStrings.at(i)); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->color(), QColor(colorStrings.at(i))); } @@ -318,9 +370,37 @@ void tst_qfxtextedit::color() QmlComponent texteditComponent(&engine, componentStr.toLatin1()); QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); QCOMPARE(textEditObject->color(), testColor); } } + +void tst_qfxtextedit::cursorDelegate() +{ + QString componentStr = "TextEdit { text: \""+ standard[1] +"\"; focusable: true; resources [ Component { id:cursor; Item { id:cursorInstance } } ] cursorDelegate: cursor}"; + QTest::qWait(10000); + QmlComponent texteditComponent(&engine, componentStr.toLatin1(), QUrl()); + QFxTextEdit *textEditObject = qobject_cast<QFxTextEdit*>(texteditComponent.create()); + QVERIFY(textEditObject != 0); + QVERIFY(!findItem<QFxItem>(textEditObject, "cursorInstance")); + //Test Delegate gets created + textEditObject->setFocus(true); + QFxItem* delegateObject = findItem<QFxItem>(textEditObject, "cursorInstance"); + QVERIFY(delegateObject); + //Test Delegate gets moved + for(int i=0; i<= standard[1].size(); i++){ + textEditObject->setCursorPosition(i); + QCOMPARE(textEditObject->cursorRect().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRect().y(), qRound(delegateObject->y())); + } + textEditObject->setCursorPosition(0); + QCOMPARE(textEditObject->cursorRect().x(), qRound(delegateObject->x())); + QCOMPARE(textEditObject->cursorRect().y(), qRound(delegateObject->y())); + //Test Delegate gets deleted + textEditObject->setCursorDelegate(0); + QVERIFY(!findItem<QFxItem>(textEditObject, "cursorInstance")); +} + QTEST_MAIN(tst_qfxtextedit) #include "tst_qfxtextedit.moc" |