LibreOffice Module test (master) 1
accessibletestbase.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 */
9
11
12#include <string>
13
14#include <com/sun/star/accessibility/AccessibleRole.hpp>
15#include <com/sun/star/accessibility/AccessibleStateType.hpp>
16#include <com/sun/star/accessibility/XAccessible.hpp>
17#include <com/sun/star/accessibility/XAccessibleAction.hpp>
18#include <com/sun/star/accessibility/XAccessibleContext.hpp>
19#include <com/sun/star/awt/XDialog2.hpp>
20#include <com/sun/star/awt/XExtendedToolkit.hpp>
21#include <com/sun/star/awt/XTopWindow.hpp>
22#include <com/sun/star/awt/XTopWindowListener.hpp>
23#include <com/sun/star/frame/Desktop.hpp>
24#include <com/sun/star/frame/FrameSearchFlag.hpp>
25#include <com/sun/star/frame/XFrame.hpp>
26#include <com/sun/star/frame/XFrame2.hpp>
27#include <com/sun/star/frame/XModel.hpp>
28#include <com/sun/star/uno/Reference.hxx>
29#include <com/sun/star/uno/RuntimeException.hpp>
30#include <com/sun/star/util/XCloseable.hpp>
31
32#include <vcl/idle.hxx>
33#include <vcl/scheduler.hxx>
34#include <vcl/svapp.hxx>
35
37
39
40using namespace css;
41
43{
45
46 mxDesktop = frame::Desktop::create(mxComponentContext);
47}
48
50{
51 if (mxDocument.is())
52 {
53 uno::Reference<util::XCloseable> xCloseable(mxDocument, uno::UNO_QUERY_THROW);
54 xCloseable->close(false);
55 mxDocument.clear();
56 }
57}
58
60
61void test::AccessibleTestBase::load(const rtl::OUString& sURL)
62{
63 // make sure there is no open document in case it is called more than once
64 close();
65 mxDocument = mxDesktop->loadComponentFromURL(sURL, "_blank", frame::FrameSearchFlag::AUTO, {});
66
67 uno::Reference<frame::XModel> xModel(mxDocument, uno::UNO_QUERY_THROW);
68 mxWindow.set(xModel->getCurrentController()->getFrame()->getContainerWindow());
69
70 // bring window to front
71 uno::Reference<awt::XTopWindow> xTopWindow(mxWindow, uno::UNO_QUERY_THROW);
72 xTopWindow->toFront();
73}
74
75void test::AccessibleTestBase::loadFromSrc(const rtl::OUString& sSrcPath)
76{
77 load(m_directories.getURLFromSrc(sSrcPath));
78}
79
80uno::Reference<accessibility::XAccessibleContext>
82{
83 uno::Reference<accessibility::XAccessible> xAccessible(mxWindow, uno::UNO_QUERY_THROW);
84
85 return xAccessible->getAccessibleContext();
86}
87
89{
90 return (role == accessibility::AccessibleRole::DOCUMENT
91 || role == accessibility::AccessibleRole::DOCUMENT_PRESENTATION
92 || role == accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
93 || role == accessibility::AccessibleRole::DOCUMENT_TEXT);
94}
95
96uno::Reference<accessibility::XAccessibleContext>
98{
99 uno::Reference<frame::XModel> xModel(mxDocument, uno::UNO_QUERY_THROW);
100 uno::Reference<accessibility::XAccessible> xAccessible(
101 xModel->getCurrentController()->getFrame()->getComponentWindow(), uno::UNO_QUERY_THROW);
102
104 xAccessible->getAccessibleContext(),
105 [](const uno::Reference<accessibility::XAccessibleContext>& xCtx) {
106 return (isDocumentRole(xCtx->getAccessibleRole())
107 && xCtx->getAccessibleStateSet() & accessibility::AccessibleStateType::SHOWING);
108 });
109}
110
111uno::Reference<accessibility::XAccessibleContext>
113 const uno::Reference<accessibility::XAccessibleContext>& xContext, sal_Int16 relationType)
114{
115 auto relset = xContext->getAccessibleRelationSet();
116
117 if (relset.is())
118 {
119 for (sal_Int32 i = 0; i < relset->getRelationCount(); ++i)
120 {
121 const auto& rel = relset->getRelation(i);
122 if (rel.RelationType == relationType)
123 {
124 for (auto& target : rel.TargetSet)
125 {
126 uno::Reference<accessibility::XAccessible> targetAccessible(target,
127 uno::UNO_QUERY);
128 if (targetAccessible.is())
129 return targetAccessible->getAccessibleContext();
130 }
131 }
132 }
133 }
134
135 return nullptr;
136}
137
138std::deque<uno::Reference<accessibility::XAccessibleContext>>
140 const uno::Reference<accessibility::XAccessibleContext>& xContext)
141{
142 std::deque<uno::Reference<accessibility::XAccessibleContext>> children;
143 auto childCount = xContext->getAccessibleChildCount();
144
145 for (sal_Int64 i = 0; i < childCount && i < AccessibilityTools::MAX_CHILDREN; i++)
146 {
147 auto child = xContext->getAccessibleChild(i);
148 children.push_back(child->getAccessibleContext());
149 }
150
151 return children;
152}
153
156 const uno::Reference<accessibility::XAccessibleContext>& xContext, const int depth)
157{
159 auto xRelSet = xContext->getAccessibleRelationSet();
160
161 std::cout << AccessibilityTools::debugString(xContext);
162 /* relation set is not included in AccessibilityTools::debugString(), but might be useful in
163 * this context, so we compute it here */
164 if (xRelSet.is())
165 {
166 auto relCount = xRelSet->getRelationCount();
167 if (relCount)
168 {
169 std::cout << " rels=[";
170 for (sal_Int32 i = 0; i < relCount; ++i)
171 {
172 if (i > 0)
173 std::cout << ", ";
174
175 const auto& rel = xRelSet->getRelation(i);
176 std::cout << "(type=" << AccessibilityTools::getRelationTypeName(rel.RelationType)
177 << " (" << rel.RelationType << ")";
178 std::cout << " targets=[";
179 int j = 0;
180 for (auto& target : rel.TargetSet)
181 {
182 if (j++ > 0)
183 std::cout << ", ";
184 uno::Reference<accessibility::XAccessible> ta(target, uno::UNO_QUERY_THROW);
185 std::cout << AccessibilityTools::debugString(ta);
186 }
187 std::cout << "])";
188 }
189 std::cout << "]";
190 }
191 }
192 std::cout << std::endl;
193
194 sal_Int32 i = 0;
195 for (auto& child : getAllChildren(xContext))
196 {
197 for (int j = 0; j < depth; j++)
198 std::cout << " ";
199 std::cout << " * child " << i++ << ": ";
200 dumpA11YTree(child, depth + 1);
201 }
202}
203
205uno::Reference<accessibility::XAccessibleContext> test::AccessibleTestBase::getItemFromName(
206 const uno::Reference<accessibility::XAccessibleContext>& xMenuCtx, std::u16string_view name)
207{
208 auto childCount = xMenuCtx->getAccessibleChildCount();
209
210 std::cout << "looking up item " << OUString(name) << " in "
211 << AccessibilityTools::debugString(xMenuCtx) << std::endl;
212 for (sal_Int64 i = 0; i < childCount && i < AccessibilityTools::MAX_CHILDREN; i++)
213 {
214 auto item = xMenuCtx->getAccessibleChild(i)->getAccessibleContext();
215 if (AccessibilityTools::nameEquals(item, name))
216 {
217 std::cout << "-> found " << AccessibilityTools::debugString(item) << std::endl;
218 return item;
219 }
220 }
221
222 std::cout << "-> NOT FOUND!" << std::endl;
223 std::cout << " Contents was: ";
224 dumpA11YTree(xMenuCtx, 1);
225
226 return uno::Reference<accessibility::XAccessibleContext>();
227}
228
230 const uno::Reference<accessibility::XAccessibleAction>& xAction)
231{
232 // assume first action is the right one, there's not description anyway
233 CPPUNIT_ASSERT_EQUAL(sal_Int32(1), xAction->getAccessibleActionCount());
234 if (xAction->doAccessibleAction(0))
235 {
237 return true;
238 }
239 return false;
240}
241
242uno::Reference<accessibility::XAccessibleContext> test::AccessibleTestBase::getFocusedObject(
243 const uno::Reference<accessibility::XAccessibleContext>& xCtx)
244{
246 xCtx, [](const uno::Reference<accessibility::XAccessibleContext>& xCandidateCtx) {
247 const auto states = (accessibility::AccessibleStateType::FOCUSED
248 | accessibility::AccessibleStateType::SHOWING);
249 return (xCandidateCtx->getAccessibleStateSet() & states) == states;
250 });
251}
252
253uno::Reference<accessibility::XAccessibleContext>
254test::AccessibleTestBase::tabTo(const uno::Reference<accessibility::XAccessible>& xRoot,
255 const sal_Int16 role, const std::u16string_view name,
256 const EventPosterHelperBase* pEventPosterHelper)
257{
258 AccessibleEventPosterHelper eventHelper;
259 if (!pEventPosterHelper)
260 {
261 eventHelper.setWindow(xRoot);
262 pEventPosterHelper = &eventHelper;
263 }
264
265 auto xOriginalFocus = getFocusedObject(xRoot);
266 auto xFocus = xOriginalFocus;
267 int nSteps = 0;
268
269 std::cout << "Tabbing to '" << OUString(name) << "'..." << std::endl;
270 while (xFocus && (nSteps == 0 || xFocus != xOriginalFocus))
271 {
272 std::cout << " focused object is: " << AccessibilityTools::debugString(xFocus)
273 << std::endl;
274 if (xFocus->getAccessibleRole() == role && AccessibilityTools::nameEquals(xFocus, name))
275 {
276 std::cout << " -> OK, focus matches" << std::endl;
277 return xFocus;
278 }
279 if (++nSteps > 100)
280 {
281 std::cerr << "Object not found after tabbing 100 times! bailing out" << std::endl;
282 break;
283 }
284
285 std::cout << " -> no match, sending <TAB>" << std::endl;
286 pEventPosterHelper->postKeyEventAsync(0, awt::Key::TAB);
288
289 const auto xPrevFocus = xFocus;
290 xFocus = getFocusedObject(xRoot);
291 if (!xFocus)
292 std::cerr << "Focus lost after sending <TAB>!" << std::endl;
293 else if (xPrevFocus == xFocus)
294 {
295 std::cerr << "Focus didn't move after sending <TAB>! bailing out" << std::endl;
296 std::cerr << "Focused object(s):" << std::endl;
297 int iFocusedCount = 0;
298 // count and print out objects with focused state
300 xRoot,
301 [&iFocusedCount](const uno::Reference<accessibility::XAccessibleContext>& xCtx) {
302 const auto states = (accessibility::AccessibleStateType::FOCUSED
303 | accessibility::AccessibleStateType::SHOWING);
304 if ((xCtx->getAccessibleStateSet() & states) == states)
305 {
306 std::cerr << " * " << AccessibilityTools::debugString(xCtx) << std::endl;
307 iFocusedCount++;
308 }
309 return false; // keep going
310 });
311 std::cerr << "Total focused element(s): " << iFocusedCount << std::endl;
312 if (iFocusedCount > 1)
313 std::cerr << "WARNING: there are more than one focused object! This usually means "
314 "there is a BUG in the focus handling of that accessibility tree."
315 << std::endl;
316 break;
317 }
318 }
319
320 std::cerr << "NOT FOUND" << std::endl;
321 return nullptr;
322}
323
325 const uno::Reference<accessibility::XAccessible>& xRoot,
326 const uno::Reference<accessibility::XAccessibleContext>& xChild,
327 const EventPosterHelperBase* pEventPosterHelper)
328{
329 AccessibleEventPosterHelper eventHelper;
330 if (!pEventPosterHelper)
331 {
332 eventHelper.setWindow(xRoot);
333 pEventPosterHelper = &eventHelper;
334 }
335
336 std::cout << "Tabbing to " << AccessibilityTools::debugString(xChild) << "..." << std::endl;
337 for (int i = 0; i < 100; i++)
338 {
339 if (xChild->getAccessibleStateSet() & accessibility::AccessibleStateType::FOCUSED)
340 return true;
341
342 std::cout << " no match, sending <TAB>" << std::endl;
343 pEventPosterHelper->postKeyEventAsync(0, awt::Key::TAB);
345 }
346
347 std::cerr << "NOT FOUND" << std::endl;
348 return false;
349}
350
351#if !defined(MACOSX)
352/* Dialog handling
353 *
354 * For now this doesn't actually work under macos, so the API is not available there not to create
355 * confusion. The problem there is we don't get notified of new dialogs, so we can't manage them
356 * or interact with them.
357 */
358
359test::AccessibleTestBase::Dialog::Dialog(uno::Reference<awt::XDialog2>& xDialog2, bool bAutoClose)
360 : mbAutoClose(bAutoClose)
361 , mxDialog2(xDialog2)
362{
363 CPPUNIT_ASSERT(xDialog2.is());
364
365 mxAccessible.set(xDialog2, uno::UNO_QUERY);
366 if (mxAccessible)
368 else
369 {
370 std::cerr << "WARNING: AccessibleTestBase::Dialog() constructed with awt::XDialog2 '"
371 << xDialog2->getTitle()
372 << "' not implementing accessibility::XAccessible. Event delivery will not work."
373 << std::endl;
374 }
375}
376
378{
379 if (mbAutoClose)
380 close();
381}
382
384{
385 if (mxDialog2)
386 {
387 mxDialog2->endDialog(result);
388 mxDialog2.clear();
389 }
390}
391
392std::shared_ptr<test::AccessibleTestBase::DialogWaiter>
393test::AccessibleTestBase::awaitDialog(const std::u16string_view name,
394 std::function<void(Dialog&)> callback, bool bAutoClose)
395{
396 /* Helper class to wait on a dialog to pop up and to close, running user code between the
397 * two. This has to work both for "other window"-style dialogues (non-modal), as well as
398 * for modal dialogues using Dialog::Execute() (which runs a nested main loop, hence
399 * blocking our test flow execution.
400 * The approach here is to wait on the WindowActivate event for the dialog, and run the
401 * test code in there. Then, close the dialog if not already done, resuming normal flow to
402 * the caller. */
403 class ListenerHelper : public DialogWaiter
404 {
405 DialogCancelMode miPreviousDialogCancelMode;
406 uno::Reference<awt::XExtendedToolkit> mxToolkit;
407 bool mbWaitingForDialog;
408 std::exception_ptr mpException;
409 std::u16string_view msName;
410 std::function<void(Dialog&)> mCallback;
411 bool mbAutoClose;
412 Timer maTimeoutTimer;
413 Idle maIdleHandler;
414 uno::Reference<awt::XTopWindowListener> mxTopWindowListener;
415 std::unique_ptr<Dialog> mxDialog;
416
417 public:
418 virtual ~ListenerHelper()
419 {
420 Application::SetDialogCancelMode(miPreviousDialogCancelMode);
421 mxToolkit->removeTopWindowListener(mxTopWindowListener);
422 maTimeoutTimer.Stop();
423 maIdleHandler.Stop();
424 }
425
426 ListenerHelper(const std::u16string_view& name, std::function<void(Dialog&)> callback,
427 bool bAutoClose)
428 : mbWaitingForDialog(true)
429 , msName(name)
430 , mCallback(callback)
431 , mbAutoClose(bAutoClose)
432 , maTimeoutTimer("workaround timer if we don't catch WindowActivate")
433 , maIdleHandler("runs user callback in idle time")
434 {
435 mxTopWindowListener.set(new MyTopWindowListener(this));
436 mxToolkit.set(Application::GetVCLToolkit(), uno::UNO_QUERY_THROW);
437 mxToolkit->addTopWindowListener(mxTopWindowListener);
438
439 maTimeoutTimer.SetInvokeHandler(LINK(this, ListenerHelper, timeoutTimerHandler));
440 maTimeoutTimer.SetTimeout(60000);
441 maTimeoutTimer.Start();
442
443 maIdleHandler.SetInvokeHandler(LINK(this, ListenerHelper, idleHandler));
444 maIdleHandler.SetPriority(TaskPriority::DEFAULT_IDLE);
445
446 miPreviousDialogCancelMode = Application::GetDialogCancelMode();
447 Application::SetDialogCancelMode(DialogCancelMode::Off);
448 }
449
450 private:
451 // mimic IMPL_LINK inline
452 static void LinkStubtimeoutTimerHandler(void* instance, Timer* timer)
453 {
454 static_cast<ListenerHelper*>(instance)->timeoutTimerHandler(timer);
455 }
456
457 void timeoutTimerHandler(Timer*)
458 {
459 std::cerr << "timeout waiting for dialog '" << OUString(msName) << "' to show up"
460 << std::endl;
461
462 assert(mbWaitingForDialog);
463
464 // This is not very nice, but it should help fail earlier if we never catch the dialog
465 // yet we're in a sub-loop and waitEndDialog() didn't have a chance to run yet.
466 throw new css::uno::RuntimeException("Timeout waiting for dialog");
467 }
468
469 class MyTopWindowListener : public ::cppu::WeakImplHelper<awt::XTopWindowListener>
470 {
471 private:
472 ListenerHelper* mpHelper;
473
474 public:
475 MyTopWindowListener(ListenerHelper* pHelper)
476 : mpHelper(pHelper)
477 {
478 assert(mpHelper);
479 }
480
481 // XTopWindowListener
482 virtual void SAL_CALL windowOpened(const lang::EventObject&) override {}
483 virtual void SAL_CALL windowClosing(const lang::EventObject&) override {}
484 virtual void SAL_CALL windowClosed(const lang::EventObject&) override {}
485 virtual void SAL_CALL windowMinimized(const lang::EventObject&) override {}
486 virtual void SAL_CALL windowNormalized(const lang::EventObject&) override {}
487 virtual void SAL_CALL windowDeactivated(const lang::EventObject&) override {}
488 virtual void SAL_CALL windowActivated(const lang::EventObject& xEvent) override
489 {
490 assert(mpHelper->mbWaitingForDialog);
491
492 if (!xEvent.Source)
493 return;
494
495 uno::Reference<awt::XDialog2> xDialog(xEvent.Source, uno::UNO_QUERY);
496 if (!xDialog)
497 return;
498
499 // remove ourselves, we don't want to run again
500 mpHelper->mxToolkit->removeTopWindowListener(this);
501
502 mpHelper->mxDialog = std::make_unique<Dialog>(xDialog, true);
503
504 mpHelper->maIdleHandler.Start();
505 }
506
507 // XEventListener
508 virtual void SAL_CALL disposing(const lang::EventObject&) override {}
509 };
510
511 // mimic IMPL_LINK inline
512 static void LinkStubidleHandler(void* instance, Timer* idle)
513 {
514 static_cast<ListenerHelper*>(instance)->idleHandler(idle);
515 }
516
517 void idleHandler(Timer*)
518 {
519 mbWaitingForDialog = false;
520
521 maTimeoutTimer.ClearInvokeHandler();
522 maTimeoutTimer.Stop();
523
524 /* The popping up dialog ought to be the right one, or something's fishy and
525 * we're bound to failure (e.g. waiting on a dialog that either will never come, or
526 * that will not run after the current one -- deadlock style) */
527 if (msName != mxDialog->getWindow()->GetText())
528 {
529 mpException = std::make_exception_ptr(css::uno::RuntimeException(
530 "Unexpected dialog '" + mxDialog->getWindow()->GetText()
531 + "' opened instead of the expected '" + msName + "'"));
532 }
533 else
534 {
535 std::cout << "found dialog, calling user callback" << std::endl;
536
537 // set the real requested auto close now we're just calling the user callback
538 mxDialog->setAutoClose(mbAutoClose);
539
540 try
541 {
542 mCallback(*mxDialog);
543 }
544 catch (...)
545 {
546 mpException = std::current_exception();
547 }
548 }
549
550 mxDialog.reset();
551 }
552
553 public:
554 virtual bool waitEndDialog(sal_uInt64 nTimeoutMs) override
555 {
556 /* Usually this loop will actually never run at all because a previous
557 * Scheduler::ProcessEventsToIdle() would have triggered the dialog already, but we
558 * can't be sure of that or of delays, so be safe and wait with a timeout. */
559 if (mbWaitingForDialog)
560 {
561 Timer aTimer("wait for dialog");
562 aTimer.SetTimeout(nTimeoutMs);
563 aTimer.Start();
564 do
565 {
567 } while (mbWaitingForDialog && aTimer.IsActive());
568 }
569
570 if (mpException)
571 std::rethrow_exception(mpException);
572
573 return !mbWaitingForDialog;
574 }
575 };
576
577 return std::make_shared<ListenerHelper>(name, callback, bAutoClose);
578}
579#endif //defined(MACOSX)
580
581/* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */
static const sal_Int32 MAX_CHILDREN
Maximum number of children to work on.
static bool nameEquals(const css::uno::Reference< css::accessibility::XAccessibleContext > &xCtx, const std::u16string_view name)
Compares the accessible name against a string.
static OUString getRelationTypeName(const sal_Int16 rel_type)
static std::string debugString(const css::uno::Reference< T > &x)
static css::uno::Reference< css::accessibility::XAccessibleContext > getAccessibleObjectForPredicate(const css::uno::Reference< css::accessibility::XAccessibleContext > &xCtx, const std::function< bool(const css::uno::Reference< css::accessibility::XAccessibleContext > &)> &cPredicate)
static void SetDialogCancelMode(DialogCancelMode mode)
static void Yield()
static css::uno::Reference< css::awt::XToolkit > GetVCLToolkit()
static DialogCancelMode GetDialogCancelMode()
static void ProcessEventsToIdle()
bool IsActive() const
void SetPriority(TaskPriority ePriority)
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual void Start(bool bStartTimer=true) override
void ClearInvokeHandler()
void setWindow(css::uno::Reference< css::accessibility::XAccessible > xAcc)
Sets the window on which post events based on an accessible object inside it.
Definition: eventposter.cxx:30
Dialog(css::uno::Reference< css::awt::XDialog2 > &xDialog2, bool bAutoClose=true)
css::uno::Reference< css::accessibility::XAccessible > mxAccessible
void close(sal_Int32 result=VclResponseType::RET_CANCEL)
virtual void load(const rtl::OUString &sURL)
virtual void tearDown() override
static css::uno::Reference< css::accessibility::XAccessibleContext > getFocusedObject(const css::uno::Reference< css::accessibility::XAccessibleContext > &xCtx)
Gets the focused accessible object at xAcc level or below.
static bool isDocumentRole(const sal_Int16 role)
void dumpA11YTree(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext, const int depth=0)
Prints the tree of accessible objects starting at xContext to stdout.
bool activateMenuItem(const css::uno::Reference< css::accessibility::XAccessibleAction > &xAction)
static css::uno::Reference< css::accessibility::XAccessibleContext > getFirstRelationTargetOfType(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext, sal_Int16 relationType)
css::uno::Reference< css::accessibility::XAccessibleContext > getWindowAccessibleContext()
css::uno::Reference< css::frame::XDesktop2 > mxDesktop
virtual std::deque< css::uno::Reference< css::accessibility::XAccessibleContext > > getAllChildren(const css::uno::Reference< css::accessibility::XAccessibleContext > &xContext)
Tries to list all children of an accessible.
virtual void setUp() override
virtual void loadFromSrc(const rtl::OUString &sSrcPath)
static css::uno::Reference< css::accessibility::XAccessibleContext > tabTo(const css::uno::Reference< css::accessibility::XAccessible > &xRoot, const sal_Int16 role, const std::u16string_view name, const EventPosterHelperBase *pEventPosterHelper=nullptr)
Navigates through focusable elements using the Tab keyboard shortcut.
static std::shared_ptr< DialogWaiter > awaitDialog(const std::u16string_view name, std::function< void(Dialog &)> callback, bool bAutoClose=true)
Helper to call user code when a given dialog opens.
virtual css::uno::Reference< css::accessibility::XAccessibleContext > getDocumentAccessibleContext()
css::uno::Reference< css::accessibility::XAccessibleContext > getItemFromName(const css::uno::Reference< css::accessibility::XAccessibleContext > &xMenuCtx, std::u16string_view name)
css::uno::Reference< css::uno::XComponentContext > mxComponentContext
virtual void setUp() override
bool close
const char * name
void SAL_CALL windowClosed(const css::lang::EventObject &e) override
void SAL_CALL windowMinimized(const css::lang::EventObject &e) override
void SAL_CALL windowDeactivated(const css::lang::EventObject &e) override
void SAL_CALL windowActivated(const css::lang::EventObject &e) override
DECL_LISTENERMULTIPLEXER_END void SAL_CALL windowOpened(const css::lang::EventObject &e) override
void SAL_CALL windowClosing(const css::lang::EventObject &e) override
void SAL_CALL windowNormalized(const css::lang::EventObject &e) override
int i
Reference< XModel > xModel
DialogCancelMode
OUString msName
Any result