Bug Summary

File:home/maarten/src/libreoffice/core/include/rtl/ref.hxx
Warning:line 77, column 13
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name uiobject.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/glm -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/libmount -isystem /usr/include/blkid -isystem /usr/include/cairo -isystem /usr/include/glib-2.0 -isystem /usr/lib64/glib-2.0/include -isystem /usr/include/pixman-1 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/libxml2 -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -isystem /usr/include/freetype2 -isystem /usr/include/libpng16 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D VCL_DLLIMPLEMENTATION -D DLLIMPLEMENTATION_UITEST -D CUI_DLL_NAME="libcuilo.so" -D DESKTOP_DETECTOR_DLL_NAME="libdesktop_detectorlo.so" -D TK_DLL_NAME="libtklo.so" -D SYSTEM_ZLIB -D GLM_FORCE_CTOR_INIT -D SK_USER_CONFIG_HEADER=</home/maarten/src/libreoffice/core/config_host/config_skia.h> -D SKIA_DLL -D ENABLE_CUPS -D HAVE_VALGRIND_HEADERS -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/epoxy/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/core -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/effects -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/config -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/ports -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/include/third_party/vulkan -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia/tools/gpu -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/skia -I /home/maarten/src/libreoffice/core/external/skia/inc/ -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/mdds/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/lcms2/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/harfbuzz/src -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/graphite/include -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/pdfium/public -D COMPONENT_BUILD -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libpng -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/libjpeg-turbo -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/vcl/inc -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /usr/include/freetype2 -I /usr/include/libpng16 -I /usr/include/libxml2 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx

