/* -*- 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 #include "uiobject_uno.hxx" #include #include #include #include #include UIObjectUnoObj::UIObjectUnoObj(std::unique_ptr pObj): UIObjectBase(m_aMutex), mpObj(std::move(pObj)), mReady(true) { } UIObjectUnoObj::~UIObjectUnoObj() { { std::lock_guard lk3(mMutex); } SolarMutexGuard aGuard; mpObj.reset(); } css::uno::Reference SAL_CALL UIObjectUnoObj::getChild(const OUString& rID) { if (!mpObj) throw css::uno::RuntimeException(); SolarMutexGuard aGuard; std::unique_ptr pObj = mpObj->get_child(rID); return new UIObjectUnoObj(std::move(pObj)); } IMPL_LINK_NOARG(UIObjectUnoObj, NotifyHdl, Timer*, void) { std::lock_guard lk(mMutex); mReady = true; cv.notify_all(); } namespace { class ExecuteWrapper { std::function mFunc; Link mHandler; bool mbSignal; std::mutex mMutex; public: ExecuteWrapper(std::function func, Link handler): mFunc(func), mHandler(handler), mbSignal(false) { } void setSignal() { mbSignal = true; } std::mutex& getMutex() { return mMutex; } DECL_LINK( ExecuteActionHdl, Timer*, void ); }; IMPL_LINK_NOARG(ExecuteWrapper, ExecuteActionHdl, Timer*, void) { Idle aIdle; { mFunc(); aIdle.SetDebugName("UI Test Idle Handler2"); aIdle.SetPriority(TaskPriority::LOWEST); aIdle.SetInvokeHandler(mHandler); aIdle.Start(); } Scheduler::ProcessEventsToSignal(mbSignal); std::unique_lock lock(mMutex); while (!mbSignal) { std::this_thread::sleep_for(std::chrono::milliseconds(5)); } delete this; } } void SAL_CALL UIObjectUnoObj::executeAction(const OUString& rAction, const css::uno::Sequence& rPropValues) { if (!mpObj) throw css::uno::RuntimeException(); std::unique_lock lk(mMutex); mAction = rAction; mPropValues = rPropValues; mReady = false; Idle aIdle; aIdle.SetDebugName("UI Test Idle Handler"); aIdle.SetPriority(TaskPriority::HIGH); std::function func = [this](){ SolarMutexGuard aGuard; StringMap aMap; for (sal_Int32 i = 0, n = mPropValues.getLength(); i < n; ++i) { OUString aVal; if (!(mPropValues[i].Value >>= aVal)) continue; aMap[mPropValues[i].Name] = aVal; } mpObj->execute(mAction, aMap); }; ExecuteWrapper* pWrapper = new ExecuteWrapper(func, LINK(this, UIObjectUnoObj, NotifyHdl)); std::unique_lock(pWrapper->getMutex()); aIdle.SetInvokeHandler(LINK(pWrapper, ExecuteWrapper, ExecuteActionHdl)); { SolarMutexGuard aGuard; aIdle.Start(); } cv.wait(lk, [this]{return mReady;}); pWrapper->setSignal(); } css::uno::Sequence UIObjectUnoObj::getState() { if (!mpObj) throw css::uno::RuntimeException(); SolarMutexGuard aGuard; StringMap aMap = mpObj->get_state(); css::uno::Sequence aProps(aMap.size()); sal_Int32 i = 0; for (auto itr = aMap.begin(), itrEnd = aMap.end(); itr != itrEnd; ++itr, ++i) { aProps[i].Name = itr->first; aProps[i].Value <<= itr->second; } return aProps; } css::uno::Sequence UIObjectUnoObj::getChildren() { if (!mpObj) throw css::uno::RuntimeException(); std::set aChildren = mpObj->get_children(); css::uno::Sequence aRet(aChildren.size()); sal_Int32 i = 0; for (auto itr = aChildren.begin(), itrEnd = aChildren.end(); itr != itrEnd; ++itr, ++i) { aRet[i] = *itr; } return aRet; } OUString SAL_CALL UIObjectUnoObj::getType() { if (!mpObj) throw css::uno::RuntimeException(); return mpObj->get_type(); } OUString SAL_CALL UIObjectUnoObj::getImplementationName() { return OUString("org.libreoffice.uitest.UIObject"); } sal_Bool UIObjectUnoObj::supportsService(OUString const & ServiceName) { return cppu::supportsService(this, ServiceName); } css::uno::Sequence UIObjectUnoObj::getSupportedServiceNames() { css::uno::Sequence aServiceNames(1); aServiceNames[0] = "com.sun.star.ui.test.UIObject"; return aServiceNames; } OUString SAL_CALL UIObjectUnoObj::getHierarchy() { if (!mpObj) throw css::uno::RuntimeException(); SolarMutexGuard aGuard; return mpObj->dumpHierarchy(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */