summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlan Alpert <alan.alpert@nokia.com>2009-07-08 02:49:52 (GMT)
committerAlan Alpert <alan.alpert@nokia.com>2009-07-08 02:49:52 (GMT)
commit69bf65348194ab339575aa0743832c1960e22962 (patch)
tree5c73baf07402e612331f5f24129f2149b7bb9794
parent131541866b374b90e04af75ec1382154c78b69b9 (diff)
downloadQt-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.cpp70
-rw-r--r--src/declarative/fx/qfxtextedit.h6
-rw-r--r--src/declarative/fx/qfxtextedit_p.h4
-rw-r--r--tests/auto/declarative/qfxtextedit/tst_qfxtextedit.cpp80
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"