1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "XAccessibleEventBroadcasterTester.hxx"
24 #include <cppunit/TestAssert.h>
26 #include <com/sun/star/accessibility/AccessibleEventObject.hpp>
27 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
28 #include <com/sun/star/accessibility/XAccessible.hpp>
29 #include <com/sun/star/accessibility/XAccessibleContext.hpp>
30 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp>
31 #include <com/sun/star/accessibility/XAccessibleEventListener.hpp>
32 #include <com/sun/star/awt/PosSize.hpp>
33 #include <com/sun/star/awt/Rectangle.hpp>
34 #include <com/sun/star/awt/XWindow.hpp>
35 #include <com/sun/star/lang/EventObject.hpp>
37 #include <cppuhelper/implbase.hxx>
38 #include <rtl/ref.hxx>
39 #include <sal/log.hxx>
41 #include <test/a11y/AccessibilityTools.hxx>
47 class EvListener
: public cppu::WeakImplHelper
<accessibility::XAccessibleEventListener
>
58 virtual void SAL_CALL
disposing(const lang::EventObject
&) override
{}
60 // XAccessibleEventListener
61 virtual void SAL_CALL
notifyEvent(const accessibility::AccessibleEventObject
& aEvent
) override
63 std::cout
<< "Listener got event: " << AccessibilityTools::debugString(aEvent
) << std::endl
;
64 uno::Reference
<accessibility::XAccessible
> xOld(aEvent
.OldValue
, uno::UNO_QUERY
);
66 std::cout
<< "Old: " << AccessibilityTools::debugString(xOld
) << std::endl
;
68 uno::Reference
<accessibility::XAccessible
> xNew(aEvent
.NewValue
, uno::UNO_QUERY
);
70 std::cout
<< "New: " << AccessibilityTools::debugString(xNew
) << std::endl
;
77 XAccessibleEventBroadcasterTester::XAccessibleEventBroadcasterTester(
78 const uno::Reference
<accessibility::XAccessibleEventBroadcaster
>& xBroadcaster
,
79 const uno::Reference
<awt::XWindow
>& xWindow
)
80 : mxBroadcaster(xBroadcaster
)
85 bool XAccessibleEventBroadcasterTester::isTransient(
86 const uno::Reference
<accessibility::XAccessibleEventBroadcaster
> xBroadcaster
)
88 uno::Reference
<accessibility::XAccessibleContext
> xCtx(xBroadcaster
, uno::UNO_QUERY_THROW
);
89 return isTransient(xCtx
);
92 bool XAccessibleEventBroadcasterTester::isTransient(
93 const uno::Reference
<accessibility::XAccessibleContext
> xCtx
)
95 return ((xCtx
->getAccessibleStateSet() & accessibility::AccessibleStateType::TRANSIENT
)
96 && (xCtx
->getAccessibleParent()->getAccessibleContext()->getAccessibleStateSet()
97 & accessibility::AccessibleStateType::MANAGES_DESCENDANTS
));
101 * @brief Generates an event on @c mxBroadcaster.
103 * This method indirectly alters the state of @c mxBroadcaster so that an
104 * accessible event will be fired for it. It can be called as many times as
105 * needed and triggers an event each time.
107 void XAccessibleEventBroadcasterTester::fireEvent()
109 awt::Rectangle newPosSize
= mxWindow
->getPosSize();
110 newPosSize
.Width
= newPosSize
.Width
- 20;
111 newPosSize
.Height
= newPosSize
.Height
- 20;
112 newPosSize
.X
= newPosSize
.X
+ 20;
113 newPosSize
.Y
= newPosSize
.Y
+ 20;
114 mxWindow
->setPosSize(newPosSize
.X
, newPosSize
.Y
, newPosSize
.Width
, newPosSize
.Height
,
115 awt::PosSize::POSSIZE
);
119 * @brief Adds a listener and fires events by mean of object relation.
121 * Asserts that the listener was properly called.
123 void XAccessibleEventBroadcasterTester::testAddEventListener()
125 rtl::Reference
<EvListener
> xListener(new EvListener
);
126 mxBroadcaster
->addAccessibleEventListener(xListener
);
127 bool transient
= isTransient(mxBroadcaster
);
129 std::cout
<< "firing event" << std::endl
;
132 AccessibilityTools::Await([&xListener
]() { return xListener
->mbGotEvent
; });
135 CPPUNIT_ASSERT_MESSAGE("listener wasn't called", xListener
->mbGotEvent
);
137 CPPUNIT_ASSERT_MESSAGE("Object is Transient, listener isn't expected to be called",
138 !xListener
->mbGotEvent
);
140 mxBroadcaster
->removeAccessibleEventListener(xListener
);
144 * @brief Similar to @c testAddEventListener() but also removes the listener
146 * Adds an event listener just like @c testAddEventListener(), and then removes it and verifies an
147 * event doesn't trigger the supposedly removed listener.
149 * @see testAddEventListener()
151 void XAccessibleEventBroadcasterTester::testRemoveEventListener()
153 /* there is nothing we can really test for transient objects */
154 if (isTransient(mxBroadcaster
))
156 std::cerr
<< "could not test removing listener on transient object " << mxBroadcaster
161 rtl::Reference
<EvListener
> xListener(new EvListener
);
162 mxBroadcaster
->addAccessibleEventListener(xListener
);
164 std::cout
<< "firing event (with listener)" << std::endl
;
167 AccessibilityTools::Await([&xListener
]() { return xListener
->mbGotEvent
; });
169 CPPUNIT_ASSERT_MESSAGE("listener wasn't called", xListener
->mbGotEvent
);
171 /* reset listener, remove it and try again */
172 xListener
->mbGotEvent
= false;
174 std::cout
<< "removing listener" << std::endl
;
175 mxBroadcaster
->removeAccessibleEventListener(xListener
);
177 std::cout
<< "firing event (without listener)" << std::endl
;
180 AccessibilityTools::Wait(500);
182 CPPUNIT_ASSERT_MESSAGE("removed listener was called", !xListener
->mbGotEvent
);
185 /* vim:set shiftwidth=4 softtabstop=4 expandtab cinoptions=b1,g0,N-s cinkeys+=0=break: */