File indexing completed on 2025-01-26 03:28:31
0001 /* 0002 SPDX-FileCopyrightText: 2023 Montel Laurent <montel@kde.org> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "mainwidget.h" 0008 #include "accessibletreewidget.h" 0009 #include "accessiblewrapper.h" 0010 #include "eventview.h" 0011 #include "model/accessibleobjecttreemodel.h" 0012 #include "propertytreewidget.h" 0013 #include "uiview.h" 0014 0015 #include <KLocalizedString> 0016 0017 #include <QHBoxLayout> 0018 #include <QSplitter> 0019 #include <QTabWidget> 0020 0021 MainWidget::MainWidget(QAccessibleClient::Registry *registry, QWidget *parent) 0022 : QWidget{parent} 0023 , mSplitter(new QSplitter(this)) 0024 , mTabWidget(new QTabWidget(this)) 0025 , mAccessibleTreeWidget(new AccessibleTreeWidget(registry, this)) 0026 , mPropertyTreeWidget(new PropertyTreeWidget(this)) 0027 , mEventsWidget(new EventsWidget(this)) 0028 , mUiview(new UiView(this)) 0029 , mRegistry(registry) 0030 { 0031 auto mainLayout = new QHBoxLayout(this); 0032 mainLayout->setContentsMargins({}); 0033 mainLayout->setObjectName(QLatin1StringView("mainLayout")); 0034 0035 mSplitter->setObjectName(QLatin1StringView("mSplitter")); 0036 mainLayout->addWidget(mSplitter); 0037 0038 mAccessibleTreeWidget->setObjectName(QLatin1StringView("mAccessibleTreeWidget")); 0039 mTabWidget->setObjectName(QLatin1StringView("mTabWidget")); 0040 mTabWidget->setMovable(true); 0041 mTabWidget->setDocumentMode(true); 0042 0043 mSplitter->addWidget(mAccessibleTreeWidget); 0044 mSplitter->addWidget(mTabWidget); 0045 0046 mPropertyTreeWidget->setObjectName(QLatin1StringView("mPropertyTreeWidget")); 0047 mEventsWidget->setObjectName(QLatin1StringView("mEventsWidget")); 0048 mUiview->setObjectName(QLatin1StringView("mUiview")); 0049 0050 mTabWidget->addTab(mPropertyTreeWidget, i18nc("@title:window", "Properties")); 0051 mTabWidget->addTab(mEventsWidget, i18nc("@title:window", "Events")); 0052 mTabWidget->addTab(mUiview, i18nc("@title:window", "Boundaries")); 0053 0054 connect(mEventsWidget, &EventsWidget::anchorClicked, this, &MainWidget::anchorClicked); 0055 connect(mAccessibleTreeWidget, &AccessibleTreeWidget::accessibleTreeviewSelectionChanged, this, &MainWidget::selectionChanged); 0056 connect(mRegistry, &QAccessibleClient::Registry::added, this, &MainWidget::added); 0057 connect(mRegistry, &QAccessibleClient::Registry::removed, this, &MainWidget::removed); 0058 connect(mRegistry, &QAccessibleClient::Registry::defunct, this, &MainWidget::defunct); 0059 0060 connect(mRegistry, &QAccessibleClient::Registry::windowCreated, this, &MainWidget::windowCreated); 0061 connect(mRegistry, &QAccessibleClient::Registry::windowDestroyed, this, &MainWidget::windowDestroyed); 0062 connect(mRegistry, &QAccessibleClient::Registry::windowClosed, this, &MainWidget::windowClosed); 0063 connect(mRegistry, &QAccessibleClient::Registry::windowReparented, this, &MainWidget::windowReparented); 0064 connect(mRegistry, &QAccessibleClient::Registry::windowMinimized, this, &MainWidget::windowMinimized); 0065 connect(mRegistry, &QAccessibleClient::Registry::windowMaximized, this, &MainWidget::windowMaximized); 0066 connect(mRegistry, &QAccessibleClient::Registry::windowRestored, this, &MainWidget::windowRestored); 0067 connect(mRegistry, &QAccessibleClient::Registry::windowActivated, this, &MainWidget::windowActivated); 0068 connect(mRegistry, &QAccessibleClient::Registry::windowDeactivated, this, &MainWidget::windowDeactivated); 0069 connect(mRegistry, &QAccessibleClient::Registry::windowDesktopCreated, this, &MainWidget::windowDesktopCreated); 0070 connect(mRegistry, &QAccessibleClient::Registry::windowDesktopDestroyed, this, &MainWidget::windowDesktopDestroyed); 0071 connect(mRegistry, &QAccessibleClient::Registry::windowRaised, this, &MainWidget::windowRaised); 0072 connect(mRegistry, &QAccessibleClient::Registry::windowLowered, this, &MainWidget::windowLowered); 0073 connect(mRegistry, &QAccessibleClient::Registry::windowMoved, this, &MainWidget::windowMoved); 0074 connect(mRegistry, &QAccessibleClient::Registry::windowResized, this, &MainWidget::windowResized); 0075 connect(mRegistry, &QAccessibleClient::Registry::windowShaded, this, &MainWidget::windowShaded); 0076 connect(mRegistry, &QAccessibleClient::Registry::windowUnshaded, this, &MainWidget::windowUnshaded); 0077 0078 connect(mRegistry, &QAccessibleClient::Registry::stateChanged, this, &MainWidget::stateChanged); 0079 connect(mRegistry, &QAccessibleClient::Registry::childAdded, this, &MainWidget::childAdded); 0080 connect(mRegistry, &QAccessibleClient::Registry::childRemoved, this, &MainWidget::childRemoved); 0081 connect(mRegistry, &QAccessibleClient::Registry::visibleDataChanged, this, &MainWidget::visibleDataChanged); 0082 connect(mRegistry, &QAccessibleClient::Registry::selectionChanged, this, &MainWidget::selectionChanged2); 0083 connect(mRegistry, &QAccessibleClient::Registry::modelChanged, this, &MainWidget::modelChanged); 0084 0085 connect(mRegistry, &QAccessibleClient::Registry::focusChanged, this, &MainWidget::focusChanged); 0086 connect(mRegistry, &QAccessibleClient::Registry::textCaretMoved, this, &MainWidget::textCaretMoved); 0087 connect(mRegistry, &QAccessibleClient::Registry::textSelectionChanged, this, &MainWidget::textSelectionChanged); 0088 0089 connect(mRegistry, &QAccessibleClient::Registry::textInserted, this, &MainWidget::textInserted); 0090 connect(mRegistry, &QAccessibleClient::Registry::textRemoved, this, &MainWidget::textRemoved); 0091 connect(mRegistry, &QAccessibleClient::Registry::textChanged, this, &MainWidget::textChanged); 0092 0093 connect(mRegistry, &QAccessibleClient::Registry::accessibleNameChanged, this, &MainWidget::accessibleNameChanged); 0094 connect(mRegistry, &QAccessibleClient::Registry::accessibleDescriptionChanged, this, &MainWidget::accessibleDescriptionChanged); 0095 } 0096 0097 MainWidget::~MainWidget() = default; 0098 0099 void MainWidget::saveSettings(QSettings &settings) 0100 { 0101 mEventsWidget->saveSettings(settings); 0102 mAccessibleTreeWidget->saveSettings(settings); 0103 mPropertyTreeWidget->saveSettings(settings); 0104 } 0105 0106 void MainWidget::loadSettings(QSettings &settings) 0107 { 0108 mEventsWidget->loadSettings(settings); 0109 mAccessibleTreeWidget->loadSettings(settings); 0110 mPropertyTreeWidget->loadSettings(settings); 0111 } 0112 0113 void MainWidget::copyValue() 0114 { 0115 mPropertyTreeWidget->copyValue(); 0116 } 0117 0118 void MainWidget::resetModel() 0119 { 0120 mAccessibleTreeWidget->accessibleObjectTreeModel()->resetModel(); 0121 } 0122 0123 void MainWidget::updateDetails(const QAccessibleClient::AccessibleObject &object, bool force) 0124 { 0125 mPropertyTreeWidget->updateDetails(object, force); 0126 } 0127 0128 void MainWidget::anchorClicked(const QUrl &url) 0129 { 0130 const QAccessibleClient::AccessibleObject object = mRegistry->accessibleFromUrl(url); 0131 mAccessibleTreeWidget->setCurrentObject(object); 0132 } 0133 0134 bool MainWidget::followFocus() const 0135 { 0136 return mFollowFocus; 0137 } 0138 0139 void MainWidget::setFollowFocus(bool newFollowFocus) 0140 { 0141 mFollowFocus = newFollowFocus; 0142 } 0143 0144 void MainWidget::stateChanged(const QAccessibleClient::AccessibleObject &object, const QString &state, bool active) 0145 { 0146 if (state == QLatin1String("focused")) { 0147 mEventsWidget->addLog(object, EventsWidget::Focus, (active ? i18n("true") : i18n("false"))); 0148 } else { 0149 const QString s = state + QStringLiteral(": ") + (active ? i18n("true") : i18n("false")); 0150 mEventsWidget->addLog(object, EventsWidget::StateChanged, s); 0151 } 0152 updateDetails(object); 0153 } 0154 0155 void MainWidget::childAdded(const QAccessibleClient::AccessibleObject &object, int childIndex) 0156 { 0157 updateDetails(object); 0158 mEventsWidget->addLog(object, EventsWidget::Object, i18n("Child Added %1", QString::number(childIndex))); 0159 } 0160 0161 void MainWidget::childRemoved(const QAccessibleClient::AccessibleObject &object, int childIndex) 0162 { 0163 updateDetails(object); 0164 mEventsWidget->addLog(object, EventsWidget::Object, i18n("Child Removed %1", QString::number(childIndex))); 0165 } 0166 0167 void MainWidget::visibleDataChanged(const QAccessibleClient::AccessibleObject &object) 0168 { 0169 updateDetails(object); 0170 mEventsWidget->addLog(object, EventsWidget::Object, i18n("Visible Data Changed")); 0171 } 0172 0173 void MainWidget::selectionChanged2(const QAccessibleClient::AccessibleObject &object) 0174 { 0175 updateDetails(object); 0176 mEventsWidget->addLog(object, EventsWidget::Table, i18n("Selection Changed")); 0177 } 0178 0179 void MainWidget::modelChanged(const QAccessibleClient::AccessibleObject &object) 0180 { 0181 updateDetails(object); 0182 mEventsWidget->addLog(object, EventsWidget::Table, i18n("Model Changed")); 0183 } 0184 0185 void MainWidget::selectionChanged(const QModelIndex ¤t) 0186 { 0187 QAccessibleClient::AccessibleObject acc; 0188 if (current.isValid() && current.internalPointer()) { 0189 acc = static_cast<AccessibleWrapper *>(current.internalPointer())->acc; 0190 } 0191 mUiview->setAccessibleObject(acc); 0192 updateDetails(acc, true); 0193 } 0194 0195 void MainWidget::added(const QAccessibleClient::AccessibleObject &object) 0196 { 0197 mEventsWidget->addLog(object, EventsWidget::Object, i18n("Add Object")); 0198 mAccessibleTreeWidget->accessibleObjectTreeModel()->addAccessible(object); 0199 } 0200 0201 void MainWidget::removed(const QAccessibleClient::AccessibleObject &object) 0202 { 0203 mEventsWidget->addLog(object, EventsWidget::Object, i18n("Remove Object")); 0204 mAccessibleTreeWidget->accessibleObjectTreeModel()->removeAccessible(object); 0205 } 0206 0207 void MainWidget::defunct(const QAccessibleClient::AccessibleObject &object) 0208 { 0209 removed(object); 0210 } 0211 0212 void MainWidget::windowCreated(const QAccessibleClient::AccessibleObject &object) 0213 { 0214 mEventsWidget->addLog(object, EventsWidget::Window, i18n("Create")); 0215 mAccessibleTreeWidget->accessibleObjectTreeModel()->addAccessible(object); 0216 } 0217 0218 void MainWidget::windowDestroyed(const QAccessibleClient::AccessibleObject &object) 0219 { 0220 mEventsWidget->addLog(object, EventsWidget::Window, i18n("Destroy")); 0221 if (!mAccessibleTreeWidget->accessibleObjectTreeModel()->removeAccessible(object)) { 0222 // assume the app has gone 0223 mAccessibleTreeWidget->accessibleObjectTreeModel()->updateTopLevelApps(); 0224 } 0225 } 0226 0227 void MainWidget::windowClosed(const QAccessibleClient::AccessibleObject &object) 0228 { 0229 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowClose")); 0230 } 0231 0232 void MainWidget::windowReparented(const QAccessibleClient::AccessibleObject &object) 0233 { 0234 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowReparent")); 0235 } 0236 0237 void MainWidget::windowMinimized(const QAccessibleClient::AccessibleObject &object) 0238 { 0239 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowMinimize")); 0240 } 0241 0242 void MainWidget::windowMaximized(const QAccessibleClient::AccessibleObject &object) 0243 { 0244 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowMaximize")); 0245 } 0246 0247 void MainWidget::windowRestored(const QAccessibleClient::AccessibleObject &object) 0248 { 0249 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowRestore")); 0250 } 0251 0252 void MainWidget::windowActivated(const QAccessibleClient::AccessibleObject &object) 0253 { 0254 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowActivate")); 0255 } 0256 0257 void MainWidget::windowDeactivated(const QAccessibleClient::AccessibleObject &object) 0258 { 0259 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowDeactivate")); 0260 } 0261 0262 void MainWidget::windowDesktopCreated(const QAccessibleClient::AccessibleObject &object) 0263 { 0264 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowDesktopCreate")); 0265 } 0266 0267 void MainWidget::windowDesktopDestroyed(const QAccessibleClient::AccessibleObject &object) 0268 { 0269 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowDesktopDestroy")); 0270 } 0271 0272 void MainWidget::windowRaised(const QAccessibleClient::AccessibleObject &object) 0273 { 0274 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowRaise")); 0275 } 0276 0277 void MainWidget::windowLowered(const QAccessibleClient::AccessibleObject &object) 0278 { 0279 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowLower")); 0280 } 0281 0282 void MainWidget::windowMoved(const QAccessibleClient::AccessibleObject &object) 0283 { 0284 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowMove")); 0285 } 0286 0287 void MainWidget::windowResized(const QAccessibleClient::AccessibleObject &object) 0288 { 0289 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowResize")); 0290 } 0291 0292 void MainWidget::windowShaded(const QAccessibleClient::AccessibleObject &object) 0293 { 0294 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowShade")); 0295 } 0296 0297 void MainWidget::windowUnshaded(const QAccessibleClient::AccessibleObject &object) 0298 { 0299 mEventsWidget->addLog(object, EventsWidget::Window, QStringLiteral("WindowUnshade")); 0300 } 0301 0302 void MainWidget::focusChanged(const QAccessibleClient::AccessibleObject &object) 0303 { 0304 if (mFollowFocus) { 0305 // We need to block the focus for the treeView while setting the current item 0306 // to prevent that setting that item would change focus to the treeView. 0307 Qt::FocusPolicy prevFocusPolicy = mAccessibleTreeWidget->focusPolicy(); 0308 mAccessibleTreeWidget->setFocusPolicy(Qt::NoFocus); 0309 0310 mAccessibleTreeWidget->setCurrentObject(object); 0311 0312 mAccessibleTreeWidget->setFocusPolicy(prevFocusPolicy); 0313 } else { 0314 updateDetails(object); 0315 } 0316 } 0317 0318 void MainWidget::textCaretMoved(const QAccessibleClient::AccessibleObject &object, int pos) 0319 { 0320 updateDetails(object); 0321 mEventsWidget->addLog(object, EventsWidget::Text, i18n("Text caret moved (%1)", pos)); 0322 } 0323 0324 void MainWidget::textSelectionChanged(const QAccessibleClient::AccessibleObject &object) 0325 { 0326 updateDetails(object); 0327 mEventsWidget->addLog(object, EventsWidget::Text, QStringLiteral("TextSelectionChanged")); 0328 } 0329 0330 QString descriptionForText(const QString &type, const QString &text, int startOffset, int endOffset) 0331 { 0332 QString shortText = text; 0333 if (shortText.length() > 50) { 0334 shortText.truncate(50); 0335 shortText.append(QLatin1String("...")); 0336 } 0337 const QString desc = QStringLiteral("Text %1 (%2, %3): \"%4\"").arg(type).arg(QString::number(startOffset)).arg(QString::number(endOffset)).arg(shortText); 0338 return desc; 0339 } 0340 0341 void MainWidget::textChanged(const QAccessibleClient::AccessibleObject &object, const QString &text, int startOffset, int endOffset) 0342 { 0343 updateDetails(object); 0344 mEventsWidget->addLog(object, EventsWidget::Text, descriptionForText(QLatin1String("changed"), text, startOffset, endOffset)); 0345 } 0346 0347 void MainWidget::textInserted(const QAccessibleClient::AccessibleObject &object, const QString &text, int startOffset, int endOffset) 0348 { 0349 updateDetails(object); 0350 mEventsWidget->addLog(object, EventsWidget::Text, descriptionForText(QLatin1String("inserted"), text, startOffset, endOffset)); 0351 } 0352 0353 void MainWidget::textRemoved(const QAccessibleClient::AccessibleObject &object, const QString &text, int startOffset, int endOffset) 0354 { 0355 updateDetails(object); 0356 mEventsWidget->addLog(object, EventsWidget::Text, descriptionForText(QLatin1String("removed"), text, startOffset, endOffset)); 0357 } 0358 0359 void MainWidget::accessibleNameChanged(const QAccessibleClient::AccessibleObject &object) 0360 { 0361 updateDetails(object); 0362 mEventsWidget->addLog(object, EventsWidget::NameChanged); 0363 mAccessibleTreeWidget->accessibleObjectTreeModel()->updateAccessible(object); 0364 } 0365 0366 void MainWidget::accessibleDescriptionChanged(const QAccessibleClient::AccessibleObject &object) 0367 { 0368 updateDetails(object); 0369 mEventsWidget->addLog(object, EventsWidget::DescriptionChanged); 0370 mAccessibleTreeWidget->accessibleObjectTreeModel()->updateAccessible(object); 0371 } 0372 0373 #include "moc_mainwidget.cpp"