1 /*
2 Copyright 2012 Frederik Gladhorn <gladhorn@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) version 3, or any
8 later version accepted by the membership of KDE e.V. (or its
9 successor approved by the membership of KDE e.V.), which shall
10 act as a proxy defined in Section 6 of version 3 of the license.
11
12 This library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public
18 License along with this library. If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "mainwindow.h"
22
23 #include <qdialog.h>
24 #include <qdockwidget.h>
25 #include <qmenubar.h>
26 #include <qpointer.h>
27 #include <qsettings.h>
28 #include <qurl.h>
29 #include <QClipboard>
30
31 #include "qaccessibilityclient/registry.h"
32 #include "qaccessibilityclient/registrycache_p.h"
33 #include "qaccessibilityclient/accessibleobject.h"
34
35 #include "accessibleproperties.h"
36 #include "accessibletree.h"
37 #include "eventview.h"
38 #include "uiview.h"
39
40 using namespace QAccessibleClient;
41
MainWindow(QWidget * parent)42 MainWindow::MainWindow(QWidget *parent)
43 : QMainWindow(parent)
44 {
45 setWindowTitle(QLatin1String("Randamizer"));
46 m_registry = new QAccessibleClient::Registry(this);
47
48 initUi();
49 initActions();
50 initMenu();
51
52 QSettings settings("kde.org", "kdea11yapp");
53 QAccessibleClient::RegistryPrivateCacheApi cache(m_registry);
54 cache.setCacheType(QAccessibleClient::RegistryPrivateCacheApi::CacheType(settings.value("cacheStrategy", cache.cacheType()).toInt()));
55 restoreGeometry(settings.value("geometry").toByteArray());
56 restoreState(settings.value("windowState").toByteArray());
57
58 m_eventsWidget->loadSettings(settings);
59
60 connect(m_registry, SIGNAL(added(QAccessibleClient::AccessibleObject)), this, SLOT(added(QAccessibleClient::AccessibleObject)));
61 connect(m_registry, SIGNAL(removed(QAccessibleClient::AccessibleObject)), this, SLOT(removed(QAccessibleClient::AccessibleObject)));
62 connect(m_registry, SIGNAL(defunct(QAccessibleClient::AccessibleObject)), this, SLOT(defunct(QAccessibleClient::AccessibleObject)));
63
64 connect(m_registry, SIGNAL(windowCreated(QAccessibleClient::AccessibleObject)), this, SLOT(windowCreated(QAccessibleClient::AccessibleObject)));
65 connect(m_registry, SIGNAL(windowDestroyed(QAccessibleClient::AccessibleObject)), this, SLOT(windowDestroyed(QAccessibleClient::AccessibleObject)));
66 connect(m_registry, SIGNAL(windowClosed(QAccessibleClient::AccessibleObject)), this, SLOT(windowClosed(QAccessibleClient::AccessibleObject)));
67 connect(m_registry, SIGNAL(windowReparented(QAccessibleClient::AccessibleObject)), this, SLOT(windowReparented(QAccessibleClient::AccessibleObject)));
68 connect(m_registry, SIGNAL(windowMinimized(QAccessibleClient::AccessibleObject)), this, SLOT(windowMinimized(QAccessibleClient::AccessibleObject)));
69 connect(m_registry, SIGNAL(windowMaximized(QAccessibleClient::AccessibleObject)), this, SLOT(windowMaximized(QAccessibleClient::AccessibleObject)));
70 connect(m_registry, SIGNAL(windowRestored(QAccessibleClient::AccessibleObject)), this, SLOT(windowRestored(QAccessibleClient::AccessibleObject)));
71 connect(m_registry, SIGNAL(windowActivated(QAccessibleClient::AccessibleObject)), this, SLOT(windowActivated(QAccessibleClient::AccessibleObject)));
72 connect(m_registry, SIGNAL(windowDeactivated(QAccessibleClient::AccessibleObject)), this, SLOT(windowDeactivated(QAccessibleClient::AccessibleObject)));
73 connect(m_registry, SIGNAL(windowDesktopCreated(QAccessibleClient::AccessibleObject)), this, SLOT(windowDesktopCreated(QAccessibleClient::AccessibleObject)));
74 connect(m_registry, SIGNAL(windowDesktopDestroyed(QAccessibleClient::AccessibleObject)), this, SLOT(windowDesktopDestroyed(QAccessibleClient::AccessibleObject)));
75 connect(m_registry, SIGNAL(windowRaised(QAccessibleClient::AccessibleObject)), this, SLOT(windowRaised(QAccessibleClient::AccessibleObject)));
76 connect(m_registry, SIGNAL(windowLowered(QAccessibleClient::AccessibleObject)), this, SLOT(windowLowered(QAccessibleClient::AccessibleObject)));
77 connect(m_registry, SIGNAL(windowMoved(QAccessibleClient::AccessibleObject)), this, SLOT(windowMoved(QAccessibleClient::AccessibleObject)));
78 connect(m_registry, SIGNAL(windowResized(QAccessibleClient::AccessibleObject)), this, SLOT(windowResized(QAccessibleClient::AccessibleObject)));
79 connect(m_registry, SIGNAL(windowShaded(QAccessibleClient::AccessibleObject)), this, SLOT(windowShaded(QAccessibleClient::AccessibleObject)));
80 connect(m_registry, SIGNAL(windowUnshaded(QAccessibleClient::AccessibleObject)), this, SLOT(windowUnshaded(QAccessibleClient::AccessibleObject)));
81
82 connect(m_registry, SIGNAL(stateChanged(QAccessibleClient::AccessibleObject,QString,bool)), this, SLOT(stateChanged(QAccessibleClient::AccessibleObject,QString,bool)));
83 connect(m_registry, SIGNAL(childAdded(QAccessibleClient::AccessibleObject,int)), this, SLOT(childAdded(QAccessibleClient::AccessibleObject,int)));
84 connect(m_registry, SIGNAL(childRemoved(QAccessibleClient::AccessibleObject,int)), this, SLOT(childRemoved(QAccessibleClient::AccessibleObject,int)));
85 connect(m_registry, SIGNAL(visibleDataChanged(QAccessibleClient::AccessibleObject)), this, SLOT(visibleDataChanged(QAccessibleClient::AccessibleObject)));
86 connect(m_registry, SIGNAL(selectionChanged(QAccessibleClient::AccessibleObject)), this, SLOT(selectionChanged(QAccessibleClient::AccessibleObject)));
87 connect(m_registry, SIGNAL(modelChanged(QAccessibleClient::AccessibleObject)), this, SLOT(modelChanged(QAccessibleClient::AccessibleObject)));
88
89 connect(m_registry, SIGNAL(focusChanged(QAccessibleClient::AccessibleObject)), this, SLOT(focusChanged(QAccessibleClient::AccessibleObject)));
90 connect(m_registry, SIGNAL(textCaretMoved(QAccessibleClient::AccessibleObject,int)), this, SLOT(textCaretMoved(QAccessibleClient::AccessibleObject,int)));
91 connect(m_registry, SIGNAL(textSelectionChanged(QAccessibleClient::AccessibleObject)), this, SLOT(textSelectionChanged(QAccessibleClient::AccessibleObject)));
92
93 connect(m_registry, SIGNAL(textInserted(QAccessibleClient::AccessibleObject,QString,int,int)), this, SLOT(textInserted(QAccessibleClient::AccessibleObject,QString,int,int)));
94 connect(m_registry, SIGNAL(textRemoved(QAccessibleClient::AccessibleObject,QString,int,int)), this, SLOT(textRemoved(QAccessibleClient::AccessibleObject,QString,int,int)));
95 connect(m_registry, SIGNAL(textChanged(QAccessibleClient::AccessibleObject,QString,int,int)), this, SLOT(textChanged(QAccessibleClient::AccessibleObject,QString,int,int)));
96
97 connect(m_registry, SIGNAL(accessibleNameChanged(QAccessibleClient::AccessibleObject)), this, SLOT(accessibleNameChanged(QAccessibleClient::AccessibleObject)));
98 connect(m_registry, SIGNAL(accessibleDescriptionChanged(QAccessibleClient::AccessibleObject)), this, SLOT(accessibleDescriptionChanged(QAccessibleClient::AccessibleObject)));
99
100 m_registry->subscribeEventListeners(QAccessibleClient::Registry::AllEventListeners);
101 }
102
~MainWindow()103 MainWindow::~MainWindow()
104 {
105 delete m_registry;
106 }
107
closeEvent(QCloseEvent * event)108 void MainWindow::MainWindow::closeEvent(QCloseEvent *event)
109 {
110 QSettings settings("kde.org", "kdea11yapp");
111 settings.setValue("cacheStrategy", int(QAccessibleClient::RegistryPrivateCacheApi(m_registry).cacheType()));
112 settings.setValue("geometry", saveGeometry());
113 settings.setValue("windowState", saveState());
114
115 m_eventsWidget->saveSettings(settings);
116
117 settings.sync();
118
119 QMainWindow::closeEvent(event);
120 }
121
initActions()122 void MainWindow::MainWindow::initActions()
123 {
124 m_resetTreeAction = new QAction(this);
125 m_resetTreeAction->setText(QString("Reset Tree"));
126 m_resetTreeAction->setShortcut(QKeySequence(QKeySequence::Refresh));
127 connect(m_resetTreeAction, SIGNAL(triggered()), m_accessibleObjectTreeModel, SLOT(resetModel()));
128
129 m_followFocusAction = new QAction(this);
130 m_followFocusAction->setText(QString("Follow Focus"));
131 m_followFocusAction->setCheckable(true);
132 m_followFocusAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_F));
133
134 m_showClientCacheAction = new QAction(this);
135 m_showClientCacheAction->setText(QString("Cache..."));
136 connect(m_showClientCacheAction, SIGNAL(triggered()), this, SLOT(showClientCache()));
137
138 m_enableA11yAction = new QAction(this);
139 m_enableA11yAction->setText(QString("Enable Accessibility"));
140 m_enableA11yAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_E));
141 m_enableA11yAction->setCheckable(true);
142 m_enableA11yAction->setChecked(m_registry->isEnabled());
143 connect(m_registry, SIGNAL(enabledChanged(bool)), m_enableA11yAction, SLOT(setChecked(bool)));
144 connect(m_enableA11yAction, SIGNAL(toggled(bool)), m_registry, SLOT(setEnabled(bool)));
145
146 m_enableScreenReaderAction = new QAction(this);
147 m_enableScreenReaderAction->setText(QString("Enable Screen Reader"));
148 m_enableScreenReaderAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_R));
149 m_enableScreenReaderAction->setCheckable(true);
150 m_enableScreenReaderAction->setChecked(m_registry->isScreenReaderEnabled());
151 connect(m_registry, SIGNAL(screenReaderEnabledChanged(bool)), m_enableScreenReaderAction, SLOT(setChecked(bool)));
152 connect(m_enableScreenReaderAction, SIGNAL(toggled(bool)), m_registry, SLOT(setScreenReaderEnabled(bool)));
153
154 m_quitAction = new QAction(tr("&Quit"), this);
155 m_quitAction->setShortcuts(QKeySequence::Quit);
156 connect(m_quitAction, SIGNAL(triggered()), this, SLOT(close()));
157
158 m_copyValueAction = new QAction(tr("&Copy property value"), this);
159 m_copyValueAction->setShortcuts(QKeySequence::Copy);
160 connect(m_copyValueAction, SIGNAL(triggered()), this, SLOT(copyValue()));
161 }
162
copyValue()163 void MainWindow::copyValue()
164 {
165 QModelIndex selected = m_propertyView->currentIndex();
166
167 if (!selected.isValid())
168 return;
169
170 if (selected.column() == 0) {
171 selected = m_propertyView->model()->index(selected.row(), 1, selected.parent());
172 if (!selected.isValid())
173 return;
174 }
175
176 QGuiApplication::clipboard()->setText(selected.data(Qt::DisplayRole).toString());
177 }
178
initMenu()179 void MainWindow::MainWindow::initMenu()
180 {
181 QMenu *fileMenu = menuBar()->addMenu(QString("&Tree"));
182 fileMenu->addAction(m_resetTreeAction);
183 fileMenu->addAction(m_followFocusAction);
184 fileMenu->addSeparator();
185 fileMenu->addAction(m_quitAction);
186
187 QMenu *editMenu = menuBar()->addMenu(QString("&Edit"));
188 editMenu->addAction(m_copyValueAction);
189
190 QMenu *settingsMenu = menuBar()->addMenu(QString("&Settings"));
191 QMenu *dockerMenu = settingsMenu->addMenu(QString("Docker"));
192 Q_FOREACH(const QDockWidget *docker, findChildren<QDockWidget*>()) {
193 dockerMenu->addAction(docker->toggleViewAction());
194 }
195 settingsMenu->addAction(m_showClientCacheAction);
196 settingsMenu->addSeparator();
197 settingsMenu->addAction(m_enableA11yAction);
198 settingsMenu->addAction(m_enableScreenReaderAction);
199 }
200
initUi()201 void MainWindow::MainWindow::initUi()
202 {
203 setDockOptions(QMainWindow::AnimatedDocks | QMainWindow::AllowNestedDocks | QMainWindow::AllowTabbedDocks);
204 //setTabPosition(Qt::AllDockWidgetAreas, QTabWidget::North);
205
206 QDockWidget *treeDocker = new QDockWidget(QString("Tree"), this);
207 treeDocker->setObjectName("tree");
208 treeDocker->setFeatures(QDockWidget::AllDockWidgetFeatures);
209 m_accessibleObjectTreeView = new QTreeView(treeDocker);
210 m_accessibleObjectTreeView->setAccessibleName(QString("Tree of accessibles"));
211 m_accessibleObjectTreeView->setAccessibleDescription(QString("Displays a hierachical tree of accessible objects"));
212 m_accessibleObjectTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);
213 m_accessibleObjectTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
214 m_accessibleObjectTreeView->setAlternatingRowColors(true);
215 treeDocker->setWidget(m_accessibleObjectTreeView);
216
217 m_accessibleObjectTreeModel = new AccessibleTree(this);
218 m_accessibleObjectTreeModel->setRegistry(m_registry);
219 m_accessibleObjectTreeView->setModel(m_accessibleObjectTreeModel);
220 m_accessibleObjectTreeView->setColumnWidth(0, 240);
221 m_accessibleObjectTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
222 connect(m_accessibleObjectTreeView->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(selectionChanged(QModelIndex,QModelIndex)));
223 connect(m_accessibleObjectTreeView, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(treeCustomContextMenuRequested(QPoint)));
224
225 QDockWidget *propertyDocker = new QDockWidget(QString("&Properties"), this);
226 propertyDocker->setObjectName("properties");
227 propertyDocker->setFeatures(QDockWidget::AllDockWidgetFeatures);
228 m_propertyView = new QTreeView(propertyDocker);
229 propertyDocker->setWidget(m_propertyView);
230 m_propertyView->setAccessibleName(QString("List of properties"));
231 m_propertyView->setAccessibleDescription(QString("Displays a the properties of the selected accessible object"));
232 m_propertyView->setRootIsDecorated(false);
233 m_propertyView->setItemsExpandable(true);
234 m_propertyView->setExpandsOnDoubleClick(false);
235 m_propertyView->setEditTriggers(QAbstractItemView::DoubleClicked | QAbstractItemView::AnyKeyPressed | QAbstractItemView::EditKeyPressed);
236 m_propertyModel = new ObjectProperties(this);
237 m_propertyView->setModel(m_propertyModel);
238 m_propertyView->setAlternatingRowColors(true);
239 connect(m_propertyView, SIGNAL(doubleClicked(QModelIndex)), m_propertyModel, SLOT(doubleClicked(QModelIndex)));
240
241 QDockWidget *uiDocker = new QDockWidget(QString("&Boundaries"), this);
242 uiDocker->setObjectName("boundaries");
243 uiDocker->setFeatures(QDockWidget::AllDockWidgetFeatures);
244 m_uiview = new UiView(uiDocker);
245 m_uiview->setAccessibleName(QLatin1String("Boundaries"));
246 m_uiview->setAccessibleDescription(QString("Visualize the component boundaries"));
247 uiDocker->setWidget(m_uiview);
248
249 QDockWidget *eventsDocker = new QDockWidget(QString("E&vents"), this);
250 eventsDocker->setObjectName("events");
251 eventsDocker->setFeatures(QDockWidget::AllDockWidgetFeatures);
252 m_eventsWidget = new EventsWidget(m_registry, eventsDocker);
253 connect(m_eventsWidget, SIGNAL(anchorClicked(QUrl)), this, SLOT(anchorClicked(QUrl)));
254 eventsDocker->setWidget(m_eventsWidget);
255
256 addDockWidget(Qt::LeftDockWidgetArea, treeDocker);
257 addDockWidget(Qt::RightDockWidgetArea, propertyDocker);
258 addDockWidget(Qt::RightDockWidgetArea, uiDocker);
259 addDockWidget(Qt::RightDockWidgetArea, eventsDocker);
260 tabifyDockWidget(uiDocker, eventsDocker);
261 tabifyDockWidget(uiDocker, propertyDocker);
262
263 resize(minimumSize().expandedTo(QSize(760,520)));
264 }
265
anchorClicked(const QUrl & url)266 void MainWindow::anchorClicked(const QUrl &url)
267 {
268 AccessibleObject object = m_registry->accessibleFromUrl(url);
269 setCurrentObject(object);
270 }
271
showClientCache()272 void MainWindow::showClientCache()
273 {
274 QPointer<ClientCacheDialog> dlg(new ClientCacheDialog(m_registry, this));
275 dlg->setWindowTitle(m_showClientCacheAction->text());
276 if (dlg->exec() == QDialog::Accepted && dlg) {
277 }
278 if (dlg)
279 dlg->deleteLater();
280 }
281
setCurrentObject(const QAccessibleClient::AccessibleObject & object)282 void MainWindow::setCurrentObject(const QAccessibleClient::AccessibleObject &object)
283 {
284 QModelIndex index = m_accessibleObjectTreeModel->indexForAccessible(object);
285 if (index.isValid()) {
286 QModelIndex other = m_accessibleObjectTreeModel->index(index.row(), index.column()+1, index.parent());
287 Q_ASSERT(other.isValid());
288 m_accessibleObjectTreeView->selectionModel()->select(QItemSelection(index, other), QItemSelectionModel::SelectCurrent);
289 m_accessibleObjectTreeView->scrollTo(index);
290
291 // Unlike calling setCurrentIndex the select call aboves doe not emit the selectionChanged signal. So, do explicit.
292 selectionChanged(index, QModelIndex());
293 } else {
294 qWarning() << "No such indexForAccessible=" << object;
295 }
296 }
297
updateDetails(const AccessibleObject & object,bool force)298 void MainWindow::updateDetails(const AccessibleObject &object, bool force)
299 {
300 if (!force && object != m_propertyModel->currentObject())
301 return;
302
303 m_propertyModel->setAccessibleObject(object);
304 for(int r = m_propertyModel->rowCount() - 1; r >= 0; --r)
305 m_propertyView->setExpanded(m_propertyModel->indexFromItem(m_propertyModel->item(r, 0)), true);
306 m_propertyView->resizeColumnToContents(0);
307 }
308
stateChanged(const QAccessibleClient::AccessibleObject & object,const QString & state,bool active)309 void MainWindow::stateChanged(const QAccessibleClient::AccessibleObject &object, const QString &state, bool active)
310 {
311 if (state == QLatin1String("focused")) {
312 m_eventsWidget->addLog(object, EventsWidget::Focus, (active ? QString("true") : QString("false")));
313 } else {
314 QString s = state + QString(": ") + (active ? QString("true") : QString("false"));
315 m_eventsWidget->addLog(object, EventsWidget::StateChanged, s);
316 }
317 updateDetails(object);
318 }
319
childAdded(const QAccessibleClient::AccessibleObject & object,int childIndex)320 void MainWindow::childAdded(const QAccessibleClient::AccessibleObject &object, int childIndex)
321 {
322 updateDetails(object);
323 m_eventsWidget->addLog(object, EventsWidget::Object, QLatin1String("ChildAdded ") + QString::number(childIndex));
324 }
325
childRemoved(const QAccessibleClient::AccessibleObject & object,int childIndex)326 void MainWindow::childRemoved(const QAccessibleClient::AccessibleObject &object, int childIndex)
327 {
328 updateDetails(object);
329 m_eventsWidget->addLog(object, EventsWidget::Object, QLatin1String("ChildRemoved ") + QString::number(childIndex));
330 }
331
visibleDataChanged(const QAccessibleClient::AccessibleObject & object)332 void MainWindow::visibleDataChanged(const QAccessibleClient::AccessibleObject &object)
333 {
334 updateDetails(object);
335 m_eventsWidget->addLog(object, EventsWidget::Object, "VisibleDataChanged");
336 }
337
selectionChanged(const QAccessibleClient::AccessibleObject & object)338 void MainWindow::selectionChanged(const QAccessibleClient::AccessibleObject &object)
339 {
340 updateDetails(object);
341 m_eventsWidget->addLog(object, EventsWidget::Table, "SelectionChanged");
342 }
343
modelChanged(const QAccessibleClient::AccessibleObject & object)344 void MainWindow::modelChanged(const QAccessibleClient::AccessibleObject &object)
345 {
346 updateDetails(object);
347 m_eventsWidget->addLog(object, EventsWidget::Table, "ModelChanged");
348 }
349
selectionChanged(const QModelIndex & current,const QModelIndex &)350 void MainWindow::selectionChanged(const QModelIndex& current, const QModelIndex&)
351 {
352 QAccessibleClient::AccessibleObject acc;
353 if (current.isValid() && current.internalPointer()) {
354 acc = static_cast<AccessibleWrapper*>(current.internalPointer())->acc;
355 }
356 m_uiview->setAccessibleObject(acc);
357 updateDetails(acc, true);
358 }
359
treeCustomContextMenuRequested(const QPoint & pos)360 void MainWindow::treeCustomContextMenuRequested(const QPoint &pos)
361 {
362 QModelIndex current = m_accessibleObjectTreeView->currentIndex();
363 if (!current.isValid())
364 return;
365 QAccessibleClient::AccessibleObject acc = static_cast<AccessibleWrapper*>(current.internalPointer())->acc;
366 QMenu *menu = new QMenu(this);
367 connect(menu, SIGNAL(aboutToHide()), menu, SLOT(deleteLater()));
368 Q_FOREACH(const QSharedPointer<QAction> &a, acc.actions()) {
369 menu->addAction(a.data());
370 }
371 menu->popup(m_accessibleObjectTreeView->mapToGlobal(pos));
372 }
373
added(const QAccessibleClient::AccessibleObject & object)374 void MainWindow::added(const QAccessibleClient::AccessibleObject &object)
375 {
376 m_eventsWidget->addLog(object, EventsWidget::Object, QString("Add Object"));
377 m_accessibleObjectTreeModel->addAccessible(object);
378 }
379
removed(const QAccessibleClient::AccessibleObject & object)380 void MainWindow::removed(const QAccessibleClient::AccessibleObject &object)
381 {
382 m_eventsWidget->addLog(object, EventsWidget::Object, "RemoveObject");
383 m_accessibleObjectTreeModel->removeAccessible(object);
384 }
385
defunct(const QAccessibleClient::AccessibleObject & object)386 void MainWindow::defunct(const QAccessibleClient::AccessibleObject &object)
387 {
388 removed(object);
389 }
390
windowCreated(const QAccessibleClient::AccessibleObject & object)391 void MainWindow::windowCreated(const QAccessibleClient::AccessibleObject &object)
392 {
393 m_eventsWidget->addLog(object, EventsWidget::Window, "Create");
394 m_accessibleObjectTreeModel->addAccessible(object);
395 }
396
windowDestroyed(const QAccessibleClient::AccessibleObject & object)397 void MainWindow::windowDestroyed(const QAccessibleClient::AccessibleObject &object)
398 {
399 m_eventsWidget->addLog(object, EventsWidget::Window, QString("Destroy"));
400 if (!m_accessibleObjectTreeModel->removeAccessible(object)) {
401 // assume the app has gone
402 m_accessibleObjectTreeModel->updateTopLevelApps();
403 }
404 }
405
windowClosed(const QAccessibleClient::AccessibleObject & object)406 void MainWindow::windowClosed(const QAccessibleClient::AccessibleObject &object)
407 {
408 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowClose"));
409 }
410
windowReparented(const QAccessibleClient::AccessibleObject & object)411 void MainWindow::windowReparented(const QAccessibleClient::AccessibleObject &object)
412 {
413 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowReparent"));
414 }
415
windowMinimized(const QAccessibleClient::AccessibleObject & object)416 void MainWindow::windowMinimized(const QAccessibleClient::AccessibleObject &object)
417 {
418 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowMinimize"));
419 }
420
windowMaximized(const QAccessibleClient::AccessibleObject & object)421 void MainWindow::windowMaximized(const QAccessibleClient::AccessibleObject &object)
422 {
423 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowMaximize"));
424 }
425
windowRestored(const QAccessibleClient::AccessibleObject & object)426 void MainWindow::windowRestored(const QAccessibleClient::AccessibleObject &object)
427 {
428 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowRestore"));
429 }
430
windowActivated(const QAccessibleClient::AccessibleObject & object)431 void MainWindow::windowActivated(const QAccessibleClient::AccessibleObject &object)
432 {
433 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowActivate"));
434 }
435
windowDeactivated(const QAccessibleClient::AccessibleObject & object)436 void MainWindow::windowDeactivated(const QAccessibleClient::AccessibleObject &object)
437 {
438 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowDeactivate"));
439 }
440
windowDesktopCreated(const QAccessibleClient::AccessibleObject & object)441 void MainWindow::windowDesktopCreated(const QAccessibleClient::AccessibleObject &object)
442 {
443 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowDesktopCreate"));
444 }
445
windowDesktopDestroyed(const QAccessibleClient::AccessibleObject & object)446 void MainWindow::windowDesktopDestroyed(const QAccessibleClient::AccessibleObject &object)
447 {
448 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowDesktopDestroy"));
449 }
450
windowRaised(const QAccessibleClient::AccessibleObject & object)451 void MainWindow::windowRaised(const QAccessibleClient::AccessibleObject &object)
452 {
453 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowRaise"));
454 }
455
windowLowered(const QAccessibleClient::AccessibleObject & object)456 void MainWindow::windowLowered(const QAccessibleClient::AccessibleObject &object)
457 {
458 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowLower"));
459 }
460
windowMoved(const QAccessibleClient::AccessibleObject & object)461 void MainWindow::windowMoved(const QAccessibleClient::AccessibleObject &object)
462 {
463 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowMove"));
464 }
465
windowResized(const QAccessibleClient::AccessibleObject & object)466 void MainWindow::windowResized(const QAccessibleClient::AccessibleObject &object)
467 {
468 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowResize"));
469 }
470
windowShaded(const QAccessibleClient::AccessibleObject & object)471 void MainWindow::windowShaded(const QAccessibleClient::AccessibleObject &object)
472 {
473 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowShade"));
474 }
475
windowUnshaded(const QAccessibleClient::AccessibleObject & object)476 void MainWindow::windowUnshaded(const QAccessibleClient::AccessibleObject &object)
477 {
478 m_eventsWidget->addLog(object, EventsWidget::Window, QString("WindowUnshade"));
479 }
480
focusChanged(const QAccessibleClient::AccessibleObject & object)481 void MainWindow::focusChanged(const QAccessibleClient::AccessibleObject &object)
482 {
483 if (m_followFocusAction->isChecked()) {
484 // We need to block the focus for the treeView while setting the current item
485 // to prevent that setting that item would change focus to the treeView.
486 Qt::FocusPolicy prevFocusPolicy = m_accessibleObjectTreeView->focusPolicy();
487 m_accessibleObjectTreeView->setFocusPolicy(Qt::NoFocus);
488
489 setCurrentObject(object);
490
491 m_accessibleObjectTreeView->setFocusPolicy(prevFocusPolicy);
492 } else {
493 updateDetails(object);
494 }
495 }
496
textCaretMoved(const QAccessibleClient::AccessibleObject & object,int pos)497 void MainWindow::MainWindow::textCaretMoved(const QAccessibleClient::AccessibleObject &object, int pos)
498 {
499 updateDetails(object);
500 m_eventsWidget->addLog(object, EventsWidget::Text, QString("Text caret moved (%1)").arg(pos));
501 }
502
textSelectionChanged(const QAccessibleClient::AccessibleObject & object)503 void MainWindow::MainWindow::textSelectionChanged(const QAccessibleClient::AccessibleObject &object)
504 {
505 updateDetails(object);
506 m_eventsWidget->addLog(object, EventsWidget::Text, QString("TextSelectionChanged"));
507 }
508
descriptionForText(const QString & type,const QString & text,int startOffset,int endOffset)509 QString descriptionForText(const QString& type, const QString& text, int startOffset, int endOffset)
510 {
511 QString shortText = text;
512 if (shortText.length() > 50) {
513 shortText.truncate(50);
514 shortText.append(QLatin1String("..."));
515 }
516 QString desc = QString("Text %1 (%2, %3): \"%4\"").arg(type).arg(QString::number(startOffset)).arg(QString::number(endOffset)).arg(shortText);
517 return desc;
518 }
519
textChanged(const QAccessibleClient::AccessibleObject & object,const QString & text,int startOffset,int endOffset)520 void MainWindow::textChanged(const QAccessibleClient::AccessibleObject &object, const QString& text, int startOffset, int endOffset)
521 {
522 updateDetails(object);
523 m_eventsWidget->addLog(object, EventsWidget::Text, descriptionForText(QLatin1String("changed"), text, startOffset, endOffset));
524 }
525
textInserted(const QAccessibleClient::AccessibleObject & object,const QString & text,int startOffset,int endOffset)526 void MainWindow::textInserted(const QAccessibleClient::AccessibleObject &object, const QString& text, int startOffset, int endOffset)
527 {
528 updateDetails(object);
529 m_eventsWidget->addLog(object, EventsWidget::Text, descriptionForText(QLatin1String("inserted"), text, startOffset, endOffset));
530 }
531
textRemoved(const QAccessibleClient::AccessibleObject & object,const QString & text,int startOffset,int endOffset)532 void MainWindow::textRemoved(const QAccessibleClient::AccessibleObject &object, const QString& text, int startOffset, int endOffset)
533 {
534 updateDetails(object);
535 m_eventsWidget->addLog(object, EventsWidget::Text, descriptionForText(QLatin1String("removed"), text, startOffset, endOffset));
536 }
537
accessibleNameChanged(const QAccessibleClient::AccessibleObject & object)538 void MainWindow::accessibleNameChanged(const QAccessibleClient::AccessibleObject &object)
539 {
540 updateDetails(object);
541 m_eventsWidget->addLog(object, EventsWidget::NameChanged);
542 m_accessibleObjectTreeModel->updateAccessible(object);
543 }
544
accessibleDescriptionChanged(const QAccessibleClient::AccessibleObject & object)545 void MainWindow::accessibleDescriptionChanged(const QAccessibleClient::AccessibleObject &object)
546 {
547 updateDetails(object);
548 m_eventsWidget->addLog(object, EventsWidget::DescriptionChanged);
549 m_accessibleObjectTreeModel->updateAccessible(object);
550 }
551
552