/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
* This file is part of the LibreOffice project.
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <sal/config.h>
#include <algorithm>
#include <atomic>
#include <condition_variable>
#include <memory>
#include <mutex>
#include "uiobject_uno.hxx"
#include <utility>
#include <comphelper/propertyvalue.hxx>
#include <cppuhelper/supportsservice.hxx>
#include <tools/link.hxx>
#include <vcl/scheduler.hxx>
#include <vcl/svapp.hxx>
#include <vcl/idle.hxx>
#include <vcl/window.hxx>
#include <set>
class Timer;
namespace {
struct Notifier {
std::condition_variable cv;
std::mutex mMutex;
bool mReady =
false ;
DECL_LINK( NotifyHdl, Timer*,
void );
};
}
UIObjectUnoObj::UIObjectUnoObj(std::unique_ptr<UIObject> pObj):
mpObj(std::move(pObj))
{
assert(mpObj);
}
UIObjectUnoObj::~UIObjectUnoObj()
{
SolarMutexGuard aGuard;
mpObj.reset();
}
css::uno::Reference<css::ui::test::XUIObject> SAL_CALL UIObjectUnoObj::getChild(
const OUString& rID)
{
SolarMutexGuard aGuard;
std::unique_ptr<UIObject> pObj = mpObj->get_child(rID);
SAL_WARN_IF(!pObj,
"vcl" ,
"child " << rID <<
" of parent " << mpObj->dumpState() <<
" does not exist" );
if (!pObj)
throw css::uno::RuntimeException(
"getChild with id " + rID +
" did not find a child" )
;
return new UIObjectUnoObj(std::move(pObj));
}
IMPL_LINK_NOARG(Notifier, NotifyHdl, Timer*, void )
{
std::scoped_lock<std::mutex> lk(mMutex);
mReady = true ;
cv.notify_all();
}
namespace {
class ExecuteWrapper
{
std::function<void ()> mFunc;
Link<Timer*, void > mHandler;
std::atomic<bool > mbSignal;
public :
ExecuteWrapper(std::function<void ()> func, Link<Timer*, void > handler):
mFunc(std::move(func)),
mHandler(handler),
mbSignal(false )
{
}
void setSignal()
{
mbSignal = true ;
}
DECL_LINK( ExecuteActionHdl, Timer*, void );
};
IMPL_LINK_NOARG(ExecuteWrapper, ExecuteActionHdl, Timer*, void )
{
{
Idle aIdle("UI Test Idle Handler2" );
{
mFunc();
aIdle.SetPriority(TaskPriority::LOWEST);
aIdle.SetInvokeHandler(mHandler);
aIdle.Start();
}
while (!mbSignal) {
Application::Reschedule();
}
}
delete this ;
}
}
void SAL_CALL UIObjectUnoObj::executeAction(const OUString& rAction, const css::uno::Sequence<css::beans::PropertyValue>& rPropValues)
{
auto aIdle = std::make_unique<Idle>("UI Test Idle Handler" );
aIdle->SetPriority(TaskPriority::HIGHEST);
std::function<void ()> func = [&rAction, &rPropValues, this ](){
SolarMutexGuard aGuard;
StringMap aMap;
for (const auto & rPropVal : rPropValues)
{
OUString aVal;
if (!(rPropVal.Value >>= aVal))
continue ;
aMap[rPropVal.Name] = aVal;
}
mpObj->execute(rAction, aMap);
};
Notifier notifier;
ExecuteWrapper* pWrapper = new ExecuteWrapper(std::move(func), LINK(¬ifier, Notifier, NotifyHdl));
aIdle->SetInvokeHandler(LINK(pWrapper, ExecuteWrapper, ExecuteActionHdl));
{
SolarMutexGuard aGuard;
aIdle->Start();
}
{
std::unique_lock<std::mutex> lk(notifier.mMutex);
notifier.cv.wait(lk, [¬ifier]{return notifier.mReady;});
}
pWrapper->setSignal();
SolarMutexGuard aGuard;
aIdle.reset();
Scheduler::ProcessEventsToIdle();
}
css::uno::Sequence<css::beans::PropertyValue> UIObjectUnoObj::getState()
{
SolarMutexGuard aGuard;
StringMap aMap = mpObj->get_state();
css::uno::Sequence<css::beans::PropertyValue> aProps(aMap.size());
std::transform(aMap.begin(), aMap.end(), aProps.getArray(),
[](auto const & elem)
{ return comphelper::makePropertyValue(elem.first, elem.second); });
return aProps;
}
css::uno::Sequence<OUString> UIObjectUnoObj::getChildren()
{
std::set<OUString> aChildren;
{
SolarMutexGuard aGuard;
aChildren = mpObj->get_children();
}
css::uno::Sequence<OUString> aRet(aChildren.size());
std::copy(aChildren.begin(), aChildren.end(), aRet.getArray());
return aRet;
}
OUString SAL_CALL UIObjectUnoObj::getType()
{
SolarMutexGuard aGuard;
return mpObj->get_type();
}
OUString SAL_CALL UIObjectUnoObj::getImplementationName()
{
return u"org.libreoffice.uitest.UIObject" _ustr;
}
sal_Bool UIObjectUnoObj::supportsService(OUString const & ServiceName)
{
return cppu::supportsService(this , ServiceName);
}
css::uno::Sequence<OUString> UIObjectUnoObj::getSupportedServiceNames()
{
return { u"com.sun.star.ui.test.UIObject" _ustr };
}
OUString SAL_CALL UIObjectUnoObj::getHierarchy()
{
SolarMutexGuard aGuard;
return mpObj->dumpHierarchy();
}
sal_Bool SAL_CALL UIObjectUnoObj::equals(const css::uno::Reference<css::ui::test::XUIObject>& rOther)
{
return mpObj->equals(*static_cast <UIObjectUnoObj&>(*rOther).mpObj);
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
Messung V0.5 C=93 H=97 G=94
¤ Dauer der Verarbeitung: 0.14 Sekunden
(vorverarbeitet)
¤
*© Formatika GbR, Deutschland