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