File indexing completed on 2024-04-28 05:50:55

0001 /*
0002  *  SPDX-FileCopyrightText: 2012 Frederik Gladhorn <gladhorn@kde.org>
0003  *
0004  *  SPDX-License-Identifier: GPL-2.0-or-later
0005  */
0006 
0007 #include "TerminalDisplayAccessible.h"
0008 #include "session/SessionController.h"
0009 #include <klocalizedstring.h>
0010 
0011 #include "terminalDisplay/TerminalFonts.h"
0012 
0013 using namespace Konsole;
0014 
0015 TerminalDisplayAccessible::TerminalDisplayAccessible(TerminalDisplay *display)
0016     : QAccessibleWidget(display, QAccessible::Terminal, display->sessionController()->userTitle())
0017 {
0018 }
0019 
0020 QString TerminalDisplayAccessible::text(QAccessible::Text t) const
0021 {
0022     if (t == QAccessible::Value) {
0023         return visibleText();
0024     }
0025     return QAccessibleWidget::text(t);
0026 }
0027 
0028 int TerminalDisplayAccessible::characterCount() const
0029 {
0030     return display()->_usedLines * display()->_usedColumns;
0031 }
0032 
0033 int TerminalDisplayAccessible::cursorPosition() const
0034 {
0035     if (display()->screenWindow() == nullptr) {
0036         return 0;
0037     }
0038 
0039     int offset = display()->_usedColumns * display()->screenWindow()->screen()->getCursorY();
0040     return offset + display()->screenWindow()->screen()->getCursorX();
0041 }
0042 
0043 void TerminalDisplayAccessible::selection(int selectionIndex, int *startOffset, int *endOffset) const
0044 {
0045     *startOffset = 0;
0046     *endOffset = 0;
0047     if ((display()->screenWindow() == nullptr) || (selectionIndex != 0)) {
0048         return;
0049     }
0050 
0051     int startLine = 0;
0052     int startColumn = 0;
0053     int endLine = 0;
0054     int endColumn = 0;
0055     display()->screenWindow()->getSelectionStart(startColumn, startLine);
0056     display()->screenWindow()->getSelectionEnd(endColumn, endLine);
0057     if ((startLine == endLine) && (startColumn == endColumn)) {
0058         return;
0059     }
0060     *startOffset = positionToOffset(startColumn, startLine);
0061     *endOffset = positionToOffset(endColumn, endLine);
0062 }
0063 
0064 int TerminalDisplayAccessible::selectionCount() const
0065 {
0066     if (display()->screenWindow() == nullptr) {
0067         return 0;
0068     }
0069 
0070     int startLine = 0;
0071     int startColumn = 0;
0072     int endLine = 0;
0073     int endColumn = 0;
0074     display()->screenWindow()->getSelectionStart(startColumn, startLine);
0075     display()->screenWindow()->getSelectionEnd(endColumn, endLine);
0076     return ((startLine == endLine) && (startColumn == endColumn)) ? 0 : 1;
0077 }
0078 
0079 QString TerminalDisplayAccessible::visibleText() const
0080 {
0081     // This function should be const to allow calling it from const interface functions.
0082     TerminalDisplay *display = const_cast<TerminalDisplayAccessible *>(this)->display();
0083     if (display->screenWindow() == nullptr) {
0084         return QString();
0085     }
0086 
0087     return display->screenWindow()->screen()->text(0, display->_usedColumns * display->_usedLines, Screen::PreserveLineBreaks);
0088 }
0089 
0090 void TerminalDisplayAccessible::addSelection(int startOffset, int endOffset)
0091 {
0092     if (display()->screenWindow() == nullptr) {
0093         return;
0094     }
0095     display()->screenWindow()->setSelectionStart(columnForOffset(startOffset), lineForOffset(startOffset), false);
0096     display()->screenWindow()->setSelectionEnd(columnForOffset(endOffset), lineForOffset(endOffset), display()->trimTrailingWhitespace());
0097 }
0098 
0099 QString TerminalDisplayAccessible::attributes(int offset, int *startOffset, int *endOffset) const
0100 {
0101     // FIXME: this function should return css like attributes
0102     // as defined in the web ARIA standard
0103     Q_UNUSED(offset)
0104     *startOffset = 0;
0105     *endOffset = characterCount();
0106     return QString();
0107 }
0108 
0109 QRect TerminalDisplayAccessible::characterRect(int offset) const
0110 {
0111     int row = offset / display()->_usedColumns;
0112     int col = offset - row * display()->_usedColumns;
0113     QPoint position = QPoint(col * display()->terminalFont()->fontWidth(), row * display()->terminalFont()->fontHeight());
0114     return QRect(position, QSize(display()->terminalFont()->fontWidth(), display()->terminalFont()->fontHeight()));
0115 }
0116 
0117 int TerminalDisplayAccessible::offsetAtPoint(const QPoint &point) const
0118 {
0119     // FIXME return the offset into the text from the given point
0120     Q_UNUSED(point)
0121     return 0;
0122 }
0123 
0124 void TerminalDisplayAccessible::removeSelection(int selectionIndex)
0125 {
0126     if ((display()->screenWindow() == nullptr) || (selectionIndex != 0)) {
0127         return;
0128     }
0129     display()->screenWindow()->clearSelection();
0130 }
0131 
0132 void TerminalDisplayAccessible::scrollToSubstring(int startIndex, int endIndex)
0133 {
0134     // FIXME: make sure the string between startIndex and endIndex is visible
0135     Q_UNUSED(startIndex)
0136     Q_UNUSED(endIndex)
0137 }
0138 
0139 void TerminalDisplayAccessible::setCursorPosition(int position)
0140 {
0141     if (display()->screenWindow() == nullptr) {
0142         return;
0143     }
0144 
0145     display()->screenWindow()->screen()->setCursorYX(lineForOffset(position), columnForOffset(position));
0146 }
0147 
0148 void *TerminalDisplayAccessible::interface_cast(QAccessible::InterfaceType type)
0149 {
0150     if (type == QAccessible::TextInterface) {
0151         return static_cast<QAccessibleTextInterface *>(this);
0152     }
0153 
0154     return QAccessibleWidget::interface_cast(type);
0155 }
0156 
0157 void TerminalDisplayAccessible::setSelection(int selectionIndex, int startOffset, int endOffset)
0158 {
0159     if (selectionIndex != 0) {
0160         return;
0161     }
0162     addSelection(startOffset, endOffset);
0163 }
0164 
0165 QString TerminalDisplayAccessible::text(int startOffset, int endOffset) const
0166 {
0167     if (display()->screenWindow() == nullptr) {
0168         return QString();
0169     }
0170 
0171     return display()->screenWindow()->screen()->text(startOffset, endOffset, Screen::PreserveLineBreaks);
0172 }
0173 
0174 TerminalDisplay *TerminalDisplayAccessible::display() const
0175 {
0176     return qobject_cast<TerminalDisplay *>(widget());
0177 }