[Konsole-devel] Fwd: [konsole] src: Accessible interface for TerminalDisplay

Jekyll Wu adaptee at gmail.com
Mon Apr 9 21:38:00 UTC 2012


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi:

I just realized that this commit increases the requirement for Qt
version to 4.8+, since it uses some Enums introduced in Qt 4.8.0, like
QAccessible::TextUpdated and QAccessible::TextInserted.

Now Konsole fails to compile on Debian Sid, which ships Qt-4.7.4 as its
newest version.

So questions:

1. Is this requirement too high? IIRC, even kdelibs hasn't increased
the requirement to Qt 4.8+ now.

2. Should we add explicit requirement for Qt 4.8+ in CMakeLists.txt ?

Regards
Jekyll

- -------- 原始信息 --------
主题: [konsole] src: Accessible interface for TerminalDisplay
日期: Thu, 29 Mar 2012 20:00:52 +0200 (CEST)
发件人: Frederik Gladhorn <gladhorn at kde.org>
回复地址: kde-commits at kde.org
收件人: kde-commits at kde.org

Git commit 7e0ba7079ae48ed9afe49301feed1e8ee13baba8 by Frederik Gladhorn.
Committed on 29/03/2012 at 19:37.
Pushed by gladhorn into branch 'master'.

Accessible interface for TerminalDisplay

This allows screen readers to read the output
in the konsole window.

M  +1    -0    src/CMakeLists.txt
M  +9    -1    src/Screen.cpp
M  +7    -0    src/Screen.h
M  +37   -0    src/TerminalDisplay.cpp
M  +1    -0    src/TerminalDisplay.h
A  +215  -0    src/TerminalDisplayAccessible.cpp     [License: GPL (v2+)]
A  +96   -0    src/TerminalDisplayAccessible.h     [License: GPL (v2+)]

http://commits.kde.org/konsole/7e0ba7079ae48ed9afe49301feed1e8ee13baba8

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6844238..bea5885 100644
- --- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -101,6 +101,7 @@ ${CMAKE_CURRENT_BINARY_DIR}/tests/CTestCustom.cmake)
         TerminalCharacterDecoder.cpp
         ExtendedCharTable.cpp
         TerminalDisplay.cpp
+        TerminalDisplayAccessible.cpp
         ViewContainer.cpp
         ViewManager.cpp
         ViewProperties.cpp
