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 <memory>
11 #include "uiobject_uno.hxx"
12 #include <utility>
14 #include <vcl/svapp.hxx>
15 #include <vcl/idle.hxx>
16 #include <vcl/window.hxx>
17 
18 #include <set>
19 
20 UIObjectUnoObj::UIObjectUnoObj(std::unique_ptr<UIObject> pObj):
22  mpObj(std::move(pObj)),
23  mReady(true)
24 {
25 }
26 
28 {
29  {
30  std::scoped_lock<std::mutex> lk3(mMutex);
31  }
32  SolarMutexGuard aGuard;
33  mpObj.reset();
34 }
35 
36 css::uno::Reference<css::ui::test::XUIObject> SAL_CALL UIObjectUnoObj::getChild(const OUString& rID)
37 {
38  if (!mpObj)
39  throw css::uno::RuntimeException();
40 
41  SolarMutexGuard aGuard;
42  std::unique_ptr<UIObject> pObj = mpObj->get_child(rID);
43  return new UIObjectUnoObj(std::move(pObj));
44 }
45 
47 {
48  std::scoped_lock<std::mutex> lk(mMutex);
49  mReady = true;
50  cv.notify_all();
51 }
52 
53 namespace {
54 
55 class ExecuteWrapper
56 {
57  std::function<void()> mFunc;
58  Link<Timer*, void> mHandler;
59  volatile bool mbSignal;
60 
61 public:
62 
63  ExecuteWrapper(std::function<void()> func, Link<Timer*, void> handler):
64  mFunc(std::move(func)),
65  mHandler(handler),
66  mbSignal(false)
67  {
68  }
69 
70  void setSignal()
71  {
72  mbSignal = true;
73  }
74 
75  DECL_LINK( ExecuteActionHdl, Timer*, void );
76 };
77 
78 
79 IMPL_LINK_NOARG(ExecuteWrapper, ExecuteActionHdl, Timer*, void)
80 {
81  {
82  Idle aIdle;
83  {
84  mFunc();
85  aIdle.SetDebugName("UI Test Idle Handler2");
87  aIdle.SetInvokeHandler(mHandler);
88  aIdle.Start();
89  }
90 
91  while (!mbSignal) {
93  }
94  }
95  delete this;
96 }
97 
98 }
99 
100 void SAL_CALL UIObjectUnoObj::executeAction(const OUString& rAction, const css::uno::Sequence<css::beans::PropertyValue>& rPropValues)
101 {
102  if (!mpObj)
103  throw css::uno::RuntimeException();
104 
105  std::unique_lock<std::mutex> lk(mMutex);
106  mAction = rAction;
107  mPropValues = rPropValues;
108  mReady = false;
109  auto aIdle = std::make_unique<Idle>();
110  aIdle->SetDebugName("UI Test Idle Handler");
112 
113  std::function<void()> func = [this](){
114 
115  SolarMutexGuard aGuard;
116  StringMap aMap;
117  for (const auto& rPropVal : std::as_const(mPropValues))
118  {
119  OUString aVal;
120  if (!(rPropVal.Value >>= aVal))
121  continue;
122 
123  aMap[rPropVal.Name] = aVal;
124  }
125  mpObj->execute(mAction, aMap);
126  };
127 
128  ExecuteWrapper* pWrapper = new ExecuteWrapper(func, LINK(this, UIObjectUnoObj, NotifyHdl));
129  aIdle->SetInvokeHandler(LINK(pWrapper, ExecuteWrapper, ExecuteActionHdl));
130  {
131  SolarMutexGuard aGuard;
132  aIdle->Start();
133  }
134 
135  cv.wait(lk, [this]{return mReady;});
136  pWrapper->setSignal();
137 
138  SolarMutexGuard aGuard;
139  aIdle.reset();
140 }
141 
142 css::uno::Sequence<css::beans::PropertyValue> UIObjectUnoObj::getState()
143 {
144  if (!mpObj)
145  throw css::uno::RuntimeException();
146 
147  SolarMutexGuard aGuard;
148  StringMap aMap = mpObj->get_state();
149  css::uno::Sequence<css::beans::PropertyValue> aProps(aMap.size());
150  sal_Int32 i = 0;
151  for (auto const& elem : aMap)
152  {
153  aProps[i].Name = elem.first;
154  aProps[i].Value <<= elem.second;
155  ++i;
156  }
157 
158  return aProps;
159 }
160 
161 css::uno::Sequence<OUString> UIObjectUnoObj::getChildren()
162 {
163  if (!mpObj)
164  throw css::uno::RuntimeException();
165 
166  std::set<OUString> aChildren;
167 
168  {
169  SolarMutexGuard aGuard;
170  aChildren = mpObj->get_children();
171  }
172 
173  css::uno::Sequence<OUString> aRet(aChildren.size());
174  sal_Int32 i = 0;
175  for (auto const& child : aChildren)
176  {
177  aRet[i] = child;
178  ++i;
179  }
180 
181  return aRet;
182 }
183 
184 OUString SAL_CALL UIObjectUnoObj::getType()
185 {
186  if (!mpObj)
187  throw css::uno::RuntimeException();
188 
189  SolarMutexGuard aGuard;
190  return mpObj->get_type();
191 }
192 
194 {
195  return "org.libreoffice.uitest.UIObject";
196 }
197 
198 sal_Bool UIObjectUnoObj::supportsService(OUString const & ServiceName)
199 {
200  return cppu::supportsService(this, ServiceName);
201 }
202 
203 css::uno::Sequence<OUString> UIObjectUnoObj::getSupportedServiceNames()
204 {
205  return { "com.sun.star.ui.test.UIObject" };
206 }
207 
208 OUString SAL_CALL UIObjectUnoObj::getHierarchy()
209 {
210  if (!mpObj)
211  throw css::uno::RuntimeException();
212 
213  SolarMutexGuard aGuard;
214  return mpObj->dumpHierarchy();
215 }
216 
217 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
OUString SAL_CALL getHierarchy() override
css::uno::Sequence< OUString > SAL_CALL getSupportedServiceNames() override
std::condition_variable cv
css::uno::Reference< css::ui::test::XUIObject > SAL_CALL getChild(const OUString &rID) override
sal_Bool SAL_CALL supportsService(OUString const &ServiceName) override
OUString mAction
HashMap_OWString_Interface aMap
bool CPPUHELPER_DLLPUBLIC supportsService(css::lang::XServiceInfo *implementation, rtl::OUString const &name)
virtual void Start() override
Activates the timer task.
Definition: idle.cxx:34
IMPL_LINK_NOARG(UIObjectUnoObj, NotifyHdl, Timer *, void)
void SetDebugName(const char *pDebugName)
Definition: task.hxx:82
std::mutex mMutex
static bool Reschedule(bool bHandleAllCurrentEvents=false)
Attempt to process current pending event(s)
Definition: svapp.cxx:476
int i
unsigned char sal_Bool
css::uno::Sequence< css::beans::PropertyValue > mPropValues
UIObjectUnoObj(std::unique_ptr< UIObject > pObj)
OUString SAL_CALL getType() override
virtual ~UIObjectUnoObj() override
void SAL_CALL executeAction(const OUString &rAction, const css::uno::Sequence< css::beans::PropertyValue > &xPropValues) override
std::map< OUString, OUString > StringMap
css::uno::Sequence< OUString > SAL_CALL getChildren() override
std::unique_ptr< UIObject > mpObj
void SetInvokeHandler(const Link< Timer *, void > &rLink)
Definition: timer.hxx:56
These events should run very fast!
css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getState() override
Definition: timer.hxx:26
void SetPriority(TaskPriority ePriority)
Definition: scheduler.cxx:594
osl::Mutex m_aMutex
Definition: dtranscomp.cxx:213
Low, very idle cleanup tasks.
OUString SAL_CALL getImplementationName() override
::cppu::WeakComponentImplHelper< css::ui::test::XUIObject, css::lang::XServiceInfo > UIObjectBase
An idle is a timer to be scheduled immediately.
Definition: idle.hxx:34