LibreOffice Module vcl (master) 1
uiobject_uno.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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
10#include <sal/config.h>
11
12#include <algorithm>
13#include <atomic>
14#include <condition_variable>
15#include <memory>
16#include <mutex>
17#include "uiobject_uno.hxx"
18#include <utility>
21#include <tools/link.hxx>
22#include <vcl/scheduler.hxx>
23#include <vcl/svapp.hxx>
24#include <vcl/idle.hxx>
25#include <vcl/window.hxx>
26
27#include <set>
28
29class Timer;
30
31namespace {
32
33struct Notifier {
34 std::condition_variable cv;
35 std::mutex mMutex;
36 bool mReady = false;
37
38 DECL_LINK( NotifyHdl, Timer*, void );
39};
40
41}
42
43UIObjectUnoObj::UIObjectUnoObj(std::unique_ptr<UIObject> pObj):
44 mpObj(std::move(pObj))
45{
46}
47
49{
50 SolarMutexGuard aGuard;
51 mpObj.reset();
52}
53
54css::uno::Reference<css::ui::test::XUIObject> SAL_CALL UIObjectUnoObj::getChild(const OUString& rID)
55{
56 if (!mpObj)
57 throw css::uno::RuntimeException();
58
59 SolarMutexGuard aGuard;
60 std::unique_ptr<UIObject> pObj = mpObj->get_child(rID);
61 return new UIObjectUnoObj(std::move(pObj));
62}
63
64IMPL_LINK_NOARG(Notifier, NotifyHdl, Timer*, void)
65{
66 std::scoped_lock<std::mutex> lk(mMutex);
67 mReady = true;
68 cv.notify_all();
69}
70
71namespace {
72
73class ExecuteWrapper
74{
75 std::function<void()> mFunc;
76 Link<Timer*, void> mHandler;
77 std::atomic<bool> mbSignal;
78
79public:
80
81 ExecuteWrapper(std::function<void()> func, Link<Timer*, void> handler):
82 mFunc(std::move(func)),
83 mHandler(handler),
84 mbSignal(false)
85 {
86 }
87
88 void setSignal()
89 {
90 mbSignal = true;
91 }
92
93 DECL_LINK( ExecuteActionHdl, Timer*, void );
94};
95
96
97IMPL_LINK_NOARG(ExecuteWrapper, ExecuteActionHdl, Timer*, void)
98{
99 {
100 Idle aIdle("UI Test Idle Handler2");
101 {
102 mFunc();
103 aIdle.SetPriority(TaskPriority::LOWEST);
104 aIdle.SetInvokeHandler(mHandler);
105 aIdle.Start();
106 }
107
108 while (!mbSignal) {
110 }
111 }
112 delete this;
113}
114
115}
116
117void SAL_CALL UIObjectUnoObj::executeAction(const OUString& rAction, const css::uno::Sequence<css::beans::PropertyValue>& rPropValues)
118{
119 if (!mpObj)
120 throw css::uno::RuntimeException();
121
122 auto aIdle = std::make_unique<Idle>("UI Test Idle Handler");
123 aIdle->SetPriority(TaskPriority::HIGHEST);
124
125 std::function<void()> func = [&rAction, &rPropValues, this](){
126
127 SolarMutexGuard aGuard;
129 for (const auto& rPropVal : rPropValues)
130 {
131 OUString aVal;
132 if (!(rPropVal.Value >>= aVal))
133 continue;
134
135 aMap[rPropVal.Name] = aVal;
136 }
137 mpObj->execute(rAction, aMap);
138 };
139
140 Notifier notifier;
141 ExecuteWrapper* pWrapper = new ExecuteWrapper(std::move(func), LINK(&notifier, Notifier, NotifyHdl));
142 aIdle->SetInvokeHandler(LINK(pWrapper, ExecuteWrapper, ExecuteActionHdl));
143 {
144 SolarMutexGuard aGuard;
145 aIdle->Start();
146 }
147
148 {
149 std::unique_lock<std::mutex> lk(notifier.mMutex);
150 notifier.cv.wait(lk, [&notifier]{return notifier.mReady;});
151 }
152 pWrapper->setSignal();
153
154 SolarMutexGuard aGuard;
155 aIdle.reset();
157}
158
159css::uno::Sequence<css::beans::PropertyValue> UIObjectUnoObj::getState()
160{
161 if (!mpObj)
162 throw css::uno::RuntimeException();
163
164 SolarMutexGuard aGuard;
165 StringMap aMap = mpObj->get_state();
166 css::uno::Sequence<css::beans::PropertyValue> aProps(aMap.size());
167 std::transform(aMap.begin(), aMap.end(), aProps.getArray(),
168 [](auto const& elem)
169 { return comphelper::makePropertyValue(elem.first, elem.second); });
170
171 return aProps;
172}
173
174css::uno::Sequence<OUString> UIObjectUnoObj::getChildren()
175{
176 if (!mpObj)
177 throw css::uno::RuntimeException();
178
179 std::set<OUString> aChildren;
180
181 {
182 SolarMutexGuard aGuard;
183 aChildren = mpObj->get_children();
184 }
185
186 css::uno::Sequence<OUString> aRet(aChildren.size());
187 std::copy(aChildren.begin(), aChildren.end(), aRet.getArray());
188
189 return aRet;
190}
191
192OUString SAL_CALL UIObjectUnoObj::getType()
193{
194 if (!mpObj)
195 throw css::uno::RuntimeException();
196
197 SolarMutexGuard aGuard;
198 return mpObj->get_type();
199}
200
202{
203 return "org.libreoffice.uitest.UIObject";
204}
205
206sal_Bool UIObjectUnoObj::supportsService(OUString const & ServiceName)
207{
209}
210
211css::uno::Sequence<OUString> UIObjectUnoObj::getSupportedServiceNames()
212{
213 return { "com.sun.star.ui.test.UIObject" };
214}
215
217{
218 if (!mpObj)
219 throw css::uno::RuntimeException();
220
221 SolarMutexGuard aGuard;
222 return mpObj->dumpHierarchy();
223}
224
225/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool Reschedule(bool bHandleAllCurrentEvents=false)
Attempt to process current pending event(s)
Definition: svapp.cxx:363
An idle is a timer to be scheduled immediately.
Definition: idle.hxx:35
static void ProcessEventsToIdle()
Process all events until none is pending.
Definition: svapp.cxx:379
Definition: timer.hxx:27
css::uno::Reference< css::ui::test::XUIObject > SAL_CALL getChild(const OUString &rID) override
OUString SAL_CALL getType() override
OUString SAL_CALL getHierarchy() override
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
virtual ~UIObjectUnoObj() override
sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getState() override
css::uno::Sequence< OUString > SAL_CALL getChildren() override
UIObjectUnoObj(std::unique_ptr< UIObject > pObj)
std::unique_ptr< UIObject > mpObj
void SAL_CALL executeAction(const OUString &rAction, const css::uno::Sequence< css::beans::PropertyValue > &xPropValues) override
OUString SAL_CALL getImplementationName() override
DECL_LINK(CheckNameHdl, SvxNameDialog &, bool)
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
HashMap_OWString_Interface aMap
@ LOWEST
Low, very idle cleanup tasks.
@ HIGHEST
These events should run very fast!
unsigned char sal_Bool
IMPL_LINK_NOARG(Notifier, NotifyHdl, Timer *, void)
std::map< OUString, OUString > StringMap