diff --git a/src/Screen.cpp b/src/Screen.cpp
index 764bf87..bd52544 100644
- --- a/src/Screen.cpp
+++ b/src/Screen.cpp
@@ -1094,12 +1094,20 @@ bool Screen::isSelected(const int x, const int
y) const

 QString Screen::selectedText(bool preserveLineBreaks) const
 {
+    if (!isSelectionValid())
+        return QString();
+
+    return text(_selTopLeft, _selBottomRight, preserveLineBreaks);
+}
+
+QString Screen::text(int startIndex, int endIndex, bool
preserveLineBreaks) const
+{
     QString result;
     QTextStream stream(&result, QIODevice::ReadWrite);

     PlainTextDecoder decoder;
     decoder.begin(&stream);
- -    writeSelectionToStream(&decoder , preserveLineBreaks);
+    writeToStream(&decoder, startIndex, endIndex, preserveLineBreaks);
     decoder.end();

     return result;
diff --git a/src/Screen.h b/src/Screen.h
index 8e2a846..7cf1349 100644
- --- a/src/Screen.h
+++ b/src/Screen.h
@@ -449,6 +449,13 @@ public:
     QString selectedText(bool preserveLineBreaks) const;

     /**
+     * Convenience method.  Returns the text from @p startIndex to @p
endIndex.
+     * @param preserveLineBreaks Specifies whether new line
characters should
+     * be inserted into the returned text at the end of each terminal
line.
+     */
+    QString text(int startIndex, int endIndex, bool
preserveLineBreaks) const;
+
+    /**
      * Copies part of the output to a stream.
      *
      * @param decoder A decoder which converts terminal characters
into text
diff --git a/src/TerminalDisplay.cpp b/src/TerminalDisplay.cpp
index 691e22b..664a84e 100644
- --- a/src/TerminalDisplay.cpp
+++ b/src/TerminalDisplay.cpp
@@ -38,6 +38,7 @@
 #include <QtGui/QStyle>
 #include <QtCore/QTimer>
 #include <QtGui/QToolTip>
+#include <QtGui/QAccessible>

 // KDE
 #include <KShell>
@@ -61,6 +62,7 @@
 #include "SessionController.h"
 #include "WindowSystemInfo.h"
 #include "ExtendedCharTable.h"
+#include "TerminalDisplayAccessible.h"

 using namespace Konsole;

@@ -250,6 +252,27 @@ void TerminalDisplay::setLineSpacing(uint i)
     setVTFont(font()); // Trigger an update.
 }

+
+/*
- -------------------------------------------------------------------------
*/
+/*
        */
+/*                         Accessibility
        */
+/*
        */
+/*
- -------------------------------------------------------------------------
*/
+
+namespace Konsole {
+    /**
+     * This function installs the factory function which lets Qt
instanciate the QAccessibleInterface
+     * for the TerminalDisplay.
+     */
+    QAccessibleInterface* accessibleInterfaceFactory(const QString
&key, QObject *object)
+    {
+        Q_UNUSED(key)
+        if (TerminalDisplay *display =
qobject_cast<TerminalDisplay*>(object))
+            return new TerminalDisplayAccessible(display);
+        return 0;
+    }
+}
+
 /*
- -------------------------------------------------------------------------
*/
 /*
        */
 /*                         Constructor / Destructor
        */
@@ -353,6 +376,11 @@ TerminalDisplay::TerminalDisplay(QWidget* parent)
     setLayout(_gridLayout);

     new AutoScrollHandler(this);
+
+
+#ifndef QT_NO_ACCESSIBILITY
+  QAccessible::installFactory(Konsole::accessibleInterfaceFactory);
+#endif
 }

 TerminalDisplay::~TerminalDisplay()
@@ -1059,6 +1087,10 @@ void TerminalDisplay::updateImage()
     }
     delete[] dirtyMask;

+#ifndef QT_NO_ACCESSIBILITY
+    QAccessible::updateAccessibility(this, 0, QAccessible::TextUpdated);
+    QAccessible::updateAccessibility(this, 0,
QAccessible::TextCaretMoved);
+#endif
 }

 void TerminalDisplay::showResizeNotification()
@@ -2631,6 +2663,11 @@ void TerminalDisplay::keyPressEvent(QKeyEvent*
event)

     emit keyPressedSignal(event);

+#ifndef QT_NO_ACCESSIBILITY
+    QAccessible::updateAccessibility(this, 0,
QAccessible::TextCaretMoved);
+    QAccessible::updateAccessibility(this, 0, QAccessible::TextInserted);
+#endif
+
     event->accept();
 }

diff --git a/src/TerminalDisplay.h b/src/TerminalDisplay.h
index c00b83f..5b067cd 100644
- --- a/src/TerminalDisplay.h
+++ b/src/TerminalDisplay.h
@@ -804,6 +804,7 @@ private:
     static const int DEFAULT_TOP_MARGIN = 1;

     SessionController* _sessionController;
+    friend class TerminalDisplayAccessible;
 };

 class AutoScrollHandler : public QObject
