Simplify QAccessibleTextEdit.

Before the text edit tried to represent each line of text as a child
of itself. With the editable text interface this is no longer needed.

Change-Id: If9927e522f955e863e91fd0a529a1ce6fafaddc3
Reviewed-on: http://codereview.qt-project.org/5624
Reviewed-by: Qt Sanity Bot <qt_sanity_bot@ovi.com>
Reviewed-by: Jan-Arve Sæther <jan-arve.saether@nokia.com>
This commit is contained in:
Frederik Gladhorn 2011-09-27 14:28:19 +02:00 committed by Qt by Nokia
parent 96b6a16220
commit e918598e2d
3 changed files with 418 additions and 491 deletions

View File

@ -254,7 +254,6 @@ QAccessibleTextEdit::QAccessibleTextEdit(QWidget *o)
: QAccessibleWidget(o, EditableText)
{
Q_ASSERT(widget()->inherits("QTextEdit"));
childOffset = QAccessibleWidget::childCount();
}
/*! Returns the text edit. */
@ -263,96 +262,37 @@ QTextEdit *QAccessibleTextEdit::textEdit() const
return static_cast<QTextEdit *>(widget());
}
QRect QAccessibleTextEdit::rect(int child) const
/*! \reimp */
QString QAccessibleTextEdit::text(Text t, int) const
{
if (child <= childOffset)
return QAccessibleWidget::rect(child);
if (t == Value)
return textEdit()->toPlainText();
QTextEdit *edit = textEdit();
QTextBlock block = qTextBlockAt(edit->document(), child - childOffset - 1);
if (!block.isValid())
return QRect();
QRect rect = edit->document()->documentLayout()->blockBoundingRect(block).toRect();
rect.translate(-edit->horizontalScrollBar()->value(), -edit->verticalScrollBar()->value());
rect = edit->viewport()->rect().intersect(rect);
if (rect.isEmpty())
return QRect();
return rect.translated(edit->viewport()->mapToGlobal(QPoint(0, 0)));
}
int QAccessibleTextEdit::childAt(int x, int y) const
{
QTextEdit *edit = textEdit();
if (!edit->isVisible())
return -1;
QPoint point = edit->viewport()->mapFromGlobal(QPoint(x, y));
QTextBlock block = edit->cursorForPosition(point).block();
if (block.isValid())
return qTextBlockPosition(block) + childOffset;
return QAccessibleWidget::childAt(x, y);
return QAccessibleWidget::text(t, 0);
}
/*! \reimp */
QString QAccessibleTextEdit::text(Text t, int child) const
void QAccessibleTextEdit::setText(Text t, int, const QString &text)
{
if (t == Value) {
if (child > childOffset)
return qTextBlockAt(textEdit()->document(), child - childOffset - 1).text();
if (!child)
return textEdit()->toPlainText();
}
return QAccessibleWidget::text(t, child);
}
/*! \reimp */
void QAccessibleTextEdit::setText(Text t, int child, const QString &text)
{
if (t != Value || (child > 0 && child <= childOffset)) {
QAccessibleWidget::setText(t, child, text);
if (t != Value) {
QAccessibleWidget::setText(t, 0, text);
return;
}
if (textEdit()->isReadOnly())
return;
if (!child) {
textEdit()->setText(text);
return;
}
QTextBlock block = qTextBlockAt(textEdit()->document(), child - childOffset - 1);
if (!block.isValid())
return;
QTextCursor cursor(block);
cursor.select(QTextCursor::BlockUnderCursor);
cursor.insertText(text);
textEdit()->setText(text);
}
/*! \reimp */
QAccessible::Role QAccessibleTextEdit::role(int child) const
{
if (child > childOffset)
return EditableText;
return QAccessibleWidget::role(child);
}
QVariant QAccessibleTextEdit::invokeMethod(QAccessible::Method method, int child,
QVariant QAccessibleTextEdit::invokeMethod(QAccessible::Method method, int,
const QVariantList &params)
{
if (child)
return QVariant();
switch (method) {
case ListSupportedMethods: {
QSet<QAccessible::Method> set;
set << ListSupportedMethods << SetCursorPosition << GetCursorPosition;
return QVariant::fromValue(set | qvariant_cast<QSet<QAccessible::Method> >(
QAccessibleWidget::invokeMethod(method, child, params)));
QAccessibleWidget::invokeMethod(method, 0, params)));
}
case SetCursorPosition:
setCursorPosition(params.value(0).toInt());
@ -360,13 +300,404 @@ QVariant QAccessibleTextEdit::invokeMethod(QAccessible::Method method, int child
case GetCursorPosition:
return textEdit()->textCursor().position();
default:
return QAccessibleWidget::invokeMethod(method, child, params);
return QAccessibleWidget::invokeMethod(method, 0, params);
}
}
int QAccessibleTextEdit::childCount() const
void QAccessibleTextEdit::addSelection(int startOffset, int endOffset)
{
return childOffset + textEdit()->document()->blockCount();
setSelection(0, startOffset, endOffset);
}
QString QAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOffset)
{
/* The list of attributes can be found at:
http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes
*/
if (offset >= characterCount()) {
*startOffset = -1;
*endOffset = -1;
return QString();
}
QMap<QString, QString> attrs;
QTextCursor cursor = textEdit()->textCursor();
//cursor.charFormat returns the format of the previous character
cursor.setPosition(offset + 1);
QTextCharFormat charFormat = cursor.charFormat();
cursor.setPosition(offset);
QTextBlockFormat blockFormat = cursor.blockFormat();
QTextCharFormat charFormatComp;
QTextBlockFormat blockFormatComp;
*startOffset = offset;
cursor.setPosition(*startOffset);
while (*startOffset > 0) {
charFormatComp = cursor.charFormat();
cursor.setPosition(*startOffset - 1);
blockFormatComp = cursor.blockFormat();
if ((charFormat == charFormatComp) && (blockFormat == blockFormatComp))
(*startOffset)--;
else
break;
}
int limit = characterCount() + 1;
*endOffset = offset + 1;
cursor.setPosition(*endOffset);
while (*endOffset < limit) {
blockFormatComp = cursor.blockFormat();
cursor.setPosition(*endOffset + 1);
charFormatComp = cursor.charFormat();
if ((charFormat == charFormatComp) && (cursor.blockFormat() == blockFormatComp))
(*endOffset)++;
else
break;
}
QString family = charFormat.fontFamily();
if (!family.isEmpty()) {
family = family.replace('\\',"\\\\");
family = family.replace(':',"\\:");
family = family.replace(',',"\\,");
family = family.replace('=',"\\=");
family = family.replace(';',"\\;");
family = family.replace('\"',"\\\"");
attrs["font-family"] = '"'+family+'"';
}
int fontSize = int(charFormat.fontPointSize());
if (fontSize)
attrs["font-size"] = QString::number(fontSize).append("pt");
//Different weight values are not handled
attrs["font-weight"] = (charFormat.fontWeight() > QFont::Normal) ? "bold" : "normal";
QFont::Style style = charFormat.font().style();
attrs["font-style"] = (style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal");
attrs["text-underline-style"] = charFormat.font().underline() ? "solid" : "none";
QTextCharFormat::VerticalAlignment alignment = charFormat.verticalAlignment();
attrs["text-position"] = (alignment == QTextCharFormat::AlignSubScript) ? "sub" : ((alignment == QTextCharFormat::AlignSuperScript) ? "super" : "baseline" );
QBrush background = charFormat.background();
if (background.style() == Qt::SolidPattern) {
attrs["background-color"] = QString("rgb(%1,%2,%3)").arg(background.color().red()).arg(background.color().green()).arg(background.color().blue());
}
QBrush foreground = charFormat.foreground();
if (foreground.style() == Qt::SolidPattern) {
attrs["color"] = QString("rgb(%1,%2,%3)").arg(foreground.color().red()).arg(foreground.color().green()).arg(foreground.color().blue());
}
switch (blockFormat.alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify)) {
case Qt::AlignLeft:
attrs["text-align"] = "left";
break;
case Qt::AlignRight:
attrs["text-align"] = "right";
break;
case Qt::AlignHCenter:
attrs["text-align"] = "center";
break;
case Qt::AlignJustify:
attrs["text-align"] = "left";
break;
}
QString result;
foreach (const QString &attributeName, attrs.keys()) {
result.append(attributeName).append(':').append(attrs[attributeName]).append(';');
}
return result;
}
int QAccessibleTextEdit::cursorPosition()
{
return textEdit()->textCursor().position();
}
QRect QAccessibleTextEdit::characterRect(int offset, CoordinateType coordType)
{
QTextEdit *edit = textEdit();
QTextCursor cursor(edit->document());
cursor.setPosition(offset);
if (cursor.position() != offset)
return QRect();
QRect r = edit->cursorRect(cursor);
if (cursor.movePosition(QTextCursor::NextCharacter)) {
r.setWidth(edit->cursorRect(cursor).x() - r.x());
} else {
// we don't know the width of the character - maybe because we're at document end
// in that case, IAccessible2 tells us to return the width of a default character
int averageCharWidth = QFontMetrics(cursor.charFormat().font()).averageCharWidth();
if (edit->layoutDirection() == Qt::RightToLeft)
averageCharWidth *= -1;
r.setWidth(averageCharWidth);
}
switch (coordType) {
case RelativeToScreen:
r.moveTo(edit->viewport()->mapToGlobal(r.topLeft()));
break;
case RelativeToParent:
break;
}
return r;
}
int QAccessibleTextEdit::selectionCount()
{
return textEdit()->textCursor().hasSelection() ? 1 : 0;
}
int QAccessibleTextEdit::offsetAtPoint(const QPoint &point, CoordinateType coordType)
{
QTextEdit *edit = textEdit();
QPoint p = point;
if (coordType == RelativeToScreen)
p = edit->viewport()->mapFromGlobal(p);
// convert to document coordinates
p += QPoint(edit->horizontalScrollBar()->value(), edit->verticalScrollBar()->value());
return edit->document()->documentLayout()->hitTest(p, Qt::ExactHit);
}
void QAccessibleTextEdit::selection(int selectionIndex, int *startOffset, int *endOffset)
{
*startOffset = *endOffset = 0;
QTextCursor cursor = textEdit()->textCursor();
if (selectionIndex != 0 || !cursor.hasSelection())
return;
*startOffset = cursor.selectionStart();
*endOffset = cursor.selectionEnd();
}
QString QAccessibleTextEdit::text(int startOffset, int endOffset)
{
QTextCursor cursor(textEdit()->document());
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
return cursor.selectedText();
}
QString QAccessibleTextEdit::textBeforeOffset (int offset, BoundaryType boundaryType,
int *startOffset, int *endOffset)
{
// TODO - what exactly is before?
Q_UNUSED(offset);
Q_UNUSED(boundaryType);
Q_UNUSED(startOffset);
Q_UNUSED(endOffset);
return QString();
}
QString QAccessibleTextEdit::textAfterOffset(int offset, BoundaryType boundaryType,
int *startOffset, int *endOffset)
{
// TODO - what exactly is after?
Q_UNUSED(offset);
Q_UNUSED(boundaryType);
Q_UNUSED(startOffset);
Q_UNUSED(endOffset);
return QString();
}
QString QAccessibleTextEdit::textAtOffset(int offset, BoundaryType boundaryType,
int *startOffset, int *endOffset)
{
Q_ASSERT(startOffset);
Q_ASSERT(endOffset);
*startOffset = *endOffset = -1;
QTextEdit *edit = textEdit();
QTextCursor cursor(edit->document());
if (offset >= characterCount())
return QString();
cursor.setPosition(offset);
switch (boundaryType) {
case CharBoundary:
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case WordBoundary:
cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case SentenceBoundary:
// TODO - what's a sentence?
return QString();
case LineBoundary:
cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case ParagraphBoundary:
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case NoBoundary: {
*startOffset = 0;
const QString txt = edit->toPlainText();
*endOffset = txt.count();
return txt; }
default:
qDebug("AccessibleTextAdaptor::textAtOffset: Unknown boundary type %d", boundaryType);
return QString();
}
return cursor.selectedText();
}
void QAccessibleTextEdit::removeSelection(int selectionIndex)
{
if (selectionIndex != 0)
return;
QTextCursor cursor = textEdit()->textCursor();
cursor.clearSelection();
textEdit()->setTextCursor(cursor);
}
void QAccessibleTextEdit::setCursorPosition(int position)
{
QTextCursor cursor = textEdit()->textCursor();
cursor.setPosition(position);
textEdit()->setTextCursor(cursor);
}
void QAccessibleTextEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
{
if (selectionIndex != 0)
return;
QTextCursor cursor = textEdit()->textCursor();
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
textEdit()->setTextCursor(cursor);
}
int QAccessibleTextEdit::characterCount()
{
return textEdit()->toPlainText().count();
}
void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
{
QTextEdit *edit = textEdit();
QTextCursor cursor(edit->document());
cursor.setPosition(startIndex);
QRect r = edit->cursorRect(cursor);
cursor.setPosition(endIndex);
r.setBottomRight(edit->cursorRect(cursor).bottomRight());
r.moveTo(r.x() + edit->horizontalScrollBar()->value(),
r.y() + edit->verticalScrollBar()->value());
// E V I L, but ensureVisible is not public
if (!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r)))
qWarning("AccessibleTextEdit::scrollToSubstring failed!");
}
static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endOffset)
{
QTextCursor cursor(textEdit->document());
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
return cursor;
}
void QAccessibleTextEdit::copyText(int startOffset, int endOffset)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
if (!cursor.hasSelection())
return;
// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
}
void QAccessibleTextEdit::deleteText(int startOffset, int endOffset)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
cursor.removeSelectedText();
}
void QAccessibleTextEdit::insertText(int offset, const QString &text)
{
QTextCursor cursor(textEdit()->document());
cursor.setPosition(offset);
cursor.insertText(text);
}
void QAccessibleTextEdit::cutText(int startOffset, int endOffset)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
if (!cursor.hasSelection())
return;
// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
cursor.removeSelectedText();
}
void QAccessibleTextEdit::pasteText(int offset)
{
QTextEdit *edit = textEdit();
QTextCursor oldCursor = edit->textCursor();
QTextCursor newCursor = oldCursor;
newCursor.setPosition(offset);
edit->setTextCursor(newCursor);
#ifndef QT_NO_CLIPBOARD
edit->paste();
#endif
edit->setTextCursor(oldCursor);
}
void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QString &text)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
cursor.removeSelectedText();
cursor.insertText(text);
}
void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QString &attributes)
{
// TODO
Q_UNUSED(startOffset);
Q_UNUSED(endOffset);
Q_UNUSED(attributes);
}
#endif // QT_NO_TEXTEDIT
@ -1325,405 +1656,6 @@ bool QAccessibleTitleBar::isValid() const
#endif // QT_NO_DOCKWIDGET
#ifndef QT_NO_TEXTEDIT
void QAccessibleTextEdit::addSelection(int startOffset, int endOffset)
{
setSelection(0, startOffset, endOffset);
}
QString QAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOffset)
{
/* The list of attributes can be found at:
http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes
*/
if (offset >= characterCount()) {
*startOffset = -1;
*endOffset = -1;
return QString();
}
QMap<QString, QString> attrs;
QTextCursor cursor = textEdit()->textCursor();
//cursor.charFormat returns the format of the previous character
cursor.setPosition(offset + 1);
QTextCharFormat charFormat = cursor.charFormat();
cursor.setPosition(offset);
QTextBlockFormat blockFormat = cursor.blockFormat();
QTextCharFormat charFormatComp;
QTextBlockFormat blockFormatComp;
*startOffset = offset;
cursor.setPosition(*startOffset);
while (*startOffset > 0) {
charFormatComp = cursor.charFormat();
cursor.setPosition(*startOffset - 1);
blockFormatComp = cursor.blockFormat();
if ((charFormat == charFormatComp) && (blockFormat == blockFormatComp))
(*startOffset)--;
else
break;
}
int limit = characterCount() + 1;
*endOffset = offset + 1;
cursor.setPosition(*endOffset);
while (*endOffset < limit) {
blockFormatComp = cursor.blockFormat();
cursor.setPosition(*endOffset + 1);
charFormatComp = cursor.charFormat();
if ((charFormat == charFormatComp) && (cursor.blockFormat() == blockFormatComp))
(*endOffset)++;
else
break;
}
QString family = charFormat.fontFamily();
if (!family.isEmpty()) {
family = family.replace('\\',"\\\\");
family = family.replace(':',"\\:");
family = family.replace(',',"\\,");
family = family.replace('=',"\\=");
family = family.replace(';',"\\;");
family = family.replace('\"',"\\\"");
attrs["font-family"] = '"'+family+'"';
}
int fontSize = int(charFormat.fontPointSize());
if (fontSize)
attrs["font-size"] = QString::number(fontSize).append("pt");
//Different weight values are not handled
attrs["font-weight"] = (charFormat.fontWeight() > QFont::Normal) ? "bold" : "normal";
QFont::Style style = charFormat.font().style();
attrs["font-style"] = (style == QFont::StyleItalic) ? "italic" : ((style == QFont::StyleOblique) ? "oblique": "normal");
attrs["text-underline-style"] = charFormat.font().underline() ? "solid" : "none";
QTextCharFormat::VerticalAlignment alignment = charFormat.verticalAlignment();
attrs["text-position"] = (alignment == QTextCharFormat::AlignSubScript) ? "sub" : ((alignment == QTextCharFormat::AlignSuperScript) ? "super" : "baseline" );
QBrush background = charFormat.background();
if (background.style() == Qt::SolidPattern) {
attrs["background-color"] = QString("rgb(%1,%2,%3)").arg(background.color().red()).arg(background.color().green()).arg(background.color().blue());
}
QBrush foreground = charFormat.foreground();
if (foreground.style() == Qt::SolidPattern) {
attrs["color"] = QString("rgb(%1,%2,%3)").arg(foreground.color().red()).arg(foreground.color().green()).arg(foreground.color().blue());
}
switch (blockFormat.alignment() & (Qt::AlignLeft | Qt::AlignRight | Qt::AlignHCenter | Qt::AlignJustify)) {
case Qt::AlignLeft:
attrs["text-align"] = "left";
break;
case Qt::AlignRight:
attrs["text-align"] = "right";
break;
case Qt::AlignHCenter:
attrs["text-align"] = "center";
break;
case Qt::AlignJustify:
attrs["text-align"] = "left";
break;
}
QString result;
foreach (const QString &attributeName, attrs.keys()) {
result.append(attributeName).append(':').append(attrs[attributeName]).append(';');
}
return result;
}
int QAccessibleTextEdit::cursorPosition()
{
return textEdit()->textCursor().position();
}
QRect QAccessibleTextEdit::characterRect(int offset, CoordinateType coordType)
{
QTextEdit *edit = textEdit();
QTextCursor cursor(edit->document());
cursor.setPosition(offset);
if (cursor.position() != offset)
return QRect();
QRect r = edit->cursorRect(cursor);
if (cursor.movePosition(QTextCursor::NextCharacter)) {
r.setWidth(edit->cursorRect(cursor).x() - r.x());
} else {
// we don't know the width of the character - maybe because we're at document end
// in that case, IAccessible2 tells us to return the width of a default character
int averageCharWidth = QFontMetrics(cursor.charFormat().font()).averageCharWidth();
if (edit->layoutDirection() == Qt::RightToLeft)
averageCharWidth *= -1;
r.setWidth(averageCharWidth);
}
switch (coordType) {
case RelativeToScreen:
r.moveTo(edit->viewport()->mapToGlobal(r.topLeft()));
break;
case RelativeToParent:
break;
}
return r;
}
int QAccessibleTextEdit::selectionCount()
{
return textEdit()->textCursor().hasSelection() ? 1 : 0;
}
int QAccessibleTextEdit::offsetAtPoint(const QPoint &point, CoordinateType coordType)
{
QTextEdit *edit = textEdit();
QPoint p = point;
if (coordType == RelativeToScreen)
p = edit->viewport()->mapFromGlobal(p);
// convert to document coordinates
p += QPoint(edit->horizontalScrollBar()->value(), edit->verticalScrollBar()->value());
return edit->document()->documentLayout()->hitTest(p, Qt::ExactHit);
}
void QAccessibleTextEdit::selection(int selectionIndex, int *startOffset, int *endOffset)
{
*startOffset = *endOffset = 0;
QTextCursor cursor = textEdit()->textCursor();
if (selectionIndex != 0 || !cursor.hasSelection())
return;
*startOffset = cursor.selectionStart();
*endOffset = cursor.selectionEnd();
}
QString QAccessibleTextEdit::text(int startOffset, int endOffset)
{
QTextCursor cursor(textEdit()->document());
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
return cursor.selectedText();
}
QString QAccessibleTextEdit::textBeforeOffset (int offset, BoundaryType boundaryType,
int *startOffset, int *endOffset)
{
// TODO - what exactly is before?
Q_UNUSED(offset);
Q_UNUSED(boundaryType);
Q_UNUSED(startOffset);
Q_UNUSED(endOffset);
return QString();
}
QString QAccessibleTextEdit::textAfterOffset(int offset, BoundaryType boundaryType,
int *startOffset, int *endOffset)
{
// TODO - what exactly is after?
Q_UNUSED(offset);
Q_UNUSED(boundaryType);
Q_UNUSED(startOffset);
Q_UNUSED(endOffset);
return QString();
}
QString QAccessibleTextEdit::textAtOffset(int offset, BoundaryType boundaryType,
int *startOffset, int *endOffset)
{
Q_ASSERT(startOffset);
Q_ASSERT(endOffset);
*startOffset = *endOffset = -1;
QTextEdit *edit = textEdit();
QTextCursor cursor(edit->document());
if (offset >= characterCount())
return QString();
cursor.setPosition(offset);
switch (boundaryType) {
case CharBoundary:
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case WordBoundary:
cursor.movePosition(QTextCursor::StartOfWord, QTextCursor::MoveAnchor);
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::EndOfWord, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case SentenceBoundary:
// TODO - what's a sentence?
return QString();
case LineBoundary:
cursor.movePosition(QTextCursor::StartOfLine, QTextCursor::MoveAnchor);
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::EndOfLine, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case ParagraphBoundary:
cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor);
*startOffset = cursor.position();
cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor);
*endOffset = cursor.position();
break;
case NoBoundary: {
*startOffset = 0;
const QString txt = edit->toPlainText();
*endOffset = txt.count();
return txt; }
default:
qDebug("AccessibleTextAdaptor::textAtOffset: Unknown boundary type %d", boundaryType);
return QString();
}
return cursor.selectedText();
}
void QAccessibleTextEdit::removeSelection(int selectionIndex)
{
if (selectionIndex != 0)
return;
QTextCursor cursor = textEdit()->textCursor();
cursor.clearSelection();
textEdit()->setTextCursor(cursor);
}
void QAccessibleTextEdit::setCursorPosition(int position)
{
QTextCursor cursor = textEdit()->textCursor();
cursor.setPosition(position);
textEdit()->setTextCursor(cursor);
}
void QAccessibleTextEdit::setSelection(int selectionIndex, int startOffset, int endOffset)
{
if (selectionIndex != 0)
return;
QTextCursor cursor = textEdit()->textCursor();
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
textEdit()->setTextCursor(cursor);
}
int QAccessibleTextEdit::characterCount()
{
return textEdit()->toPlainText().count();
}
void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex)
{
QTextEdit *edit = textEdit();
QTextCursor cursor(edit->document());
cursor.setPosition(startIndex);
QRect r = edit->cursorRect(cursor);
cursor.setPosition(endIndex);
r.setBottomRight(edit->cursorRect(cursor).bottomRight());
r.moveTo(r.x() + edit->horizontalScrollBar()->value(),
r.y() + edit->verticalScrollBar()->value());
// E V I L, but ensureVisible is not public
if (!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r)))
qWarning("AccessibleTextEdit::scrollToSubstring failed!");
}
static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endOffset)
{
QTextCursor cursor(textEdit->document());
cursor.setPosition(startOffset, QTextCursor::MoveAnchor);
cursor.setPosition(endOffset, QTextCursor::KeepAnchor);
return cursor;
}
void QAccessibleTextEdit::copyText(int startOffset, int endOffset)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
if (!cursor.hasSelection())
return;
// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
}
void QAccessibleTextEdit::deleteText(int startOffset, int endOffset)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
cursor.removeSelectedText();
}
void QAccessibleTextEdit::insertText(int offset, const QString &text)
{
QTextCursor cursor(textEdit()->document());
cursor.setPosition(offset);
cursor.insertText(text);
}
void QAccessibleTextEdit::cutText(int startOffset, int endOffset)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
if (!cursor.hasSelection())
return;
// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection()));
cursor.removeSelectedText();
}
void QAccessibleTextEdit::pasteText(int offset)
{
QTextEdit *edit = textEdit();
QTextCursor oldCursor = edit->textCursor();
QTextCursor newCursor = oldCursor;
newCursor.setPosition(offset);
edit->setTextCursor(newCursor);
#ifndef QT_NO_CLIPBOARD
edit->paste();
#endif
edit->setTextCursor(oldCursor);
}
void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QString &text)
{
QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset);
cursor.removeSelectedText();
cursor.insertText(text);
}
void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QString &attributes)
{
// TODO
Q_UNUSED(startOffset);
Q_UNUSED(endOffset);
Q_UNUSED(attributes);
}
#endif // QT_NO_TEXTEDIT
#ifndef QT_NO_MAINWINDOW
QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget)
: QAccessibleWidget(widget, Window) { }