/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx

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 <vcl/uitest/uiobject.hxx>
11#include <vcl/uitest/metricfielduiobject.hxx>
12#include <vcl/uitest/formattedfielduiobject.hxx>
13
14#include <vcl/svapp.hxx>
15#include <vcl/toolkit/combobox.hxx>
16#include <vcl/event.hxx>
17#include <vcl/floatwin.hxx>
18#include <vcl/tabpage.hxx>
19#include <vcl/tabctrl.hxx>
20#include <vcl/toolkit/lstbox.hxx>
21#include <vcl/toolkit/spin.hxx>
22#include <vcl/toolkit/fmtfield.hxx>
23#include <vcl/toolkit/spinfld.hxx>
24#include <vcl/toolkit/ivctrl.hxx>
25#include <vcl/toolkit/button.hxx>
26#include <vcl/toolkit/dialog.hxx>
27#include <vcl/toolkit/edit.hxx>
28#include <vcl/toolkit/field.hxx>
29#include <vcl/menubtn.hxx>
30#include <vcl/toolkit/vclmedit.hxx>
31#include <vcl/uitest/logger.hxx>
32#include <uiobject-internal.hxx>
33#include <verticaltabctrl.hxx>
34#include <vcl/toolbox.hxx>
35
36#include <comphelper/string.hxx>
37#include <comphelper/lok.hxx>
38
39#include <rtl/ustrbuf.hxx>
40#include <sal/log.hxx>
41
42#include <iostream>
43#include <memory>
44#include <vector>
45
46UIObject::~UIObject()
47{
48}
49
50StringMap UIObject::get_state()
51{
52 StringMap aMap;
53 aMap["NotImplemented"] = "NotImplemented";
54 return aMap;
55}
56
57void UIObject::execute(const OUString& /*rAction*/,
58 const StringMap& /*rParameters*/)
59{
60 // should never be called
61 throw std::exception();
62}
63
64OUString UIObject::get_type() const
65{
66 return "Generic UIObject";
67}
68
69std::unique_ptr<UIObject> UIObject::get_child(const OUString&)
70{
71 return std::unique_ptr<UIObject>();
72}
73
74std::set<OUString> UIObject::get_children() const
75{
76 return std::set<OUString>();
77}
78
79OUString UIObject::dumpState() const
80{
81 return OUString();
82}
83
84OUString UIObject::dumpHierarchy() const
85{
86 return OUString();
87}
88
89OUString UIObject::get_action(VclEventId /*nEvent*/) const
90{
91 return OUString();
92}
93
94namespace {
95
96bool isDialogWindow(vcl::Window const * pWindow)
97{
98 WindowType nType = pWindow->GetType();
99 if (nType == WindowType::DIALOG || nType == WindowType::MODELESSDIALOG)
100 return true;
101
102 // MESSBOX, INFOBOX, WARNINGBOX, ERRORBOX, QUERYBOX
103 if (nType >= WindowType::MESSBOX && nType <= WindowType::QUERYBOX)
104 return true;
105
106 if (nType == WindowType::TABDIALOG)
107 return true;
108
109 return false;
110}
111
112bool isTopWindow(vcl::Window const * pWindow)
113{
114 WindowType eType = pWindow->GetType();
115 if (eType == WindowType::FLOATINGWINDOW)
116 {
117 return pWindow->GetStyle() & WB_SYSTEMFLOATWIN;
118 }
119 return false;
120}
121
122vcl::Window* get_top_parent(vcl::Window* pWindow)
123{
124 if (isDialogWindow(pWindow) || isTopWindow(pWindow))
125 return pWindow;
126
127 vcl::Window* pParent = pWindow->GetParent();
128 if (!pParent)
129 return pWindow;
130
131 return get_top_parent(pParent);
132}
133
134std::vector<KeyEvent> generate_key_events_from_text(const OUString& rStr)
135{
136 std::vector<KeyEvent> aEvents;
137 vcl::KeyCode aCode;
138 for (sal_Int32 i = 0, n = rStr.getLength();
139 i != n; ++i)
140 {
141 aEvents.emplace_back(rStr[i], aCode);
142 }
143 return aEvents;
144}
145
146sal_uInt16 get_key(sal_Unicode cChar, bool& bShift)
147{
148 bShift = false;
149 if (cChar >= 'a' && cChar <= 'z')
150 return KEY_A + (cChar - 'a');
151 else if (cChar >= 'A' && cChar <= 'Z')
152 {
153 bShift = true;
154 return KEY_A + (cChar - 'A');
155 }
156 else if (cChar >= '0' && cChar <= '9')
157 return KEY_0 + (cChar - 'A');
158
159 return cChar;
160}
161
162bool isFunctionKey(const OUString& rStr, sal_uInt16& rKeyCode)
163{
164 std::map<OUString, sal_uInt16> aFunctionKeyMap = {
165 {"F1", KEY_F1},
166 {"F2", KEY_F2},
167 {"F3", KEY_F3},
168 {"F4", KEY_F4},
169 {"F5", KEY_F5},
170 {"F6", KEY_F6},
171 {"F7", KEY_F7},
172 {"F8", KEY_F8},
173 {"F9", KEY_F9},
174 {"F10", KEY_F10},
175 {"F11", KEY_F11},
176 {"F12", KEY_F12}
177 };
178
179 rKeyCode = 0;
180 auto itr = aFunctionKeyMap.find(rStr);
181 if (itr == aFunctionKeyMap.end())
182 return false;
183
184 rKeyCode = itr->second;
185 return true;
186}
187
188std::vector<KeyEvent> generate_key_events_from_keycode(const OUString& rStr)
189{
190 std::vector<KeyEvent> aEvents;
191
192 std::map<OUString, sal_uInt16> aKeyMap = {
193 {"ESC", KEY_ESCAPE},
194 {"TAB", KEY_TAB},
195 {"DOWN", KEY_DOWN},
196 {"UP", KEY_UP},
197 {"LEFT", KEY_LEFT},
198 {"RIGHT", KEY_RIGHT},
199 {"DELETE", KEY_DELETE},
200 {"INSERT", KEY_INSERT},
201 {"SPACE", KEY_SPACE},
202 {"BACKSPACE", KEY_BACKSPACE},
203 {"RETURN", KEY_RETURN},
204 {"HOME", KEY_HOME},
205 {"END", KEY_END},
206 {"PAGEUP", KEY_PAGEUP},
207 {"PAGEDOWN", KEY_PAGEDOWN}
208 };
209
210 // split string along '+'
211 // then translate to keycodes
212 bool bShift = false;
213 bool bMod1 = false;
214 bool bMod2 = false;
215 OUString aRemainingText;
216
217 std::vector<OUString> aTokens = comphelper::string::split(rStr, '+');
218 for (auto const& token : aTokens)
219 {
220 OUString aToken = token.trim();
221 if (aToken == "CTRL")
222 {
223 bMod1 = true;
224 }
225 else if (aToken == "SHIFT")
226 {
227 bShift = true;
228 }
229 else if (aToken == "ALT")
230 {
231 bMod2 = true;
232 }
233 else
234 aRemainingText = aToken;
235 }
236
237 sal_uInt16 nFunctionKey = 0;
238 if (isFunctionKey(aRemainingText, nFunctionKey))
239 {
240 vcl::KeyCode aCode(nFunctionKey, bShift, bMod1, bMod2, false);
241 aEvents.emplace_back(0, aCode);
242 }
243 else if (aKeyMap.find(aRemainingText) != aKeyMap.end())
244 {
245 sal_uInt16 nKey = aKeyMap[aRemainingText];
246 vcl::KeyCode aCode(nKey, bShift, bMod1, bMod2, false);
247 aEvents.emplace_back( 'a', aCode);
248 }
249 else
250 {
251 for (sal_Int32 i = 0; i < aRemainingText.getLength(); ++i)
252 {
253 bool bShiftThroughKey = false;
254 sal_uInt16 nKey = get_key(aRemainingText[i], bShiftThroughKey);
255 vcl::KeyCode aCode(nKey, bShift || bShiftThroughKey, bMod1, bMod2, false);
256 aEvents.emplace_back(aRemainingText[i], aCode);
257 }
258 }
259
260 return aEvents;
261}
262
263OUString to_string(const Point& rPos)
264{
265 OUString sStr = OUString::number(rPos.X())
266 + "x"
267 + OUString::number(rPos.Y());
268
269 return sStr;
270}
271
272OUString to_string(const Size& rSize)
273{
274 OUString sStr = OUString::number(rSize.Width())
275 + "x"
276 + OUString::number(rSize.Height());
277
278 return sStr;
279}
280
281}
282
283WindowUIObject::WindowUIObject(const VclPtr<vcl::Window>& xWindow):
284 mxWindow(xWindow)
285{
286}
287
288StringMap WindowUIObject::get_state()
289{
290 // Double-buffering is not interesting for uitesting, but can result in direct paint for a
291 // double-buffered widget, which is incorrect.
292 if (mxWindow->SupportsDoubleBuffering())
293 mxWindow->RequestDoubleBuffering(false);
294
295 StringMap aMap;
296 aMap["Visible"] = OUString::boolean(mxWindow->IsVisible());
297 aMap["ReallyVisible"] = OUString::boolean(mxWindow->IsReallyVisible());
298 aMap["Enabled"] = OUString::boolean(mxWindow->IsEnabled());
299 aMap["WindowType"] = OUString::number(static_cast<sal_uInt16>(mxWindow->GetType()), 16);
300
301 Point aPos = mxWindow->GetPosPixel();
302 aMap["RelPosition"] = to_string(aPos);
303 aMap["Size"] = to_string(mxWindow->GetSizePixel());
304 aMap["ID"] = mxWindow->get_id();
305 vcl::Window* pParent = mxWindow->GetParent();
306 if (pParent)
307 aMap["Parent"] = mxWindow->GetParent()->get_id();
308
309 bool bIgnoreAllExceptTop = isDialogWindow(mxWindow.get());
310 while(pParent)
311 {
312 Point aParentPos = pParent->GetPosPixel();
313 if (!bIgnoreAllExceptTop)
314 aPos += aParentPos;
315
316 if (isDialogWindow(pParent))
317 {
318 bIgnoreAllExceptTop = true;
319 }
320
321 pParent = pParent->GetParent();
322
323 if (!pParent && bIgnoreAllExceptTop)
324 aPos += aParentPos;
325 }
326 aMap["AbsPosition"] = to_string(aPos);
327 aMap["Text"] = mxWindow->GetText();
328 aMap["DisplayText"] = mxWindow->GetDisplayText();
329
330 return aMap;
331}
332
333void WindowUIObject::execute(const OUString& rAction,
334 const StringMap& rParameters)
335{
336 bool bHandled = true;
337 if (rAction == "SET")
338 {
339 for (auto const& parameter : rParameters)
340 {
341 std::cout << parameter.first;
342 }
343 }
344 else if (rAction == "TYPE")
345 {
346 auto it = rParameters.find("TEXT");
347 if (it != rParameters.end())
348 {
349 const OUString& rText = it->second;
350 auto aKeyEvents = generate_key_events_from_text(rText);
351 for (auto const& keyEvent : aKeyEvents)
352 {
353 mxWindow->KeyInput(keyEvent);
354 }
355 }
356 else if (rParameters.find("KEYCODE") != rParameters.end())
357 {
358 auto itr = rParameters.find("KEYCODE");
359 const OUString rText = itr->second;
360 auto aKeyEvents = generate_key_events_from_keycode(rText);
361 for (auto const& keyEvent : aKeyEvents)
362 {
363 mxWindow->KeyInput(keyEvent);
364 }
365 }
366 else
367 {
368 SAL_WARN("vcl.uitest", "missing parameter TEXT to action TYPE")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.uitest")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "missing parameter TEXT to action TYPE"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"
), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "368" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "missing parameter TEXT to action TYPE"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "missing parameter TEXT to action TYPE"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "368" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "missing parameter TEXT to action TYPE") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest")
, ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "368" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "missing parameter TEXT to action TYPE"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "missing parameter TEXT to action TYPE"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "368" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
369 return;
370 }
371 }
372 else if (rAction == "FOCUS")
373 {
374 mxWindow->GrabFocus();
375 }
376 else
377 {
378 bHandled = false;
379 }
380
381 if (!bHandled)
382 {
383 SAL_WARN("vcl.uitest", "unknown action or parameter for " << get_name() << ". Action: " << rAction)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.uitest")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "unknown action or parameter for "
<< get_name() << ". Action: " << rAction) ==
1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"
), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "383" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "unknown action or parameter for " <<
get_name() << ". Action: " << rAction), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown action or parameter for " << get_name() <<
". Action: " << rAction; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl.uitest"), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "383" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "unknown action or parameter for " << get_name
() << ". Action: " << rAction) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "383" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "unknown action or parameter for " <<
get_name() << ". Action: " << rAction), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"unknown action or parameter for " << get_name() <<
". Action: " << rAction; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("vcl.uitest"), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "383" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
384 }
385}
386
387OUString WindowUIObject::get_type() const
388{
389 return get_name();
390}
391
392namespace {
393
394vcl::Window* findChild(vcl::Window* pParent, const OUString& rID, bool bRequireVisible = false)
395{
396 if (!pParent)
397 return nullptr;
398
399 if (pParent->get_id() == rID)
400 return pParent;
401
402 size_t nCount = pParent->GetChildCount();
403 for (size_t i = 0; i < nCount; ++i)
404 {
405 vcl::Window* pChild = pParent->GetChild(i);
406 if (pChild && pChild->get_id() == rID
407 && (!bRequireVisible || pChild->IsVisible()))
408 return pChild;
409
410 if (!bRequireVisible || pChild->IsVisible())
411 {
412 vcl::Window* pResult = findChild(pChild, rID);
413 if (pResult)
414 return pResult;
415 }
416 }
417
418 return nullptr;
419}
420
421void addChildren(vcl::Window const * pParent, std::set<OUString>& rChildren)
422{
423 if (!pParent)
424 return;
425
426 size_t nCount = pParent->GetChildCount();
427 for (size_t i = 0; i < nCount; ++i)
428 {
429 vcl::Window* pChild = pParent->GetChild(i);
430 if (pChild)
431 {
432 OUString aId = pChild->get_id();
433 if (!aId.isEmpty())
434 {
435 auto ret = rChildren.insert(aId);
436 SAL_WARN_IF(!ret.second, "vcl.uitest", "duplicate ids for ui elements. violates locally unique requirement")do { if (true && (!ret.second)) { switch (sal_detail_log_report
(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl.uitest")) { case SAL_DETAIL_LOG_ACTION_IGNORE
: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail
::getResult( ::sal::detail::StreamStart() << "duplicate ids for ui elements. violates locally unique requirement"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"
), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "436" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "duplicate ids for ui elements. violates locally unique requirement"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "duplicate ids for ui elements. violates locally unique requirement"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"
), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "436" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "duplicate ids for ui elements. violates locally unique requirement"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"
), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "436" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "duplicate ids for ui elements. violates locally unique requirement"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "duplicate ids for ui elements. violates locally unique requirement"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"
), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "436" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
437 }
438
439 addChildren(pChild, rChildren);
440 }
441 }
442}
443
444}
445
446std::unique_ptr<UIObject> WindowUIObject::get_child(const OUString& rID)
447{
448 // in a first step try the real children before moving to the top level parent
449 // This makes it easier to handle cases with the same ID as there is a way
450 // to resolve conflicts
451 vcl::Window* pWindow = findChild(mxWindow.get(), rID);
452 if (!pWindow)
453 {
454 vcl::Window* pDialogParent = get_top_parent(mxWindow.get());
455 pWindow = findChild(pDialogParent, rID);
456 }
457
458 if (!pWindow)
459 throw css::uno::RuntimeException("Could not find child with id: " + rID);
460
461 FactoryFunction aFunction = pWindow->GetUITestFactory();
462 return aFunction(pWindow);
463}
464
465std::unique_ptr<UIObject> WindowUIObject::get_visible_child(const OUString& rID)
466{
467 // in a first step try the real children before moving to the top level parent
468 // This makes it easier to handle cases with the same ID as there is a way
469 // to resolve conflicts
470 vcl::Window* pWindow = findChild(mxWindow.get(), rID, true);
471 if (!pWindow)
472 {
473 vcl::Window* pDialogParent = get_top_parent(mxWindow.get());
474 pWindow = findChild(pDialogParent, rID, true);
475 }
476
477 if (!pWindow)
478 throw css::uno::RuntimeException("Could not find child with id: " + rID);
479
480 FactoryFunction aFunction = pWindow->GetUITestFactory();
481 return aFunction(pWindow);
482}
483
484std::set<OUString> WindowUIObject::get_children() const
485{
486 vcl::Window* pDialogParent = get_top_parent(mxWindow.get());
487 std::set<OUString> aChildren;
488 aChildren.insert(pDialogParent->get_id());
489 addChildren(pDialogParent, aChildren);
490 return aChildren;
491}
492
493OUString WindowUIObject::get_name() const
494{
495 return "WindowUIObject";
496}
497
498namespace {
499
500OUString escape(const OUString& rStr)
501{
502 return rStr.replaceAll("\"", "\\\"");
503}
504
505}
506
507OUString WindowUIObject::dumpState() const
508{
509 OUStringBuffer aStateString = "{\"name\":\"" + mxWindow->get_id() + "\"";
510 aStateString.append(", \"ImplementationName\":\"").appendAscii(typeid(*mxWindow).name()).append("\"");
511 StringMap aState = const_cast<WindowUIObject*>(this)->get_state();
512 for (auto const& elem : aState)
513 {
514 OUString property = ",\"" + elem.first + "\":\"" + escape(elem.second) + "\"";
515 aStateString.append(property);
516 }
517
518 size_t nCount = mxWindow->GetChildCount();
519
520 if (nCount)
521 aStateString.append(",\"children\":[");
522
523 for (size_t i = 0; i < nCount; ++i)
524 {
525 if (i != 0)
526 {
527 aStateString.append(",");
528 }
529 vcl::Window* pChild = mxWindow->GetChild(i);
530 std::unique_ptr<UIObject> pChildWrapper =
531 pChild->GetUITestFactory()(pChild);
532 OUString children = pChildWrapper->dumpState();
533 aStateString.append(children);
534 }
535
536 if (nCount)
537 aStateString.append("]");
538
539 aStateString.append("}");
540
541 OUString aString = aStateString.makeStringAndClear();
542 return aString.replaceAll("\n", "\\n");
543}
544
545OUString WindowUIObject::dumpHierarchy() const
546{
547 vcl::Window* pDialogParent = get_top_parent(mxWindow.get());
548 std::unique_ptr<UIObject> pParentWrapper =
549 pDialogParent->GetUITestFactory()(pDialogParent);
550 return pParentWrapper->dumpState();
551}
552
553OUString WindowUIObject::get_action(VclEventId nEvent) const
554{
555
556 OUString aActionName;
557 switch (nEvent)
558 {
559 case VclEventId::ControlGetFocus:
560 case VclEventId::ControlLoseFocus:
561 return OUString();
562
563 case VclEventId::ButtonClick:
564 case VclEventId::CheckboxToggle:
565 aActionName = "CLICK";
566 break;
567
568 case VclEventId::EditModify:
569 aActionName = "TYPE";
570 break;
571 default:
572 aActionName = OUString::number(static_cast<int>(nEvent));
573 }
574 return "";
575 //return "Action on element: " + mxWindow->get_id() + " with action : " + aActionName;
576}
577
578std::unique_ptr<UIObject> WindowUIObject::create(vcl::Window* pWindow)
579{
580 return std::unique_ptr<UIObject>(new WindowUIObject(pWindow));
581}
582
583ButtonUIObject::ButtonUIObject(const VclPtr<Button>& xButton):
584 WindowUIObject(xButton),
585 mxButton(xButton)
586{
587}
588
589ButtonUIObject::~ButtonUIObject()
590{
591}
592
593StringMap ButtonUIObject::get_state()
594{
595 StringMap aMap = WindowUIObject::get_state();
596 // Move that to a Control base class
597 aMap["Label"] = mxButton->GetDisplayText();
598
599 return aMap;
600}
601
602void ButtonUIObject::execute(const OUString& rAction,
603 const StringMap& rParameters)
604{
605 if (rAction == "CLICK")
606 {
607 //Click doesn't call toggle when it's a pushbutton tweaked to be a toggle-button
608 if (PushButton *pPushButton = (mxButton->GetStyle() & WB_TOGGLE) ? dynamic_cast<PushButton*>(mxButton.get()) : nullptr)
609 {
610 pPushButton->Check(!pPushButton->IsChecked());
611 pPushButton->Toggle();
612 return;
613 }
614 mxButton->Click();
615 }
616 else
617 WindowUIObject::execute(rAction, rParameters);
618}
619
620OUString ButtonUIObject::get_name() const
621{
622 return "ButtonUIObject";
623}
624
625OUString ButtonUIObject::get_action(VclEventId nEvent) const
626{
627 if (nEvent == VclEventId::ButtonClick)
628 {
629 if(mxButton->get_id()=="writer_all")
630 {
631 UITestLogger::getInstance().setAppName("writer");
632 return "Start writer" ;
633 }
634 else if(mxButton->get_id()=="calc_all")
635 {
636 UITestLogger::getInstance().setAppName("calc");
637 return "Start calc" ;
638 }
639 else if(mxButton->get_id()=="impress_all")
640 {
641 UITestLogger::getInstance().setAppName("impress");
642 return "Start impress" ;
643 }
644 else if(mxButton->get_id()=="draw_all")
645 {
646 UITestLogger::getInstance().setAppName("draw");
647 return "Start draw" ;
648 }
649 else if(mxButton->get_id()=="math_all")
650 {
651 UITestLogger::getInstance().setAppName("math");
652 return "Start math" ;
653 }
654 else if(mxButton->get_id()=="database_all")
655 {
656 UITestLogger::getInstance().setAppName("database");
657 return "Start database" ;
658 }
659 else{
660 if (get_top_parent(mxButton)->get_id().isEmpty()){
661 //This part because if we don't have parent
662 return "Click on '" + mxButton->get_id() ;
663 }
664 return "Click on '" + mxButton->get_id() + "' from "+
665 get_top_parent(mxButton)->get_id();
666 }
667 }
668 else
669 return WindowUIObject::get_action(nEvent);
670}
671
672std::unique_ptr<UIObject> ButtonUIObject::create(vcl::Window* pWindow)
673{
674 Button* pButton = dynamic_cast<Button*>(pWindow);
675 assert(pButton)(static_cast <bool> (pButton) ? void (0) : __assert_fail
("pButton", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 675, __extension__ __PRETTY_FUNCTION__))
;
676 return std::unique_ptr<UIObject>(new ButtonUIObject(pButton));
677}
678
679DialogUIObject::DialogUIObject(const VclPtr<Dialog>& xDialog):
680 WindowUIObject(xDialog),
681 mxDialog(xDialog)
682{
683}
684
685DialogUIObject::~DialogUIObject()
686{
687}
688
689StringMap DialogUIObject::get_state()
690{
691 StringMap aMap = WindowUIObject::get_state();
692 aMap["Modal"] = OUString::boolean(mxDialog->IsModalInputMode());
693
694 return aMap;
695}
696
697OUString DialogUIObject::get_name() const
698{
699 return "DialogUIObject";
700}
701
702std::unique_ptr<UIObject> DialogUIObject::create(vcl::Window* pWindow)
703{
704 Dialog* pDialog = dynamic_cast<Dialog*>(pWindow);
705 assert(pDialog)(static_cast <bool> (pDialog) ? void (0) : __assert_fail
("pDialog", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 705, __extension__ __PRETTY_FUNCTION__))
;
706 return std::unique_ptr<UIObject>(new DialogUIObject(pDialog));
707}
708
709EditUIObject::EditUIObject(const VclPtr<Edit>& xEdit):
710 WindowUIObject(xEdit),
711 mxEdit(xEdit)
712{
713}
714
715EditUIObject::~EditUIObject()
716{
717}
718
719void EditUIObject::execute(const OUString& rAction,
720 const StringMap& rParameters)
721{
722 bool bHandled = true;
723 if (rAction == "SET")
724 {
725 if (rParameters.find("TEXT") != rParameters.end())
726 {
727 auto it = rParameters.find("TEXT");
728 if (it == rParameters.end())
729 {
730 SAL_WARN("vcl.uitest", "missing parameter TEXT to action SET")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "vcl.uitest")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "missing parameter TEXT to action SET"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"
), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "730" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "missing parameter TEXT to action SET"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "missing parameter TEXT to action SET"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "730" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "missing parameter TEXT to action SET") == 1) { ::
sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest")
, ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "730" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "missing parameter TEXT to action SET"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "missing parameter TEXT to action SET"; ::sal::detail
::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.uitest"), ("/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
":" "730" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
731 return;
732 }
733
734 const OUString& rText = it->second;
735 auto aKeyEvents = generate_key_events_from_text(rText);
736 for (auto const& keyEvent : aKeyEvents)
737 {
738 mxEdit->KeyInput(keyEvent);
739 }
740 }
741 else
742 {
743 bHandled = false;
744 }
745 }
746 else if (rAction == "SELECT")
747 {
748 if (rParameters.find("FROM") != rParameters.end() &&
749 rParameters.find("TO") != rParameters.end())
750 {
751 long nMin = rParameters.find("FROM")->second.toInt32();
752 long nMax = rParameters.find("TO")->second.toInt32();
753 Selection aSelection(nMin, nMax);
754 mxEdit->SetSelection(aSelection);
755 }
756 }
757 else if (rAction == "CLEAR")
758 {
759 mxEdit->SetText("");
760 mxEdit->Modify();
761 bHandled = true;
762 }
763 else
764 {
765 bHandled = false;
766 }
767
768 if (!bHandled)
769 WindowUIObject::execute(rAction, rParameters);
770}
771
772StringMap EditUIObject::get_state()
773{
774 StringMap aMap = WindowUIObject::get_state();
775 aMap["MaxTextLength"] = OUString::number(mxEdit->GetMaxTextLen());
776 aMap["SelectedText"] = mxEdit->GetSelected();
777 aMap["Text"] = mxEdit->GetText();
778
779 return aMap;
780}
781
782OUString EditUIObject::get_action(VclEventId nEvent) const
783{
784 if (nEvent == VclEventId::EditSelectionChanged)
785 {
786 const Selection& rSelection = mxEdit->GetSelection();
787 long nMin = rSelection.Min();
788 long nMax = rSelection.Max();
789 if(get_top_parent(mxEdit)->get_id().isEmpty()){
790 //This part because if we don't have parent
791 return "Select in '" +
792 mxEdit->get_id() +
793 "' {\"FROM\": \"" + OUString::number(nMin) + "\", \"TO\": \"" +
794 OUString::number(nMax) + "\"}"
795 ;
796 }
797 return "Select in '" +
798 mxEdit->get_id() +
799 "' {\"FROM\": \"" + OUString::number(nMin) + "\", \"TO\": \"" +
800 OUString::number(nMax) + "\"} from "
801 + get_top_parent(mxEdit)->get_id()
802 ;
803 }
804 else
805 return WindowUIObject::get_action(nEvent);
806}
807
808OUString EditUIObject::get_name() const
809{
810 return "EditUIObject";
811}
812
813std::unique_ptr<UIObject> EditUIObject::create(vcl::Window* pWindow)
814{
815 Edit* pEdit = dynamic_cast<Edit*>(pWindow);
816 assert(pEdit)(static_cast <bool> (pEdit) ? void (0) : __assert_fail (
"pEdit", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 816, __extension__ __PRETTY_FUNCTION__))
;
817 return std::unique_ptr<UIObject>(new EditUIObject(pEdit));
818}
819
820MultiLineEditUIObject::MultiLineEditUIObject(const VclPtr<VclMultiLineEdit>& xEdit):
821 WindowUIObject(xEdit),
822 mxEdit(xEdit)
823{
824}
825
826MultiLineEditUIObject::~MultiLineEditUIObject()
827{
828}
829
830void MultiLineEditUIObject::execute(const OUString& rAction,
831 const StringMap& rParameters)
832{
833 bool bHandled = true;
834 if (rAction == "TYPE")
835 {
836 WindowUIObject aChildObj(mxEdit->GetTextWindow());
837 aChildObj.execute(rAction, rParameters);
838 }
839 else if (rAction == "SELECT")
840 {
841 if (rParameters.find("FROM") != rParameters.end() &&
842 rParameters.find("TO") != rParameters.end())
843 {
844 long nMin = rParameters.find("FROM")->second.toInt32();
845 long nMax = rParameters.find("TO")->second.toInt32();
846 Selection aSelection(nMin, nMax);
847 mxEdit->SetSelection(aSelection);
848 }
849 }
850 else
851 {
852 bHandled = false;
853 }
854
855 if (!bHandled)
856 WindowUIObject::execute(rAction, rParameters);
857}
858
859StringMap MultiLineEditUIObject::get_state()
860{
861 StringMap aMap = WindowUIObject::get_state();
862 aMap["MaxTextLength"] = OUString::number(mxEdit->GetMaxTextLen());
863 aMap["SelectedText"] = mxEdit->GetSelected();
864 aMap["Text"] = mxEdit->GetText();
865
866 return aMap;
867}
868
869OUString MultiLineEditUIObject::get_name() const
870{
871 return "MultiLineEditUIObject";
872}
873
874std::unique_ptr<UIObject> MultiLineEditUIObject::create(vcl::Window* pWindow)
875{
876 VclMultiLineEdit* pEdit = dynamic_cast<VclMultiLineEdit*>(pWindow);
877 assert(pEdit)(static_cast <bool> (pEdit) ? void (0) : __assert_fail (
"pEdit", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 877, __extension__ __PRETTY_FUNCTION__))
;
878 return std::unique_ptr<UIObject>(new MultiLineEditUIObject(pEdit));
879}
880
881CheckBoxUIObject::CheckBoxUIObject(const VclPtr<CheckBox>& xCheckbox):
882 WindowUIObject(xCheckbox),
883 mxCheckBox(xCheckbox)
884{
885}
886
887CheckBoxUIObject::~CheckBoxUIObject()
888{
889}
890
891void CheckBoxUIObject::execute(const OUString& rAction,
892 const StringMap& /*rParameters*/)
893{
894 if (rAction == "CLICK")
895 {
896 // don't use toggle directly, it does not set the value
897 mxCheckBox->ImplCheck();
898 }
899}
900
901StringMap CheckBoxUIObject::get_state()
902{
903 StringMap aMap = WindowUIObject::get_state();
904 aMap["Selected"] = OUString::boolean(mxCheckBox->IsChecked());
905 aMap["TriStateEnabled"] = OUString::boolean(mxCheckBox->IsTriStateEnabled());
906 return aMap;
907}
908
909OUString CheckBoxUIObject::get_name() const
910{
911 return "CheckBoxUIObject";
912}
913
914OUString CheckBoxUIObject::get_action(VclEventId nEvent) const
915{
916 if (nEvent == VclEventId::CheckboxToggle)
917 {
918 if(get_top_parent(mxCheckBox)->get_id().isEmpty()){
919 //This part because if we don't have parent
920 return "Toggle '" + mxCheckBox->get_id() + "' CheckBox";
921 }
922 return "Toggle '" + mxCheckBox->get_id() + "' CheckBox from " +
923 get_top_parent(mxCheckBox)->get_id();
924 }
925 else
926 return WindowUIObject::get_action(nEvent);
927}
928
929std::unique_ptr<UIObject> CheckBoxUIObject::create(vcl::Window* pWindow)
930{
931 CheckBox* pCheckBox = dynamic_cast<CheckBox*>(pWindow);
932 assert(pCheckBox)(static_cast <bool> (pCheckBox) ? void (0) : __assert_fail
("pCheckBox", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 932, __extension__ __PRETTY_FUNCTION__))
;
933 return std::unique_ptr<UIObject>(new CheckBoxUIObject(pCheckBox));
934}
935
936RadioButtonUIObject::RadioButtonUIObject(const VclPtr<RadioButton>& xRadioButton):
937 WindowUIObject(xRadioButton),
938 mxRadioButton(xRadioButton)
939{
940}
941
942RadioButtonUIObject::~RadioButtonUIObject()
943{
944}
945
946void RadioButtonUIObject::execute(const OUString& rAction,
947 const StringMap& /*rParameters*/)
948{
949 if (rAction == "CLICK")
950 {
951 mxRadioButton->ImplCallClick();
952 }
953}
954
955StringMap RadioButtonUIObject::get_state()
956{
957 StringMap aMap = WindowUIObject::get_state();
958 aMap["Checked"] = OUString::boolean(mxRadioButton->IsChecked());
959
960 return aMap;
961}
962
963OUString RadioButtonUIObject::get_name() const
964{
965 return "RadioButtonUIObject";
966}
967
968OUString RadioButtonUIObject::get_action(VclEventId nEvent) const
969{
970 if (nEvent == VclEventId::RadiobuttonToggle)
971 {
972 if(get_top_parent(mxRadioButton)->get_id().isEmpty()){
973 //This part because if we don't have parent
974 return "Select '" + mxRadioButton->get_id() + "' RadioButton";
975 }
976 return "Select '" + mxRadioButton->get_id() + "' RadioButton from " +
977 get_top_parent(mxRadioButton)->get_id();
978 }
979 else
980 return WindowUIObject::get_action(nEvent);
981}
982
983std::unique_ptr<UIObject> RadioButtonUIObject::create(vcl::Window* pWindow)
984{
985 RadioButton* pRadioButton = dynamic_cast<RadioButton*>(pWindow);
986 assert(pRadioButton)(static_cast <bool> (pRadioButton) ? void (0) : __assert_fail
("pRadioButton", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 986, __extension__ __PRETTY_FUNCTION__))
;
987 return std::unique_ptr<UIObject>(new RadioButtonUIObject(pRadioButton));
988}
989
990TabPageUIObject::TabPageUIObject(const VclPtr<TabPage>& xTabPage):
991 WindowUIObject(xTabPage),
992 mxTabPage(xTabPage)
993{
994}
995
996TabPageUIObject::~TabPageUIObject()
997{
998}
999
1000void TabPageUIObject::execute(const OUString& rAction,
1001 const StringMap& /*rParameters*/)
1002{
1003 if (rAction == "SELECT")
1004 {
1005 /* code */
1006 }
1007}
1008
1009StringMap TabPageUIObject::get_state()
1010{
1011 StringMap aMap = WindowUIObject::get_state();
1012
1013 return aMap;
1014}
1015
1016OUString TabPageUIObject::get_name() const
1017{
1018 return "TabPageUIObject";
1019}
1020
1021ListBoxUIObject::ListBoxUIObject(const VclPtr<ListBox>& xListBox):
1022 WindowUIObject(xListBox),
1023 mxListBox(xListBox)
1024{
1025}
1026
1027ListBoxUIObject::~ListBoxUIObject()
1028{
1029}
1030
1031void ListBoxUIObject::execute(const OUString& rAction,
1032 const StringMap& rParameters)
1033{
1034 if (!mxListBox->IsEnabled())
1035 return;
1036
1037 bool isTiledRendering = comphelper::LibreOfficeKit::isActive();
1038 if (!isTiledRendering && !mxListBox->IsReallyVisible())
1039 return;
1040
1041 if (rAction == "SELECT")
1042 {
1043 bool bSelect = true;
1044 if (rParameters.find("POS") != rParameters.end())
1045 {
1046 auto itr = rParameters.find("POS");
1047 OUString aVal = itr->second;
1048 sal_Int32 nPos = aVal.toInt32();
1049 mxListBox->SelectEntryPos(nPos, bSelect);
1050 }
1051 else if (rParameters.find("TEXT") != rParameters.end())
1052 {
1053 auto itr = rParameters.find("TEXT");
1054 OUString aText = itr->second;
1055 mxListBox->SelectEntry(aText, bSelect);
1056 }
1057 mxListBox->Select();
1058 }
1059 else
1060 WindowUIObject::execute(rAction, rParameters);
1061}
1062
1063StringMap ListBoxUIObject::get_state()
1064{
1065 StringMap aMap = WindowUIObject::get_state();
1066 aMap["ReadOnly"] = OUString::boolean(mxListBox->IsReadOnly());
1067 aMap["MultiSelect"] = OUString::boolean(mxListBox->IsMultiSelectionEnabled());
1068 aMap["EntryCount"] = OUString::number(mxListBox->GetEntryCount());
1069 aMap["SelectEntryCount"] = OUString::number(mxListBox->GetSelectedEntryCount());
1070 aMap["SelectEntryPos"] = OUString::number(mxListBox->GetSelectedEntryPos());
1071 aMap["SelectEntryText"] = mxListBox->GetSelectedEntry();
1072
1073 return aMap;
1074}
1075
1076OUString ListBoxUIObject::get_name() const
1077{
1078 return "ListBoxUIObject";
1079}
1080
1081OUString ListBoxUIObject::get_action(VclEventId nEvent) const
1082{
1083 if (nEvent == VclEventId::ListboxSelect)
1084 {
1085 sal_Int32 nPos = mxListBox->GetSelectedEntryPos();
1086 if(get_top_parent(mxListBox)->get_id().isEmpty()){
1087 //This part because if we don't have parent
1088 return "Select element with position " + OUString::number(nPos) +
1089 " in '" + mxListBox->get_id();
1090 }
1091 return "Select element with position " + OUString::number(nPos) +
1092 " in '" + mxListBox->get_id() +"' from" + get_top_parent(mxListBox)->get_id() ;
1093 }
1094 else if (nEvent == VclEventId::ListboxFocus)
1095 {
1096 if(get_top_parent(mxListBox)->get_id().isEmpty())
1097 {
1098 //This part because if we don't have parent
1099 return this->get_type() + " Action:FOCUS Id:" + mxListBox->get_id();
1100 }
1101 return this->get_type() + " Action:FOCUS Id:" + mxListBox->get_id() +
1102 " Parent:" + get_top_parent(mxListBox)->get_id();
1103 }
1104 else
1105 return WindowUIObject::get_action(nEvent);
1106}
1107
1108std::unique_ptr<UIObject> ListBoxUIObject::create(vcl::Window* pWindow)
1109{
1110 ListBox* pListBox = dynamic_cast<ListBox*>(pWindow);
1111 assert(pListBox)(static_cast <bool> (pListBox) ? void (0) : __assert_fail
("pListBox", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1111, __extension__ __PRETTY_FUNCTION__))
;
1112 return std::unique_ptr<UIObject>(new ListBoxUIObject(pListBox));
1113}
1114
1115ComboBoxUIObject::ComboBoxUIObject(const VclPtr<ComboBox>& xComboBox):
1116 WindowUIObject(xComboBox),
1117 mxComboBox(xComboBox)
1118{
1119}
1120
1121ComboBoxUIObject::~ComboBoxUIObject()
1122{
1123}
1124
1125void ComboBoxUIObject::execute(const OUString& rAction,
1126 const StringMap& rParameters)
1127{
1128 if (rAction == "SELECT")
1129 {
1130 if (rParameters.find("POS") != rParameters.end())
1131 {
1132 auto itr = rParameters.find("POS");
1133 OUString aVal = itr->second;
1134 sal_Int32 nPos = aVal.toInt32();
1135 mxComboBox->SelectEntryPos(nPos);
1136 }
1137 else if(rParameters.find("TEXT") != rParameters.end()){
1138 auto itr = rParameters.find("TEXT");
1139 OUString aVal = itr->second;
1140 sal_Int32 nPos = mxComboBox->GetEntryPos(aVal);
1141 mxComboBox->SelectEntryPos(nPos);
1142 }
1143 mxComboBox->Select();
1144 }
1145 else if ( rAction == "TYPE" || rAction == "SET" || rAction == "CLEAR" ){
1146 if (mxComboBox->GetSubEdit())
1147 {
1148 Edit* pEdit = mxComboBox->GetSubEdit();
1149 std::unique_ptr<UIObject> pObj = EditUIObject::create(pEdit);
1150 pObj->execute(rAction, rParameters);
1151 }
1152 else
1153 WindowUIObject::execute(rAction, rParameters);
1154 }
1155 else
1156 WindowUIObject::execute(rAction, rParameters);
1157}
1158
1159StringMap ComboBoxUIObject::get_state()
1160{
1161 StringMap aMap = WindowUIObject::get_state();
1162 return aMap;
1163}
1164
1165OUString ComboBoxUIObject::get_name() const
1166{
1167 return "ComboBoxUIObject";
1168}
1169
1170OUString ComboBoxUIObject::get_action(VclEventId nEvent) const
1171{
1172 if (nEvent == VclEventId::ComboboxSelect)
1173 {
1174 sal_Int32 nPos = mxComboBox->GetSelectedEntryPos();
1175 if (get_top_parent(mxComboBox)->get_id().isEmpty()){
1176 //This part because if we don't have parent
1177 return "Select in '" + mxComboBox->get_id() +
1178 "' ComboBox item number " + OUString::number(nPos);
1179 }
1180 return "Select in '" + mxComboBox->get_id() +
1181 "' ComboBox item number " + OUString::number(nPos) +
1182 " from " + get_top_parent(mxComboBox)->get_id();
1183 }
1184 else
1185 return WindowUIObject::get_action(nEvent);
1186}
1187
1188std::unique_ptr<UIObject> ComboBoxUIObject::create(vcl::Window* pWindow)
1189{
1190 ComboBox* pComboBox = dynamic_cast<ComboBox*>(pWindow);
1191 assert(pComboBox)(static_cast <bool> (pComboBox) ? void (0) : __assert_fail
("pComboBox", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1191, __extension__ __PRETTY_FUNCTION__))
;
1192 return std::unique_ptr<UIObject>(new ComboBoxUIObject(pComboBox));
1193}
1194
1195SpinUIObject::SpinUIObject(const VclPtr<SpinButton>& xSpinButton):
1196 WindowUIObject(xSpinButton),
1197 mxSpinButton(xSpinButton)
1198{
1199}
1200
1201SpinUIObject::~SpinUIObject()
1202{
1203}
1204
1205void SpinUIObject::execute(const OUString& rAction,
1206 const StringMap& /*rParameters*/)
1207{
1208 if (rAction == "UP")
1209 {
1210 mxSpinButton->Up();
1211 }
1212 else if (rAction == "DOWN")
1213 {
1214 mxSpinButton->Down();
1215 }
1216}
1217
1218StringMap SpinUIObject::get_state()
1219{
1220 StringMap aMap = WindowUIObject::get_state();
1221 aMap["Min"] = OUString::number(mxSpinButton->GetRangeMin());
1222 aMap["Max"] = OUString::number(mxSpinButton->GetRangeMax());
1223 aMap["Step"] = OUString::number(mxSpinButton->GetValueStep());
1224 aMap["Value"] = OUString::number(mxSpinButton->GetValue());
1225
1226 return aMap;
1227}
1228
1229OUString SpinUIObject::get_action(VclEventId nEvent) const
1230{
1231 if (nEvent == VclEventId::SpinbuttonUp)
1232 {
1233 return this->get_type() + " Action:UP Id:" + mxSpinButton->get_id() +
1234 " Parent:" + get_top_parent(mxSpinButton)->get_id();
1235 }
1236 else if (nEvent == VclEventId::SpinbuttonDown)
1237 {
1238 return this->get_type() + " Action:DOWN Id:" + mxSpinButton->get_id() +
1239 " Parent:" + get_top_parent(mxSpinButton)->get_id();
1240 }
1241 else
1242 return WindowUIObject::get_action(nEvent);
1243}
1244
1245OUString SpinUIObject::get_name() const
1246{
1247 return "SpinUIObject";
1248}
1249
1250SpinFieldUIObject::SpinFieldUIObject(const VclPtr<SpinField>& xSpinField):
1251 EditUIObject(xSpinField),
1252 mxSpinField(xSpinField)
1253{
1254}
1255
1256SpinFieldUIObject::~SpinFieldUIObject()
1257{
1258}
1259
1260void SpinFieldUIObject::execute(const OUString& rAction,
1261 const StringMap& rParameters)
1262{
1263 if (rAction == "UP")
1264 {
1265 mxSpinField->Up();
1266 }
1267 else if (rAction == "DOWN")
1268 {
1269 mxSpinField->Down();
1270 }
1271 else if (rAction == "TYPE")
1272 {
1273 if (mxSpinField->GetSubEdit())
1274 {
1275 Edit* pSubEdit = mxSpinField->GetSubEdit();
1276 EditUIObject aSubObject(pSubEdit);
1277 aSubObject.execute(rAction, rParameters);
1278 }
1279 }
1280 else
1281 EditUIObject::execute(rAction, rParameters);
1282}
1283
1284StringMap SpinFieldUIObject::get_state()
1285{
1286 StringMap aMap = EditUIObject::get_state();
1287
1288 return aMap;
1289}
1290
1291OUString SpinFieldUIObject::get_action(VclEventId nEvent) const
1292{
1293 if (nEvent == VclEventId::SpinfieldUp)
1294 {
1295 if(get_top_parent(mxSpinField)->get_id().isEmpty())
1296 {
1297 //This part because if we don't have parent
1298 return "Increase '" + mxSpinField->get_id();
1299 }
1300 return "Increase '" + mxSpinField->get_id() +
1301 "' from " + get_top_parent(mxSpinField)->get_id();
1302 }
1303 else if (nEvent == VclEventId::SpinfieldDown)
1304 {
1305 if(get_top_parent(mxSpinField)->get_id().isEmpty())
1306 {
1307 //This part because if we don't have parent
1308 return "Decrease '" + mxSpinField->get_id();
1309 }
1310 return "Decrease '" + mxSpinField->get_id() +
1311 "' from " + get_top_parent(mxSpinField)->get_id();
1312 }
1313 else
1314 return WindowUIObject::get_action(nEvent);
1315}
1316
1317OUString SpinFieldUIObject::get_name() const
1318{
1319 return "SpinFieldUIObject";
1320}
1321
1322std::unique_ptr<UIObject> SpinFieldUIObject::create(vcl::Window* pWindow)
1323{
1324 SpinField* pSpinField = dynamic_cast<SpinField*>(pWindow);
1325 assert(pSpinField)(static_cast <bool> (pSpinField) ? void (0) : __assert_fail
("pSpinField", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1325, __extension__ __PRETTY_FUNCTION__))
;
1326 return std::unique_ptr<UIObject>(new SpinFieldUIObject(pSpinField));
1327}
1328
1329
1330MetricFieldUIObject::MetricFieldUIObject(const VclPtr<MetricField>& xMetricField):
1331 SpinFieldUIObject(xMetricField),
1332 mxMetricField(xMetricField)
1333{
1334}
1335
1336MetricFieldUIObject::~MetricFieldUIObject()
1337{
1338}
1339
1340void MetricFieldUIObject::execute(const OUString& rAction,
1341 const StringMap& rParameters)
1342{
1343 if (rAction == "VALUE")
1344 {
1345 auto itPos = rParameters.find("VALUE");
1346 if (itPos != rParameters.end())
1347 {
1348 mxMetricField->SetValueFromString(itPos->second);
1349 }
1350 }
1351 else
1352 SpinFieldUIObject::execute(rAction, rParameters);
1353}
1354
1355StringMap MetricFieldUIObject::get_state()
1356{
1357 StringMap aMap = EditUIObject::get_state();
1358 aMap["Value"] = mxMetricField->GetValueString();
1359
1360 return aMap;
1361}
1362
1363OUString MetricFieldUIObject::get_name() const
1364{
1365 return "MetricFieldUIObject";
1366}
1367
1368std::unique_ptr<UIObject> MetricFieldUIObject::create(vcl::Window* pWindow)
1369{
1370 MetricField* pMetricField = dynamic_cast<MetricField*>(pWindow);
1371 assert(pMetricField)(static_cast <bool> (pMetricField) ? void (0) : __assert_fail
("pMetricField", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1371, __extension__ __PRETTY_FUNCTION__))
;
1372 return std::unique_ptr<UIObject>(new MetricFieldUIObject(pMetricField));
1373}
1374
1375FormattedFieldUIObject::FormattedFieldUIObject(const VclPtr<FormattedField>& xFormattedField):
1376 SpinFieldUIObject(xFormattedField),
1377 mxFormattedField(xFormattedField)
1378{
1379}
1380
1381FormattedFieldUIObject::~FormattedFieldUIObject()
1382{
1383}
1384
1385void FormattedFieldUIObject::execute(const OUString& rAction,
1386 const StringMap& rParameters)
1387{
1388 if (rAction == "VALUE")
1389 {
1390 auto itPos = rParameters.find("VALUE");
1391 if (itPos != rParameters.end())
1392 {
1393 mxFormattedField->SetValueFromString(itPos->second);
1394 }
1395 }
1396 else
1397 SpinFieldUIObject::execute(rAction, rParameters);
1398}
1399
1400StringMap FormattedFieldUIObject::get_state()
1401{
1402 StringMap aMap = EditUIObject::get_state();
1403 aMap["Value"] = OUString::number(mxFormattedField->GetFormatter().GetValue());
1404
1405 return aMap;
1406}
1407
1408OUString FormattedFieldUIObject::get_name() const
1409{
1410 return "FormattedFieldUIObject";
1411}
1412
1413std::unique_ptr<UIObject> FormattedFieldUIObject::create(vcl::Window* pWindow)
1414{
1415 FormattedField* pFormattedField = dynamic_cast<FormattedField*>(pWindow);
1416 assert(pFormattedField)(static_cast <bool> (pFormattedField) ? void (0) : __assert_fail
("pFormattedField", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1416, __extension__ __PRETTY_FUNCTION__))
;
1417 return std::unique_ptr<UIObject>(new FormattedFieldUIObject(pFormattedField));
1418}
1419
1420TabControlUIObject::TabControlUIObject(const VclPtr<TabControl>& xTabControl):
1421 WindowUIObject(xTabControl),
1422 mxTabControl(xTabControl)
1423{
1424}
1425
1426TabControlUIObject::~TabControlUIObject()
1427{
1428}
1429
1430void TabControlUIObject::execute(const OUString& rAction,
1431 const StringMap& rParameters)
1432{
1433 if (rAction == "SELECT")
1434 {
1435 if (rParameters.find("POS") != rParameters.end())
1436 {
1437 auto itr = rParameters.find("POS");
1438 sal_uInt32 nPos = itr->second.toUInt32();
1439 std::vector<sal_uInt16> aIds = mxTabControl->GetPageIDs();
1440 mxTabControl->SelectTabPage(aIds[nPos]);
1441 }
1442 }
1443 else
1444 WindowUIObject::execute(rAction, rParameters);
1445}
1446
1447StringMap TabControlUIObject::get_state()
1448{
1449 StringMap aMap = WindowUIObject::get_state();
1450 aMap["PageCount"] = OUString::number(mxTabControl->GetPageCount());
1451
1452 sal_uInt16 nPageId = mxTabControl->GetCurPageId();
1453 aMap["CurrPageId"] = OUString::number(nPageId);
1454 aMap["CurrPagePos"] = OUString::number(mxTabControl->GetPagePos(nPageId));
1455
1456 return aMap;
1457}
1458
1459OUString TabControlUIObject::get_action(VclEventId nEvent) const
1460{
1461 if (nEvent == VclEventId::TabpageActivate)
1462 {
1463 sal_Int32 nPageId = mxTabControl->GetCurPageId();
1464
1465 if(get_top_parent(mxTabControl)->get_id().isEmpty()){
1466 //This part because if we don't have parent
1467 return "Choose Tab number " + OUString::number(mxTabControl->GetPagePos(nPageId)) +
1468 " in '" + mxTabControl->get_id();
1469 }
1470 return "Choose Tab number " + OUString::number(mxTabControl->GetPagePos(nPageId)) +
1471 " in '" + mxTabControl->get_id()+
1472 "' from " + get_top_parent(mxTabControl)->get_id() ;
1473 }
1474 else
1475 return WindowUIObject::get_action(nEvent);
1476}
1477
1478OUString TabControlUIObject::get_name() const
1479{
1480 return "TabControlUIObject";
1481}
1482
1483std::unique_ptr<UIObject> TabControlUIObject::create(vcl::Window* pWindow)
1484{
1485 TabControl* pTabControl = dynamic_cast<TabControl*>(pWindow);
1486 assert(pTabControl)(static_cast <bool> (pTabControl) ? void (0) : __assert_fail
("pTabControl", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1486, __extension__ __PRETTY_FUNCTION__))
;
1487 return std::unique_ptr<UIObject>(new TabControlUIObject(pTabControl));
1488}
1489
1490RoadmapWizardUIObject::RoadmapWizardUIObject(const VclPtr<vcl::RoadmapWizard>& xRoadmapWizard):
1491 WindowUIObject(xRoadmapWizard),
1492 mxRoadmapWizard(xRoadmapWizard)
1493{
1494}
1495
1496RoadmapWizardUIObject::~RoadmapWizardUIObject()
1497{
1498}
1499
1500void RoadmapWizardUIObject::execute(const OUString& rAction,
1501 const StringMap& rParameters)
1502{
1503 if (rAction == "SELECT")
1504 {
1505 if (rParameters.find("POS") != rParameters.end())
1506 {
1507 auto itr = rParameters.find("POS");
1508 sal_uInt32 nPos = itr->second.toUInt32();
1509 mxRoadmapWizard->SelectRoadmapItemByID(nPos);
1510 }
1511 }
1512 else
1513 WindowUIObject::execute(rAction, rParameters);
1514}
1515
1516StringMap RoadmapWizardUIObject::get_state()
1517{
1518 StringMap aMap = WindowUIObject::get_state();
1519
1520 aMap["CurrentStep"] = OUString::number(mxRoadmapWizard->GetCurrentRoadmapItemID());
1521
1522 return aMap;
1523}
1524
1525OUString RoadmapWizardUIObject::get_name() const
1526{
1527 return "RoadmapWizardUIObject";
1528}
1529
1530std::unique_ptr<UIObject> RoadmapWizardUIObject::create(vcl::Window* pWindow)
1531{
1532 vcl::RoadmapWizard* pRoadmapWizard = dynamic_cast<vcl::RoadmapWizard*>(pWindow);
1533 assert(pRoadmapWizard)(static_cast <bool> (pRoadmapWizard) ? void (0) : __assert_fail
("pRoadmapWizard", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1533, __extension__ __PRETTY_FUNCTION__))
;
1534 return std::unique_ptr<UIObject>(new RoadmapWizardUIObject(pRoadmapWizard));
1535}
1536
1537VerticalTabControlUIObject::VerticalTabControlUIObject(const VclPtr<VerticalTabControl>& xTabControl):
1538 WindowUIObject(xTabControl),
1539 mxTabControl(xTabControl)
1540{
1541}
1542
1543VerticalTabControlUIObject::~VerticalTabControlUIObject()
1544{
1545}
1546
1547void VerticalTabControlUIObject::execute(const OUString& rAction,
1548 const StringMap& rParameters)
1549{
1550 if (rAction == "SELECT")
1551 {
1552 if (rParameters.find("POS") != rParameters.end())
1553 {
1554 auto itr = rParameters.find("POS");
1555 sal_uInt32 nPos = itr->second.toUInt32();
1556 OString xid = mxTabControl->GetPageId(nPos);
1557 mxTabControl->SetCurPageId(xid);
1558 }
1559 }
1560 else
1561 WindowUIObject::execute(rAction, rParameters);
1562}
1563
1564StringMap VerticalTabControlUIObject::get_state()
1565{
1566 StringMap aMap = WindowUIObject::get_state();
1567 aMap["PageCount"] = OUString::number(mxTabControl->GetPageCount());
1568
1569 OString nPageId = mxTabControl->GetCurPageId();
1570 aMap["CurrPageTitel"] = mxTabControl->GetPageText(nPageId);
1571 aMap["CurrPagePos"] = OUString::number(mxTabControl->GetPagePos(nPageId));
1572
1573 return aMap;
1574}
1575
1576OUString VerticalTabControlUIObject::get_name() const
1577{
1578 return "VerticalTabControlUIObject";
1579}
1580
1581std::unique_ptr<UIObject> VerticalTabControlUIObject::create(vcl::Window* pWindow)
1582{
1583 VerticalTabControl* pTabControl = dynamic_cast<VerticalTabControl*>(pWindow);
1584 assert(pTabControl)(static_cast <bool> (pTabControl) ? void (0) : __assert_fail
("pTabControl", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1584, __extension__ __PRETTY_FUNCTION__))
;
1585 return std::unique_ptr<UIObject>(new VerticalTabControlUIObject(pTabControl));
1586}
1587
1588
1589ToolBoxUIObject::ToolBoxUIObject(const VclPtr<ToolBox>& xToolBox):
1590 WindowUIObject(xToolBox),
1591 mxToolBox(xToolBox)
1592{
1593}
1594
1595ToolBoxUIObject::~ToolBoxUIObject()
1596{
1597}
1598
1599void ToolBoxUIObject::execute(const OUString& rAction,
1600 const StringMap& rParameters)
1601{
1602 if (rAction == "CLICK")
1603 {
1604 if (rParameters.find("POS") != rParameters.end())
1605 {
1606 auto itr = rParameters.find("POS");
1607 sal_uInt16 nPos = itr->second.toUInt32();
1608 mxToolBox->SetCurItemId(nPos);
1609 mxToolBox->Click();
1610 mxToolBox->Select();
1611 }
1612 }
1613 else
1614 WindowUIObject::execute(rAction, rParameters);
1615}
1616
1617OUString ToolBoxUIObject::get_action(VclEventId nEvent) const
1618{
1619 if (nEvent == VclEventId::ToolboxClick)
1620 {
1621 return "Click on item number " + OUString::number(mxToolBox->GetCurItemId()) +
1622 " in " + mxToolBox->get_id();
1623 }
1624 else
1625 return WindowUIObject::get_action(nEvent);
1626}
1627
1628StringMap ToolBoxUIObject::get_state()
1629{
1630 StringMap aMap = WindowUIObject::get_state();
1631 aMap["CurrSelectedItemID"] = OUString::number(mxToolBox->GetCurItemId());
1632 aMap["CurrSelectedItemText"] = mxToolBox->GetItemText(mxToolBox->GetCurItemId());
1633 aMap["CurrSelectedItemCommand"] = mxToolBox->GetItemCommand(mxToolBox->GetCurItemId());
1634 aMap["ItemCount"] = OUString::number(mxToolBox->GetItemCount());
1635 return aMap;
1636}
1637
1638OUString ToolBoxUIObject::get_name() const
1639{
1640 return "ToolBoxUIObject";
1641}
1642
1643std::unique_ptr<UIObject> ToolBoxUIObject::create(vcl::Window* pWindow)
1644{
1645 ToolBox* pToolBox = dynamic_cast<ToolBox*>(pWindow);
1646 assert(pToolBox)(static_cast <bool> (pToolBox) ? void (0) : __assert_fail
("pToolBox", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1646, __extension__ __PRETTY_FUNCTION__))
;
1647 return std::unique_ptr<UIObject>(new ToolBoxUIObject(pToolBox));
1648}
1649
1650MenuButtonUIObject::MenuButtonUIObject(const VclPtr<MenuButton>& xMenuButton):
1651 WindowUIObject(xMenuButton),
4
Calling implicit destructor for 'VclPtr<vcl::Window>'
5
Calling '~Reference'
12
Returning from '~Reference'
13
Returning from destructor for 'VclPtr<vcl::Window>'
1652 mxMenuButton(xMenuButton)
14
Calling implicit copy constructor for 'VclPtr<MenuButton>'
15
Calling copy constructor for 'Reference<MenuButton>'
1653{
1654}
1655
1656MenuButtonUIObject::~MenuButtonUIObject()
1657{
1658}
1659
1660StringMap MenuButtonUIObject::get_state()
1661{
1662 StringMap aMap = WindowUIObject::get_state();
1663 aMap["Label"] = mxMenuButton->GetDisplayText();
1664 return aMap;
1665}
1666
1667void MenuButtonUIObject::execute(const OUString& rAction,
1668 const StringMap& rParameters)
1669{
1670 if (rAction == "CLICK")
1671 {
1672 mxMenuButton->Check(!mxMenuButton->IsChecked());
1673 mxMenuButton->Toggle();
1674 }
1675 else if (rAction == "OPENLIST")
1676 {
1677 mxMenuButton->ExecuteMenu();
1678 }
1679 else if (rAction == "OPENFROMLIST")
1680 {
1681 auto itr = rParameters.find("POS");
1682 sal_uInt32 nPos = itr->second.toUInt32();
1683
1684 sal_uInt32 nId = mxMenuButton->GetPopupMenu()->GetItemId(nPos);
1685 mxMenuButton->GetPopupMenu()->SetSelectedEntry(nId);
1686 mxMenuButton->SetCurItemId();
1687 mxMenuButton->Select();
1688 }
1689 else if (rAction == "CLOSELIST")
1690 {
1691 mxMenuButton->GetPopupMenu()->EndExecute();
1692 }
1693 else
1694 WindowUIObject::execute(rAction, rParameters);
1695}
1696
1697OUString MenuButtonUIObject::get_name() const
1698{
1699 return "MenuButtonUIObject";
1700}
1701
1702std::unique_ptr<UIObject> MenuButtonUIObject::create(vcl::Window* pWindow)
1703{
1704 MenuButton* pMenuButton = dynamic_cast<MenuButton*>(pWindow);
1705 assert(pMenuButton)(static_cast <bool> (pMenuButton) ? void (0) : __assert_fail
("pMenuButton", "/home/maarten/src/libreoffice/core/vcl/source/uitest/uiobject.cxx"
, 1705, __extension__ __PRETTY_FUNCTION__))
;
1
Assuming 'pMenuButton' is non-null
2
'?' condition is true
1706 return std::unique_ptr<UIObject>(new MenuButtonUIObject(pMenuButton));
3
Calling constructor for 'MenuButtonUIObject'
1707}
1708
1709/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody
15.1
Field 'm_pBody' is non-null
15.1
Field 'm_pBody' is non-null
15.1
Field 'm_pBody' is non-null
)
16
Taking true branch
77 m_pBody->acquire();
17
Use of memory after it is freed
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
5.1
Field 'm_pBody' is non-null
)
6
Taking true branch
113 m_pBody->release();
7
Calling 'VclReferenceBase::release'
11
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/vcl/vclreferencebase.hxx

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 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_VCL_Reference_HXX
20#define INCLUDED_VCL_Reference_HXX
21
22#include <vcl/dllapi.h>
23#include <osl/interlck.h>
24
25class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase
26{
27 mutable oslInterlockedCount mnRefCnt;
28
29 template<typename T> friend class VclPtr;
30
31public:
32 void acquire() const
33 {
34 osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1);
35 }
36
37 void release() const
38 {
39 if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0)
8
Assuming the condition is true
9
Taking true branch
40 delete this;
10
Memory is released
41 }
42#ifdef DBG_UTIL
43#ifndef _WIN32
44 sal_Int32 getRefCount() const { return mnRefCnt; }
45#endif
46#endif
47
48
49private:
50 VclReferenceBase(const VclReferenceBase&) = delete;
51 VclReferenceBase& operator=(const VclReferenceBase&) = delete;
52
53 bool mbDisposed : 1;
54
55protected:
56 VclReferenceBase();
57protected:
58 virtual ~VclReferenceBase();
59
60protected:
61 virtual void dispose();
62
63public:
64 void disposeOnce();
65 bool isDisposed() const { return mbDisposed; }
66
67};
68#endif