diff --git a/src/TerminalDisplayAccessible.cpp
b/src/TerminalDisplayAccessible.cpp
new file mode 100644
index 0000000..48eca3e
- --- /dev/null
+++ b/src/TerminalDisplayAccessible.cpp
@@ -0,0 +1,215 @@
+/*
+ *  This file is part of Konsole, a terminal emulator for KDE.
+ *
+ *  Copyright 2012  Frederik Gladhorn <gladhorn at kde.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301  USA.
+ */
+
+#include "TerminalDisplayAccessible.h"
+
+#if QT_VERSION >= 0x040800 // added in Qt 4.8.0
+QString Q_GUI_EXPORT qTextBeforeOffsetFromString (int offset,
QAccessible2::BoundaryType boundaryType,
+        int* startOffset, int* endOffset, const QString& text);
+QString Q_GUI_EXPORT qTextAtOffsetFromString (int offset,
QAccessible2::BoundaryType boundaryType,
+        int* startOffset, int* endOffset, const QString& text);
+QString Q_GUI_EXPORT qTextAfterOffsetFromString (int offset,
QAccessible2::BoundaryType boundaryType,
+        int* startOffset, int* endOffset, const QString& text);
+#endif
+
+using namespace Konsole;
+
+TerminalDisplayAccessible::TerminalDisplayAccessible(TerminalDisplay*
display)
+    : QAccessibleWidgetEx (display,
+#if QT_VERSION > 0x040800 // added in Qt 4.8.1
+                           QAccessible::Terminal
+#else
+                           QAccessible::EditableText
+#endif
+                          )
+    , QAccessibleSimpleEditableTextInterface (this)
+{}
+
+int TerminalDisplayAccessible::characterCount()
+{
+
+    return display()->_usedLines * display()->_usedColumns;
+}
+
+int TerminalDisplayAccessible::cursorPosition()
+{
+    if (!display()->screenWindow())
+        return 0;
+
+    int offset = display()->_usedColumns *
display()->screenWindow()->screen()->getCursorY();
+    return offset + display()->screenWindow()->screen()->getCursorX();
+}
+
+void TerminalDisplayAccessible::selection(int selectionIndex, int*
startOffset, int* endOffset)
+{
+    *startOffset = 0;
+    *endOffset = 0;
+    if (!display()->screenWindow() || selectionIndex)
+        return;
+
+    int startLine;
+    int startColumn;
+    int endLine;
+    int endColumn;
+    display()->screenWindow()->getSelectionStart(startColumn, startLine);
+    display()->screenWindow()->getSelectionEnd(endColumn, endLine);
+    if ((startLine == endLine) && (startColumn == endColumn))
+        return;
+    *startOffset = positionToOffset(startColumn, startLine);
+    *endOffset = positionToOffset(endColumn, endLine);
+}
+
+int TerminalDisplayAccessible::selectionCount()
+{
+    if (!display()->screenWindow())
+        return 0;
+
+    int startLine;
+    int startColumn;
+    int endLine;
+    int endColumn;
+    display()->screenWindow()->getSelectionStart(startColumn, startLine);
+    display()->screenWindow()->getSelectionEnd(endColumn, endLine);
+    return ((startLine == endLine) && (startColumn == endColumn)) ? 0
: 1;
+}
+
+QString TerminalDisplayAccessible::visibleText() const
+{
+    // This function should be const to allow calling it from const
interface functions.
+    TerminalDisplay* display =
const_cast<TerminalDisplayAccessible*>(this)->display();
+    if (!display->screenWindow())
+        return QString();
+
+    return display->screenWindow()->screen()->text (0,
display->_usedColumns * display->_usedLines, true);
+}
+
+void TerminalDisplayAccessible::addSelection(int startOffset, int
endOffset)
+{
+    if (!display()->screenWindow())
+        return;
+    display()->screenWindow()->setSelectionStart (columnForOffset
(startOffset), lineForOffset (startOffset), false);
+    display()->screenWindow()->setSelectionEnd (columnForOffset
(endOffset), lineForOffset (endOffset));
+}
+
+QString TerminalDisplayAccessible::attributes(int offset, int*
startOffset, int* endOffset)
+{
+    // FIXME: this function should return css like attributes
+    // as defined in the web ARIA standard
+    Q_UNUSED (offset)
+    *startOffset = 0;
+    *endOffset = characterCount();
+    return QString();
+}
+
+QRect TerminalDisplayAccessible::characterRect(int offset,
QAccessible2::CoordinateType coordType)
+{
+    // FIXME return the rect of a letter inside the display
+    Q_UNUSED (offset)
+    Q_UNUSED (coordType)
+    return QRect();
+}
+
+int TerminalDisplayAccessible::offsetAtPoint(const QPoint& point,
QAccessible2::CoordinateType coordType)
+{
+    // FIXME return the offset into the text from the given point
+    Q_UNUSED (point)
+    Q_UNUSED (coordType)
+    return 0;
+}
+
+void TerminalDisplayAccessible::removeSelection(int selectionIndex)
+{
+    if (!display()->screenWindow() || selectionIndex)
+        return;
+    display()->screenWindow()->clearSelection();
+}
+
+void TerminalDisplayAccessible::scrollToSubstring(int startIndex, int
endIndex)
+{
+    // FIXME: make sure the string between startIndex and endIndex is
visible
+    Q_UNUSED (startIndex)
+    Q_UNUSED (endIndex)
+}
+
+void TerminalDisplayAccessible::setCursorPosition(int position)
+{
+    if (!display()->screenWindow())
+        return;
+
+    display()->screenWindow()->screen()->setCursorYX (lineForOffset
(position), columnForOffset (position));
+}
+
+void TerminalDisplayAccessible::setSelection(int selectionIndex, int
startOffset, int endOffset)
+{
+    if (selectionIndex)
+        return;
+    addSelection(startOffset, endOffset);
+}
+
+QString TerminalDisplayAccessible::text(QAccessible::Text t, int
child) const
+{
+    if (t == QAccessible::Value && child == 0)
+        return visibleText();
+    return QAccessibleWidgetEx::text(t, child);
+}
+
+QString TerminalDisplayAccessible::text(int startOffset, int endOffset)
+{
+    if (!display()->screenWindow())
+        return QString();
+
+    return display()->screenWindow()->screen()->text(startOffset,
endOffset, true);
+}
+
+QString TerminalDisplayAccessible::textAfterOffset(int offset,
QAccessible2::BoundaryType boundaryType, int* startOffset, int* endOffset)
+{
+    const QString text = visibleText();
+#if QT_VERSION >= 0x040800 // added in Qt 4.8.0
+    return qTextAfterOffsetFromString (offset, boundaryType,
startOffset, endOffset, text);
+#else
+    return text;
+#endif
+}
+
+QString TerminalDisplayAccessible::textAtOffset(int offset,
QAccessible2::BoundaryType boundaryType, int* startOffset, int* endOffset)
+{
+    const QString text = visibleText();
+#if QT_VERSION >= 0x040800 // added in Qt 4.8.0
+    return qTextAtOffsetFromString (offset, boundaryType,
startOffset, endOffset, text);
+#else
+    return text;
+#endif
+}
+
+QString TerminalDisplayAccessible::textBeforeOffset(int offset,
QAccessible2::BoundaryType boundaryType, int* startOffset, int* endOffset)
+{
+    const QString text = visibleText();
+#if QT_VERSION >= 0x040800 // added in Qt 4.8.0
+    return qTextBeforeOffsetFromString (offset, boundaryType,
startOffset, endOffset, text);
+#else
+    return text;
+#endif
+}
+
+TerminalDisplay* TerminalDisplayAccessible::display()
+{
+    return static_cast<TerminalDisplay*> (object());
+}
diff --git a/src/TerminalDisplayAccessible.h
b/src/TerminalDisplayAccessible.h
new file mode 100644
index 0000000..02dd094
- --- /dev/null
+++ b/src/TerminalDisplayAccessible.h
@@ -0,0 +1,96 @@
+/*
+ *  This file is part of Konsole, a terminal emulator for KDE.
+ *
+ *  Copyright 2012  Frederik Gladhorn <gladhorn at kde.org>
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ *  02110-1301  USA.
+ */
+
+#ifndef TERMINALDISPLAYACCESSIBLE_H
+#define TERMINALDISPLAYACCESSIBLE_H
+
+#include <QtGui/qaccessible.h>
+#include <QtGui/qaccessible2.h>
+#include <QtGui/qaccessiblewidget.h>
+
+#include "TerminalDisplay.h"
+#include "ScreenWindow.h"
+#include "Screen.h"
+
+namespace Konsole {
+
+/**
+ * Class implementing the QAccessibleInterface for the terminal display.
+ * This exposes information about the display to assistive technology
using the QAccessible framework.
+ *
+ * Most functions are re-implemented from QAccessibleTextInterface.
+ */
+class TerminalDisplayAccessible
+ : public QAccessibleWidgetEx, public QAccessibleTextInterface,
public QAccessibleSimpleEditableTextInterface
+{
+    Q_ACCESSIBLE_OBJECT
+
+public:
+    explicit TerminalDisplayAccessible(TerminalDisplay *display);
+
+    QString text(QAccessible::Text t, int child) const;
+
+    QString text(int startOffset, int endOffset);
+    QString textAfterOffset(int offset, QAccessible2::BoundaryType
boundaryType, int* startOffset, int* endOffset);
+    QString textAtOffset(int offset, QAccessible2::BoundaryType
boundaryType, int* startOffset, int* endOffset);
+    QString textBeforeOffset(int offset, QAccessible2::BoundaryType
boundaryType, int* startOffset, int* endOffset);
+    int characterCount();
+
+    int selectionCount();
+    void selection(int selectionIndex, int *startOffset, int *endOffset);
+    void addSelection(int startOffset, int endOffset);
+    void setSelection(int selectionIndex, int startOffset, int
endOffset);
+    void removeSelection(int selectionIndex);
+
+    QRect characterRect(int offset, QAccessible2::CoordinateType
coordType);
+    int offsetAtPoint(const QPoint& point,
QAccessible2::CoordinateType coordType);
+    void scrollToSubstring(int startIndex, int endIndex);
+
+    QString attributes(int offset, int* startOffset, int* endOffset);
+
+    int cursorPosition();
+    void setCursorPosition(int position);
+
+private:
+    Konsole::TerminalDisplay *display();
+
+    inline int positionToOffset(int column, int line)
+    {
+        return line * display()->_usedColumns + column;
+    }
+
+    inline int lineForOffset(int offset)
+    {
+        return offset / display()->_usedColumns;
+    }
+
+    inline int columnForOffset(int offset)
+    {
+        return offset % display()->_usedColumns;
+    }
+
+    QString visibleText() const;
+};
+
+
+} // namespace
+
+#endif // TERMINALDISPLAYACCESSIBLE_H
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.19 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQIcBAEBAgAGBQJPg1a3AAoJEOemZ9znWXlAUQcQAKixdKrFoL0ep4JByyWnghxj
kwuB85e/Cp4u4p3DUCeC/ZYBHnj+SPpo+mVn5xy5MBbzDELCxdn9OtVZHzJJHyB2
0QzucjPx8pQN18dB2OuAVsIhkH4WtoJ0NEy/npufkwT7ejbdN05X3ouO9DKPEfu2
2krspP+06sowslZzLciMe1I1qHFbsaXYt/ky7Vb1rx4f1UH8rdVHpv7fstH/3G0Y
brPd46xEl/QvWSrNkntK4LkmPWoS7oexwfx8ysUujMk1qnPZl4ucIHTNCDftRwe/
bPatcHFRHapFNpGgTJrRODrFocG2dBFvGrVUiFsr25b4IWHdS3PurkWtLkm+xeUr
x3sYYi6THaNCgkHkx8lED1P0jmDqam/rXf8ZsPXZqacqOSQDjCLVddu4mDifClVY
B6bGnzrDmolfAvb8b8Q9hWKKzErIF3uOkgCo7rWmAyswCnqtpKhbLPDnHUbGRrZq
S/GeOS2cmtvYjlEt6EzZG/X2XIbFxhUqEB5QYX9VcyCTK8HnQP+bEUslsnkyixMI
QkmMffEqD8XfLWzl8nYQqvTFhFFbSRAXt7vLWq6M0xdZN/hU/GO5w3tjRyAvhvf6
9A94mYxjLmnAX6IrwNkF2CZUhzZVznrZXglZ83zovkxaiSFYXbLTx6dlZtZ0DAZZ
n3JJ9z5PUPAHp4EjRupI
=YuML
-----END PGP SIGNATURE-----



More information about the konsole-devel mailing list