summaryrefslogtreecommitdiffstats
path: root/vcl/source/uitest/uno/uiobject_uno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'vcl/source/uitest/uno/uiobject_uno.cxx')
-rw-r--r--vcl/source/uitest/uno/uiobject_uno.cxx224
1 files changed, 224 insertions, 0 deletions
diff --git a/vcl/source/uitest/uno/uiobject_uno.cxx b/vcl/source/uitest/uno/uiobject_uno.cxx
new file mode 100644
index 000000000..042b2fcf5
--- /dev/null
+++ b/vcl/source/uitest/uno/uiobject_uno.cxx
@@ -0,0 +1,224 @@
+/* -*- 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/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):
+ UIObjectBase(m_aMutex),
+ mpObj(std::move(pObj))
+{
+}
+
+UIObjectUnoObj::~UIObjectUnoObj()
+{
+ SolarMutexGuard aGuard;
+ mpObj.reset();
+}
+
+css::uno::Reference<css::ui::test::XUIObject> SAL_CALL UIObjectUnoObj::getChild(const OUString& rID)
+{
+ if (!mpObj)
+ throw css::uno::RuntimeException();
+
+ SolarMutexGuard aGuard;
+ std::unique_ptr<UIObject> pObj = mpObj->get_child(rID);
+ 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)
+{
+ if (!mpObj)
+ throw css::uno::RuntimeException();
+
+ 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(&notifier, Notifier, NotifyHdl));
+ aIdle->SetInvokeHandler(LINK(pWrapper, ExecuteWrapper, ExecuteActionHdl));
+ {
+ SolarMutexGuard aGuard;
+ aIdle->Start();
+ }
+
+ {
+ std::unique_lock<std::mutex> lk(notifier.mMutex);
+ notifier.cv.wait(lk, [&notifier]{return notifier.mReady;});
+ }
+ pWrapper->setSignal();
+
+ SolarMutexGuard aGuard;
+ aIdle.reset();
+}
+
+css::uno::Sequence<css::beans::PropertyValue> UIObjectUnoObj::getState()
+{
+ if (!mpObj)
+ throw css::uno::RuntimeException();
+
+ 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()
+{
+ if (!mpObj)
+ throw css::uno::RuntimeException();
+
+ 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()
+{
+ if (!mpObj)
+ throw css::uno::RuntimeException();
+
+ SolarMutexGuard aGuard;
+ return mpObj->get_type();
+}
+
+OUString SAL_CALL UIObjectUnoObj::getImplementationName()
+{
+ return "org.libreoffice.uitest.UIObject";
+}
+
+sal_Bool UIObjectUnoObj::supportsService(OUString const & ServiceName)
+{
+ return cppu::supportsService(this, ServiceName);
+}
+
+css::uno::Sequence<OUString> UIObjectUnoObj::getSupportedServiceNames()
+{
+ return { "com.sun.star.ui.test.UIObject" };
+}
+
+OUString SAL_CALL UIObjectUnoObj::getHierarchy()
+{
+ if (!mpObj)
+ throw css::uno::RuntimeException();
+
+ SolarMutexGuard aGuard;
+ return mpObj->dumpHierarchy();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */