From e918598e2d525af1709045ff172e01075bbec662 Mon Sep 17 00:00:00 2001 From: Frederik Gladhorn Date: Tue, 27 Sep 2011 14:28:19 +0200 Subject: Simplify QAccessibleTextEdit. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Reviewed-by: Jan-Arve Sæther --- .../accessible/widgets/qaccessiblewidgets.cpp | 2054 ++++++++++---------- .../accessible/widgets/qaccessiblewidgets.h | 6 - 2 files changed, 993 insertions(+), 1067 deletions(-) (limited to 'src/plugins/accessible') diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp index d811f976ab..9b3d37f50d 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.cpp +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.cpp @@ -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(widget()); } -QRect QAccessibleTextEdit::rect(int child) const -{ - if (child <= childOffset) - return QAccessibleWidget::rect(child); - - 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); -} - /*! \reimp */ -QString QAccessibleTextEdit::text(Text t, int child) const +QString QAccessibleTextEdit::text(Text t, int) const { - if (t == Value) { - if (child > childOffset) - return qTextBlockAt(textEdit()->document(), child - childOffset - 1).text(); - if (!child) - return textEdit()->toPlainText(); - } + if (t == Value) + return textEdit()->toPlainText(); - return QAccessibleWidget::text(t, child); + return QAccessibleWidget::text(t, 0); } /*! \reimp */ -void QAccessibleTextEdit::setText(Text t, int child, const QString &text) +void QAccessibleTextEdit::setText(Text t, int, 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); -} - -/*! \reimp */ -QAccessible::Role QAccessibleTextEdit::role(int child) const -{ - if (child > childOffset) - return EditableText; - return QAccessibleWidget::role(child); + textEdit()->setText(text); } -QVariant QAccessibleTextEdit::invokeMethod(QAccessible::Method method, int child, +QVariant QAccessibleTextEdit::invokeMethod(QAccessible::Method method, int, const QVariantList ¶ms) { - if (child) - return QVariant(); - switch (method) { case ListSupportedMethods: { QSet set; set << ListSupportedMethods << SetCursorPosition << GetCursorPosition; return QVariant::fromValue(set | qvariant_cast >( - QAccessibleWidget::invokeMethod(method, child, params))); + QAccessibleWidget::invokeMethod(method, 0, params))); } case SetCursorPosition: setCursorPosition(params.value(0).toInt()); @@ -360,1369 +300,1361 @@ 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); } -#endif // QT_NO_TEXTEDIT -#ifndef QT_NO_STACKEDWIDGET -// ======================= QAccessibleStackedWidget ====================== -QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget) - : QAccessibleWidget(widget, LayeredPane) +QString QAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOffset) { - Q_ASSERT(qobject_cast(widget)); -} + /* The list of attributes can be found at: + http://linuxfoundation.org/collaborate/workgroups/accessibility/iaccessible2/textattributes + */ -QVariant QAccessibleStackedWidget::invokeMethod(QAccessible::Method, int, const QVariantList &) -{ - return QVariant(); -} + if (offset >= characterCount()) { + *startOffset = -1; + *endOffset = -1; + return QString(); + } + QMap attrs; -int QAccessibleStackedWidget::childAt(int x, int y) const -{ - if (!stackedWidget()->isVisible()) - return -1; - QWidget *currentWidget = stackedWidget()->currentWidget(); - if (!currentWidget) - return -1; - QPoint position = currentWidget->mapFromGlobal(QPoint(x, y)); - if (currentWidget->rect().contains(position)) - return 1; - return -1; -} + QTextCursor cursor = textEdit()->textCursor(); -int QAccessibleStackedWidget::childCount() const -{ - return stackedWidget()->count(); -} + //cursor.charFormat returns the format of the previous character + cursor.setPosition(offset + 1); + QTextCharFormat charFormat = cursor.charFormat(); -int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const -{ - if (!child) - return -1; + cursor.setPosition(offset); + QTextBlockFormat blockFormat = cursor.blockFormat(); - QWidget* widget = qobject_cast(child->object()); - int index = stackedWidget()->indexOf(widget); - if (index >= 0) // one based counting of children - return index + 1; - return -1; -} + QTextCharFormat charFormatComp; + QTextBlockFormat blockFormatComp; -QAccessibleInterface *QAccessibleStackedWidget::child(int index) const -{ - if (index < 0 || index >= stackedWidget()->count()) - return 0; - return QAccessible::queryAccessibleInterface(stackedWidget()->widget(index)); -} + *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 QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const -{ - switch (relation) { - case Child: - *target = child(entry - 1); - return *target ? 0 : -1; - default: - return QAccessibleWidget::navigate(relation, entry, target); + 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; } -} -QStackedWidget *QAccessibleStackedWidget::stackedWidget() const -{ - return static_cast(object()); -} -#endif // QT_NO_STACKEDWIDGET + 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+'"'; + } -#ifndef QT_NO_TOOLBOX -// ======================= QAccessibleToolBox ====================== -QAccessibleToolBox::QAccessibleToolBox(QWidget *widget) - : QAccessibleWidget(widget, LayeredPane) -{ - Q_ASSERT(qobject_cast(widget)); + 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; } -QString QAccessibleToolBox::text(Text textType, int child) const +int QAccessibleTextEdit::cursorPosition() { - if (textType != Value || child <= 0 || child > toolBox()->count()) - return QAccessibleWidget::text(textType, child); - return toolBox()->itemText(child - 1); + return textEdit()->textCursor().position(); } -void QAccessibleToolBox::setText(Text textType, int child, const QString &text) +QRect QAccessibleTextEdit::characterRect(int offset, CoordinateType coordType) { - if (textType != Value || child <= 0 || child > toolBox()->count()) { - QAccessibleWidget::setText(textType, child, text); - return; + 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); } - toolBox()->setItemText(child - 1, text); -} -QAccessible::State QAccessibleToolBox::state(int child) const -{ - QWidget *childWidget = toolBox()->widget(child - 1); - if (!childWidget) - return QAccessibleWidget::state(child); - QAccessible::State childState = QAccessible::Normal; - if (toolBox()->currentWidget() == childWidget) - childState |= QAccessible::Expanded; - else - childState |= QAccessible::Collapsed; - return childState; + switch (coordType) { + case RelativeToScreen: + r.moveTo(edit->viewport()->mapToGlobal(r.topLeft())); + break; + case RelativeToParent: + break; + } + + return r; } -QVariant QAccessibleToolBox::invokeMethod(QAccessible::Method, int, const QVariantList &) +int QAccessibleTextEdit::selectionCount() { - return QVariant(); + return textEdit()->textCursor().hasSelection() ? 1 : 0; } -int QAccessibleToolBox::childCount() const +int QAccessibleTextEdit::offsetAtPoint(const QPoint &point, CoordinateType coordType) { - return toolBox()->count(); + 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); } -int QAccessibleToolBox::indexOfChild(const QAccessibleInterface *child) const +void QAccessibleTextEdit::selection(int selectionIndex, int *startOffset, int *endOffset) { - if (!child) - return -1; - QWidget *childWidget = qobject_cast(child->object()); - if (!childWidget) - return -1; - int index = toolBox()->indexOf(childWidget); - if (index != -1) - ++index; - return index; -} + *startOffset = *endOffset = 0; + QTextCursor cursor = textEdit()->textCursor(); -int QAccessibleToolBox::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const -{ - *target = 0; - if (entry <= 0 || entry > toolBox()->count()) - return QAccessibleWidget::navigate(relation, entry, target); - int index = -1; - if (relation == QAccessible::Up) - index = entry - 2; - else if (relation == QAccessible::Down) - index = entry; - *target = QAccessible::queryAccessibleInterface(toolBox()->widget(index)); - return *target ? 0: -1; -} + if (selectionIndex != 0 || !cursor.hasSelection()) + return; -QToolBox * QAccessibleToolBox::toolBox() const -{ - return static_cast(object()); + *startOffset = cursor.selectionStart(); + *endOffset = cursor.selectionEnd(); } -#endif // QT_NO_TOOLBOX -// ======================= QAccessibleMdiArea ====================== -#ifndef QT_NO_MDIAREA -QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget) - : QAccessibleWidget(widget, LayeredPane) +QString QAccessibleTextEdit::text(int startOffset, int endOffset) { - Q_ASSERT(qobject_cast(widget)); -} + QTextCursor cursor(textEdit()->document()); -QAccessible::State QAccessibleMdiArea::state(int child) const -{ - if (child < 0) - return QAccessibleWidget::state(child); - if (child == 0) - return QAccessible::Normal; - QList subWindows = mdiArea()->subWindowList(); - if (subWindows.isEmpty() || child > subWindows.count()) - return QAccessibleWidget::state(child); - if (subWindows.at(child - 1) == mdiArea()->activeSubWindow()) - return QAccessible::Focused; - return QAccessible::Normal; -} + cursor.setPosition(startOffset, QTextCursor::MoveAnchor); + cursor.setPosition(endOffset, QTextCursor::KeepAnchor); -QVariant QAccessibleMdiArea::invokeMethod(QAccessible::Method, int, const QVariantList &) -{ - return QVariant(); + return cursor.selectedText(); } -int QAccessibleMdiArea::childCount() const +QString QAccessibleTextEdit::textBeforeOffset (int offset, BoundaryType boundaryType, + int *startOffset, int *endOffset) { - return mdiArea()->subWindowList().count(); + // TODO - what exactly is before? + Q_UNUSED(offset); + Q_UNUSED(boundaryType); + Q_UNUSED(startOffset); + Q_UNUSED(endOffset); + return QString(); } -int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const +QString QAccessibleTextEdit::textAfterOffset(int offset, BoundaryType boundaryType, + int *startOffset, int *endOffset) { - if (!child || !child->object() || mdiArea()->subWindowList().isEmpty()) - return -1; - if (QMdiSubWindow *window = qobject_cast(child->object())) { - int index = mdiArea()->subWindowList().indexOf(window); - if (index != -1) - return ++index; - } - return -1; + // TODO - what exactly is after? + Q_UNUSED(offset); + Q_UNUSED(boundaryType); + Q_UNUSED(startOffset); + Q_UNUSED(endOffset); + return QString(); } -int QAccessibleMdiArea::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +QString QAccessibleTextEdit::textAtOffset(int offset, BoundaryType boundaryType, + int *startOffset, int *endOffset) { - *target = 0; - QWidget *targetObject = 0; - QList subWindows = mdiArea()->subWindowList(); - switch (relation) { - case Child: - if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count()) - return -1; - targetObject = subWindows.at(entry - 1); + 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 Up: - case Down: - case Left: - case Right: - targetObject = mdiAreaNavigate(mdiArea(), relation, entry); + 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: - return QAccessibleWidget::navigate(relation, entry, target); + qDebug("AccessibleTextAdaptor::textAtOffset: Unknown boundary type %d", boundaryType); + return QString(); } - *target = QAccessible::queryAccessibleInterface(targetObject); - return *target ? 0: -1; + + return cursor.selectedText(); } -QMdiArea *QAccessibleMdiArea::mdiArea() const +void QAccessibleTextEdit::removeSelection(int selectionIndex) { - return static_cast(object()); + if (selectionIndex != 0) + return; + + QTextCursor cursor = textEdit()->textCursor(); + cursor.clearSelection(); + textEdit()->setTextCursor(cursor); } -// ======================= QAccessibleMdiSubWindow ====================== -QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget) - : QAccessibleWidget(widget, QAccessible::Window) +void QAccessibleTextEdit::setCursorPosition(int position) { - Q_ASSERT(qobject_cast(widget)); + QTextCursor cursor = textEdit()->textCursor(); + cursor.setPosition(position); + textEdit()->setTextCursor(cursor); } -QString QAccessibleMdiSubWindow::text(Text textType, int child) const +void QAccessibleTextEdit::setSelection(int selectionIndex, int startOffset, int endOffset) { - if (textType == QAccessible::Name && (child == 0 || child == 1)) { - QString title = mdiSubWindow()->windowTitle(); - title.replace(QLatin1String("[*]"), QLatin1String("")); - return title; - } - return QAccessibleWidget::text(textType, child); + if (selectionIndex != 0) + return; + + QTextCursor cursor = textEdit()->textCursor(); + cursor.setPosition(startOffset, QTextCursor::MoveAnchor); + cursor.setPosition(endOffset, QTextCursor::KeepAnchor); + textEdit()->setTextCursor(cursor); } -void QAccessibleMdiSubWindow::setText(Text textType, int child, const QString &text) +int QAccessibleTextEdit::characterCount() { - if (textType == QAccessible::Name && (child == 0 || child == 1)) - mdiSubWindow()->setWindowTitle(text); - else - QAccessibleWidget::setText(textType, child, text); + return textEdit()->toPlainText().count(); } -QAccessible::State QAccessibleMdiSubWindow::state(int child) const +void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex) { - if (child != 0 || !mdiSubWindow()->parent()) - return QAccessibleWidget::state(child); - QAccessible::State state = QAccessible::Normal | QAccessible::Focusable; - if (!mdiSubWindow()->isMaximized()) - state |= (QAccessible::Movable | QAccessible::Sizeable); - if (mdiSubWindow()->isAncestorOf(QApplication::focusWidget()) - || QApplication::focusWidget() == mdiSubWindow()) - state |= QAccessible::Focused; - if (!mdiSubWindow()->isVisible()) - state |= QAccessible::Invisible; - if (!mdiSubWindow()->parentWidget()->contentsRect().contains(mdiSubWindow()->geometry())) - state |= QAccessible::Offscreen; - if (!mdiSubWindow()->isEnabled()) - state |= QAccessible::Unavailable; - return state; + 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!"); } -QVariant QAccessibleMdiSubWindow::invokeMethod(QAccessible::Method, int, const QVariantList &) +static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endOffset) { - return QVariant(); + QTextCursor cursor(textEdit->document()); + cursor.setPosition(startOffset, QTextCursor::MoveAnchor); + cursor.setPosition(endOffset, QTextCursor::KeepAnchor); + + return cursor; } -int QAccessibleMdiSubWindow::childCount() const +void QAccessibleTextEdit::copyText(int startOffset, int endOffset) { - if (mdiSubWindow()->widget()) - return 1; - return 0; + QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); + + if (!cursor.hasSelection()) + return; + +// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection())); } -int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) const +void QAccessibleTextEdit::deleteText(int startOffset, int endOffset) { - if (child && child->object() && child->object() == mdiSubWindow()->widget()) - return 1; - return -1; + QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); + + cursor.removeSelectedText(); } -int QAccessibleMdiSubWindow::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +void QAccessibleTextEdit::insertText(int offset, const QString &text) { - *target = 0; + QTextCursor cursor(textEdit()->document()); + cursor.setPosition(offset); - if (!mdiSubWindow()->parent()) - return QAccessibleWidget::navigate(relation, entry, target); + cursor.insertText(text); +} - QWidget *targetObject = 0; - QMdiSubWindow *source = mdiSubWindow(); - switch (relation) { - case Child: - if (entry != 1 || !source->widget()) - return -1; - targetObject = source->widget(); - break; - case Up: - case Down: - case Left: - case Right: { - if (entry != 0) - break; - QWidget *parent = source->parentWidget(); - while (parent && !parent->inherits("QMdiArea")) - parent = parent->parentWidget(); - QMdiArea *mdiArea = qobject_cast(parent); - if (!mdiArea) - break; - int index = mdiArea->subWindowList().indexOf(source); - if (index == -1) - break; - if (QWidget *dest = mdiAreaNavigate(mdiArea, relation, index + 1)) { - *target = QAccessible::queryAccessibleInterface(dest); - return *target ? 0 : -1; - } - break; - } - default: - return QAccessibleWidget::navigate(relation, entry, target); - } - *target = QAccessible::queryAccessibleInterface(targetObject); - return *target ? 0: -1; +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(); } -QRect QAccessibleMdiSubWindow::rect(int child) const +void QAccessibleTextEdit::pasteText(int offset) { - if (mdiSubWindow()->isHidden()) - return QRect(); - if (!mdiSubWindow()->parent()) - return QAccessibleWidget::rect(child); - const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0)); - if (child == 0) - return QRect(pos, mdiSubWindow()->size()); - if (child == 1 && mdiSubWindow()->widget()) { - if (mdiSubWindow()->widget()->isHidden()) - return QRect(); - const QRect contentsRect = mdiSubWindow()->contentsRect(); - return QRect(pos.x() + contentsRect.x(), pos.y() + contentsRect.y(), - contentsRect.width(), contentsRect.height()); - } - return QRect(); + 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); } -int QAccessibleMdiSubWindow::childAt(int x, int y) const +void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QString &text) { - if (!mdiSubWindow()->isVisible()) - return -1; - if (!mdiSubWindow()->parent()) - return QAccessibleWidget::childAt(x, y); - const QRect globalGeometry = rect(0); - if (!globalGeometry.isValid()) - return -1; - const QRect globalChildGeometry = rect(1); - if (globalChildGeometry.isValid() && globalChildGeometry.contains(QPoint(x, y))) - return 1; - if (globalGeometry.contains(QPoint(x, y))) - return 0; - return -1; + QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); + + cursor.removeSelectedText(); + cursor.insertText(text); } -QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const +void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QString &attributes) { - return static_cast(object()); + // TODO + Q_UNUSED(startOffset); + Q_UNUSED(endOffset); + Q_UNUSED(attributes); } -#endif // QT_NO_MDIAREA +#endif // QT_NO_TEXTEDIT -// ======================= QAccessibleWorkspace ====================== -#ifndef QT_NO_WORKSPACE -QAccessibleWorkspace::QAccessibleWorkspace(QWidget *widget) +#ifndef QT_NO_STACKEDWIDGET +// ======================= QAccessibleStackedWidget ====================== +QAccessibleStackedWidget::QAccessibleStackedWidget(QWidget *widget) : QAccessibleWidget(widget, LayeredPane) { - Q_ASSERT(qobject_cast(widget)); + Q_ASSERT(qobject_cast(widget)); } -QAccessible::State QAccessibleWorkspace::state(int child) const +QVariant QAccessibleStackedWidget::invokeMethod(QAccessible::Method, int, const QVariantList &) { - if (child < 0) - return QAccessibleWidget::state(child); - if (child == 0) - return QAccessible::Normal; - QWidgetList subWindows = workspace()->windowList(); - if (subWindows.isEmpty() || child > subWindows.count()) - return QAccessibleWidget::state(child); - if (subWindows.at(child - 1) == workspace()->activeWindow()) - return QAccessible::Focused; - return QAccessible::Normal; + return QVariant(); } -QVariant QAccessibleWorkspace::invokeMethod(QAccessible::Method, int, const QVariantList &) + +int QAccessibleStackedWidget::childAt(int x, int y) const { - return QVariant(); + if (!stackedWidget()->isVisible()) + return -1; + QWidget *currentWidget = stackedWidget()->currentWidget(); + if (!currentWidget) + return -1; + QPoint position = currentWidget->mapFromGlobal(QPoint(x, y)); + if (currentWidget->rect().contains(position)) + return 1; + return -1; } -int QAccessibleWorkspace::childCount() const +int QAccessibleStackedWidget::childCount() const { - return workspace()->windowList().count(); + return stackedWidget()->count(); } -int QAccessibleWorkspace::indexOfChild(const QAccessibleInterface *child) const +int QAccessibleStackedWidget::indexOfChild(const QAccessibleInterface *child) const { - if (!child || !child->object() || workspace()->windowList().isEmpty()) + if (!child) return -1; - if (QWidget *window = qobject_cast(child->object())) { - int index = workspace()->windowList().indexOf(window); - if (index != -1) - return ++index; - } + + QWidget* widget = qobject_cast(child->object()); + int index = stackedWidget()->indexOf(widget); + if (index >= 0) // one based counting of children + return index + 1; return -1; } -int QAccessibleWorkspace::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +QAccessibleInterface *QAccessibleStackedWidget::child(int index) const +{ + if (index < 0 || index >= stackedWidget()->count()) + return 0; + return QAccessible::queryAccessibleInterface(stackedWidget()->widget(index)); +} + +int QAccessibleStackedWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const { - *target = 0; - QWidget *targetObject = 0; - QWidgetList subWindows = workspace()->windowList(); switch (relation) { case Child: - if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count()) - return -1; - targetObject = subWindows.at(entry - 1); - break; - case Up: - case Down: - case Left: - case Right: - targetObject = mdiAreaNavigate(workspace(), relation, entry); - break; + *target = child(entry - 1); + return *target ? 0 : -1; default: return QAccessibleWidget::navigate(relation, entry, target); } - *target = QAccessible::queryAccessibleInterface(targetObject); - return *target ? 0: -1; -} - -QWorkspace *QAccessibleWorkspace::workspace() const -{ - return static_cast(object()); } -#endif -#ifndef QT_NO_DIALOGBUTTONBOX -// ======================= QAccessibleDialogButtonBox ====================== -QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) - : QAccessibleWidget(widget, Grouping) +QStackedWidget *QAccessibleStackedWidget::stackedWidget() const { - Q_ASSERT(qobject_cast(widget)); + return static_cast(object()); } +#endif // QT_NO_STACKEDWIDGET -QVariant QAccessibleDialogButtonBox::invokeMethod(QAccessible::Method, int, const QVariantList &) +#ifndef QT_NO_TOOLBOX +// ======================= QAccessibleToolBox ====================== +QAccessibleToolBox::QAccessibleToolBox(QWidget *widget) + : QAccessibleWidget(widget, LayeredPane) { - return QVariant(); + Q_ASSERT(qobject_cast(widget)); } -#endif // QT_NO_DIALOGBUTTONBOX -#ifndef QT_NO_TEXTBROWSER -QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget) - : QAccessibleTextEdit(widget) +QString QAccessibleToolBox::text(Text textType, int child) const { - Q_ASSERT(qobject_cast(widget)); + if (textType != Value || child <= 0 || child > toolBox()->count()) + return QAccessibleWidget::text(textType, child); + return toolBox()->itemText(child - 1); } -QAccessible::Role QAccessibleTextBrowser::role(int child) const +void QAccessibleToolBox::setText(Text textType, int child, const QString &text) { - if (child != 0) - return QAccessibleTextEdit::role(child); - return QAccessible::StaticText; + if (textType != Value || child <= 0 || child > toolBox()->count()) { + QAccessibleWidget::setText(textType, child, text); + return; + } + toolBox()->setItemText(child - 1, text); } -#endif // QT_NO_TEXTBROWSER -#ifndef QT_NO_CALENDARWIDGET -// ===================== QAccessibleCalendarWidget ======================== -QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget) - : QAccessibleWidget(widget, Table) +QAccessible::State QAccessibleToolBox::state(int child) const { - Q_ASSERT(qobject_cast(widget)); + QWidget *childWidget = toolBox()->widget(child - 1); + if (!childWidget) + return QAccessibleWidget::state(child); + QAccessible::State childState = QAccessible::Normal; + if (toolBox()->currentWidget() == childWidget) + childState |= QAccessible::Expanded; + else + childState |= QAccessible::Collapsed; + return childState; } -QVariant QAccessibleCalendarWidget::invokeMethod(QAccessible::Method, int, const QVariantList &) +QVariant QAccessibleToolBox::invokeMethod(QAccessible::Method, int, const QVariantList &) { return QVariant(); } -int QAccessibleCalendarWidget::childCount() const +int QAccessibleToolBox::childCount() const { - return calendarWidget()->isNavigationBarVisible() ? 2 : 1; + return toolBox()->count(); } -int QAccessibleCalendarWidget::indexOfChild(const QAccessibleInterface *child) const +int QAccessibleToolBox::indexOfChild(const QAccessibleInterface *child) const { - if (!child || !child->object() || childCount() <= 0) + if (!child) return -1; - if (qobject_cast(child->object())) - return childCount(); - return 1; + QWidget *childWidget = qobject_cast(child->object()); + if (!childWidget) + return -1; + int index = toolBox()->indexOf(childWidget); + if (index != -1) + ++index; + return index; } -int QAccessibleCalendarWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const +int QAccessibleToolBox::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const { *target = 0; - if (entry <= 0 || entry > childCount()) - return QAccessibleWidget::navigate(relation, entry, target); - QWidget *targetWidget = 0; - switch (relation) { - case Child: - if (childCount() == 1) { - targetWidget = calendarView(); - } else { - if (entry == 1) - targetWidget = navigationBar(); - else - targetWidget = calendarView(); - } - break; - case Up: - if (entry == 2) - targetWidget = navigationBar(); - break; - case Down: - if (entry == 1 && childCount() == 2) - targetWidget = calendarView(); - break; - default: + if (entry <= 0 || entry > toolBox()->count()) return QAccessibleWidget::navigate(relation, entry, target); - } - *target = queryAccessibleInterface(targetWidget); + int index = -1; + if (relation == QAccessible::Up) + index = entry - 2; + else if (relation == QAccessible::Down) + index = entry; + *target = QAccessible::queryAccessibleInterface(toolBox()->widget(index)); return *target ? 0: -1; } -QRect QAccessibleCalendarWidget::rect(int child) const -{ - if (!calendarWidget()->isVisible() || child > childCount()) - return QRect(); - if (child == 0) - return QAccessibleWidget::rect(child); - QWidget *childWidget = 0; - if (childCount() == 2) - childWidget = child == 1 ? navigationBar() : calendarView(); - else - childWidget = calendarView(); - return QRect(childWidget->mapToGlobal(QPoint(0, 0)), childWidget->size()); -} - -int QAccessibleCalendarWidget::childAt(int x, int y) const +QToolBox * QAccessibleToolBox::toolBox() const { - const QPoint globalTargetPos = QPoint(x, y); - if (!rect(0).contains(globalTargetPos)) - return -1; - if (rect(1).contains(globalTargetPos)) - return 1; - if (rect(2).contains(globalTargetPos)) - return 2; - return 0; + return static_cast(object()); } +#endif // QT_NO_TOOLBOX -QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const +// ======================= QAccessibleMdiArea ====================== +#ifndef QT_NO_MDIAREA +QAccessibleMdiArea::QAccessibleMdiArea(QWidget *widget) + : QAccessibleWidget(widget, LayeredPane) { - return static_cast(object()); + Q_ASSERT(qobject_cast(widget)); } -QAbstractItemView *QAccessibleCalendarWidget::calendarView() const +QAccessible::State QAccessibleMdiArea::state(int child) const { - foreach (QObject *child, calendarWidget()->children()) { - if (child->objectName() == QLatin1String("qt_calendar_calendarview")) - return static_cast(child); - } - return 0; + if (child < 0) + return QAccessibleWidget::state(child); + if (child == 0) + return QAccessible::Normal; + QList subWindows = mdiArea()->subWindowList(); + if (subWindows.isEmpty() || child > subWindows.count()) + return QAccessibleWidget::state(child); + if (subWindows.at(child - 1) == mdiArea()->activeSubWindow()) + return QAccessible::Focused; + return QAccessible::Normal; } -QWidget *QAccessibleCalendarWidget::navigationBar() const +QVariant QAccessibleMdiArea::invokeMethod(QAccessible::Method, int, const QVariantList &) { - foreach (QObject *child, calendarWidget()->children()) { - if (child->objectName() == QLatin1String("qt_calendar_navigationbar")) - return static_cast(child); - } - return 0; + return QVariant(); } -#endif // QT_NO_CALENDARWIDGET -#ifndef QT_NO_DOCKWIDGET -QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget) - : QAccessibleWidget(widget, Window) +int QAccessibleMdiArea::childCount() const { - + return mdiArea()->subWindowList().count(); } -int QAccessibleDockWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const +int QAccessibleMdiArea::indexOfChild(const QAccessibleInterface *child) const { - if (relation == Child) { - if (entry == 1) { - *iface = new QAccessibleTitleBar(dockWidget()); - return 0; - } else if (entry == 2) { - if (dockWidget()->widget()) - *iface = QAccessible::queryAccessibleInterface(dockWidget()->widget()); - return 0; - } - *iface = 0; + if (!child || !child->object() || mdiArea()->subWindowList().isEmpty()) return -1; + if (QMdiSubWindow *window = qobject_cast(child->object())) { + int index = mdiArea()->subWindowList().indexOf(window); + if (index != -1) + return ++index; } - return QAccessibleWidget::navigate(relation, entry, iface); + return -1; } -int QAccessibleDockWidget::childAt(int x, int y) const +int QAccessibleMdiArea::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const { - for (int i = childCount(); i >= 0; --i) { - if (rect(i).contains(x,y)) - return i; + *target = 0; + QWidget *targetObject = 0; + QList subWindows = mdiArea()->subWindowList(); + switch (relation) { + case Child: + if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count()) + return -1; + targetObject = subWindows.at(entry - 1); + break; + case Up: + case Down: + case Left: + case Right: + targetObject = mdiAreaNavigate(mdiArea(), relation, entry); + break; + default: + return QAccessibleWidget::navigate(relation, entry, target); } - return -1; + *target = QAccessible::queryAccessibleInterface(targetObject); + return *target ? 0: -1; } -int QAccessibleDockWidget::childCount() const +QMdiArea *QAccessibleMdiArea::mdiArea() const { - return dockWidget()->widget() ? 2 : 1; + return static_cast(object()); } -int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const +// ======================= QAccessibleMdiSubWindow ====================== +QAccessibleMdiSubWindow::QAccessibleMdiSubWindow(QWidget *widget) + : QAccessibleWidget(widget, QAccessible::Window) { - if (child) { - if (child->role(0) == TitleBar) { - return 1; - } else { - return 2; //### - } - } - return -1; + Q_ASSERT(qobject_cast(widget)); } -QAccessible::Role QAccessibleDockWidget::role(int child) const +QString QAccessibleMdiSubWindow::text(Text textType, int child) const { - switch (child) { - case 0: - return Window; - case 1: - return TitleBar; - case 2: - //### - break; - default: - break; + if (textType == QAccessible::Name && (child == 0 || child == 1)) { + QString title = mdiSubWindow()->windowTitle(); + title.replace(QLatin1String("[*]"), QLatin1String("")); + return title; } - return NoRole; + return QAccessibleWidget::text(textType, child); } -QAccessible::State QAccessibleDockWidget::state(int child) const +void QAccessibleMdiSubWindow::setText(Text textType, int child, const QString &text) { - //### mark tabified widgets as invisible - return QAccessibleWidget::state(child); + if (textType == QAccessible::Name && (child == 0 || child == 1)) + mdiSubWindow()->setWindowTitle(text); + else + QAccessibleWidget::setText(textType, child, text); } -QRect QAccessibleDockWidget::rect (int child ) const +QAccessible::State QAccessibleMdiSubWindow::state(int child) const { - QRect rect; - bool mapToGlobal = true; - if (child == 0) { - if (dockWidget()->isFloating()) { - rect = dockWidget()->frameGeometry(); - mapToGlobal = false; - } else { - rect = dockWidget()->rect(); - } - }else if (child == 1) { - QDockWidgetLayout *layout = qobject_cast(dockWidget()->layout()); - rect = layout->titleArea(); - }else if (child == 2) { - if (dockWidget()->widget()) - rect = dockWidget()->widget()->geometry(); - } - if (rect.isNull()) - return rect; - - if (mapToGlobal) - rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); - - return rect; + if (child != 0 || !mdiSubWindow()->parent()) + return QAccessibleWidget::state(child); + QAccessible::State state = QAccessible::Normal | QAccessible::Focusable; + if (!mdiSubWindow()->isMaximized()) + state |= (QAccessible::Movable | QAccessible::Sizeable); + if (mdiSubWindow()->isAncestorOf(QApplication::focusWidget()) + || QApplication::focusWidget() == mdiSubWindow()) + state |= QAccessible::Focused; + if (!mdiSubWindow()->isVisible()) + state |= QAccessible::Invisible; + if (!mdiSubWindow()->parentWidget()->contentsRect().contains(mdiSubWindow()->geometry())) + state |= QAccessible::Offscreen; + if (!mdiSubWindow()->isEnabled()) + state |= QAccessible::Unavailable; + return state; } -QVariant QAccessibleDockWidget::invokeMethod(QAccessible::Method, int, const QVariantList &) +QVariant QAccessibleMdiSubWindow::invokeMethod(QAccessible::Method, int, const QVariantList &) { return QVariant(); } -QDockWidget *QAccessibleDockWidget::dockWidget() const +int QAccessibleMdiSubWindow::childCount() const { - return static_cast(object()); + if (mdiSubWindow()->widget()) + return 1; + return 0; } -//// -// QAccessibleTitleBar -//// -QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget) - : m_dockWidget(widget) +int QAccessibleMdiSubWindow::indexOfChild(const QAccessibleInterface *child) const { - + if (child && child->object() && child->object() == mdiSubWindow()->widget()) + return 1; + return -1; } -QAccessibleInterface *QAccessibleTitleBar::parent() const +int QAccessibleMdiSubWindow::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const { - return new QAccessibleDockWidget(dockWidget()); -} + *target = 0; -QAccessibleInterface *QAccessibleTitleBar::child(int index) const -{ - if (index >= 0) { - QDockWidgetLayout *layout = dockWidgetLayout(); - int role; - int currentIndex = 0; - for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (!w || !w->isVisible()) - continue; - if (currentIndex == index) - return QAccessible::queryAccessibleInterface(w); - ++currentIndex; - } - } - return 0; -} + if (!mdiSubWindow()->parent()) + return QAccessibleWidget::navigate(relation, entry, target); -int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const -{ + QWidget *targetObject = 0; + QMdiSubWindow *source = mdiSubWindow(); switch (relation) { case Child: - *iface = child(entry - 1); - return *iface ? 0 : -1; - case FocusChild: - // ### - if (entry >= 1) { - QDockWidgetLayout *layout = dockWidgetLayout(); - int index = 1; - int role; - for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (!w->isVisible()) - continue; - if (index == entry) - break; - ++index; - } - *iface = 0; - return role > QDockWidgetLayout::FloatButton ? -1 : index; - } + if (entry != 1 || !source->widget()) + return -1; + targetObject = source->widget(); break; - case Ancestor: - *iface = parent(); - return iface ? 0 : -1; - case Sibling: - return navigate(Child, entry, iface); + case Up: + case Down: + case Left: + case Right: { + if (entry != 0) + break; + QWidget *parent = source->parentWidget(); + while (parent && !parent->inherits("QMdiArea")) + parent = parent->parentWidget(); + QMdiArea *mdiArea = qobject_cast(parent); + if (!mdiArea) + break; + int index = mdiArea->subWindowList().indexOf(source); + if (index == -1) + break; + if (QWidget *dest = mdiAreaNavigate(mdiArea, relation, index + 1)) { + *target = QAccessible::queryAccessibleInterface(dest); + return *target ? 0 : -1; + } break; + } default: - break; + return QAccessibleWidget::navigate(relation, entry, target); } - *iface = 0; - return -1; + *target = QAccessible::queryAccessibleInterface(targetObject); + return *target ? 0: -1; } -QAccessible::Relation QAccessibleTitleBar::relationTo(int /*child*/, const QAccessibleInterface * /*other*/, int /*otherChild*/) const +QRect QAccessibleMdiSubWindow::rect(int child) const { - return Unrelated; //### + if (mdiSubWindow()->isHidden()) + return QRect(); + if (!mdiSubWindow()->parent()) + return QAccessibleWidget::rect(child); + const QPoint pos = mdiSubWindow()->mapToGlobal(QPoint(0, 0)); + if (child == 0) + return QRect(pos, mdiSubWindow()->size()); + if (child == 1 && mdiSubWindow()->widget()) { + if (mdiSubWindow()->widget()->isHidden()) + return QRect(); + const QRect contentsRect = mdiSubWindow()->contentsRect(); + return QRect(pos.x() + contentsRect.x(), pos.y() + contentsRect.y(), + contentsRect.width(), contentsRect.height()); + } + return QRect(); } -int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const +int QAccessibleMdiSubWindow::childAt(int x, int y) const { + if (!mdiSubWindow()->isVisible()) + return -1; + if (!mdiSubWindow()->parent()) + return QAccessibleWidget::childAt(x, y); + const QRect globalGeometry = rect(0); + if (!globalGeometry.isValid()) + return -1; + const QRect globalChildGeometry = rect(1); + if (globalChildGeometry.isValid() && globalChildGeometry.contains(QPoint(x, y))) + return 1; + if (globalGeometry.contains(QPoint(x, y))) + return 0; return -1; } -int QAccessibleTitleBar::childCount() const +QMdiSubWindow *QAccessibleMdiSubWindow::mdiSubWindow() const { - QDockWidgetLayout *layout = dockWidgetLayout(); - int count = 0; - for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (w && w->isVisible()) - ++count; - } - return count; + return static_cast(object()); } +#endif // QT_NO_MDIAREA -QString QAccessibleTitleBar::text(Text t, int child) const +// ======================= QAccessibleWorkspace ====================== +#ifndef QT_NO_WORKSPACE +QAccessibleWorkspace::QAccessibleWorkspace(QWidget *widget) + : QAccessibleWidget(widget, LayeredPane) { - if (!child) { - if (t == Name || t == Value) { - return qt_accStripAmp(dockWidget()->windowTitle()); - } - } - return QString(); + Q_ASSERT(qobject_cast(widget)); } -QAccessible::State QAccessibleTitleBar::state(int child) const +QAccessible::State QAccessibleWorkspace::state(int child) const { - QAccessible::State state = Normal; - if (child) { - QDockWidgetLayout *layout = dockWidgetLayout(); - QAbstractButton *b = static_cast(layout->widgetForRole((QDockWidgetLayout::Role)child)); - if (b) { - if (b->isDown()) - state |= Pressed; - } - } else { - QDockWidget *w = dockWidget(); - if (w->testAttribute(Qt::WA_WState_Visible) == false) - state |= Invisible; - if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow()) - state |= Focusable; - if (w->hasFocus()) - state |= Focused; - if (!w->isEnabled()) - state |= Unavailable; - } - - return state; + if (child < 0) + return QAccessibleWidget::state(child); + if (child == 0) + return QAccessible::Normal; + QWidgetList subWindows = workspace()->windowList(); + if (subWindows.isEmpty() || child > subWindows.count()) + return QAccessibleWidget::state(child); + if (subWindows.at(child - 1) == workspace()->activeWindow()) + return QAccessible::Focused; + return QAccessible::Normal; } -QRect QAccessibleTitleBar::rect(int child) const +QVariant QAccessibleWorkspace::invokeMethod(QAccessible::Method, int, const QVariantList &) { - bool mapToGlobal = true; - QRect rect; - if (child == 0) { - if (dockWidget()->isFloating()) { - rect = dockWidget()->frameGeometry(); - if (dockWidget()->widget()) { - QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft()); - globalPos.ry()--; - rect.setBottom(globalPos.y()); - mapToGlobal = false; - } - } else { - QDockWidgetLayout *layout = qobject_cast(dockWidget()->layout()); - rect = layout->titleArea(); - } - }else if (child >= 1 && child <= childCount()) { - QDockWidgetLayout *layout = dockWidgetLayout(); - int index = 1; - for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { - QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); - if (!w || !w->isVisible()) - continue; - if (index == child) { - rect = w->geometry(); - break; - } - ++index; - } - } - if (rect.isNull()) - return rect; + return QVariant(); +} - if (mapToGlobal) - rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); - return rect; +int QAccessibleWorkspace::childCount() const +{ + return workspace()->windowList().count(); } -int QAccessibleTitleBar::childAt(int x, int y) const +int QAccessibleWorkspace::indexOfChild(const QAccessibleInterface *child) const { - for (int i = childCount(); i >= 0; --i) { - if (rect(i).contains(x,y)) - return i; + if (!child || !child->object() || workspace()->windowList().isEmpty()) + return -1; + if (QWidget *window = qobject_cast(child->object())) { + int index = workspace()->windowList().indexOf(window); + if (index != -1) + return ++index; } return -1; } -QObject *QAccessibleTitleBar::object() const +int QAccessibleWorkspace::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const { - return 0; + *target = 0; + QWidget *targetObject = 0; + QWidgetList subWindows = workspace()->windowList(); + switch (relation) { + case Child: + if (entry < 1 || subWindows.isEmpty() || entry > subWindows.count()) + return -1; + targetObject = subWindows.at(entry - 1); + break; + case Up: + case Down: + case Left: + case Right: + targetObject = mdiAreaNavigate(workspace(), relation, entry); + break; + default: + return QAccessibleWidget::navigate(relation, entry, target); + } + *target = QAccessible::queryAccessibleInterface(targetObject); + return *target ? 0: -1; } -QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const +QWorkspace *QAccessibleWorkspace::workspace() const { - return qobject_cast(dockWidget()->layout()); + return static_cast(object()); } +#endif -QDockWidget *QAccessibleTitleBar::dockWidget() const +#ifndef QT_NO_DIALOGBUTTONBOX +// ======================= QAccessibleDialogButtonBox ====================== +QAccessibleDialogButtonBox::QAccessibleDialogButtonBox(QWidget *widget) + : QAccessibleWidget(widget, Grouping) { - return m_dockWidget; + Q_ASSERT(qobject_cast(widget)); } -QString QAccessibleTitleBar::actionText(int action, Text t, int child) const +QVariant QAccessibleDialogButtonBox::invokeMethod(QAccessible::Method, int, const QVariantList &) { - QString str; - if (child >= 1 && child <= childCount()) { - if (t == Name) { - switch (action) { - case Press: - case DefaultAction: - if (child == QDockWidgetLayout::CloseButton) { - str = QDockWidget::tr("Close"); - } else if (child == QDockWidgetLayout::FloatButton) { - str = dockWidget()->isFloating() ? QDockWidget::tr("Dock") - : QDockWidget::tr("Float"); - } - break; - default: - break; - } - } - } - return str; + return QVariant(); } +#endif // QT_NO_DIALOGBUTTONBOX -bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/) +#ifndef QT_NO_TEXTBROWSER +QAccessibleTextBrowser::QAccessibleTextBrowser(QWidget *widget) + : QAccessibleTextEdit(widget) { - if (!child || !dockWidget()->isEnabled()) - return false; - - switch (action) { - case DefaultAction: - case Press: { - QDockWidgetLayout *layout = dockWidgetLayout(); - QAbstractButton *btn = static_cast(layout->widgetForRole((QDockWidgetLayout::Role)child)); - if (btn) - btn->animateClick(); - return true; - break;} - default: - break; - } - - return false; + Q_ASSERT(qobject_cast(widget)); } -int QAccessibleTitleBar::userActionCount (int /*child*/) const +QAccessible::Role QAccessibleTextBrowser::role(int child) const { - return 0; + if (child != 0) + return QAccessibleTextEdit::role(child); + return QAccessible::StaticText; } +#endif // QT_NO_TEXTBROWSER -QAccessible::Role QAccessibleTitleBar::role(int child) const +#ifndef QT_NO_CALENDARWIDGET +// ===================== QAccessibleCalendarWidget ======================== +QAccessibleCalendarWidget::QAccessibleCalendarWidget(QWidget *widget) + : QAccessibleWidget(widget, Table) { - switch (child) { - case 0: - return TitleBar; - break; - default: - if (child >= 1 && child <= childCount()) - return PushButton; - break; - } - - return NoRole; + Q_ASSERT(qobject_cast(widget)); } -void QAccessibleTitleBar::setText(Text /*t*/, int /*child*/, const QString &/*text*/) +QVariant QAccessibleCalendarWidget::invokeMethod(QAccessible::Method, int, const QVariantList &) { - + return QVariant(); } -bool QAccessibleTitleBar::isValid() const +int QAccessibleCalendarWidget::childCount() const { - return dockWidget(); + return calendarWidget()->isNavigationBarVisible() ? 2 : 1; } -#endif // QT_NO_DOCKWIDGET - -#ifndef QT_NO_TEXTEDIT -void QAccessibleTextEdit::addSelection(int startOffset, int endOffset) +int QAccessibleCalendarWidget::indexOfChild(const QAccessibleInterface *child) const { - setSelection(0, startOffset, endOffset); + if (!child || !child->object() || childCount() <= 0) + return -1; + if (qobject_cast(child->object())) + return childCount(); + return 1; } -QString QAccessibleTextEdit::attributes(int offset, int *startOffset, int *endOffset) +int QAccessibleCalendarWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **target) const { - /* 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(); + *target = 0; + if (entry <= 0 || entry > childCount()) + return QAccessibleWidget::navigate(relation, entry, target); + QWidget *targetWidget = 0; + switch (relation) { + case Child: + if (childCount() == 1) { + targetWidget = calendarView(); + } else { + if (entry == 1) + targetWidget = navigationBar(); + else + targetWidget = calendarView(); + } + break; + case Up: + if (entry == 2) + targetWidget = navigationBar(); + break; + case Down: + if (entry == 1 && childCount() == 2) + targetWidget = calendarView(); + break; + default: + return QAccessibleWidget::navigate(relation, entry, target); } + *target = queryAccessibleInterface(targetWidget); + return *target ? 0: -1; +} - QMap 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(); +QRect QAccessibleCalendarWidget::rect(int child) const +{ + if (!calendarWidget()->isVisible() || child > childCount()) + return QRect(); + if (child == 0) + return QAccessibleWidget::rect(child); + QWidget *childWidget = 0; + if (childCount() == 2) + childWidget = child == 1 ? navigationBar() : calendarView(); + else + childWidget = calendarView(); + return QRect(childWidget->mapToGlobal(QPoint(0, 0)), childWidget->size()); +} - QTextCharFormat charFormatComp; - QTextBlockFormat blockFormatComp; +int QAccessibleCalendarWidget::childAt(int x, int y) const +{ + const QPoint globalTargetPos = QPoint(x, y); + if (!rect(0).contains(globalTargetPos)) + return -1; + if (rect(1).contains(globalTargetPos)) + return 1; + if (rect(2).contains(globalTargetPos)) + return 2; + return 0; +} - *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; - } +QCalendarWidget *QAccessibleCalendarWidget::calendarWidget() const +{ + return static_cast(object()); +} - 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; +QAbstractItemView *QAccessibleCalendarWidget::calendarView() const +{ + foreach (QObject *child, calendarWidget()->children()) { + if (child->objectName() == QLatin1String("qt_calendar_calendarview")) + return static_cast(child); } + return 0; +} - 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+'"'; +QWidget *QAccessibleCalendarWidget::navigationBar() const +{ + foreach (QObject *child, calendarWidget()->children()) { + if (child->objectName() == QLatin1String("qt_calendar_navigationbar")) + return static_cast(child); } + return 0; +} +#endif // QT_NO_CALENDARWIDGET - 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()); - } +#ifndef QT_NO_DOCKWIDGET +QAccessibleDockWidget::QAccessibleDockWidget(QWidget *widget) + : QAccessibleWidget(widget, Window) +{ - 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; +int QAccessibleDockWidget::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const +{ + if (relation == Child) { + if (entry == 1) { + *iface = new QAccessibleTitleBar(dockWidget()); + return 0; + } else if (entry == 2) { + if (dockWidget()->widget()) + *iface = QAccessible::queryAccessibleInterface(dockWidget()->widget()); + return 0; + } + *iface = 0; + return -1; } + return QAccessibleWidget::navigate(relation, entry, iface); +} - QString result; - foreach (const QString &attributeName, attrs.keys()) { - result.append(attributeName).append(':').append(attrs[attributeName]).append(';'); +int QAccessibleDockWidget::childAt(int x, int y) const +{ + for (int i = childCount(); i >= 0; --i) { + if (rect(i).contains(x,y)) + return i; } - - return result; + return -1; } -int QAccessibleTextEdit::cursorPosition() +int QAccessibleDockWidget::childCount() const { - return textEdit()->textCursor().position(); + return dockWidget()->widget() ? 2 : 1; } -QRect QAccessibleTextEdit::characterRect(int offset, CoordinateType coordType) +int QAccessibleDockWidget::indexOfChild(const QAccessibleInterface *child) const { - 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); + if (child) { + if (child->role(0) == TitleBar) { + return 1; + } else { + return 2; //### + } } + return -1; +} - switch (coordType) { - case RelativeToScreen: - r.moveTo(edit->viewport()->mapToGlobal(r.topLeft())); - break; - case RelativeToParent: - break; +QAccessible::Role QAccessibleDockWidget::role(int child) const +{ + switch (child) { + case 0: + return Window; + case 1: + return TitleBar; + case 2: + //### + break; + default: + break; } - - return r; + return NoRole; } -int QAccessibleTextEdit::selectionCount() +QAccessible::State QAccessibleDockWidget::state(int child) const { - return textEdit()->textCursor().hasSelection() ? 1 : 0; + //### mark tabified widgets as invisible + return QAccessibleWidget::state(child); } -int QAccessibleTextEdit::offsetAtPoint(const QPoint &point, CoordinateType coordType) +QRect QAccessibleDockWidget::rect (int child ) const { - QTextEdit *edit = textEdit(); + QRect rect; + bool mapToGlobal = true; + if (child == 0) { + if (dockWidget()->isFloating()) { + rect = dockWidget()->frameGeometry(); + mapToGlobal = false; + } else { + rect = dockWidget()->rect(); + } + }else if (child == 1) { + QDockWidgetLayout *layout = qobject_cast(dockWidget()->layout()); + rect = layout->titleArea(); + }else if (child == 2) { + if (dockWidget()->widget()) + rect = dockWidget()->widget()->geometry(); + } + if (rect.isNull()) + return rect; - QPoint p = point; - if (coordType == RelativeToScreen) - p = edit->viewport()->mapFromGlobal(p); - // convert to document coordinates - p += QPoint(edit->horizontalScrollBar()->value(), edit->verticalScrollBar()->value()); + if (mapToGlobal) + rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); - return edit->document()->documentLayout()->hitTest(p, Qt::ExactHit); + return rect; } -void QAccessibleTextEdit::selection(int selectionIndex, int *startOffset, int *endOffset) +QVariant QAccessibleDockWidget::invokeMethod(QAccessible::Method, int, const QVariantList &) { - *startOffset = *endOffset = 0; - QTextCursor cursor = textEdit()->textCursor(); - - if (selectionIndex != 0 || !cursor.hasSelection()) - return; - - *startOffset = cursor.selectionStart(); - *endOffset = cursor.selectionEnd(); + return QVariant(); } -QString QAccessibleTextEdit::text(int startOffset, int endOffset) +QDockWidget *QAccessibleDockWidget::dockWidget() const { - QTextCursor cursor(textEdit()->document()); + return static_cast(object()); +} - cursor.setPosition(startOffset, QTextCursor::MoveAnchor); - cursor.setPosition(endOffset, QTextCursor::KeepAnchor); +//// +// QAccessibleTitleBar +//// +QAccessibleTitleBar::QAccessibleTitleBar(QDockWidget *widget) + : m_dockWidget(widget) +{ - return cursor.selectedText(); } -QString QAccessibleTextEdit::textBeforeOffset (int offset, BoundaryType boundaryType, - int *startOffset, int *endOffset) +QAccessibleInterface *QAccessibleTitleBar::parent() const { - // TODO - what exactly is before? - Q_UNUSED(offset); - Q_UNUSED(boundaryType); - Q_UNUSED(startOffset); - Q_UNUSED(endOffset); - return QString(); + return new QAccessibleDockWidget(dockWidget()); } -QString QAccessibleTextEdit::textAfterOffset(int offset, BoundaryType boundaryType, - int *startOffset, int *endOffset) +QAccessibleInterface *QAccessibleTitleBar::child(int index) const { - // TODO - what exactly is after? - Q_UNUSED(offset); - Q_UNUSED(boundaryType); - Q_UNUSED(startOffset); - Q_UNUSED(endOffset); - return QString(); + if (index >= 0) { + QDockWidgetLayout *layout = dockWidgetLayout(); + int role; + int currentIndex = 0; + for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { + QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); + if (!w || !w->isVisible()) + continue; + if (currentIndex == index) + return QAccessible::queryAccessibleInterface(w); + ++currentIndex; + } + } + return 0; } -QString QAccessibleTextEdit::textAtOffset(int offset, BoundaryType boundaryType, - int *startOffset, int *endOffset) +int QAccessibleTitleBar::navigate(RelationFlag relation, int entry, QAccessibleInterface **iface) const { - 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(); + switch (relation) { + case Child: + *iface = child(entry - 1); + return *iface ? 0 : -1; + case FocusChild: + // ### + if (entry >= 1) { + QDockWidgetLayout *layout = dockWidgetLayout(); + int index = 1; + int role; + for (role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { + QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); + if (!w->isVisible()) + continue; + if (index == entry) + break; + ++index; + } + *iface = 0; + return role > QDockWidgetLayout::FloatButton ? -1 : index; + } break; - case ParagraphBoundary: - cursor.movePosition(QTextCursor::StartOfBlock, QTextCursor::MoveAnchor); - *startOffset = cursor.position(); - cursor.movePosition(QTextCursor::EndOfBlock, QTextCursor::KeepAnchor); - *endOffset = cursor.position(); + case Ancestor: + *iface = parent(); + return iface ? 0 : -1; + case Sibling: + return navigate(Child, entry, iface); 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(); + break; } - - return cursor.selectedText(); + *iface = 0; + return -1; } -void QAccessibleTextEdit::removeSelection(int selectionIndex) +QAccessible::Relation QAccessibleTitleBar::relationTo(int /*child*/, const QAccessibleInterface * /*other*/, int /*otherChild*/) const { - if (selectionIndex != 0) - return; - - QTextCursor cursor = textEdit()->textCursor(); - cursor.clearSelection(); - textEdit()->setTextCursor(cursor); + return Unrelated; //### } -void QAccessibleTextEdit::setCursorPosition(int position) +int QAccessibleTitleBar::indexOfChild(const QAccessibleInterface * /*child*/) const { - QTextCursor cursor = textEdit()->textCursor(); - cursor.setPosition(position); - textEdit()->setTextCursor(cursor); + return -1; } -void QAccessibleTextEdit::setSelection(int selectionIndex, int startOffset, int endOffset) +int QAccessibleTitleBar::childCount() const { - if (selectionIndex != 0) - return; - - QTextCursor cursor = textEdit()->textCursor(); - cursor.setPosition(startOffset, QTextCursor::MoveAnchor); - cursor.setPosition(endOffset, QTextCursor::KeepAnchor); - textEdit()->setTextCursor(cursor); + QDockWidgetLayout *layout = dockWidgetLayout(); + int count = 0; + for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { + QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); + if (w && w->isVisible()) + ++count; + } + return count; } -int QAccessibleTextEdit::characterCount() +QString QAccessibleTitleBar::text(Text t, int child) const { - return textEdit()->toPlainText().count(); + if (!child) { + if (t == Name || t == Value) { + return qt_accStripAmp(dockWidget()->windowTitle()); + } + } + return QString(); } -void QAccessibleTextEdit::scrollToSubstring(int startIndex, int endIndex) +QAccessible::State QAccessibleTitleBar::state(int child) const { - 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()); + QAccessible::State state = Normal; + if (child) { + QDockWidgetLayout *layout = dockWidgetLayout(); + QAbstractButton *b = static_cast(layout->widgetForRole((QDockWidgetLayout::Role)child)); + if (b) { + if (b->isDown()) + state |= Pressed; + } + } else { + QDockWidget *w = dockWidget(); + if (w->testAttribute(Qt::WA_WState_Visible) == false) + state |= Invisible; + if (w->focusPolicy() != Qt::NoFocus && w->isActiveWindow()) + state |= Focusable; + if (w->hasFocus()) + state |= Focused; + if (!w->isEnabled()) + state |= Unavailable; + } - // E V I L, but ensureVisible is not public - if (!QMetaObject::invokeMethod(edit, "_q_ensureVisible", Q_ARG(QRectF, r))) - qWarning("AccessibleTextEdit::scrollToSubstring failed!"); + return state; } -static QTextCursor cursorForRange(QTextEdit *textEdit, int startOffset, int endOffset) +QRect QAccessibleTitleBar::rect(int child) const { - QTextCursor cursor(textEdit->document()); - cursor.setPosition(startOffset, QTextCursor::MoveAnchor); - cursor.setPosition(endOffset, QTextCursor::KeepAnchor); + bool mapToGlobal = true; + QRect rect; + if (child == 0) { + if (dockWidget()->isFloating()) { + rect = dockWidget()->frameGeometry(); + if (dockWidget()->widget()) { + QPoint globalPos = dockWidget()->mapToGlobal(dockWidget()->widget()->rect().topLeft()); + globalPos.ry()--; + rect.setBottom(globalPos.y()); + mapToGlobal = false; + } + } else { + QDockWidgetLayout *layout = qobject_cast(dockWidget()->layout()); + rect = layout->titleArea(); + } + }else if (child >= 1 && child <= childCount()) { + QDockWidgetLayout *layout = dockWidgetLayout(); + int index = 1; + for (int role = QDockWidgetLayout::CloseButton; role <= QDockWidgetLayout::FloatButton; ++role) { + QWidget *w = layout->widgetForRole((QDockWidgetLayout::Role)role); + if (!w || !w->isVisible()) + continue; + if (index == child) { + rect = w->geometry(); + break; + } + ++index; + } + } + if (rect.isNull()) + return rect; - return cursor; + if (mapToGlobal) + rect.moveTopLeft(dockWidget()->mapToGlobal(rect.topLeft())); + return rect; } -void QAccessibleTextEdit::copyText(int startOffset, int endOffset) +int QAccessibleTitleBar::childAt(int x, int y) const { - QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); - - if (!cursor.hasSelection()) - return; - -// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection())); + for (int i = childCount(); i >= 0; --i) { + if (rect(i).contains(x,y)) + return i; + } + return -1; } -void QAccessibleTextEdit::deleteText(int startOffset, int endOffset) +QObject *QAccessibleTitleBar::object() const { - QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); + return 0; +} - cursor.removeSelectedText(); +QDockWidgetLayout *QAccessibleTitleBar::dockWidgetLayout() const +{ + return qobject_cast(dockWidget()->layout()); } -void QAccessibleTextEdit::insertText(int offset, const QString &text) +QDockWidget *QAccessibleTitleBar::dockWidget() const { - QTextCursor cursor(textEdit()->document()); - cursor.setPosition(offset); + return m_dockWidget; +} - cursor.insertText(text); +QString QAccessibleTitleBar::actionText(int action, Text t, int child) const +{ + QString str; + if (child >= 1 && child <= childCount()) { + if (t == Name) { + switch (action) { + case Press: + case DefaultAction: + if (child == QDockWidgetLayout::CloseButton) { + str = QDockWidget::tr("Close"); + } else if (child == QDockWidgetLayout::FloatButton) { + str = dockWidget()->isFloating() ? QDockWidget::tr("Dock") + : QDockWidget::tr("Float"); + } + break; + default: + break; + } + } + } + return str; } -void QAccessibleTextEdit::cutText(int startOffset, int endOffset) +bool QAccessibleTitleBar::doAction(int action, int child, const QVariantList& /*params*/) { - QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); + if (!child || !dockWidget()->isEnabled()) + return false; - if (!cursor.hasSelection()) - return; + switch (action) { + case DefaultAction: + case Press: { + QDockWidgetLayout *layout = dockWidgetLayout(); + QAbstractButton *btn = static_cast(layout->widgetForRole((QDockWidgetLayout::Role)child)); + if (btn) + btn->animateClick(); + return true; + break;} + default: + break; + } -// QApplication::clipboard()->setMimeData(new QTextEditMimeData(cursor.selection())); - cursor.removeSelectedText(); + return false; } -void QAccessibleTextEdit::pasteText(int offset) +int QAccessibleTitleBar::userActionCount (int /*child*/) const { - QTextEdit *edit = textEdit(); + return 0; +} - QTextCursor oldCursor = edit->textCursor(); - QTextCursor newCursor = oldCursor; - newCursor.setPosition(offset); +QAccessible::Role QAccessibleTitleBar::role(int child) const +{ + switch (child) { + case 0: + return TitleBar; + break; + default: + if (child >= 1 && child <= childCount()) + return PushButton; + break; + } - edit->setTextCursor(newCursor); -#ifndef QT_NO_CLIPBOARD - edit->paste(); -#endif - edit->setTextCursor(oldCursor); + return NoRole; } -void QAccessibleTextEdit::replaceText(int startOffset, int endOffset, const QString &text) +void QAccessibleTitleBar::setText(Text /*t*/, int /*child*/, const QString &/*text*/) { - QTextCursor cursor = cursorForRange(textEdit(), startOffset, endOffset); - cursor.removeSelectedText(); - cursor.insertText(text); } -void QAccessibleTextEdit::setAttributes(int startOffset, int endOffset, const QString &attributes) +bool QAccessibleTitleBar::isValid() const { - // TODO - Q_UNUSED(startOffset); - Q_UNUSED(endOffset); - Q_UNUSED(attributes); + return dockWidget(); } -#endif // QT_NO_TEXTEDIT +#endif // QT_NO_DOCKWIDGET #ifndef QT_NO_MAINWINDOW QAccessibleMainWindow::QAccessibleMainWindow(QWidget *widget) diff --git a/src/plugins/accessible/widgets/qaccessiblewidgets.h b/src/plugins/accessible/widgets/qaccessiblewidgets.h index 6cb31726dd..bf3c769048 100644 --- a/src/plugins/accessible/widgets/qaccessiblewidgets.h +++ b/src/plugins/accessible/widgets/qaccessiblewidgets.h @@ -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 ¶ms); - 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); -- cgit v1.2.3