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/svapp.hxx>
23#include <vcl/idle.hxx>
24#include <vcl/window.hxx>
25
26#include <set>
27
28class Timer;
29
30namespace {
31
32struct Notifier {
33 std::condition_variable cv;
34 std::mutex mMutex;
35 bool mReady = false;
36
37 DECL_LINK( NotifyHdl, Timer*, void );
38};
39
40}
41
42UIObjectUnoObj::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();
156}
157
158css::uno::Sequence<css::beans::PropertyValue> UIObjectUnoObj::getState()
159{
160 if (!mpObj)
161 throw css::uno::RuntimeException();
162
163 SolarMutexGuard aGuard;
164 StringMap aMap = mpObj->get_state();
165 css::uno::Sequence<css::beans::PropertyValue> aProps(aMap.size());
166 std::transform(aMap.begin(), aMap.end(), aProps.getArray(),
167 [](auto const& elem)
168 { return comphelper::makePropertyValue(elem.first, elem.second); });
169
170 return aProps;
171}
172
173css::uno::Sequence<OUString> UIObjectUnoObj::getChildren()
174{
175 if (!mpObj)
176 throw css::uno::RuntimeException();
177
178 std::set<OUString> aChildren;
179
180 {
181 SolarMutexGuard aGuard;
182 aChildren = mpObj->get_children();
183 }
184
185 css::uno::Sequence<OUString> aRet(aChildren.size());
186 std::copy(aChildren.begin(), aChildren.end(), aRet.getArray());
187
188 return aRet;
189}
190
191OUString SAL_CALL UIObjectUnoObj::getType()
192{
193 if (!mpObj)
194 throw css::uno::RuntimeException();
195
196 SolarMutexGuard aGuard;
197 return mpObj->get_type();
198}
199
201{
202 return "org.libreoffice.uitest.UIObject";
203}
204
205sal_Bool UIObjectUnoObj::supportsService(OUString const & ServiceName)
206{
208}
209
210css::uno::Sequence<OUString> UIObjectUnoObj::getSupportedServiceNames()
211{
212 return { "com.sun.star.ui.test.UIObject" };
213}
214
216{
217 if (!mpObj)
218 throw css::uno::RuntimeException();
219
220 SolarMutexGuard aGuard;
221 return mpObj->dumpHierarchy();
222}
223
224/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static bool Reschedule(bool bHandleAllCurrentEvents=false)
Attempt to process current pending event(s)
Definition: svapp.cxx:486
An idle is a timer to be scheduled immediately.
Definition: idle.hxx:35
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)
std::mutex m_aMutex
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)
::cppu::WeakComponentImplHelper< css::ui::test::XUIObject, css::lang::XServiceInfo > UIObjectBase
std::map< OUString, OUString > StringMap