View File

@ -75,15 +75,9 @@ public:
QString text(Text t, int child) const;
void setText(Text t, int control, const QString &text);
Role role(int child) const;
QVariant invokeMethod(QAccessible::Method method, int child, const QVariantList &params);
QRect rect(int child) const;
int childAt(int x, int y) const;
int childCount() const;
// QAccessibleTextInterface
void addSelection(int startOffset, int endOffset);
QString attributes(int offset, int *startOffset, int *endOffset);

View File

@ -1773,16 +1773,12 @@ void tst_QAccessibility::textEditTest()
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&edit);
QCOMPARE(iface->text(QAccessible::Value, 0), text);
QCOMPARE(iface->childCount(), 6);
QCOMPARE(iface->text(QAccessible::Value, 4), QString("hello world"));
QCOMPARE(iface->text(QAccessible::Value, 5), QString("how are you today?"));
QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
QCOMPARE(startOffset, 6);
QCOMPARE(endOffset, 11);
QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
QCOMPARE(startOffset, 12);
QCOMPARE(endOffset, 30);
QCOMPARE(iface->text(QAccessible::Value, 6), QString());
QCOMPARE(iface->textInterface()->characterCount(), 31);
QFontMetrics fm(edit.font());
QCOMPARE(iface->textInterface()->characterRect(0, QAccessible2::RelativeToParent).size(), QSize(fm.width("h"), fm.height()));
@ -1800,14 +1796,19 @@ void tst_QAccessibility::textBrowserTest()
textBrowser.setText(text);
textBrowser.show();
QAccessibleInterface *interface = QAccessible::queryAccessibleInterface(&textBrowser);
QVERIFY(interface);
QCOMPARE(interface->role(0), QAccessible::StaticText);
QCOMPARE(interface->text(QAccessible::Value, 0), text);
QCOMPARE(interface->childCount(), 6);
QCOMPARE(interface->text(QAccessible::Value, 4), QString("Hello world"));
QCOMPARE(interface->text(QAccessible::Value, 5), QString("how are you today?"));
QCOMPARE(interface->text(QAccessible::Value, 6), QString());
QAccessibleInterface *iface = QAccessible::queryAccessibleInterface(&textBrowser);
QVERIFY(iface);
QCOMPARE(iface->role(0), QAccessible::StaticText);
QCOMPARE(iface->text(QAccessible::Value, 0), text);
int startOffset;
int endOffset;
QCOMPARE(iface->textInterface()->textAtOffset(8, QAccessible2::WordBoundary, &startOffset, &endOffset), QString("world"));
QCOMPARE(startOffset, 6);
QCOMPARE(endOffset, 11);
QCOMPARE(iface->textInterface()->textAtOffset(14, QAccessible2::LineBoundary, &startOffset, &endOffset), QString("how are you today?"));
QCOMPARE(startOffset, 12);
QCOMPARE(endOffset, 30);
QCOMPARE(iface->textInterface()->characterCount(), 31);
}
QTestAccessibility::clearEvents();
}