[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